import { useState, useEffect, useMemo, useCallback, useRef } from "react";
const DEFAULT_TEACHERS = [
{name:"خالد علي العطوي",id:"",specialty:"",jobNum:"",phone:""},
{name:"احمد ظافر الشهري",id:"",specialty:"",jobNum:"",phone:""},
{name:"اسامة عبدالرحمن العتيق",id:"",specialty:"",jobNum:"",phone:""},
{name:"سهل عبدالله البلوي",id:"",specialty:"",jobNum:"",phone:""},
{name:"عمر فالح البلوي",id:"",specialty:"",jobNum:"",phone:""},
{name:"فهد محمد الشامان",id:"",specialty:"",jobNum:"",phone:""},
{name:"طارق حسن حكمي",id:"",specialty:"",jobNum:"",phone:""},
{name:"سلمان عوده البلوي",id:"",specialty:"",jobNum:"",phone:""},
{name:"احمد موسى نوح",id:"",specialty:"",jobNum:"",phone:""},
{name:"عبدالهادي عمر العنزي",id:"",specialty:"",jobNum:"",phone:""},
{name:"سلطان صالح الشمري",id:"",specialty:"",jobNum:"",phone:""},
{name:"صالح شرفاتي العبدلي",id:"",specialty:"",jobNum:"",phone:""},
{name:"سليمان حمد العطوي",id:"",specialty:"",jobNum:"",phone:""},
{name:"محمد عياد البلوي",id:"",specialty:"",jobNum:"",phone:""},
{name:"عبدالله محمد سلامي",id:"",specialty:"",jobNum:"",phone:""},
{name:"محمد مسلم البلوي",id:"",specialty:"",jobNum:"",phone:""}
];
const TASK_KEYS=["morning","waiting","supervision","duty","madrasati"];
const TASK_LABELS=["الطابور الصباحي","الانتظار","الإشراف","المناوبة","منصة مدرستي"];
const DAYS_AR=["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس"];
const MONTHS_G=["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"];
const SK="task_reg_v5";
const DEFAULT_SCHOOL={schoolName:"مسلمة بن عبدالملك الابتدائية",region:"الإدارة العامة للتعليم بمنطقة تبوك",principal:"صالح فريج الحويطي",vice:"سعد عتيق العطوي",gender:"male"};
const GL={male:{principal:"مدير المدرسة",vice:"وكيل المدرسة",teacher:"المعلم",teachers:"المعلمين"},female:{principal:"مديرة المدرسة",vice:"وكيلة المدرسة",teacher:"المعلمة",teachers:"المعلمات"}};
function dk(d){return`${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`}
function fmtD(d){return`${d.getDate()} ${MONTHS_G[d.getMonth()]} ${d.getFullYear()}م`}
function dayN(d){return["الأحد","الإثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"][d.getDay()]}
function dayI(d){return d.getDay()}
function wkD(b){const d=new Date(b),diff=d.getDate()-d.getDay();return Array.from({length:5},(_,i)=>{const x=new Date(d);x.setDate(diff+i);return x})}
function mKey(d){return`${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}`}
function getWD(y,m){const days=[],dim=new Date(y,m+1,0).getDate();for(let i=1;i<=dim;i++){const d=new Date(y,m,i);if(d.getDay()<=4)days.push(d)}return days}
const Chk=()=> ;
const Xm=()=> ;
const Lk=()=> ;
const ARi=()=> ;
const ALi=()=> ;
export default function App(){
const[teachers,setTeachers]=useState(DEFAULT_TEACHERS);
const[records,setRecords]=useState({});
const[att,setAtt]=useState({});
const[schedules,setSchedules]=useState({supervisionDay:{},dutyMonth:{},dailyDuty:{}});
const[school,setSchool]=useState(DEFAULT_SCHOOL);
const[curDate,setCurDate]=useState(new Date());
const[page,setPage]=useState("daily");
const[toast,setToast]=useState(null);
const[loaded,setLoaded]=useState(false);
const[accForm,setAccForm]=useState(null);
const dKey=dk(curDate),tDI=dayI(curDate),gl=GL[school.gender]||GL.male;
useEffect(()=>{(async()=>{try{if(window.storage){const r=await window.storage.get(SK);if(r?.value){const p=JSON.parse(r.value);if(p.teachers)setTeachers(p.teachers);if(p.records)setRecords(p.records);if(p.att)setAtt(p.att);if(p.schedules)setSchedules(s=>({...s,...p.schedules}));if(p.school)setSchool(s=>({...s,...p.school}));}}}catch(e){}setLoaded(true)})();},[]);
const save=useCallback((t,r,s,sc,a)=>{try{window.storage?.set(SK,JSON.stringify({teachers:t,records:r,schedules:s,school:sc,att:a}))}catch(e){}},[]);
const upT=t=>{setTeachers(t);save(t,records,schedules,school,att)};
const upR=r=>{setRecords(r);save(teachers,r,schedules,school,att)};
const upS=s=>{setSchedules(s);save(teachers,records,s,school,att)};
const upSc=sc=>{setSchool(sc);save(teachers,records,schedules,sc,att)};
const upA=a=>{setAtt(a);save(teachers,records,schedules,school,a)};
const emptyDay=useCallback(()=>teachers.map(()=>TASK_KEYS.map(()=>null)),[teachers]);
const dayData=useMemo(()=>records[dKey]||emptyDay(),[records,dKey,emptyDay]);
const dayAtt=useMemo(()=>att[dKey]||{},[att,dKey]);
const setDD=useCallback(nd=>{upR({...records,[dKey]:nd})},[dKey,records]);
const togAtt=useCallback(ti=>{const na={...att};if(!na[dKey])na[dKey]={};const cur=na[dKey][ti];na[dKey][ti]=cur===undefined?true:cur===true?false:undefined;if(na[dKey][ti]===undefined)delete na[dKey][ti];upA(na)},[att,dKey]);
const appTasks=useMemo(()=>teachers.map((_,ti)=>TASK_KEYS.map(key=>{
if(dayAtt[ti]===false)return false;
if(key==="supervision")return schedules.supervisionDay[ti]!==undefined&&schedules.supervisionDay[ti]===tDI;
if(key==="duty"){if(schedules.dailyDuty?.[ti])return true;const mk2=mKey(curDate),dm=schedules.dutyMonth?.[mk2];if(dm)return Object.entries(dm).some(([d2,idx])=>idx===ti&&d2===dKey);return false}
return true
})),[schedules,tDI,teachers,curDate,dKey,dayAtt]);
const togCell=useCallback((ti,ki)=>{if(!appTasks[ti]?.[ki])return;const nd=dayData.map(r=>[...r]);const c=nd[ti]?.[ki];nd[ti][ki]=c===null?1:c===1?0:null;setDD(nd)},[dayData,setDD,appTasks]);
const stats=useMemo(()=>{let comp=0,nonC=0,absent=0,present=0;teachers.forEach((_,ti)=>{if(dayAtt[ti]===false){absent++;return}if(dayAtt[ti]===true)present++;let has=false,allG=true;(dayData[ti]||[]).forEach((v,ki)=>{if(!appTasks[ti]?.[ki])return;if(v!==null){has=true;if(v!==1)allG=false}});if(has){if(allG)comp++;else nonC++}});const rated=comp+nonC;return{total:teachers.length,comp,nonC,rate:rated>0?Math.round(comp/rated*100):0,absent,present}},[dayData,appTasks,teachers,dayAtt]);
const nav=n=>{const d=new Date(curDate);d.setDate(d.getDate()+n);setCurDate(d)};
const sToast=m=>{setToast(m);setTimeout(()=>setToast(null),2500)};
if(!loaded)return
سجل متابعة المهام
جاري التحميل...
;
return(
{school.region} {school.schoolName}
سجل متابعة المهام
{[{k:'daily',l:'📋 اليومية'},{k:'teachers',l:`👥 ${gl.teachers}`},{k:'schedules',l:'📅 الجداول'},{k:'reports',l:'📊 التقارير'},{k:'settings',l:'⚙️'}].map(t=>setPage(t.k)} style={{flex:1,padding:'8px 2px',borderRadius:8,background:page===t.k?'#1a5c3a':'white',color:page===t.k?'white':'#666',fontWeight:700,fontSize:9.5,boxShadow:page===t.k?'0 3px 8px rgba(26,92,58,.3)':'0 1px 2px rgba(0,0,0,.04)',border:page===t.k?'none':'1px solid #e8e8e8'}}>{t.l} )}
{page==='daily'&&
setCurDate(new Date())} resetDay={()=>{if(confirm('مسح بيانات هذا اليوم؟')){setDD(emptyDay());const na={...att};delete na[dKey];upA(na);sToast('تم ✓')}}}/>}
{page==='teachers'&&}
{page==='schedules'&&}
{page==='reports'&& }
{page==='settings'&&}
{accForm&&setAccForm(null)}/>}
{gl.principal}
{school.principal}
{toast&&{toast}
}
);
}
/* ═══════ DAILY ═══════ */
function DailyPage({teachers,curDate,nav,dayData,togCell,stats,appTasks,goToday,resetDay,dKey,gl,dayAtt,togAtt,school,setAccForm,sToast,emptyDay}){
const isToday=dk(curDate)===dk(new Date()),isWE=dayI(curDate)>=5;
const exportCSV=()=>{let csv='\uFEFF#,الحالة,اسم '+gl.teacher+','+TASK_LABELS.join(',')+'\n';dayData.forEach((row,i)=>{if(i>=teachers.length)return;const a=dayAtt[i]===false?'غائب':'حاضر';const vals=row.map((v,ki)=>!appTasks[i]?.[ki]?'غير مطلوب':v===1?'ملتزم':v===0?'غير ملتزم':'-');csv+=[i+1,a,teachers[i].name,...vals].join(',')+'\n'});const b=new Blob([csv],{type:'text/csv;charset=utf-8;'});const a=document.createElement('a');a.href=URL.createObjectURL(b);a.download=`سجل_${dKey}.csv`;a.click();sToast('تم التصدير ✓')};
return
nav(1)} style={{padding:4,borderRadius:5,background:'#f0f2f5'}}>
{dayN(curDate)} - {fmtD(curDate)}
{!isToday&&
العودة لليوم }{isToday&&
● اليوم
}
nav(-1)} style={{padding:4,borderRadius:5,background:'#f0f2f5'}}>
{isWE?
:<>
{[{l:'إجمالي',v:stats.total,c:'#1a5c3a'},{l:'حاضر',v:stats.present,c:'#3b82f6'},{l:'غائب',v:stats.absent,c:'#f59e0b'},{l:'ملتزم',v:stats.comp,c:'#22c55e'},{l:'الالتزام',v:stats.rate+'%',c:'#c8a951'}].map((s,i)=>
)}
بيانات {gl.teachers}
#
الحضور
اسم {gl.teacher}
{TASK_LABELS.map((t,i)=>{t} )}
إجراء
{teachers.map((t,ti)=>{
const isAbs=dayAtt[ti]===false,isPres=dayAtt[ti]===true;
const hasViol=(dayData[ti]||[]).some((v,ki)=>appTasks[ti]?.[ki]&&v===0);
return
{ti+1}
togAtt(ti)} style={{padding:'3px 8px',borderRadius:5,fontSize:9,fontWeight:700,background:isAbs?'#fef3c7':isPres?'#dcfce7':'#f5f5f5',color:isAbs?'#92400e':isPres?'#166534':'#aaa',border:`1.5px solid ${isAbs?'#f59e0b':isPres?'#22c55e':'#ddd'}`,minWidth:38}}>{isAbs?'غائب':isPres?'حاضر':'—'}
{t.name}
{TASK_KEYS.map((_,ki)=>{const ap=appTasks[ti]?.[ki],val=dayData[ti]?.[ki]??null;return {ap?togCell(ti,ki)} style={{width:30,height:30,borderRadius:6,border:`2px solid ${val===1?'#22c55e':val===0?'#ef4444':'#e2e5ea'}`,background:val===1?'#f0fdf4':val===0?'#fef2f2':'white',color:val===1?'#22c55e':val===0?'#ef4444':'#ddd',display:'inline-flex',alignItems:'center',justifyContent:'center'}}>{val===1? :val===0? :'–'} :
} })}
{isAbs&&setAccForm({ti,task:'غياب',date:dKey,type:'absence'})} style={{padding:'2px 6px',borderRadius:4,background:'#fef3c7',color:'#92400e',fontSize:8,fontWeight:700,border:'1px solid #f59e0b',whiteSpace:'nowrap'}}>📄 مساءلة }
{!isAbs&&hasViol&&{const viol=(dayData[ti]||[]).map((v,ki)=>appTasks[ti]?.[ki]&&v===0?TASK_LABELS[ki]:null).filter(Boolean);setAccForm({ti,task:viol.join('، '),date:dKey,type:'violation'})}} style={{padding:'2px 6px',borderRadius:4,background:'#fef2f2',color:'#dc2626',fontSize:8,fontWeight:700,border:'1px solid #fca5a5',whiteSpace:'nowrap'}}>⚠️ مساءلة }
})}
window.print()} style={{...BTN,background:'#1a5c3a',color:'white'}}>🖨️ طباعة
📥 تصدير
🗑️ مسح
>}
;
}
/* ═══════ ACCOUNTABILITY MODAL ═══════ */
function AccModal({accForm,teachers,school,gl,onClose}){
const t=teachers[accForm.ti],isAbs=accForm.type==='absence';
const printForm=()=>{const w=window.open('','_blank','width=800,height=1000');w.document.write(`
المملكة العربية السعودية - وزارة التعليم ${school.region} ${school.schoolName}
${isAbs?'نموذج رقم (٢٠)':'نموذج مساءلة'}
${isAbs?'مساءلة غياب':'مساءلة عدم التزام'}
الاسم ${t.name} التخصص ${t.specialty||'—'} رقم الهوية ${t.id||'—'} الرقم الوظيفي ${t.jobNum||'—'} التاريخ ${accForm.date} ${!isAbs?`المخالفة ${accForm.task} `:''}
${isAbs?`(١) طلب الإفادة المكرم / ${t.name} وفقه الله
السلام عليكم ورحمة الله وبركاته وبعد ،،،
من خلال متابعة سجل العمل تبيّن غيابكم خلال الفترة الموضحة بعاليه، آمل الإفادة عن أسباب ذلك وعليكم تقديم ما يؤيد عذركم خلال أسبوع من تاريخه، علماً بأنه في حالة عدم الالتزام سيتم اتخاذ اللازم حسب التعليمات.
اسم الرئيس المباشر: ${school.principal}
التوقيع: .........
التاريخ: / / ١٤هـ
(٢) الإفادة المكرم / ${gl.principal} وفقه الله
السلام عليكم ورحمة الله وبركاته وبعد:
أفيدكم أن غيابي كان للأسباب التالية:
وسأقوم بتقديم ما يثبت ذلك خلال أسبوع من تاريخه
اسم ${gl.teacher}: .........
التوقيع: .........
التاريخ: / / ١٤هـ
(٣) ${gl.principal}: أ. تحتسب له إجازة مرضية بعد التأكد من نظامية التقرير
ب. يحتسب غيابه من رصيده للإجازات الاضطرارية لقبول عذره إذا كان رصيده يسمح وإلا يحسم عليه.
ج. يعتمد الحسم لعدم قبول عذره
اسم الرئيس المباشر: .........
التوقيع: .........
التاريخ: / / ١٤هـ
ملاحظات هامة: تستكمل الاستمارة من المدير المباشر وإصدار القرار بموجبه. إذا سبق إجازة نهاية الأسبوع غياب وألحقها غياب تحتسب مدة الغياب كاملة. يجب أن يوضح المتغيب أسباب غيابه فور تسلمه الاستمارة ويعيدها لمديره المباشر. يعطى المتغيب مدة أسبوع لتقديم ما يؤيد عذره فإذا انقضت المدة تستكمل الاستمارة ويتم الحسم. `
:`تفاصيل المخالفة تبيّن من خلال المتابعة اليومية عدم التزام ${gl.teacher} / ${t.name} بالمهام التالية:
${accForm.task}
وذلك بتاريخ: ${accForm.date}
نأمل الإفادة عن أسباب ذلك:
توقيع ${gl.teacher}
${t.name}
${gl.principal}
${school.principal}
`}
🖨️ طباعة `);w.document.close()};
return
e.stopPropagation()} style={{background:'white',borderRadius:14,padding:'18px',maxWidth:400,width:'100%',maxHeight:'80vh',overflow:'auto',boxShadow:'0 16px 50px rgba(0,0,0,.3)'}}>
{isAbs?'📄 مساءلة غياب':'⚠️ مساءلة عدم التزام'}
{isAbs?'نموذج رقم (٢٠) - الدليل الإجرائي':'نموذج مساءلة'}
الاسم: {t.name}
التاريخ: {accForm.date}
{!isAbs&&
المخالفة: {accForm.task}
}
🖨️ طباعة النموذج
إغلاق
;
}
/* ═══════ TEACHERS ═══════ */
function TeachersPage({teachers,upT,sToast,gl}){
const[nn,setNN]=useState('');const[eIdx,setEIdx]=useState(null);const[eVal,setEVal]=useState({});const fRef=useRef();
const add=()=>{const n=nn.trim();if(!n)return;upT([...teachers,{name:n,id:'',specialty:'',jobNum:'',phone:''}]);setNN('');sToast('تمت الإضافة ✓')};
const del=i=>{if(!confirm(`حذف ${teachers[i].name}؟`))return;const t=[...teachers];t.splice(i,1);upT(t);sToast('تم الحذف ✓')};
const importFile=e=>{const file=e.target.files[0];if(!file)return;const reader=new FileReader();reader.onload=evt=>{const s=document.createElement('script');s.src='https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js';s.onload=()=>{try{const wb=window.XLSX.read(evt.target.result,{type:'array'});const ws=wb.Sheets[wb.SheetNames[0]];const json=window.XLSX.utils.sheet_to_json(ws);const imp=json.map(r=>{const name=(r['الاسم']||r['اسم المعلم']||Object.values(r)[1]||'').toString().trim();const id=String(r['رقم الهوية']||r['الهوية']||Object.values(r)[0]||'');const phone=String(r['الجوال']||'');const specialty=String(r['التخصص']||'');const jobNum=String(r['رقم الوظيفة']||'');return{name,id,specialty,jobNum,phone}}).filter(t=>t.name);if(imp.length>0){upT(imp);sToast(`تم استيراد ${imp.length} ${gl.teacher} ✓`)}else sToast('لم يتم العثور على بيانات')}catch(err){sToast('خطأ في الملف')}};document.head.appendChild(s)};reader.readAsArrayBuffer(file)};
return
قائمة {gl.teachers} ({teachers.length})
{teachers.map((t,i)=>
{eIdx===i?
setEVal(p=>({...p,name:e.target.value}))} placeholder="الاسم" style={inpS}/>
setEVal(p=>({...p,id:e.target.value}))} placeholder="رقم الهوية" style={{...inpS,flex:1}}/> setEVal(p=>({...p,specialty:e.target.value}))} placeholder="التخصص" style={{...inpS,flex:1}}/>
{const tt=[...teachers];tt[eIdx]=eVal;upT(tt);setEIdx(null);sToast('تم ✓')}} style={{...BTN,background:'#1a5c3a',color:'white',flex:1,justifyContent:'center'}}>حفظ setEIdx(null)} style={{...BTN,background:'#f5f5f5',color:'#888'}}>إلغاء
:
{i+1}. {t.name}
{(t.id||t.specialty)&&
{t.id&&`هوية: ${t.id}`}{t.specialty&&` • ${t.specialty}`}
}
{setEIdx(i);setEVal({...t})}} style={{padding:4,borderRadius:4,background:'#f0f2f5',fontSize:9}}>✏️ del(i)} style={{padding:4,borderRadius:4,background:'#fef2f2',fontSize:9}}>🗑️
}
)}
;
}
/* ═══════ SCHEDULES ═══════ */
function SchedPage({teachers,schedules,upS,curDate,sToast,gl}){
const[tab,setTab]=useState('supervision');const[dm,setDm]=useState(new Date(curDate));
const mk=mKey(dm),wds=useMemo(()=>getWD(dm.getFullYear(),dm.getMonth()),[dm]),dutyMap=schedules.dutyMonth?.[mk]||{};
return
{[{k:'supervision',l:'🔍 الإشراف'},{k:'duty',l:'🛡️ المناوبة'}].map(t=>setTab(t.k)} style={{flex:1,padding:'7px',borderRadius:7,background:tab===t.k?'#e8f5ee':'white',color:tab===t.k?'#1a5c3a':'#999',fontWeight:700,fontSize:10,border:tab===t.k?'2px solid #1a5c3a':'1px solid #eee'}}>{t.l} )}
{tab==='supervision'&&
# {gl.teacher} {DAYS_AR.map((d,i)=>{d} )}{teachers.map((t,ti)=>{ti+1} {t.name} {[0,1,2,3,4].map(di=>{const ns={...schedules,supervisionDay:{...schedules.supervisionDay}};if(ns.supervisionDay[ti]===di)delete ns.supervisionDay[ti];else ns.supervisionDay[ti]=di;upS(ns)}} style={{padding:'2px 6px',borderRadius:4,fontSize:8,fontWeight:700,background:schedules.supervisionDay[ti]===di?'#e8f5ee':'#f5f5f5',color:schedules.supervisionDay[ti]===di?'#1a5c3a':'#ccc',border:schedules.supervisionDay[ti]===di?'2px solid #1a5c3a':'1px solid #eee'}}>{schedules.supervisionDay[ti]===di?'✓':'–'} )} )}
}
{tab==='duty'&&<>
{teachers.map((t,ti)=>{const ns={...schedules,dailyDuty:{...schedules.dailyDuty||{}}};if(ns.dailyDuty[ti])delete ns.dailyDuty[ti];else ns.dailyDuty[ti]=true;upS(ns)}} style={{padding:'3px 8px',borderRadius:4,fontSize:9,fontWeight:700,background:schedules.dailyDuty?.[ti]?'#e8f5ee':'#f5f5f5',color:schedules.dailyDuty?.[ti]?'#1a5c3a':'#ccc',border:schedules.dailyDuty?.[ti]?'2px solid #1a5c3a':'1px solid #eee'}}>{t.name}{schedules.dailyDuty?.[ti]?' ✓':''} )}
{const d=new Date(dm);d.setMonth(d.getMonth()+1);setDm(d)}} style={{padding:3,borderRadius:4,background:'#f0f2f5'}}> {MONTHS_G[dm.getMonth()]} {dm.getFullYear()} {const d=new Date(dm);d.setMonth(d.getMonth()-1);setDm(d)}} style={{padding:3,borderRadius:4,background:'#f0f2f5'}}> # اليوم التاريخ {gl.teacher} {wds.map((wd,wi)=>{const wdk2=dk(wd),assigned=dutyMap[wdk2];return {wi+1} {dayN(wd)} {wd.getDate()}/{wd.getMonth()+1} {const v=e.target.value,ns={...schedules,dutyMonth:{...schedules.dutyMonth}};if(!ns.dutyMonth[mk])ns.dutyMonth[mk]={};if(v==='')delete ns.dutyMonth[mk][wdk2];else ns.dutyMonth[mk][wdk2]=parseInt(v);upS(ns)}} style={{width:'100%',padding:'4px 6px',borderRadius:5,border:'1.5px solid #e2e5ea',fontSize:10,fontWeight:600,background:assigned!==undefined?'#e8f5ee':'#fafafa',color:assigned!==undefined?'#1a5c3a':'#999',fontFamily:'Tajawal'}}>— اختر — {teachers.map((n,ti)=>{n.name} )} })}
>}
;
}
/* ═══════ REPORTS ═══════ */
function ReportsPage({teachers,curDate,nav,records,schedules,att,gl}){
const wd=wkD(curDate);
const wr=useMemo(()=>wd.map(d=>{const k=dk(d),data=records[k],at=att[k]||{};if(!data)return{date:d,filled:false,rate:0,comp:0,rated:0,abs:0};const di=dayI(d),mk2=mKey(d);let comp=0,rated=0,abs=0;data.forEach((row,ti)=>{if(ti>=teachers.length)return;if(at[ti]===false){abs++;return}let has=false,good=true;row.forEach((v,ki)=>{const tk=TASK_KEYS[ki];let ap=true;if(tk==="supervision")ap=schedules.supervisionDay[ti]===di;if(tk==="duty"){if(schedules.dailyDuty?.[ti])ap=true;else{const dm=schedules.dutyMonth?.[mk2];ap=dm?Object.entries(dm).some(([d2,idx])=>idx===ti&&d2===dk(d)):false}}if(!ap)return;if(v!==null){has=true;if(v!==1)good=false}});if(has){rated++;if(good)comp++}});return{date:d,filled:rated>0||abs>0,rate:rated>0?Math.round(comp/rated*100):0,comp,rated,abs}}),[records,curDate,schedules,teachers,att]);
return
nav(7)} style={{padding:4,borderRadius:5,background:'#f0f2f5'}}>
التقرير الأسبوعي
{fmtD(wd[0])} — {fmtD(wd[4])}
nav(-7)} style={{padding:4,borderRadius:5,background:'#f0f2f5'}}>
{wr.map((d,i)=>
{DAYS_AR[i]}
=70?'#22c55e':d.rate>=40?'#f59e0b':'#ef4444'):'#ddd'}}>{d.filled?d.rate+'%':'–'}
{d.filled?`${d.comp}/${d.rated}`:''}{d.abs>0?` غياب:${d.abs}`:''}
)}
ملخص الأسبوع
{(()=>{const f=wr.filter(d=>d.filled),avg=f.length>0?Math.round(f.reduce((s,d)=>s+d.rate,0)/f.length):0,tAbs=f.reduce((s,d)=>s+d.abs,0);return[{l:'أيام مسجّلة',v:f.length+'/5'},{l:'متوسط الالتزام',v:avg+'%'},{l:'إجمالي الغياب',v:tAbs}].map((s,i)=>
)})()}
;
}
/* ═══════ SETTINGS ═══════ */
function SettPage({school,upSc,sToast,gl}){
const[f,sF]=useState({...school});const fgl=GL[f.gender]||GL.male;const ch=JSON.stringify(f)!==JSON.stringify(school);
return
⚧ جنس الكادر
{[{k:'male',l:'بنين 👦'},{k:'female',l:'بنات 👧'}].map(g=>sF(p=>({...p,gender:g.k}))} style={{flex:1,padding:'8px',borderRadius:7,background:f.gender===g.k?'#e8f5ee':'#fafafa',border:f.gender===g.k?'2px solid #1a5c3a':'2px solid #eee',fontWeight:700,fontSize:12,color:f.gender===g.k?'#1a5c3a':'#999'}}>{g.l} )}
{[{k:'schoolName',l:'اسم المدرسة'},{k:'region',l:'الإدارة'},{k:'principal',l:fgl.principal},{k:'vice',l:fgl.vice}].map(x=>
)}
{upSc({...f});sToast('تم الحفظ ✓')}} style={{...BTN,width:'100%',justifyContent:'center',background:ch?'#1a5c3a':'#ccc',color:'white',padding:'10px',fontSize:12,pointerEvents:ch?'auto':'none'}}>💾 حفظ
;
}
const TH={background:'#1a5c3a',color:'white',fontWeight:600,fontSize:8.5,padding:'7px 4px',textAlign:'center',whiteSpace:'nowrap'};
const TD={padding:'3px 3px',textAlign:'center',fontSize:9,verticalAlign:'middle'};
const BTN={padding:'7px 12px',borderRadius:6,fontFamily:"'Tajawal',sans-serif",fontSize:10,fontWeight:700,display:'flex',alignItems:'center',gap:3,transition:'all .2s',border:'none'};
const inpS={padding:'7px 9px',borderRadius:6,border:'2px solid #e2e5ea',fontSize:11,outline:'none',background:'#fafafa',fontFamily:'Tajawal'};