<!DOCTYPE html> <html lang="fa" dir="rtl"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"> <meta name="theme-color" content="#071722"> <title>رهپویان وصال | گروه امام حسن (ع)</title> <script src="https://cdn.jsdelivr.net/npm/lucide@0.468.0/dist/umd/lucide.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/qrcode@1.5.4/build/qrcode.min.js"></script> <script src="https://unpkg.com/html5-qrcode"></script> <style> :root{color-scheme:dark;--bg:#06151e;--panel:#102631df;--panel2:#17343a;--ink:#f7f1e4;--muted:#b9c7c5;--gold:#e6ca82;--teal:#39c9ba;--red:#c94c5b;--line:#dec47744;--shadow:0 18px 48px #0006;--r:22px} *{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;min-height:100vh;color:var(--ink);font-family:'Vazirmatn',system-ui,sans-serif;line-height:1.85;background:radial-gradient(ellipse at 50% -15%,#1a5360 0,transparent 55%),radial-gradient(ellipse at 90% 55%,#115b5840,transparent 35%),linear-gradient(145deg,#06151e,#08242e 65%,#062b30);padding-bottom:94px} body:before{content:"";position:fixed;inset:0;pointer-events:none;opacity:.045;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'%3E%3Cg fill='none' stroke='%23e6ca82' stroke-width='1'%3E%3Cpath d='M50 3 61 25 85 15 75 39 97 50 75 61 85 85 61 75 50 97 39 75 15 85 25 61 3 50 25 39 15 15 39 25Z'/%3E%3Ccircle cx='50' cy='50' r='18'/%3E%3C/g%3E%3C/svg%3E");z-index:-1} body:after{content:"";position:fixed;inset:0;pointer-events:none;background-image:radial-gradient(1px 1px at 12% 23%,#fff 50%,transparent),radial-gradient(1px 1px at 78% 17%,#fff 50%,transparent),radial-gradient(1px 1px at 35% 75%,#ffe7a0 50%,transparent),radial-gradient(1px 1px at 90% 62%,#fff 50%,transparent);background-size:190px 170px;opacity:.28;animation:twinkle 6s ease-in-out infinite alternate;z-index:-1} @keyframes twinkle{to{opacity:.1}}@keyframes enter{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}} button,input,select,textarea{font:inherit}button{cursor:pointer;color:var(--ink);background:linear-gradient(135deg,#14786f,#17585c);border:1px solid #51c5b34b;border-radius:15px;padding:10px 15px;transition:transform .18s,filter .18s,box-shadow .18s}button:hover{transform:translateY(-2px);filter:brightness(1.12);box-shadow:0 7px 18px #0004}button:active{transform:scale(.98)}button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:2px solid var(--gold);outline-offset:2px}.secondary{background:#18343b;border-color:var(--line)}.danger{background:#752f3b;border-color:#ee8290}.gold{background:linear-gradient(135deg,#96713a,#665025)}.small{padding:6px 10px;font-size:.86rem}.disabled{opacity:.55;cursor:not-allowed}.wrap{width:min(1020px,100%);margin:auto;padding:14px}.top{position:sticky;top:0;z-index:4;background:#071923df;border-bottom:1px solid var(--line);backdrop-filter:blur(18px)}.topin{max-width:1020px;margin:auto;padding:9px 16px;display:flex;align-items:center;justify-content:space-between;gap:10px}.brand{font-weight:900;color:var(--gold);font-size:1.05rem}.brand small{display:block;color:var(--muted);font-weight:400;font-size:.75rem}.userbox{display:flex;align-items:center;gap:8px}.avatar{width:40px;height:40px;border-radius:50%;display:grid;place-items:center;background:linear-gradient(140deg,var(--gold),#8b6b2f);color:#17212a;font-weight:900}.online{color:#84e4bf}.offline{color:#ffb5a9}.card{background:linear-gradient(145deg,#14303bdc,#102631e8);border:1px solid var(--line);border-radius:var(--r);padding:18px;margin:13px 0;box-shadow:var(--shadow);backdrop-filter:blur(12px);animation:enter .3s ease both}.card h2,.card h3{color:var(--gold)}h1,h2,h3,p{margin-top:0}h2{font-size:1.15rem;margin-bottom:12px}h3{font-size:1rem}.muted{color:var(--muted);font-size:.88rem}.row{display:flex;align-items:end;gap:9px;flex-wrap:wrap}.row>*{flex:1}.row .fit{flex:0 0 auto}.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(135px,1fr));gap:11px}.tiles{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:11px}.tile{min-height:105px;text-align:start;background:linear-gradient(145deg,#17434a,#102a36);border-color:var(--line)}.tile i{display:block;color:var(--gold);margin-bottom:6px}.tile b{display:block}.stat{padding:13px;border-radius:17px;background:#13343b;border:1px solid var(--line)}.stat b{display:block;color:var(--gold);font-size:1.25rem}.field{margin:11px 0}label{display:block;font-size:.9rem;margin:7px 0 4px}input,select,textarea{width:100%;border:1px solid #c1d3ce35;border-radius:12px;padding:10px 12px;background:#091c26;color:var(--ink)}textarea{min-height:78px;resize:vertical}.check{display:flex;align-items:center;gap:8px}.check input{width:auto}.pill{display:inline-block;border-radius:99px;padding:2px 10px;background:#d5b54b21;color:var(--gold);font-size:.78rem;border:1px solid #d5b54b38}.notice{background:linear-gradient(120deg,#59252c,#351d2b);border-color:#e06973;border-inline-start:5px solid #ff6472}.table-wrap{overflow:auto}table{border-collapse:collapse;width:100%;min-width:580px}th,td{padding:9px;text-align:start;border-bottom:1px solid #ffffff18;font-size:.88rem}th{color:var(--gold)}.bottom{position:fixed;z-index:5;bottom:0;inset-inline:0;background:#081a23ef;border-top:1px solid var(--line);backdrop-filter:blur(18px);padding-bottom:env(safe-area-inset-bottom)}.nav{max-width:650px;margin:auto;display:grid;grid-template-columns:repeat(5,1fr)}.nav button{background:transparent;border:0;border-radius:0;color:var(--muted);padding:7px 2px;font-size:.72rem}.nav button.active{color:var(--gold);border-top:2px solid var(--gold)}.nav i{display:block;width:21px;height:21px;margin:auto}.empty{text-align:center;padding:20px;color:var(--muted)}.login{max-width:450px;margin:7vh auto}.login .card{padding:25px}.dome{height:115px;display:grid;place-items:center;border-radius:17px;background:radial-gradient(ellipse at 50% 100%,#32827a,#10232e 72%);margin-bottom:17px;color:var(--gold);font-size:2.5rem}.quote-ar{font-family:'Amiri','Vazirmatn',serif;font-size:1.35rem;color:#f4e3b3;line-height:2.2}.goldbar{display:flex;align-items:center;justify-content:space-between;gap:10px;background:linear-gradient(100deg,#725823,#b48a3c,#725823);border:1px solid #ffe6a3;border-radius:16px;padding:11px 13px;color:#fff8df;margin:13px 0;box-shadow:0 0 24px #d7b34b38}.goldbar p{margin:0;font-weight:700}.bubble{padding:10px 12px;background:#203a40;border-radius:15px;max-width:88%;margin:8px 0}.bubble.mine{background:#175c52;margin-inline-start:auto}.hidden{display:none!important}.tabs{display:flex;gap:7px;overflow:auto;padding:5px 0}.tabs button{white-space:nowrap}.warning-item{border-bottom:1px solid #ffffff1b;padding:9px 0}.section-title{display:flex;align-items:center;justify-content:space-between;gap:8px}.sun{font-size:1.15rem;text-align:center;padding:14px;background:linear-gradient(120deg,#12373a,#413526);border:1px solid var(--line);border-radius:16px}.qrbox{text-align:center;padding:20px}.qrbox canvas{background:white;padding:10px;border-radius:12px;max-width:100%} @media(min-width:700px){.tiles{grid-template-columns:repeat(3,1fr)}.wrap{padding:20px}} @media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important}} @media print{body{background:white;color:#111}.top,.bottom,button{display:none!important}.card{background:white;color:#111;box-shadow:none;border:1px solid #aaa}.muted{color:#444}} </style> </head> <body><div id="app"></div> <script> (()=>{'use strict'; const KEY='rahpouyan_v9',API=window.API_URL||'',BASE=[{id:'futsal',name:'سالن فوتسال',icon:'trophy',score:1},{id:'heyat',name:'هیئت هفتگی',icon:'landmark',score:1,summary:true},{id:'culture',name:'جلسات فرهنگی',icon:'book-open',score:1,summary:true},{id:'marefat',name:'طرح معرفت',icon:'sprout',score:2,task:true}]; const HADITH=[ {ar:'إِنَّ مَعَ الْعُسْرِ يُسْرًا',fa:'همراه دشواری، آسانی است.',src:'قرآن کریم، سوره شرح، آیه ۶'}, {ar:'وَهُوَ مَعَكُمْ أَيْنَ مَا كُنْتُمْ',fa:'و هر جا باشید، او با شماست.',src:'قرآن کریم، سوره حدید، آیه ۴'}, {ar:'فَاذْكُرُونِي أَذْكُرْكُمْ',fa:'پس مرا یاد کنید تا شما را یاد کنم.',src:'قرآن کریم، سوره بقره، آیه ۱۵۲'}, {ar:'إِنَّ اللَّهَ مَعَ الصَّابِرِينَ',fa:'همانا خداوند با شکیبایان است.',src:'قرآن کریم، سوره بقره، آیه ۱۵۳'}, {ar:'وَقُلْ رَبِّ زِدْنِي عِلْمًا',fa:'و بگو: پروردگارا، بر دانشم بیفزا.',src:'قرآن کریم، سوره طه، آیه ۱۱۴'}, {ar:'إِنَّ أَكْرَمَكُمْ عِنْدَ اللَّهِ أَتْقَاكُمْ',fa:'گرامیترین شما نزد خدا، پرهیزکارترین شماست.',src:'قرآن کریم، سوره حجرات، آیه ۱۳'}, {ar:'ادْعُونِي أَسْتَجِبْ لَكُمْ',fa:'مرا بخوانید تا شما را اجابت کنم.',src:'قرآن کریم، سوره غافر، آیه ۶۰'}, {ar:'وَبَشِّرِ الصَّابِرِينَ',fa:'و شکیبایان را بشارت ده.',src:'قرآن کریم، سوره بقره، آیه ۱۵۵'}, {ar:'إِنَّ اللَّهَ يُحِبُّ الْمُحْسِنِينَ',fa:'خداوند نیکوکاران را دوست دارد.',src:'قرآن کریم، سوره بقره، آیه ۱۹۵'}, {ar:'وَقُولُوا لِلنَّاسِ حُسْنًا',fa:'با مردم به نیکی سخن بگویید.',src:'قرآن کریم، سوره بقره، آیه ۸۳'}, {ar:'لَا تَقْنَطُوا مِنْ رَحْمَةِ اللَّهِ',fa:'از رحمت خدا نومید نشوید.',src:'قرآن کریم، سوره زمر، آیه ۵۳'}, {ar:'وَمَنْ يَتَوَكَّلْ عَلَى اللَّهِ فَهُوَ حَسْبُهُ',fa:'هر کس بر خدا توکل کند، خدا او را بس است.',src:'قرآن کریم، سوره طلاق، آیه ۳'}, {ar:'إِنَّ اللَّهَ يُحِبُّ التَّوَّابِينَ',fa:'خداوند توبهکنندگان را دوست دارد.',src:'قرآن کریم، سوره بقره، آیه ۲۲۲'}, {ar:'وَاصْبِرْ وَمَا صَبْرُكَ إِلَّا بِاللَّهِ',fa:'شکیبا باش که شکیبایی تو جز به یاری خدا نیست.',src:'قرآن کریم، سوره نحل، آیه ۱۲۷'}, {ar:'إِنَّمَا الْمُؤْمِنُونَ إِخْوَةٌ',fa:'مؤمنان با یکدیگر برادرند.',src:'قرآن کریم، سوره حجرات، آیه ۱۰'} ]; const DUAS=[['دعای عهد','هر صبح برای تجدید پیمان با امام زمان (عج)'],['زیارت آل یاسین','زیارت امام عصر (عج)'],['دعای توسل','توسل به پیامبر و اهلبیت (ع)'],['دعای کمیل','دعای مناجات و طلب آمرزش'],['دعای ندبه','مناجات و شوق دیدار امام زمان (عج)'],['دعای فرج','دعای گشایش: اَللّهُمَّ عَظُمَ الْبَلاءُ'],['زیارت عاشورا','یاد و بزرگداشت قیام امام حسین (ع)'],['حدیث کسا','حدیث شریف اهل کسا'],['دعای سمات','دعای عصر جمعه']]; let state=null,me=null,tab='home',page='main',filterSec='all',online=false,chatRoom='',qrScanner=null,charts=[]; const $=s=>document.querySelector(s),esc=x=>String(x??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])),fa=n=>new Intl.NumberFormat('fa-IR').format(Number(n)||0),uid=()=>Math.random().toString(36).slice(2,10),today=()=>new Date().toISOString().slice(0,10),dateFa=s=>s?new Date(s+'T12:00:00').toLocaleDateString('fa-IR-u-ca-persian'):'—'; const members=()=>state.users.filter(u=>u.role==='member'&&u.active!==false),U=id=>state.users.find(u=>u.id===id),S=id=>state.sections.find(s=>s.id===id),isAdmin=()=>['admin','permanent'].includes(me?.role),can=id=>isAdmin()||me?.responsibilities?.includes(id),icon=(n,z=20)=>`<i data-lucide="${n}" style="width:${z}px;height:${z}px;vertical-align:middle"></i>`; function blank(){return{users:[],sections:structuredClone(BASE),records:[],rooms:[{id:'public',name:'گروه عمومی',type:'group',members:[]}],messages:[],notice:'',hadiths:HADITH,events:[],awards:[],debts:[],leaves:[],warnings:[],polls:[],news:[],duas:DUAS.map(([title,desc])=>({title,desc,text:'',translation:'',audio:''})),posts:[],trips:[],settings:{absencePenalty:0,latePenalty:0,salawat:0,salawatUsers:{},summaryHeyat:1,summaryCulture:1,taskMarefat:1,merchant:''},birthdaySent:{}}} function passHash(p,salt='rv-salt'){return crypto.subtle.digest('SHA-256',new TextEncoder().encode(salt+':'+p)).then(b=>[...new Uint8Array(b)].map(x=>x.toString(16).padStart(2,'0')).join(''))} async function encryptPass(p){try{let k=await crypto.subtle.importKey('raw',new TextEncoder().encode('rahpouyan-local-demo-aes-key-v1'),{name:'AES-GCM'},false,['encrypt']);let iv=crypto.getRandomValues(new Uint8Array(12)),ct=await crypto.subtle.encrypt({name:'AES-GCM',iv},k,new TextEncoder().encode(p));return btoa(String.fromCharCode(...iv,...new Uint8Array(ct)))}catch{return''}} async function decryptPass(x){try{let a=Uint8Array.from(atob(x),c=>c.charCodeAt(0)),k=await crypto.subtle.importKey('raw',new TextEncoder().encode('rahpouyan-local-demo-aes-key-v1'),{name:'AES-GCM'},false,['decrypt']);return new TextDecoder().decode(await crypto.subtle.decrypt({name:'AES-GCM',iv:a.slice(0,12)},k,a.slice(12)))}catch{return'—'}} async function account(id,username,password,name,role='member',done=true){state.users.push({id,username,name,role,active:true,phone:done?'09120000000':'',birth:done?'۱۳۸۷/۰۴/۱۵':'',welcomeDone:done,responsibilities:role==='member'?BASE.map(x=>x.id):[],passHash:await passHash(password,username),passEnc:await encryptPass(password)})} async function seed(){state=blank();await account('admin','admin','admin','مدیر اصلی','admin');await account('arch','404','404','دفترچه حسابها','vault');await account('u0','1234','1234','عضو نمونه حسن یادگار','member',false);await account('s1','student1','1234','دانشآموز نمونه یک');await account('s2','student2','1234','دانشآموز نمونه دو');await account('p1','permanent1','1234','ادمین همیشگی نمونه','permanent');await account('m1','member1','1234','علی رضایی');await account('m2','member2','1234','فاطمه حسینی');await account('m3','member3','1234','حسن یادگار'); state.users.find(u=>u.id==='p1').responsibilities=BASE.map(s=>s.id);state.rooms[0].members=members().map(u=>u.id); for(let w=0;w<6;w++)for(const s of state.sections){let d=new Date();d.setDate(d.getDate()-7*w);let r={id:uid(),sectionId:s.id,date:d.toISOString().slice(0,10),entries:{}};members().forEach((u,i)=>r.entries[u.id]={status:(i+w)%8===0?'absent':(i+w)%11===0?'late':'present',summary:!!s.summary&&(i+w)%3===0,task:!!s.task&&(i+w)%2===0});state.records.push(r)} state.notice='جلسه این هفته طبق برنامه برگزار میشود. لطفاً حضور بهموقع داشته باشید.';state.events.push({id:uid(),title:'جلسه هفتگی گروه',date:today()}); state.trips=[{id:uid(),title:'اردوی فرهنگی رایگان',desc:'اردوی یکروزه گروهی',date:today(),place:'حسینیه',capacity:30,kind:'free',amount:0,members:[],registrations:{}},{id:uid(),title:'اردوی زیارتی',desc:'ثبتنام و هماهنگی با مدیریت',date:today(),place:'قم',capacity:20,kind:'money',amount:250000,card:'6037-0000-0000-0000',owner:'مدیریت مجموعه',discount:0,members:[],registrations:{}},{id:uid(),title:'اردوی امتیازی',desc:'هزینه با امتیاز لیگ',date:today(),place:'اردوگاه',capacity:12,kind:'points',amount:20,members:[],registrations:{}}]; state.warnings.push({id:uid(),userId:'u0',text:'نمونه: لطفاً در جلسه توجه بیشتری داشته باش.',level:'تذکر',by:'admin',date:today(),deduct:0}); state.posts.push({id:uid(),title:'جلسه طرح معرفت',text:'نکتههای جلسه را اینجا مرور کنید.',date:today(),pinned:true,sectionId:'marefat'}); state.messages.push({id:uid(),room:'public',from:'admin',text:'به گروه رهپویان وصال خوش آمدید 🌙',time:new Date().toISOString(),read:{}});await save()} async function save(){try{localStorage.setItem(KEY,JSON.stringify(state))}catch{}if(API){try{let r=await fetch(API.replace(/\/$/,'')+'/api/state',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(state)});online=r.ok}catch{online=false}}} function commit(){save();render()} function score(id){let n=0;for(const r of state.records){let e=r.entries?.[id],s=S(r.sectionId);if(!e)continue;if(e.status==='present')n+=Number(s?.score||0);if(e.status==='absent')n-=Number(state.settings.absencePenalty||0);if(e.status==='late')n-=Number(state.settings.latePenalty||0);if(e.summary)n+=Number(s?.id==='heyat'?state.settings.summaryHeyat:s?.id==='culture'?state.settings.summaryCulture:0);if(e.task)n+=Number(state.settings.taskMarefat||0)}return n+state.awards.filter(a=>a.userId===id).reduce((a,b)=>a+Number(b.points||0),0)} function render(){if(!me){login();return}if(me.role==='vault'){vault();return}if(!me.welcomeDone){onboard();return} $('#app').innerHTML=header()+`<main class="wrap">${tab==='home'?home():tab==='att'?attendance():tab==='chat'?chat():tab==='dua'?dua():more()}</main>${nav()}`;if(window.lucide)lucide.createIcons();if(page==='reports'||page==='profile')drawChart()} function header(){return `<header class="top"><div class="topin"><div class="brand">رهپویان وصال<small>گروه امام حسن (ع) · <span class="${online?'online':'offline'}">${online?'متصل به سرور':'ذخیره محلی'}</span></small></div><div class="userbox"><span>${esc(me.name)}</span><span class="avatar">${esc(me.name.slice(0,1))}</span><button class="secondary small" data-act="logout" aria-label="خروج">${icon('log-out',17)}</button></div></div></header>`} function nav(){return `<nav class="bottom" aria-label="ناوبری اصلی"><div class="nav">${[['home','خانه','house'],['att','حضور','calendar-check'],['chat','چت','messages-square'],['dua','دعا','heart-handshake'],['more','بیشتر','menu']].map(([t,n,i])=>`<button class="${tab===t?'active':''}" data-tab="${t}">${icon(i)}${n}</button>`).join('')}</div></nav>`} function login(){$('#app').innerHTML=`<main class="wrap login"><section class="card"><div class="dome">☾ ✦</div><h1 style="text-align:center;color:var(--gold)">سامانه رهپویان وصال</h1><p class="muted" style="text-align:center">گروه امام حسن مجتبی (ع)</p><form id="loginForm"><label>نام کاربری</label><input name="username" autocomplete="username" required><label>رمز عبور</label><input name="password" type="password" autocomplete="current-password" required><p id="loginErr" class="muted" aria-live="polite"></p><button style="width:100%">ورود</button></form><details><summary>حسابهای نمونه</summary><p class="muted"><bdi dir="ltr">admin / admin</bdi> · <bdi dir="ltr">1234 / 1234</bdi> · <bdi dir="ltr">student1 / 1234</bdi></p></details></section></main>`} function onboard(){$('#app').innerHTML=`<main class="wrap login"><section class="card"><h2>به رهپویان وصال خوش آمدید</h2><p>برای تکمیل حساب، تاریخ تولد شمسی و شماره تلفن را وارد کنید.</p><form id="welcomeForm"><label>شماره تلفن</label><input name="phone" inputmode="tel" pattern="[0-9۰-۹+ -]{8,18}" required><label>روز تولد</label><select name="day" required>${Array.from({length:31},(_,i)=>`<option value="${i+1}">${fa(i+1)}</option>`).join('')}</select><label>ماه تولد</label><select name="month" required>${Array.from({length:12},(_,i)=>`<option value="${i+1}">${fa(i+1)}</option>`).join('')}</select><label>سال تولد شمسی</label><input name="year" type="number" min="1300" max="1450" value="1387" required><label class="check"><input type="checkbox" name="consent" required> رمز عبور و اطلاعات حساب شما (نام کاربری، شماره تلفن و تاریخ تولد) برای بازیابی در صورت فراموشی، نزد مدیریت مجموعه محفوظ میماند. موافقم</label><button>تأیید و ادامه</button></form></section></main>`} function vault(){let list=state.users.filter(u=>u.role!=='vault');$('#app').innerHTML=`<main class="wrap"><section class="card"><div class="section-title"><h2>دفترچه حسابها</h2><button class="secondary small" data-act="logout">خروج</button></div><p class="muted">این حساب فقط دسترسی خواندن و خروجی دارد.</p><input id="vsearch" placeholder="جستوجوی نام، کاربری یا نقش"><div class="table-wrap"><table id="vtable"><thead><tr><th>نام</th><th>نام کاربری</th><th>رمز</th><th>تلفن</th><th>تولد</th><th>نقش</th></tr></thead><tbody>${list.map(async u=>u).length?list.map(u=>`<tr><td>${esc(u.name)}</td><td>${esc(u.username)}</td><td data-pass="${u.id}">در حال رمزگشایی…</td><td>${esc(u.phone||'—')}</td><td>${esc(u.birth||'—')}</td><td>${esc(u.role)}</td></tr>`).join(''):''}</tbody></table></div><button data-act="vaultxlsx">خروجی Excel</button></section></main>`;list.forEach(async u=>{let el=document.querySelector(`[data-pass="${u.id}"]`);if(el)el.textContent=await decryptPass(u.passEnc||'')})} function home(){let mine=state.records.filter(r=>r.entries?.[me.id]),q=state.hadiths[Math.floor(Date.now()/86400000)%Math.max(1,state.hadiths.length)],warnings=state.warnings.filter(w=>w.userId===me.id),upcoming=state.events.filter(e=>e.date>=today()).sort((a,b)=>a.date.localeCompare(b.date))[0],week=leaders(7)[0],month=leaders(30)[0],births سلام من کدهای بالا را قبلاً نوشتم و الان دیدم که یه سری مشکل داره میخوایم که با هم رفعش کنیم ببین این کدها با کلاود ساخته شده یعنی خودت چیزایی که میخوام بهش اضافه کنی اینه که مثلاً دانش آموز نتونه توی تخته سفید ایجاد انجام بده یعنی نقاشی کنه متنی بنویسه فقط و فقط ادمین میتونه و زمانی که میخوان اکانت بسازند و وارد شوند غیر از شماره خودشون و تاریخ تولدشون باید شماره تلفن پدر شماره تلفن مادر شماره تلفن خودشون که ایتا دارن روش را وارد و کنند بخش لیگها را کامل حذف کن امتیاز هر الان بهت میگم حضور جلسه فرهنگی 2 امتیاز حضور هیئت 1 امتیاز طرح معرفت 2 امتیاز نوشتن خلاصه نویسی برای هیئت و یا جلسه فرهنگی 1 امتیاز تکلیف طرح معرفت 1 امتیاز لطفاً خیلی روی تم و رابط کاربری کار کن خیلی ضعیفه لطفاً برنامه را برای آماده برای وصل کردن به سرور کن و غیر از رمز و نام کاربری 404/404 و admin/admin چیزی نباشه تا خود بچه ها برای خودشان اکانت بسازند برنامه هیچ لیگی نداشته باشد لطفاً روی خروجی اکسل حسابی کار کن











