'; w.document.open();w.document.write(html);w.document.close(); } function downloadCertificateHTML(cert){ const student=esc(cert.studentName||'Student'); const course=esc(cert.courseTitle||'Course'); const date=certificateDate(cert.issuedAt); const id=esc(cert.id||''); const code=esc(cert.verificationCode||''); const verifyUrl=certificateVerifyUrl(cert); const qr=certificateQrUrl(cert); const html=`MIDAD Certificate
MIDAD
PROFESSIONAL LEARNING PLATFORM
CERTIFICATE
OF COMPLETION
THIS CERTIFICATE IS PROUDLY PRESENTED TO
${student}
FOR SUCCESSFULLY COMPLETING THE COURSE
${course}
DATE OF ISSUE${date}
CERTIFICATE ID${id}
VERIFICATION CODE${code}
Certificate QR CodeSCAN TO VERIFY
`; const blob=new Blob([html],{type:'text/html;charset=utf-8'}),url=URL.createObjectURL(blob),a=document.createElement('a'); a.href=url;a.download=`MIDAD-Certificate-${(cert.courseTitle||'Course').replace(/[^a-z0-9_-]+/gi,'-')}-${cert.id||'certificate'}.html`; document.body.appendChild(a);a.click();a.remove();setTimeout(()=>URL.revokeObjectURL(url),1000); } async function certificates(){ const cs=await all('certificates'); const mine=cs.filter(x=>x.userId===currentUser.id); app.innerHTML=`
MIDAD CERTIFICATES

شهاداتي

شهادة إنجليزية ثابتة بتصميم MIDAD، باسم الطالب والكورس وتاريخ الإصدار.
${mine.map(x=>`
MIDAD CERTIFICATE

${esc(x.courseTitle)}

THIS CERTIFICATE IS PROUDLY PRESENTED TO

${esc(x.studentName)}

Date of Issue: ${certificateDate(x.issuedAt)}

Certificate ID: ${esc(x.id)}
Verification Code: ${esc(x.verificationCode)}
`).join('')||'
لم تحصل على شهادة بعد. أكمل جميع المحاضرات.
'}
`; } async function verify(code){ const cs=await all('certificates'),x=cs.find(c=>c.verificationCode===code); app.innerHTML=`
CERTIFICATE VERIFICATION
${x?`

✓ شهادة صالحة

${esc(x.studentName)}

أكمل كورس:

${esc(x.courseTitle)}

رقم الشهادة: ${x.id}

تاريخ الإصدار: ${new Date(x.issuedAt).toLocaleDateString('ar-SA')}

`:'

الشهادة غير موجودة

تحقق من رمز الشهادة.

'}
`; } async function dashboard(){ if(currentUser?.role==='INSTRUCTOR'){ const cs=await all('courses'), mine=cs.filter(c=>c.instructorId===currentUser.id), ms=await all('media'); const published=mine.filter(c=>c.status==='PUBLISHED').length; const lectures=mine.reduce((n,c)=>n+(c.sections||[]).reduce((a,s)=>a+(s.lectures||[]).length,0),0); app.innerHTML=`
INSTRUCTOR DASHBOARD

مرحبًا ${esc(currentUser.name)}

إدارة ملفك كمحاضر وكورساتك ومحتوى الفيديو من مكان واحد.
كورساتي${mine.length}
منشورة${published}
المحاضرات${lectures}
الفيديوهات${ms.filter(m=>mine.some(c=>c.id===m.courseId)).length}
PROFILE

ملفي كمحاضر

${esc(currentUser.name)}
${esc(currentUser.headline||'أضف المسمى المهني والخبرات والصورة')}
CONTENT

محتوى الكورسات

أضف صورة الكورس، صورة المحاضر، الأقسام، المحاضرات والفيديوهات من إدارة الكورس.

كورساتي

${mine.map(c=>`
${esc(c.title||'بدون اسم')}
${esc(c.instructorName||currentUser.name)} • ${c.sections?.reduce((a,s)=>a+(s.lectures||[]).length,0)||0} محاضرات
${esc(c.status||'DRAFT')}
`).join('')||'
لا توجد كورسات بعد. أنشئ أول كورس من زر «كورس جديد».
'}
`; return; } const ens=(await all('enrollments')).filter(e=>e.userId===currentUser.id),cs=await all('courses'); const mine=ens.map(e=>cs.find(c=>c.id===e.courseId)).filter(Boolean); const ps=await Promise.all(mine.map(c=>courseProgress(c.id))); const avg=mine.length?Math.round(ps.reduce((a,p)=>a+p.percent,0)/mine.length):0; const certs=(await all('certificates')).filter(c=>c.userId===currentUser.id); const orders=(await all('orders')).filter(o=>o.userId===currentUser.id); const cards=mine.map((c,i)=>`
${esc(c.title)}
${ps[i].completed}/${ps[i].total} محاضرات • ${ps[i].percent}%
`).join(''); app.innerHTML=`
STUDENT DASHBOARD

مرحبًا ${esc(currentUser.name)}

كورساتي${mine.length}
التقدم${avg}%
الطلبات${orders.length}
الشهادات${certs.length}

Continue Learning

${cards||'
لا توجد كورسات. استكشف الكورسات من القائمة الرئيسية.
'}
`; } async function manage(){ if(!allowedManage())return; const allCourses=await all('courses'); const isAdminUser=isAdmin(); const cs=isAdminUser?allCourses:allCourses.filter(c=>c.instructorId===currentUser?.id); const ens=await all('enrollments'); const media=await all('media'); const published=cs.filter(c=>c.status==='PUBLISHED').length; const drafts=cs.filter(c=>c.status!=='PUBLISHED').length; const rows=cs.map(c=>{ const students=ens.filter(e=>e.courseId===c.id).length; const lectures=courseLectures(c).length; const videos=media.filter(m=>m.courseId===c.id).length; return `
📚

${esc(c.title||'بدون اسم')}

${esc(c.category||'عام')} ${students} طالب ${lectures} محاضرة ${videos} فيديو
${c.status==='PUBLISHED'?'منشور':'مسودة'}
`; }).join(''); app.innerHTML=`
${isAdminUser?'MIDAD ADMIN':'INSTRUCTOR SPACE'}

إدارة الكورسات

إدارة الكورسات والمحتوى من صفحة واحدة بدون تكرار إحصائيات اللوحة المركزية.

${cs.length}كورس
${rows||'
📚

لا توجد كورسات

ابدأ بإنشاء أول كورس من زر «+ كورس جديد».

'}
`; const list=document.getElementById('midadCourseAdminList'); const search=document.getElementById('midadCourseSearch'); const filters=[...document.querySelectorAll('.midad-course-filter')]; const cards=[...list.querySelectorAll('.midad-course-admin-card')]; const data=cs.map(c=>({id:c.id,title:String(c.title||''),status:c.status})); function renderCourseFilter(){ const q=(search?.value||'').trim().toLowerCase(); const active=document.querySelector('.midad-course-filter.active')?.dataset.filter||'all'; cards.forEach(card=>{ const d=data.find(x=>x.id===card.querySelector('.midad-course-admin-actions')?.querySelector('button')?.getAttribute('onclick')?.match(/'([^']+)'/)?.[1]); if(!d){card.style.display='';return} const statusOk=active==='all'||(active==='published'&&d.status==='PUBLISHED')||(active==='draft'&&d.status!=='PUBLISHED'); const textOk=!q||d.title.toLowerCase().includes(q); card.style.display=statusOk&&textOk?'':'none'; }); } filters.forEach(btn=>btn.addEventListener('click',()=>{filters.forEach(x=>x.classList.remove('active'));btn.classList.add('active');renderCourseFilter()})); search?.addEventListener('input',renderCourseFilter); } async function player(arg){ const [courseId,lectureId]=String(arg||'').split('|'),c=await get('courses',courseId);if(!c)return alert('الكورس غير موجود'); const lecture=courseLectures(c).find(l=>l.id===lectureId);if(!lecture)return alert('المحاضرة غير موجودة'); const media=lecture.mediaId?await get('media',lecture.mediaId):null;if(!media)return alert('لا يوجد فيديو مرتبط بهذه المحاضرة'); if(!(lecture.preview||await isEnrolled(courseId))){alert('هذه المحاضرة تتطلب التسجيل في الكورس.');return checkout(courseId)} const p=currentUser?await getProgress(currentUser.id,lectureId):null,url=URL.createObjectURL(media.blob); const index=courseLectures(c).findIndex(l=>l.id===lectureId),allLect=courseLectures(c); const prev=allLect[index-1],next=allLect[index+1]; app.innerHTML=`
${esc(c.title)}

${esc(lecture.title)}

${esc(lecture.title)}
0:00 / 0:00يتم حفظ التقدم تلقائيًا
${prev&&prev.mediaId?``:''}${next&&next.mediaId?``:''}

تقدم الكورس

جاري الحساب...
`; const video=document.getElementById('midadVideo'),bar=document.getElementById('videoProgress'),label=document.getElementById('timeLabel');let last=0; const fmt=s=>{s=Math.max(0,Math.floor(s||0));return `${Math.floor(s/60)}:${String(s%60).padStart(2,'0')}`}; video.onloadedmetadata=()=>{if(p&&p.lastPositionSeconds>2&&p.lastPositionSeconds{const pct=video.duration?video.currentTime/video.duration*100:0;bar.style.width=pct+'%';label.textContent=`${fmt(video.currentTime)} / ${fmt(video.duration)}`;if(currentUser&&video.currentTime-last>=5){last=video.currentTime;await saveProgress(courseId,lectureId,video.currentTime,video.duration,false)}}; video.onpause=async()=>{if(currentUser)await saveProgress(courseId,lectureId,video.currentTime,video.duration,false)}; video.onended=async()=>{if(currentUser){await saveProgress(courseId,lectureId,video.duration,video.duration,true);await maybeIssueCertificate(courseId)}bar.style.width='100%';notify('تم إكمال المحاضرة ✓');renderCourseProgressBox(courseId)}; renderCourseProgressBox(courseId); } async function renderCourseProgressBox(courseId){ const box=document.getElementById('courseProgressBox');if(!box)return; const p=await courseProgress(courseId);box.innerHTML=`
${p.percent}%${p.completed} من ${p.total} محاضرة مكتملة
${p.percent===100?'
🎓 الكورس مكتمل. الشهادة متاحة من قسم شهاداتي.
':''}`; if(p.percent===100)await maybeIssueCertificate(courseId); } /* ================= ROLE / USER MANAGEMENT UPDATE ================= */ allowedManage=function(){return !!currentUser&&['SUPER_ADMIN','ADMIN','INSTRUCTOR'].includes(currentUser.role)}; function isAdmin(){return !!currentUser&&['SUPER_ADMIN','ADMIN'].includes(currentUser.role)} function isInstructor(){return !!currentUser&¤tUser.role==='INSTRUCTOR'} async function ownsCourse(courseId){ if(isAdmin())return true; if(!isInstructor())return false; const c=await get('courses',courseId); return !!c&&c.instructorId===currentUser.id; } async function ownedCourses(){ const cs=await all('courses'); return isAdmin()?cs:cs.filter(c=>c.instructorId===currentUser.id); } async function users(){ if(!isAdmin()&&!isInstructor()){alert('غير مصرح');return} const allUsers=await all('users'), allCourses=await all('courses'), ens=await all('enrollments'); const instructorScope=isInstructor(); const cs=instructorScope?allCourses.filter(c=>c.instructorId===currentUser.id):allCourses; const scopeIds=new Set(cs.map(c=>c.id)); const us=instructorScope ? allUsers.filter(u=>u.role==='STUDENT' && ens.some(e=>e.userId===u.id && scopeIds.has(e.courseId) && e.status!=='CANCELLED')) : allUsers; const statusLabel=u=>({ACTIVE:'نشط',SUSPENDED:'موقوف',PENDING_APPROVAL:'بانتظار الموافقة',REJECTED:'مرفوض',DELETED:'محذوف'})[u.status||'ACTIVE']||u.status||'نشط'; const roleLabel=u=>({SUPER_ADMIN:'Super Admin',ADMIN:'Admin',INSTRUCTOR:'Instructor',STUDENT:'Student'})[u.role]||u.role; const courseMap=new Map(cs.map(c=>[c.id,c])); const courseNamesForUser=u=>{ if(u.role==='INSTRUCTOR') return cs.filter(c=>c.instructorId===u.id).map(c=>c.title||'بدون اسم'); if(u.role==='STUDENT') return ens.filter(e=>e.userId===u.id).map(e=>courseMap.get(e.courseId)?.title).filter(Boolean); return []; }; const courseCellForUser=(u,names)=>{ if(u.role==='SUPER_ADMIN') return ''; if(u.role==='ADMIN') return 'إدارة المنصة'; if(!names.length) return 'لم يُسجل في كورس بعد'; if(names.length===1) return `${esc(names[0])}`; const first=esc(names[0]), rest=names.slice(1); // Store ALL enrolled courses so the dropdown shows the first course as well. const payload=encodeURIComponent(JSON.stringify(names)); return ``; }; const render=()=>{ const q=(document.getElementById('userSearch')?.value||'').trim().toLowerCase(); const cf=document.getElementById('userCourseFilter')?.value||'ALL'; const rf=document.getElementById('userRoleFilter')?.value||'ALL'; const sf=document.getElementById('userStatusFilter')?.value||'ALL'; const selectedCourse=cf==='ALL'?null:courseMap.get(cf); const filtered=us.filter(u=>{ const names=courseNamesForUser(u); const text=[u.name,u.email,...names].join(' ').toLowerCase(); const qok=!q||text.includes(q); const rok=rf==='ALL'||u.role===rf; const stok=sf==='ALL'||(u.status||'ACTIVE')===sf; let cok=true; if(selectedCourse){ cok = u.role==='INSTRUCTOR' ? u.id===selectedCourse.instructorId : u.role==='STUDENT' ? ens.some(e=>e.userId===u.id&&e.courseId===selectedCourse.id) : false; } return qok&&rok&&stok&&cok; }); const rows=filtered.map(u=>{ const st=u.status||'ACTIVE'; const names=courseNamesForUser(u); const visibleNames=cf==='ALL'?names:names.filter(n=>selectedCourse&&n===selectedCourse.title); const courseCell=courseCellForUser(u,visibleNames); const action=st==='PENDING_APPROVAL' ? `` : st==='ACTIVE' ? `` : st==='SUSPENDED' ? `` : ``; const profileBtn=u.role==='INSTRUCTOR' && st!=='PENDING_APPROVAL' ? `` : ''; return `${esc(u.name||'—')}
${esc(u.email||'—')}
${esc(roleLabel(u))}${courseCell}${esc(statusLabel(u))}${u.createdAt?new Date(u.createdAt).toLocaleDateString('ar-SA'):'—'}${u.role==='SUPER_ADMIN'?'':`
${profileBtn}${action}
`}`; }).join(''); const counts={total:filtered.length,students:filtered.filter(u=>u.role==='STUDENT').length,instructors:instructorScope?0:filtered.filter(u=>u.role==='INSTRUCTOR').length,pending:instructorScope?0:filtered.filter(u=>u.status==='PENDING_APPROVAL').length}; const table=rows||`
لا توجد حسابات مطابقة للفلاتر الحالية.
`; const host=document.getElementById('usersTableBody'); if(host)host.innerHTML=table; ['userTotal','userStudents','userInstructors','userPending'].forEach(id=>{const el=document.getElementById(id);if(el)el.textContent=counts[{userTotal:'total',userStudents:'students',userInstructors:'instructors',userPending:'pending'}[id]]}); const countEl=document.getElementById('userResultCount');if(countEl)countEl.textContent=`عرض ${filtered.length} من ${us.length} حساب`; }; app.innerHTML=`
${isInstructor()?"MIDAD INSTRUCTOR":"MIDAD ADMIN"}

إدارة الحسابات

${isInstructor()?"إدارة طلاب كورساتك فقط والتحكم في حالات حساباتهم.":"إدارة الطلاب والمحاضرين وربط كل حساب بالكورسات الخاصة به."}
إجمالي الحسابات${us.length}
الطلاب${us.filter(u=>u.role==='STUDENT').length}
المحاضرون${us.filter(u=>u.role==='INSTRUCTOR').length}
بانتظار الموافقة${us.filter(u=>u.status==='PENDING_APPROVAL').length}
SMART FILTER

فلترة الحسابات

عرض ${us.length} من ${us.length} حساب
ACCOUNT CONTROL

الحسابات

المستخدمالدورالكورسالحالةتاريخ التسجيلالإجراءات
`; window.usersFilterRender=()=>{ // Re-run the same filtering logic by reconstructing only the table from current controls. const q=(document.getElementById('userSearch')?.value||'').trim().toLowerCase(); const cf=document.getElementById('userCourseFilter')?.value||'ALL'; const rf=document.getElementById('userRoleFilter')?.value||'ALL'; const sf=document.getElementById('userStatusFilter')?.value||'ALL'; const selectedCourse=cf==='ALL'?null:courseMap.get(cf); const filtered=us.filter(u=>{ const names=courseNamesForUser(u), text=[u.name,u.email,...names].join(' ').toLowerCase(); const cok=!selectedCourse||(u.role==='INSTRUCTOR'?u.id===selectedCourse.instructorId:u.role==='STUDENT'?ens.some(e=>e.userId===u.id&&e.courseId===selectedCourse.id):false); return (!q||text.includes(q))&&(rf==='ALL'||u.role===rf)&&(sf==='ALL'||(u.status||'ACTIVE')===sf)&&cok; }); const body=document.getElementById('usersTableBody');if(!body)return; body.innerHTML=filtered.map(u=>{ const st=u.status||'ACTIVE', names=courseNamesForUser(u), visible=cf==='ALL'?names:names.filter(n=>selectedCourse&&n===selectedCourse.title); const courseCell=courseCellForUser(u,visible); const action=st==='PENDING_APPROVAL'?``:st==='ACTIVE'?``:st==='SUSPENDED'?``:``; return `${esc(u.name||'—')}
${esc(u.email||'—')}
${esc(roleLabel(u))}${courseCell}${esc(statusLabel(u))}${u.createdAt?new Date(u.createdAt).toLocaleDateString('ar-SA'):'—'}${u.role==='SUPER_ADMIN'?'':`
${action}
`}`; }).join('')||`
لا توجد حسابات مطابقة للفلاتر الحالية.
`; document.getElementById('userResultCount').textContent=`عرض ${filtered.length} من ${us.length} حساب`; document.getElementById('userTotal').textContent=filtered.length; document.getElementById('userStudents').textContent=filtered.filter(u=>u.role==='STUDENT').length; document.getElementById('userInstructors').textContent=filtered.filter(u=>u.role==='INSTRUCTOR').length; document.getElementById('userPending').textContent=filtered.filter(u=>u.status==='PENDING_APPROVAL').length; }; render(); } async function setUserStatus(id,status){ if(!isAdmin()&&!isInstructor())return alert('غير مصرح'); const u=await get('users',id); if(!u)return alert('المستخدم غير موجود'); if(isInstructor()){ if(u.role!=='STUDENT')return alert('المحاضر يستطيع التحكم في طلاب كورساته فقط.'); const mine=(await all('courses')).filter(c=>c.instructorId===currentUser.id).map(c=>c.id); const linked=(await all('enrollments')).some(e=>e.userId===u.id&&mine.includes(e.courseId)&&e.status!=='CANCELLED'); if(!linked)return alert('هذا الطالب غير مرتبط بكورساتك.'); } if(u.role==='SUPER_ADMIN')return alert('لا يمكن إيقاف حساب الأدمن الرئيسي'); u.status=status; await put('users',u); if(currentUser&¤tUser.id===id&&status!=='ACTIVE'){currentUser=null;sessionStorage.removeItem('midad');} notify(status==='SUSPENDED'?'تم إيقاف الحساب':'تم تفعيل الحساب'); await users(); } async function deleteUserAccount(id){ if(!isAdmin()&&!isInstructor())return alert('غير مصرح'); const u=await get('users',id); if(isInstructor()){ if(u?.role!=='STUDENT')return alert('المحاضر يستطيع التحكم في طلاب كورساته فقط.'); const mine=(await all('courses')).filter(c=>c.instructorId===currentUser.id).map(c=>c.id); const linked=(await all('enrollments')).some(e=>e.userId===u.id&&mine.includes(e.courseId)&&e.status!=='CANCELLED'); if(!linked)return alert('هذا الطالب غير مرتبط بكورساتك.'); } if(!u)return alert('الحساب غير موجود'); if(u.role==='SUPER_ADMIN')return alert('لا يمكن حذف حساب الأدمن الرئيسي'); if(u.status==='DELETED')return alert('الحساب محذوف بالفعل'); const ok=confirm(`حذف حساب ${u.name||u.email||'هذا المستخدم'}؟\n\nسيتم منع الحساب من تسجيل الدخول وإلغاء جميع أجهزته المسجلة.\n\nهذا الإجراء لا يمكن التراجع عنه.`); if(!ok)return; u.status='DELETED'; u.deletedAt=Date.now(); u.deletedBy=currentUser?.id||null; await put('users',u); const ds=(await all('devices')).filter(d=>d.userId===u.id&&d.status!=='REVOKED'); for(const d of ds){d.status='REVOKED';d.revokedAt=Date.now();d.revokedBy=currentUser?.id||null;await put('devices',d)} if(currentUser&¤tUser.id===u.id){currentUser=null;sessionStorage.removeItem('midad')} notify('تم حذف الحساب وإلغاء أجهزته ✓'); await users(); } async function approveInstructor(id){ if(!isAdmin())return alert('غير مصرح'); const u=await get('users',id); if(!u)return alert('المستخدم غير موجود'); u.status='ACTIVE'; await put('users',u); await put('notifications',{id:'n-'+crypto.randomUUID(),userId:u.id,title:'تمت الموافقة على حسابك',message:`تمت الموافقة على حساب ${u.role==='ADMIN'?'الأدمن':'المحاضر'} ويمكنك الآن تسجيل الدخول.`,createdAt:Date.now(),read:false}); notify(`تمت الموافقة على ${u.role==='ADMIN'?'الأدمن':'المحاضر'}`); if(document.getElementById('app')) await users(); } async function rejectInstructor(id){ if(!isAdmin())return alert('غير مصرح'); const u=await get('users',id); if(!u)return alert('المستخدم غير موجود'); u.status='REJECTED'; await put('users',u); await put('notifications',{id:'n-'+crypto.randomUUID(),userId:u.id,title:'تم رفض طلب الحساب',message:`تم رفض طلب إنشاء حساب ${u.role==='ADMIN'?'الأدمن':'المحاضر'} من إدارة MIDAD.`,createdAt:Date.now(),read:false}); notify(`تم رفض طلب ${u.role==='ADMIN'?'الأدمن':'المحاضر'}`); if(document.getElementById('app')) await users(); } async function openCourseManagement(ev){ if(ev&&ev.preventDefault)ev.preventDefault(); if(ev&&ev.stopPropagation)ev.stopPropagation(); if(!allowedManage()){alert('إدارة الكورسات متاحة للأدمن والمحاضر فقط');return;} try{ await manage(); } catch(err){ console.error('MIDAD course management error:',err); app.innerHTML=`
MIDAD SYSTEM

تعذر فتح إدارة الكورسات

${esc(err?.message||String(err))}
`; } } go=function(p,id){ header(); if(['manage','editor','media','users'].includes(p)&&!allowedManage()){alert('هذه الصفحة للإدارة والمحاضرين فقط');return} if(p==='users'&&!isAdmin()){alert('إدارة المستخدمين متاحة للأدمن فقط');return} if(['dashboard','notifications','orders','certificates','cart'].includes(p)&&!currentUser)return go('login'); const routes={home,courses,details,login,register,dashboard,manage,editor,media,player,checkout,orders,certificates,notifications,verify,users}; (routes[p]||home)(id); }; register=function(){ app.innerHTML=`
MIDAD ACCOUNT

إنشاء حساب

الطالب يمكنه الدخول مباشرة. حساب المحاضر يحتاج موافقة الإدارة قبل تسجيل الدخول.

`; }; doReg=async function(e){ e.preventDefault(); const us=await all('users'),email=document.getElementById('re').value.trim().toLowerCase(); if(us.some(u=>u.email===email))return alert('البريد مستخدم بالفعل'); const role=document.getElementById('rr').value; const status=(role==='INSTRUCTOR'||role==='ADMIN')?'PENDING_APPROVAL':'ACTIVE'; const u={id:'u-'+crypto.randomUUID(),name:document.getElementById('rn').value.trim(),email,password:await hash(document.getElementById('rp').value),role,status,createdAt:Date.now()}; await put('users',u); if(role==='INSTRUCTOR'){ app.innerHTML=`
MIDAD INSTRUCTOR

تم استلام طلبك

تم إنشاء حساب المحاضر بنجاح، لكنه بانتظار موافقة الإدارة.

لن تتمكن من تسجيل الدخول حتى توافق إدارة MIDAD على الحساب.

`; return; } currentUser=u;sessionStorage.setItem('midad',u.id);go('home'); }; doLogin=async function(e){ e.preventDefault(); const email=document.getElementById('em').value.trim().toLowerCase(),password=await hash(document.getElementById('pw').value); const u=(await all('users')).find(x=>x.email===email&&x.password===password); if(!u)return alert('بيانات الدخول غير صحيحة'); const status=u.status||'ACTIVE'; if(status==='PENDING_APPROVAL') return alert('حساب المحاضر ما زال بانتظار موافقة الإدارة.'); if(status==='SUSPENDED') return alert('هذا الحساب موقوف من إدارة MIDAD.'); if(status==='REJECTED') return alert('تم رفض طلب إنشاء هذا الحساب من إدارة MIDAD.'); currentUser=u;sessionStorage.setItem('midad',u.id); go(isAdmin()||isInstructor()?'manage':'dashboard'); }; manage=async function(){ if(!allowedManage())return; const cs=await ownedCourses(),us=await all('users'),os=await all('orders'),ens=await all('enrollments'); const pending=isAdmin()?us.filter(u=>(u.role==='INSTRUCTOR'||u.role==='ADMIN')&&u.status==='PENDING_APPROVAL'):[]; const ids=new Set(cs.map(c=>c.id)),ros=isAdmin()?os:os.filter(o=>ids.has(o.courseId)); const revenue=ros.filter(o=>o.paymentStatus==='PAID').reduce((a,o)=>a+Number(o.total||0),0); const students=isAdmin()?us.filter(u=>u.role==='STUDENT'):us.filter(u=>u.role==='STUDENT'&&ens.some(e=>ids.has(e.courseId)&&e.userId===u.id)); const published=cs.filter(c=>c.status==='PUBLISHED').length; const enrollmentData=cs.map(c=>({course:c,count:ens.filter(e=>e.courseId===c.id).length})).filter(x=>x.count>0).sort((a,b)=>b.count-a.count); const totalEnrollments=enrollmentData.reduce((a,x)=>a+x.count,0); const top=enrollmentData.slice(0,6),other=enrollmentData.slice(6).reduce((a,x)=>a+x.count,0); if(other)top.push({course:{title:'باقي الكورسات'},count:other}); let cursor=0; const palette=['#2563eb','#4f46e5','#06b6d4','#10b981','#f59e0b','#ef4444','#94a3b8']; const donutStops=totalEnrollments?top.map((x,i)=>{const start=(cursor/totalEnrollments)*100;cursor+=x.count;const end=(cursor/totalEnrollments)*100;return `${palette[i%palette.length]} ${start}% ${end}%`;}).join(', '):'#e5e7eb 0% 100%'; const donutLegend=top.length?top.map((x,i)=>`
${esc((x.course.title||'بدون اسم').slice(0,28))}${x.count}
`).join(''):'
لا توجد تسجيلات بعد.
'; const pendingBox=isAdmin()?`
ACTION REQUIRED

طلبات الحسابات الإدارية والمحاضرين

${pending.length} معلقة
${pending.length?pending.slice(0,5).map(u=>`
👤
${esc(u.name)}
${esc(u.email)}
`).join(''):'
لا توجد طلبات معلقة.
'}
`:''; app.innerHTML=`
${isAdmin()?'MIDAD ADMIN':'MIDAD INSTRUCTOR'}

لوحة التحكم

مرحبًا ${esc(currentUser.name)} — ملخص الأداء الحالي.
${isAdmin()?``:''}
ENROLLMENTS

توزيع الطلاب على الكورسات

نسبة التسجيلات الحالية لكل كورس
${totalEnrollments} تسجيل
${totalEnrollments}تسجيل
${donutLegend}
QUICK ACCESS

الوصول السريع

${isAdmin()?`
👥
المستخدمون
${us.length} حساب
`:''}
📚
الكورسات
${cs.length} كورس
🎬
الفيديو
مكتبة المحتوى
${pendingBox}
COURSES

كورساتي

${cs.length} كورس
${cs.map(c=>``).join('')}
الكورسالحالةالسعرالطلابإجراءات
${esc(c.title||'بدون اسم')}${c.status}${money(c.price,c.currency)}${ens.filter(e=>e.courseId===c.id).length}
`; }; /* Block direct access to other instructors' media deletion and video playback */ const _deleteMedia=deleteMedia; deleteMedia=async function(id){ const m=await get('media',id);if(!m)return; if(!(await ownsCourse(m.courseId)))return alert('لا تملك صلاحية حذف هذا الفيديو'); return _deleteMedia(id); }; const _playMedia=playMedia; playMedia=async function(id){ const m=await get('media',id);if(!m)return; if(!(await ownsCourse(m.courseId)))return alert('لا تملك صلاحية مشاهدة هذا الفيديو من مكتبة الإدارة'); return _playMedia(id); }; /* CSS for numeric dashboards and bar charts */ const roleStyle=document.createElement('style'); roleStyle.textContent=`.chart-panel{margin-top:18px}.bar-row{display:grid;grid-template-columns:minmax(120px,1fr) 3fr 55px;gap:12px;align-items:center;margin:12px 0}.bar-track{height:14px;border-radius:999px;background:rgba(127,127,127,.14);overflow:hidden}.bar-track i{display:block;height:100%;border-radius:999px;background:currentColor;opacity:.85}.bar-row b{text-align:left}@media(max-width:700px){.bar-row{grid-template-columns:1fr 2fr 45px;font-size:12px}}`; document.head.appendChild(roleStyle); const dashboardProStyle=document.createElement('style'); dashboardProStyle.textContent=` .chart-pill{display:inline-flex;align-items:center;padding:7px 12px;border-radius:999px;background:#eef4ff;color:#2563eb;font-weight:800;font-size:12px} .donut-wrap{display:grid;grid-template-columns:240px 1fr;gap:28px;align-items:center;padding:18px 4px 8px} .donut{width:210px;height:210px;border-radius:50%;display:grid;place-items:center;box-shadow:0 16px 35px rgba(37,99,235,.12)} .donut-hole{width:132px;height:132px;border-radius:50%;background:#fff;display:flex;flex-direction:column;align-items:center;justify-content:center;box-shadow:inset 0 0 0 1px #edf0f5} .donut-hole strong{font-size:32px;line-height:1;color:#0f172a}.donut-hole span{font-size:12px;color:#64748b;margin-top:7px} .donut-legend{display:grid;gap:10px;min-width:0}.donut-legend-item{display:grid;grid-template-columns:12px 1fr auto;gap:10px;align-items:center;padding:10px 12px;border:1px solid #edf0f5;border-radius:12px;background:#fff}.donut-legend-item i{width:10px;height:10px;border-radius:50%}.donut-legend-item span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.donut-legend-item b{font-size:13px;color:#0f172a} .users-filter-panel{background:linear-gradient(180deg,#fff,#fbfcff)}.users-filters{display:grid;grid-template-columns:2fr 1.4fr 1fr 1fr;gap:12px;margin-top:14px}.users-filters .field{display:flex;flex-direction:column;gap:7px}.users-filters .field>span{font-size:12px;font-weight:800;color:#475569}.users-filters input,.users-filters select{width:100%;min-height:44px;border:1px solid #e5e9f2;border-radius:12px;background:#fff;padding:0 13px;font:inherit;outline:none}.users-filters input:focus,.users-filters select:focus{border-color:#93b4ff;box-shadow:0 0 0 4px rgba(37,99,235,.08)} .users-table{min-width:980px}.course-tags{display:flex;flex-wrap:wrap;gap:6px;max-width:330px}.course-tag{display:inline-flex;max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:5px 9px;border-radius:999px;background:#f0f5ff;color:#2457c5;font-size:11px;font-weight:700}.course-more{font-size:11px;color:#64748b;padding:5px 2px} @media(max-width:900px){.donut-wrap{grid-template-columns:1fr}.donut{margin:auto}.users-filters{grid-template-columns:1fr 1fr}} @media(max-width:600px){.users-filters{grid-template-columns:1fr}.donut{width:185px;height:185px}.donut-hole{width:118px;height:118px}} `; document.head.appendChild(dashboardProStyle); /* V6 security + navigation patch */ const securePlayerCSS=document.createElement('style'); securePlayerCSS.textContent=` .secure-player-shell{position:relative;background:#000;border-radius:16px;overflow:hidden;box-shadow:0 20px 50px rgba(15,23,42,.18)} .secure-video{display:block;width:100%;max-height:72vh;background:#000;user-select:none;-webkit-user-select:none} .video-watermark-layer{position:absolute;inset:0;pointer-events:none;overflow:hidden;z-index:4} .video-watermark-tile{position:absolute;color:rgba(255,255,255,.22);font-size:14px;font-weight:800;letter-spacing:.03em;white-space:nowrap;text-shadow:0 1px 3px rgba(0,0,0,.7);transform:rotate(-24deg);user-select:none} .video-watermark-live{position:absolute;right:18px;bottom:18px;z-index:6;padding:8px 12px;border-radius:10px;background:rgba(0,0,0,.48);border:1px solid rgba(255,255,255,.2);color:rgba(255,255,255,.82);font-size:12px;line-height:1.5;text-align:right;backdrop-filter:blur(5px);pointer-events:none} .video-security-bar{display:flex;justify-content:space-between;gap:12px;align-items:center;padding:11px 14px;background:#0b1220;color:#dbeafe;font-size:12px;flex-wrap:wrap} .capture-shield{position:fixed;inset:0;z-index:99999;background:#07111f;display:none;align-items:center;justify-content:center;color:#fff;text-align:center;padding:25px} .capture-shield.show{display:flex} .capture-shield .shield-box{max-width:520px;border:1px solid rgba(255,255,255,.15);border-radius:18px;padding:30px;background:rgba(15,23,42,.94);box-shadow:0 20px 70px rgba(0,0,0,.35)} .capture-shield h2{margin:0 0 8px;font-size:28px}.capture-shield p{margin:0;color:#cbd5e1} @keyframes watermarkDrift{0%{transform:translate(0,0) rotate(-24deg)}50%{transform:translate(8px,-4px) rotate(-24deg)}100%{transform:translate(0,0) rotate(-24deg)}} .video-watermark-tile{animation:watermarkDrift 7s ease-in-out infinite} `; document.head.appendChild(securePlayerCSS); function ensureCaptureShield(){ let el=document.getElementById('captureShield'); if(el)return el; el=document.createElement('div');el.id='captureShield';el.className='capture-shield'; el.innerHTML='
🔒

Video Protection

Screen capture action detected. Playback has been paused. Return to the MIDAD video player to continue.

'; document.body.appendChild(el);return el; } window.resumeProtectedVideo=()=>{ const sh=ensureCaptureShield();sh.classList.remove('show'); const v=document.getElementById('midadVideo');if(v){v.play().catch(()=>{});} }; async function securePlayer(arg){ const [courseId,lectureId]=String(arg||'').split('|'); const c=await get('courses',courseId);if(!c)return alert('الكورس غير موجود'); const lecture=courseLectures(c).find(l=>l.id===lectureId);if(!lecture)return alert('المحاضرة غير موجودة'); const media=lecture.mediaId?await get('media',lecture.mediaId):null;if(!media)return alert('لا يوجد فيديو مرتبط بهذه المحاضرة'); let allowed=!!lecture.preview; if(currentUser){const ens=await all('enrollments');allowed=allowed||ens.some(e=>e.userId===currentUser.id&&e.courseId===courseId&&e.status==='ACTIVE');} if(!allowed){alert('هذه المحاضرة تتطلب التسجيل في الكورس.');details(courseId);return} const p=currentUser?await getProgress(currentUser.id,lectureId):null; const url=URL.createObjectURL(media.blob); const learnerName=currentUser?.name||'Preview Learner'; const learnerEmail=currentUser?.email||'preview@midad.local'; const watermarkText=esc(`${learnerName} • ${learnerEmail}`); const tiles=Array.from({length:12},(_,i)=>{const x=(i%3)*34+3,y=Math.floor(i/3)*25+4;return `${watermarkText}`}).join(''); app.innerHTML=`
${esc(c.title)}

${esc(lecture.title)}

🔒 Protected MIDAD lectureWatermarked for: ${watermarkText}Download controls disabled
${esc(lecture.title)}
0:00 / 0:00التقدم يُحفظ تلقائيًا

تقدمك في الكورس

جاري الحساب...
`; const video=document.getElementById('midadVideo'), progressBar=document.getElementById('videoProgress'), label=document.getElementById('timeLabel'); let lastSaved=0; const fmt=s=>{s=Math.max(0,Math.floor(s||0));return `${Math.floor(s/60)}:${String(s%60).padStart(2,'0')}`}; const shield=ensureCaptureShield(); video.addEventListener('loadedmetadata',()=>{if(p&&p.lastPositionSeconds>2&&p.lastPositionSeconds{const pct=video.duration?(video.currentTime/video.duration*100):0;progressBar.style.width=pct+'%';label.textContent=`${fmt(video.currentTime)} / ${fmt(video.duration)}`;if(currentUser&&video.currentTime-lastSaved>=5){lastSaved=video.currentTime;await saveProgress(courseId,lectureId,video.currentTime,video.duration,false)}}); video.addEventListener('pause',async()=>{if(currentUser)await saveProgress(courseId,lectureId,video.currentTime,video.duration,false)}); video.addEventListener('ended',async()=>{if(currentUser)await saveProgress(courseId,lectureId,video.duration,video.duration,true);progressBar.style.width='100%';notify('تم إكمال المحاضرة ✓');renderCourseProgressBox(courseId)}); ['contextmenu','dragstart'].forEach(evt=>video.addEventListener(evt,e=>e.preventDefault())); video.addEventListener('enterpictureinpicture',e=>{try{document.exitPictureInPicture()}catch(_){}}); const blockKeys=(e)=>{ const bad=e.key==='PrintScreen'||e.key==='F12'||(e.ctrlKey&&(e.key.toLowerCase()==='s'||e.key.toLowerCase()==='u'||e.key.toLowerCase()==='p'))||(e.ctrlKey&&e.shiftKey&&['i','j','c'].includes(e.key.toLowerCase())); if(bad){e.preventDefault();e.stopPropagation();video.pause();shield.classList.add('show');setTimeout(()=>{try{navigator.clipboard?.writeText('')}catch(_){}} ,0);return false;} }; document.addEventListener('keydown',blockKeys,true); const visibility=()=>{if(document.hidden&& !video.paused){video.pause();shield.classList.add('show')}}; document.addEventListener('visibilitychange',visibility); video.addEventListener('emptied',()=>URL.revokeObjectURL(url)); renderCourseProgressBox(courseId); } player=securePlayer; /* ===================== MIDAD V7: HERO SLIDER + COURSE/INSTRUCTOR MEDIA ===================== */ const midadV7Style=document.createElement('style'); midadV7Style.textContent=` .midad-brand-ar{font-weight:900;letter-spacing:.02em}.hero-slider{position:relative;overflow:hidden;background:#08111f;color:#fff;min-height:430px}.hero-slider .slides{position:relative;min-height:430px}.hero-slide{position:absolute;inset:0;opacity:0;transform:translateX(18px);transition:opacity .55s ease,transform .55s ease;pointer-events:none}.hero-slide.active{opacity:1;transform:none;pointer-events:auto}.hero-slide-bg{position:absolute;inset:0;background:linear-gradient(90deg,rgba(5,12,28,.98) 0%,rgba(8,20,48,.88) 48%,rgba(12,38,90,.58) 100%)}.hero-slide-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.5}.hero-slide-content{position:relative;z-index:2;min-height:430px;display:grid;grid-template-columns:1.1fr .9fr;align-items:center;gap:35px}.hero-slide-copy{padding:40px 0}.hero-slide-copy h1{font-size:clamp(34px,4vw,58px);line-height:1.12;margin:12px 0}.hero-slide-copy p{max-width:680px;color:#dbeafe;font-size:17px;line-height:1.9}.hero-course-visual{display:flex;justify-content:center;align-items:center}.hero-course-card{width:min(430px,100%);border:1px solid rgba(255,255,255,.18);border-radius:24px;overflow:hidden;background:rgba(255,255,255,.08);box-shadow:0 30px 80px rgba(0,0,0,.35);backdrop-filter:blur(10px)}.hero-course-card > img{display:block;width:100%;height:245px;object-fit:cover;background:linear-gradient(135deg,#172554,#2563eb)}.hero-course-card .instructor-mini{width:46px;height:46px;border-radius:50%;object-fit:cover;display:block;flex:0 0 46px;background:#eaf1ff;border:2px solid rgba(255,255,255,.72);box-shadow:0 6px 18px rgba(0,0,0,.18)}.hero-course-card .instructor-line{display:flex;align-items:center;gap:10px;color:#dbeafe;margin-top:10px}.hero-course-card .instructor-line span{min-width:0;line-height:1.5}.hero-course-info{padding:18px}.hero-course-info h3{font-size:23px;margin:0 0 8px}.hero-course-info .instructor-line{display:flex;align-items:center;gap:10px;color:#dbeafe}.instructor-mini{width:38px;height:38px;border-radius:50%;object-fit:cover;background:#eaf1ff;display:grid;place-items:center;color:#2563eb;font-weight:900;flex:0 0 auto}.slider-controls{position:absolute;z-index:5;left:0;right:0;bottom:24px;display:flex;align-items:center;justify-content:space-between}.slider-arrow{width:44px;height:44px;border-radius:50%;border:1px solid rgba(255,255,255,.25);background:rgba(15,23,42,.55);color:#fff;font-size:22px;cursor:pointer}.slider-dots{display:flex;gap:7px;align-items:center}.slider-dot{width:8px;height:8px;border-radius:50%;border:0;background:rgba(255,255,255,.35);cursor:pointer}.slider-dot.active{width:25px;border-radius:20px;background:#fff}.course .thumb.course-thumb{height:190px;position:relative;background:linear-gradient(135deg,#0b1d3b,#2563eb);overflow:hidden}.course .thumb.course-thumb img{width:100%;height:100%;object-fit:cover;display:block}.course .thumb.course-thumb .thumb-overlay{position:absolute;inset:auto 12px 12px auto;width:max-content;max-width:calc(100% - 24px);background:rgba(7,20,42,.86);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(96,165,250,.34);border-radius:999px;padding:7px 13px;color:#eaf3ff;font-size:11px;font-weight:800;line-height:1.2;display:flex;align-items:center;justify-content:center;box-shadow:0 8px 22px rgba(0,0,0,.22);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.course .course-body>.badge{display:none}@media (max-width:700px){.course .thumb.course-thumb .thumb-overlay{right:9px;bottom:9px;padding:6px 10px;font-size:10px;max-width:calc(100% - 18px)}}.instructor-card{display:flex;align-items:center;gap:14px;padding:14px 16px;border:1px solid var(--bd);background:#f8fafc;border-radius:14px;margin-top:16px}.instructor-card img{border:3px solid #fff;box-shadow:0 8px 20px rgba(15,23,42,.12)}.instructor-card img{width:64px;height:64px;border-radius:50%;object-fit:cover;background:#eaf1ff}.instructor-card .name{font-weight:900;font-size:18px}.image-upload-box{border:1px dashed #bfd0ea;border-radius:14px;padding:14px;background:#f8fbff}.image-preview{width:100%;height:170px;object-fit:cover;border-radius:12px;background:#eef4ff;display:block;margin-top:10px}.avatar-preview{width:84px;height:84px;border-radius:50%;object-fit:cover;background:#eef4ff;display:block;margin-top:10px}.upload-note{font-size:12px;color:#64748b;margin-top:7px;line-height:1.6} @media(max-width:900px){.hero-slide-content{grid-template-columns:1fr;min-height:520px;padding-bottom:65px}.hero-course-visual{display:none}.hero-slider,.hero-slider .slides{min-height:520px}.hero-slide-copy{padding:55px 0 85px}} @media(max-width:560px){.hero-slide-copy h1{font-size:34px}.hero-slide-copy p{font-size:15px}.slider-controls{bottom:15px}.hero-slide-content{min-height:500px}} `; document.head.appendChild(midadV7Style); function midadPlaceholder(title='MIDAD'){ const svg=`${String(title).replace(/[<>&]/g,'')}MIDAD | مِدَاد`; return 'data:image/svg+xml;charset=UTF-8,'+encodeURIComponent(svg); } function midadImage(c){return c?.thumbnail||midadPlaceholder(c?.title||'MIDAD')} function midadInstructorPhoto(c){return c?.instructorPhoto||''} function midadInstructorInitial(c){return esc((c?.instructorName||c?.instructor||'M')[0]||'M')} function readMidadImage(input,target,key,maxW,maxH){ const file=input?.files?.[0]; if(!file)return; if(!file.type.startsWith('image/')){alert('اختر صورة فقط.');input.value='';return} if(file.size>8*1024*1024){alert('حجم الصورة كبير. الحد الأقصى 8 MB.');input.value='';return} const reader=new FileReader(); reader.onload=()=>{ const img=new Image(); img.onload=()=>{ const scale=Math.min(1,maxW/img.width,maxH/img.height),w=Math.max(1,Math.round(img.width*scale)),h=Math.max(1,Math.round(img.height*scale)); const cv=document.createElement('canvas');cv.width=w;cv.height=h;const ctx=cv.getContext('2d');ctx.drawImage(img,0,0,w,h); const data=cv.toDataURL('image/jpeg',.84);window[key]=data;const el=document.getElementById(target);if(el)el.src=data; };img.src=reader.result; };reader.readAsDataURL(file); } card=function(c){ const count=courseLectures(c).length; const photo=midadInstructorPhoto(c); return `
${esc(c.title||'Course')}
${esc(c.category||'Course')}
${esc(c.category||'Course')}

${esc(c.title)}

${count} محاضرات • ${esc(c.level||'INTERMEDIATE')}
${esc(c.instructorName||c.instructor||'MIDAD Academy')}
${money(c.price,c.currency)}
`; }; home=async function(){ const cs=(await all('courses')).filter(c=>c.status==='PUBLISHED'); const slides=cs.slice(0,6); app.innerHTML=`
${slides.map((c,i)=>{ const ip=midadInstructorPhoto(c), rawTitle=(c.title||'MIDAD Course').toString(), title=esc(rawTitle), titleClass=rawTitle.length>100?'title-xxlong':rawTitle.length>70?'title-xlong':rawTitle.length>48?'title-long':rawTitle.length>30?'title-medium':''; return `
MIDAD | مِدَاد
${esc(c.category||'Course')}

${title}

${esc(c.description||'تعلّم مع محاضرين متخصصين واحصل على تجربة تعليمية احترافية.')}

${title}

${title}

المحاضر: ${esc(c.instructorName||c.instructor||'MIDAD Academy')}
${money(c.price,c.currency)}
`; }).join('')||`
MIDAD | مِدَاد

منصة تعليم إلكتروني متكاملة

أضف أول كورس منشور ليظهر هنا تلقائيًا في السلايدر.

`}
${slides.map((_,i)=>``).join('')}
ACADEMY

الكورسات المميزة

${slides.map(card).join('')||'
لا توجد كورسات منشورة.
'}
`; window._midadHeroIndex=0;window._midadHeroCount=slides.length;clearInterval(window._midadHeroTimer); if(slides.length>1)window._midadHeroTimer=setInterval(()=>midadHeroNext(),5000); }; function midadHeroRender(){const slides=[...document.querySelectorAll('.hero-slide')],dots=[...document.querySelectorAll('.slider-dot')];if(!slides.length)return;const n=slides.length;window._midadHeroIndex=(window._midadHeroIndex+n)%n;slides.forEach((s,i)=>s.classList.toggle('active',i===window._midadHeroIndex));dots.forEach((d,i)=>d.classList.toggle('active',i===window._midadHeroIndex));} window.midadHeroGo=i=>{window._midadHeroIndex=i;midadHeroRender();clearInterval(window._midadHeroTimer);if((window._midadHeroCount||0)>1)window._midadHeroTimer=setInterval(()=>midadHeroNext(),5000)}; window.midadHeroNext=()=>{window._midadHeroIndex=(window._midadHeroIndex||0)+1;midadHeroRender()}; window.midadHeroPrev=()=>{window._midadHeroIndex=(window._midadHeroIndex||0)-1;midadHeroRender()}; const __midadOriginalDetails=details; details=async function(id){ await __midadOriginalDetails(id); const c=await get('courses',id);if(!c)return; const first=document.querySelector('#app .panel');if(!first)return; const hero=document.createElement('div');hero.innerHTML=`
${esc(c.title)}
`;first.prepend(hero.firstElementChild); const instructor=document.createElement('div');instructor.className='instructor-card';instructor.innerHTML=`${c.instructorPhoto?``:`
${midadInstructorInitial(c)}
`}
INSTRUCTOR
${esc(c.instructorName||c.instructor||'MIDAD Academy')}
محاضر الكورس
`;first.appendChild(instructor); }; editor=async function(id){ const isNew=id==='new';let c; if(isNew){c={id:'course-'+crypto.randomUUID(),title:'',slug:'',category:'Cost Control',instructor:'',instructorName:currentUser?.name||'',instructorPhoto:'',instructorId:currentUser?.id||null,description:'',level:'INTERMEDIATE',language:'ar',price:0,currency:'SAR',accessType:'LIFETIME',accessDays:null,status:'DRAFT',featured:false,thumbnail:'',sections:[],createdAt:Date.now()};id=c.id;await put('courses',c)}else{c=await get('courses',id);if(!c)return alert('الكورس غير موجود')} window._editingCourseId=c.id;window._courseImageData=c.thumbnail||'';window._instructorPhotoData=c.instructorPhoto||''; app.innerHTML=`
COURSE BUILDER

${isNew?'إضافة كورس':'تعديل الكورس'}

COURSE MEDIA

صورة الكورس

هذه الصورة ستظهر في الصفحة الرئيسية والسلايدر وبطاقات الكورسات. يفضل صورة أفقية 16:9.
INSTRUCTOR

بيانات محاضر الكورس

${c.instructorPhoto?``:``}
صورة المحاضر ستظهر بجانب اسمه في الكورس والصفحة الرئيسية. يفضل صورة شخصية واضحة.

Sections & Lectures

${c.sections.map(sectionHTML).join('')||'
أضف أول Section.
'}
`; }; saveCourse=async function(id){ try{const c=await get('courses',id);if(!c)return alert('تعذر العثور على الكورس.');const val=n=>{const el=document.getElementById(n);return el?el.value.trim():''};const title=val('ct');if(!title){alert('اكتب اسم الكورس');document.getElementById('ct')?.focus();return} c.title=title;c.slug=val('cs')||title.toLowerCase().replace(/\s+/g,'-').replace(/[^\w\u0600-\u06FF-]+/g,'');c.category=val('cc')||'General';c.description=val('cd');c.level=document.getElementById('cl')?.value||'INTERMEDIATE';c.price=Math.max(0,Number(document.getElementById('cp')?.value)||0);c.currency=document.getElementById('cu')?.value||'SAR';c.accessType=document.getElementById('ca')?.value||'LIFETIME';c.accessDays=c.accessType==='DAYS'?Math.max(1,Number(document.getElementById('days')?.value)||180):null;c.status=document.getElementById('status')?.value||'DRAFT';c.thumbnail=window._courseImageData||c.thumbnail||'';c.instructorName=val('ciname')||c.instructor||currentUser?.name||'MIDAD Academy';c.instructor=c.instructorName;c.instructorPhoto=window._instructorPhotoData||c.instructorPhoto||'';c.instructorId=c.instructorId||currentUser?.id||null;c.updatedAt=Date.now();await put('courses',c);const saved=await get('courses',id);if(!saved||saved.title!==c.title)throw new Error('تعذر التحقق من حفظ الكورس');notify(c.status==='PUBLISHED'?'تم حفظ ونشر الكورس ✓':'تم حفظ الكورس كمسودة ✓');await manage(); }catch(err){console.error(err);alert('حدث خطأ أثناء حفظ الكورس: '+(err?.message||err))} }; /* Ensure older courses get usable instructor/course media defaults without changing existing data. */ async function midadV7Migrate(){ const cs=await all('courses'); for(const c of cs){let changed=false;if(c.thumbnail===undefined){c.thumbnail='';changed=true}if(c.instructorName===undefined){c.instructorName=c.instructor||'MIDAD Academy';changed=true}if(c.instructorPhoto===undefined){c.instructorPhoto='';changed=true}if(changed)await put('courses',c)} } const __midadOriginalInit=init; init=async function(){await __midadOriginalInit();try{await midadV7Migrate()}catch(e){console.warn('V7 migration',e)}}; const midadV9Style=document.createElement('style');midadV9Style.id='midad-v9-slider-fit';midadV9Style.textContent=` /* V9 — fixed-height hero layout: title/description/actions always remain visible */ .hero-slider,.hero-slider .slides{min-height:480px;height:480px;overflow:hidden} .hero-slide{height:480px;overflow:hidden} .hero-slide-content{height:480px;min-height:480px;box-sizing:border-box;align-items:center} .hero-slide-copy{height:100%;max-height:none!important;overflow:visible!important;box-sizing:border-box;padding:58px 0 78px;display:flex;flex-direction:column;justify-content:center;min-width:0} .hero-slide-copy .eyebrow{flex:0 0 auto} .hero-slide-copy .badge{align-self:flex-start;margin-top:10px} .hero-slide-copy h1{flex:0 0 auto;max-width:760px;margin:12px 0 10px;overflow:visible;display:block;word-break:normal;overflow-wrap:anywhere} .hero-slide-copy p{flex:0 0 auto;max-width:700px;margin:0 0 18px;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;line-height:1.65;max-height:56px} .hero-slide-copy .actions{flex:0 0 auto;display:flex;gap:10px;flex-wrap:nowrap;align-items:center;margin-top:2px} .hero-slide-copy .actions .btn{white-space:nowrap} .hero-slide-copy h1.title-medium{font-size:clamp(31px,3.25vw,48px);line-height:1.08} .hero-slide-copy h1.title-long{font-size:clamp(28px,2.8vw,42px);line-height:1.1} .hero-slide-copy h1.title-xlong{font-size:clamp(25px,2.35vw,36px);line-height:1.12} .hero-slide-copy h1.title-xxlong{font-size:clamp(22px,2vw,31px);line-height:1.15} .hero-course-info h3.title-xxlong{font-size:15px} .hero-course-info h3.title-xlong{font-size:16px} .hero-course-info h3.title-long{font-size:18px} .slider-controls{bottom:14px;pointer-events:none} .slider-controls .slider-arrow,.slider-controls .slider-dot{pointer-events:auto} @media(max-width:900px){ .hero-slider,.hero-slider .slides,.hero-slide{height:540px;min-height:540px} .hero-slide-content{height:540px;min-height:540px;display:block;padding-bottom:70px} .hero-slide-copy{height:100%;padding:52px 0 82px;justify-content:center} .hero-course-visual{display:none} .hero-slide-copy h1.title-medium{font-size:34px} .hero-slide-copy h1.title-long{font-size:31px} .hero-slide-copy h1.title-xlong{font-size:27px} .hero-slide-copy h1.title-xxlong{font-size:24px} } @media(max-width:560px){ .hero-slider,.hero-slider .slides,.hero-slide{height:500px;min-height:500px} .hero-slide-content{height:500px;min-height:500px} .hero-slide-copy{padding:42px 0 76px} .hero-slide-copy h1{max-width:100%} .hero-slide-copy h1.title-medium{font-size:29px} .hero-slide-copy h1.title-long{font-size:26px} .hero-slide-copy h1.title-xlong{font-size:23px} .hero-slide-copy h1.title-xxlong{font-size:21px} .hero-slide-copy p{font-size:14px;line-height:1.55;max-height:44px} .hero-slide-copy .actions{gap:8px} .hero-slide-copy .actions .btn{padding:10px 13px;font-size:13px} } `;document.head.appendChild(midadV9Style); /* V11 — Instructor profiles + rich course details + instructor self-service */ const midadV11Style=document.createElement('style'); midadV11Style.textContent=` .instructor-profile-grid{display:grid;grid-template-columns:320px 1fr;gap:22px;align-items:start} .instructor-profile-card{background:linear-gradient(145deg,#071a33,#173b83);color:#fff;border-radius:22px;padding:24px;text-align:center;box-shadow:0 18px 45px rgba(7,26,51,.16)} .instructor-profile-photo{width:150px;height:150px;border-radius:50%;object-fit:cover;display:block;margin:0 auto 16px;border:5px solid rgba(255,255,255,.9);box-shadow:0 12px 28px rgba(0,0,0,.2);background:#fff} .instructor-profile-card .muted{color:#cbd5e1}.instructor-slider{position:relative;overflow:hidden;border-radius:22px}.instructor-slide{display:none}.instructor-slide.active{display:block}.instructor-slide-grid{display:grid;grid-template-columns:340px 1fr;gap:28px;align-items:stretch}.instructor-slide-photo{width:100%;height:360px;object-fit:cover;border-radius:18px;background:#eaf1fb}.instructor-slide-info{padding:8px 0}.instructor-slide-info h1{margin:0 0 8px;font-size:36px;line-height:1.15}.instructor-stats{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0}.instructor-stat{padding:7px 11px;border-radius:999px;background:#eff6ff;color:#1d4ed8;font-size:12px;font-weight:800}.instructor-courses{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-top:14px}.instructor-course-mini{border:1px solid #e5eaf2;border-radius:13px;padding:11px;background:#fff;cursor:pointer}.instructor-course-mini:hover{border-color:#93b4ff;box-shadow:0 8px 20px rgba(37,99,235,.08)}.instructor-slider-controls{display:flex;justify-content:space-between;align-items:center;margin-top:14px}.instructor-dots{display:flex;gap:7px;justify-content:center;flex:1}.instructor-dot{width:9px;height:9px;border-radius:50%;border:0;background:#cbd5e1;padding:0}.instructor-dot.active{background:#2563eb;width:24px;border-radius:99px}.rich-course-grid{display:grid;grid-template-columns:1.35fr .65fr;gap:18px;margin-top:18px}.rich-list{display:grid;gap:9px}.rich-list-item{display:flex;gap:10px;align-items:flex-start;padding:11px 12px;border:1px solid #e8edf4;border-radius:12px;background:#fbfdff}.rich-list-item i{width:24px;height:24px;border-radius:50%;display:grid;place-items:center;background:#eff6ff;color:#2563eb;font-style:normal;font-weight:900;flex:0 0 24px}.course-meta-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}.course-meta-box{border:1px solid #e8edf4;border-radius:12px;padding:12px;background:#fff}.course-meta-box strong{display:block;font-size:17px;margin-top:4px}.profile-form-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}.profile-form-grid .full{grid-column:1/-1}.instructor-self-card{display:flex;align-items:center;gap:15px;padding:14px;border:1px solid #e7ebf2;border-radius:15px;background:#fbfdff}.instructor-self-photo{width:72px;height:72px;border-radius:50%;object-fit:cover;border:3px solid #fff;box-shadow:0 5px 15px rgba(15,23,42,.12)} @media(max-width:900px){.instructor-profile-grid,.instructor-slide-grid,.rich-course-grid{grid-template-columns:1fr}.instructor-slide-photo{height:320px}.instructor-courses{grid-template-columns:1fr}.profile-form-grid{grid-template-columns:1fr}.profile-form-grid .full{grid-column:auto}} @media(max-width:560px){.instructor-slide-photo{height:260px}.instructor-slide-info h1{font-size:28px}.course-meta-grid{grid-template-columns:1fr 1fr}} `; document.head.appendChild(midadV11Style); function midadProfilePhoto(u){return u?.photo||midadPlaceholder((u?.name||'M')[0]||'M')} function midadInstructorCoursesFor(u,cs){return cs.filter(c=>c.status==='PUBLISHED' && ((c.instructorId&&c.instructorId===u.id) || (!c.instructorId && (c.instructorName||c.instructor)===u.name)))} /* Admin can edit an instructor profile; instructors can edit their own profile. */ async function editInstructorProfile(id){ const u=await get('users',id); if(!u || u.role!=='INSTRUCTOR'){alert('حساب المحاضر غير موجود.');return} if(!isAdmin() && currentUser?.id!==id){alert('لا يمكنك تعديل ملف محاضر آخر.');return} window._midadEditingInstructorId=id;window._midadProfilePhoto=u.photo||''; app.innerHTML=`
INSTRUCTOR PROFILE

${isAdmin()?'إدارة ملف المحاضر':'ملفي كمحاضر'}

هذه البيانات تظهر للطلاب في قسم المحاضرين وصفحات الكورسات.

${esc(u.name||'')}

${esc(u.email||'')}
`; } /* Public instructors page: one-minute auto slider */ async function instructors(){ const us=(await all('users')).filter(u=>u.role==='INSTRUCTOR' && (u.status||'ACTIVE')==='ACTIVE'); const cs=await all('courses'); const data=us.map(u=>({u,courses:midadInstructorCoursesFor(u,cs)})).filter(x=>x.courses.length || x.u.bio || x.u.photo); if(!data.length){app.innerHTML=`
MIDAD INSTRUCTORS

المحاضرون

لا توجد ملفات محاضرين منشورة بعد.

`;return} const slides=data.map((x,i)=>{ const u=x.u, courses=x.courses, photo=midadProfilePhoto(u); return `
MIDAD INSTRUCTORS
${courses.length} كورسات منشورة
${esc(u.name)}
✓ محاضر معتمد
INSTRUCTOR PROFILE

${esc(u.name||'محاضر مِدَاد')}

${esc(u.headline||'محاضر متخصص في منصة مِدَاد')}

${esc(u.bio||'محاضر متخصص يقدم محتوى عمليًا واحترافيًا عبر منصة مِدَاد.')}

${courses.length}كورسات ${u.professionalExperience?'✓':'—'}خبرة مهنية ${u.academicExperience?'✓':'—'}خبرة علمية
▣

الخبرات المهنية

${esc(u.professionalExperience||'سيتم إضافة الخبرات المهنية قريبًا.')}

◆

الخبرات العلمية والأكاديمية

${esc(u.academicExperience||'سيتم إضافة المؤهلات والخبرات العلمية قريبًا.')}

AVAILABLE COURSES

الكورسات التي يقدمها المحاضر

${courses.length} كورسات
${courses.map(c=>`
${esc(c.title)}${esc(c.category||'Course')}

${esc(c.title)}

${money(c.price,c.currency)}
`).join('')}
`; }).join(''); app.innerHTML=`
MIDAD ACADEMY

محاضرو مِدَاد

تعرّف على نخبة المحاضرين وخبراتهم المهنية والعلمية والكورسات التي يقدمونها.

تعلم من الخبراء
Learn • Develop • Succeed
${slides}
${data.map((_,i)=>``).join('')}
`; window._midadInstructorIndex=0;window._midadInstructorCount=data.length;clearInterval(window._midadInstructorTimer);if(data.length>1)window._midadInstructorTimer=setInterval(midadInstructorNext,60000); } function midadInstructorRender(){const s=[...document.querySelectorAll('.instructor-slide')],d=[...document.querySelectorAll('.instructor-dot')];if(!s.length)return;const n=s.length;window._midadInstructorIndex=(window._midadInstructorIndex+n)%n;s.forEach((x,i)=>x.classList.toggle('active',i===window._midadInstructorIndex));d.forEach((x,i)=>x.classList.toggle('active',i===window._midadInstructorIndex));} window.midadInstructorGo=i=>{window._midadInstructorIndex=i;midadInstructorRender();clearInterval(window._midadInstructorTimer);if((window._midadInstructorCount||0)>1)window._midadInstructorTimer=setInterval(midadInstructorNext,60000)}; window.midadInstructorNext=()=>{window._midadInstructorIndex=(window._midadInstructorIndex||0)+1;midadInstructorRender()}; window.midadInstructorPrev=()=>{window._midadInstructorIndex=(window._midadInstructorIndex||0)-1;midadInstructorRender()}; /* Instructor profile editor */ async function instructorProfile(){ if(!currentUser || currentUser.role!=='INSTRUCTOR') return go('login'); return editInstructorProfile(currentUser.id); } async function saveInstructorProfile(){ const targetId=window._midadEditingInstructorId||currentUser?.id; const u=await get('users',targetId);if(!u||u.role!=='INSTRUCTOR'){alert('تعذر العثور على ملف المحاضر.');return} if(!isAdmin() && currentUser?.id!==targetId){alert('لا يمكنك تعديل ملف محاضر آخر.');return} u.name=document.getElementById('ipName')?.value.trim()||u.name; u.headline=document.getElementById('ipHeadline')?.value.trim()||''; u.bio=document.getElementById('ipBio')?.value.trim()||''; u.professionalExperience=document.getElementById('ipProfessional')?.value.trim()||''; u.academicExperience=document.getElementById('ipAcademic')?.value.trim()||''; u.photo=window._midadProfilePhoto||u.photo||'';u.updatedAt=Date.now(); await put('users',u); if(currentUser?.id===u.id){currentUser=u;sessionStorage.setItem('midad',u.id)} const cs=await all('courses'); for(const c of cs){ if(c.instructorId===u.id){c.instructorName=u.name;c.instructor=u.name;c.instructorPhoto=u.photo||c.instructorPhoto||'';await put('courses',c)} } window._midadEditingInstructorId=null;notify('تم تحديث ملف المحاضر ✓'); if(isAdmin()) return users(); return dashboard(); } /* ===================== MIDAD V12 NAVIGATION ===================== Clean public navigation. Management tools are not exposed in the public header. Admin gets an "الإضافات" menu; instructors get the same private management menu so they can manage their own courses/media. ================================================================== */ function v12NavButton(label, route, extra=''){ return ``; } function v12ExtrasMenu(){ const isAdmin = currentUser?.role === 'ADMIN' || currentUser?.role === 'SUPER_ADMIN'; const isInstructor = currentUser?.role === 'INSTRUCTOR'; if(!isAdmin && !isInstructor) return ''; const manageLabel = isAdmin ? 'إدارة الكورسات' : 'إدارة كورساتي'; return ``; } header=function(){ const navs = document.querySelector('.navlinks'); const publicLinks = `${v12NavButton('الرئيسية','home')}${v12NavButton('الكورسات','courses')}${currentUser ? v12NavButton('حسابي','dashboard') : ''}${v12NavButton('المحاضرون','instructors')}`; const privateExtras = currentUser ? v12ExtrasMenu() : ''; const auth = currentUser ? `
${esc(currentUser.name)}
${esc((currentUser.name||'?')[0])}
` : `
`; userbox.innerHTML = `${auth}`; }; const __v12BaseGo = go; go=function(p,id){ header(); if(['manage','editor','media','instructorProfile'].includes(p) && !allowedManage()){alert('هذه الصفحة للمحاضرين والإدارة فقط');return} if(['dashboard','notifications','orders','certificates','cart'].includes(p)&&!currentUser)return go('login'); const routes={home,courses,details,login,register,dashboard,manage,editor,media,player,checkout,orders,certificates,notifications,verify,users,instructors,instructorProfile}; (routes[p]||home)(id); }; /* Close private navigation when clicking outside it. */ document.addEventListener('click',function(e){ if(!e.target.closest('.nav-extra-wrap')) document.querySelectorAll('.nav-extra-wrap.open').forEach(x=>x.classList.remove('open')); }); /* V12 visual refinement */ (()=>{ const style=document.createElement('style'); style.textContent=` header{height:76px} #midadHeader{display:block!important} #midadHeader .nav>nav{display:none!important} .nav{gap:24px} .brand{font-size:26px;letter-spacing:.2px;white-space:nowrap} .navlinks.v12-nav{gap:3px;align-items:center;flex-wrap:nowrap} .navlinks.v12-nav .navlink{padding:10px 13px;font-weight:750;white-space:nowrap} .userbox{white-space:nowrap} .user-name{font-weight:700;max-width:150px;overflow:hidden;text-overflow:ellipsis} .auth-btn{min-width:88px;height:44px;font-size:15px} .icon-btn{width:42px;height:42px;padding:0;display:grid;place-items:center;background:#f1f5f9;border:1px solid #e2e8f0} .nav-extra-wrap{position:relative;display:inline-flex;align-items:center} .nav-extra-toggle{display:flex;align-items:center;gap:6px} .nav-extra-toggle span{font-size:13px;transition:transform .2s} .nav-extra-wrap.open .nav-extra-toggle span{transform:rotate(180deg)} .nav-extra-menu{position:absolute;top:calc(100% + 8px);right:0;min-width:190px;background:#fff;border:1px solid #e5eaf2;border-radius:14px;box-shadow:0 16px 40px rgba(15,23,42,.14);padding:7px;display:none;z-index:100} .nav-extra-wrap.open .nav-extra-menu{display:block} .nav-extra-item{width:100%;border:0;background:#fff;text-align:right;padding:11px 13px;border-radius:9px;font:inherit;font-weight:700;cursor:pointer;color:#0f172a} .nav-extra-item:hover{background:#eff6ff;color:#1d4ed8} @media(max-width:900px){header{height:auto;min-height:72px}.nav{padding-top:10px;padding-bottom:10px}.navlinks.v12-nav{display:flex;overflow-x:auto;max-width:58vw}.navlinks.v12-nav .navlink{padding:8px 9px;font-size:14px}.user-name{display:none}.nav-extra-menu{right:auto;left:0}} @media(max-width:560px){.brand{font-size:22px}.navlinks.v12-nav{max-width:100%;order:3;width:100%;justify-content:center}.nav{flex-wrap:wrap}.userbox{margin-right:auto}.auth-btn{min-width:78px;padding:9px 11px}} `; document.head.appendChild(style); })(); /* V14 HEADER HARDENING */ (()=>{ const style=document.createElement('style'); style.textContent=` #midadHeader .nav{display:flex!important;align-items:center;justify-content:space-between;gap:22px;min-height:76px} #midadHeader #userbox{display:flex!important;align-items:center;gap:14px;flex:1;justify-content:flex-end} #midadHeader .navlinks.v12-nav{display:flex!important;align-items:center;justify-content:center;gap:4px;flex:0 1 auto} #midadHeader .brand{flex:0 0 auto} #midadHeader .userbox{display:flex!important;align-items:center;gap:8px} @media(max-width:900px){#midadHeader .nav{flex-wrap:wrap}#midadHeader #userbox{width:100%;justify-content:center;flex-wrap:wrap}.navlinks.v12-nav{order:1;width:auto;max-width:100%;overflow-x:auto}} `; document.head.appendChild(style); })(); /* V15: Browser Back/Forward navigation for the single-file MIDAD app. Keeps the HTML app open and maps browser history to MIDAD screens. */ (()=>{ const __midadRouteGo = go; let __midadHistoryReady = false; function __midadState(route,id){ return {midad:true, route:route || 'home', id:id ?? null}; } go = function(route,id){ if(__midadHistoryReady){ const current = history.state; const next = __midadState(route,id); if(!current || current.midad !== true || current.route !== next.route || current.id !== next.id){ history.pushState(next,'',location.href); } } return __midadRouteGo(route,id); }; window.addEventListener('popstate', function(e){ const st=e.state; if(st && st.midad){ __midadRouteGo(st.route || 'home', st.id ?? undefined); return; } /* The first Back from the opened HTML file should stay inside MIDAD. */ if(__midadHistoryReady){ history.pushState(__midadState('home'),'',location.href); __midadRouteGo('home'); } }); /* Create an in-app starting point plus a duplicate guard entry. */ history.replaceState(__midadState('home'),'',location.href); history.pushState(__midadState('home',null), '', location.href); Promise.resolve(init()).then(()=>{ __midadHistoryReady=true; }); })();