diff --git a/README.md b/README.md index 1aabf46..1fcdf0e 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,9 @@ -

- School Library Logo -

# 📚 المكتبة المدرسية - نسخة تعليمية +# بوابة مدرسة النهضه الجديده -واجهة ويب ثابتة لعرض كتب مدرسية التعلم فقط. +هذا المستودع محدث ليصبح مخصصًا لمدرسة النهضه الجديده. يحتوي على واجهة ويب بسيطة مترجمة للعربية وتدعم الربط مع Firebase (Firestore, Storage, Auth). -## ✨ الميزات -- بحث فوري بالعنوان أو المؤلف -- فلاتر حسب المرحلة، التخصص، والصيغة -- تصميم خفيف ومتجاوب يعمل على أي متصفح +ملاحظات سريعة: +- أضفت لوحة إدارة لخلق الإعلانات والصفوف. +- يمكنك تسجيل دخول المسؤول عبر Email/Password (أنشئ المستخدم في Firebase auth ثم ضع في مجموعة users/{uid} الحقل role = 'admin'). +- لتشغيل: ضع إعدادات firebaseConfig في `index.html` ثم قم برفع المستودع إلى GitHub Pages أو Firebase Hosting. -## 🚀 التشغيل -افتح ملف `index.html` في المتصفح مباشرة -أو فعّل **GitHub Pages** من إعدادات المستودع لعرض الموقع أونلاين. - -## - -## 📜 الترخيص -MIT licnese ©2025 -moheynasir-ctrl diff --git a/app.js b/app.js new file mode 100644 index 0000000..d43245e --- /dev/null +++ b/app.js @@ -0,0 +1,172 @@ +// app.js — تكامل مع Firestore و Storage ومزايا الإدارة والرفع +const db = firebase.firestore(); +const auth = firebase.auth(); +const storage = firebase.storage(); + +// DOM helpers +const $ = id => document.getElementById(id); + +// Tab navigation +['ann','classes','teachers','attend','homework','admin'].forEach(k=>{ + $('tab-'+k).addEventListener('click', ()=> showTab(k === 'ann' ? 'announcements' : k === 'attend' ? 'attendance' : k === 'homework' ? 'homework' : k === 'admin' ? 'admin' : k+'s')); +}); +function showTab(id){ + document.querySelectorAll('.tab').forEach(s=>s.hidden=true); + document.getElementById(id).hidden=false; +} + +// Escape +function esc(s){ return String(s||'').replace(/[&<>\"']/g,m=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[m])); } + +// Renderers +function renderAnnouncements(docs){ + const ul = $('ann-list'); ul.innerHTML = ''; + docs.forEach(doc=>{ + const d = doc.data(); + const li = document.createElement('li'); + li.innerHTML = `${esc(d.title)}
${esc(d.body)}
${esc(d.date||'')}`; + ul.appendChild(li); + }); +} +function renderClasses(docs){ + const ul = $('class-list'); ul.innerHTML = ''; + docs.forEach(doc=>{ + const c = doc.data(); + const li = document.createElement('li'); + li.innerHTML = `${esc(c.name)}${esc(c.teacher)}`; + ul.appendChild(li); + }); +} +function renderTeachers(docs){ + const ul = $('teacher-list'); ul.innerHTML = ''; + docs.forEach(doc=>{ + const t = doc.data(); + const li = document.createElement('li'); + li.innerHTML = `${esc(t.name)}${esc(t.email||'')}`; + ul.appendChild(li); + }); +} +function renderAttendance(docs){ + const ul = $('att-log'); ul.innerHTML = ''; + docs.forEach(doc=>{ + const a = doc.data(); + const ts = a.createdAt && a.createdAt.toDate ? a.createdAt.toDate().toLocaleString() : ''; + const li = document.createElement('li'); li.textContent = `${ts} — ${a.name} — ${a.status}`; + ul.appendChild(li); + }); +} +function renderHomework(docs){ + const ul = $('hw-list'); ul.innerHTML = ''; + docs.forEach(doc=>{ + const h = doc.data(); + const li = document.createElement('li'); + const link = h.fileUrl ? ` تحميل الملف` : ''; + li.innerHTML = `${esc(h.title)} — ${esc(h.student)}${link} ${h.createdAt && h.createdAt.toDate ? h.createdAt.toDate().toLocaleString() : ''}`; + ul.appendChild(li); + }); +} + +// Auth: admin login (email/password) or anonymous for normal users +auth.onAuthStateChanged(user=>{ + if(user){ + // show admin if custom claim or if email verified — for simplicity, we check a field in users collection + db.collection('users').doc(user.uid).get().then(snap=>{ + const isAdmin = snap.exists && snap.data().role === 'admin'; + $('admin-logout').hidden = false; + if(isAdmin){ + $('admin-actions').hidden = false; + } else { + $('admin-actions').hidden = true; + } + }).catch(()=>{ $('admin-actions').hidden = true; }); + setupRealtime(); + }else{ + // sign in anonymously for regular usage + auth.signInAnonymously().catch(()=>{ /* ignore */ }); + } +}); + +// Admin login buttons +$('admin-login').addEventListener('click', async ()=>{ + const email = $('admin-email').value.trim(); + const pass = $('admin-pass').value; + if(!email || !pass) return alert('أدخل بيانات الدخول'); + try{ + await auth.signInWithEmailAndPassword(email, pass); + // after login, back-end (you) can set users/{uid}.role = 'admin' in Firestore + $('admin-actions').hidden = false; + alert('تم تسجيل الدخول كمسؤول'); + }catch(e){ alert('فشل تسجيل الدخول: '+e.message); } +}); +$('admin-logout').addEventListener('click', ()=>auth.signOut()); + +// Add announcement (admin) +$('add-ann-form').addEventListener('submit', async e=>{ + e.preventDefault(); + const title = $('ann-title').value.trim(); + const body = $('ann-body').value.trim(); + if(!title || !body) return; + await db.collection('announcements').add({title, body, date: new Date().toISOString()}); + $('ann-title').value=''; $('ann-body').value=''; +}); + +// Add class (admin) +$('add-class-form').addEventListener('submit', async e=>{ + e.preventDefault(); + const name = $('class-name').value.trim(); + const teacher = $('class-teacher').value.trim(); + if(!name) return; + await db.collection('classes').add({name, teacher}); + $('class-name').value=''; $('class-teacher').value=''; +}); + +// Attendance form +$('att-form').addEventListener('submit', async e=>{ + e.preventDefault(); + const name = $('att-name').value.trim(); + const status = $('att-status').value; + if(!name) return; + await db.collection('attendance').add({name, status, createdAt: firebase.firestore.FieldValue.serverTimestamp()}); + $('att-name').value=''; +}); + +// Homework upload +$('hw-form').addEventListener('submit', async e=>{ + e.preventDefault(); + const title = $('hw-title').value.trim(); + const student = $('hw-student').value.trim(); + const file = $('hw-file').files[0]; + if(!title||!student||!file) return alert('املأ الحقول واختر ملف'); + const path = `homework/${Date.now()}_${file.name}`; + const ref = storage.ref(path); + const snap = await ref.put(file); + const url = await snap.ref.getDownloadURL(); + await db.collection('homework').add({title, student, fileUrl: url, createdAt: firebase.firestore.FieldValue.serverTimestamp()}); + $('hw-title').value=''; $('hw-student').value=''; $('hw-file').value=''; + alert('تم إرسال الواجب'); +}); + +// Real-time listeners +function setupRealtime(){ + db.collection('announcements').orderBy('date','desc').onSnapshot(snap => renderAnnouncements(snap.docs)); + db.collection('classes').orderBy('name').onSnapshot(snap => renderClasses(snap.docs)); + db.collection('teachers').orderBy('name').onSnapshot(snap => renderTeachers(snap.docs)); + db.collection('attendance').orderBy('createdAt','desc').limit(50).onSnapshot(snap => renderAttendance(snap.docs)); + db.collection('homework').orderBy('createdAt','desc').onSnapshot(snap => renderHomework(snap.docs)); +} + +// Search (simple client-side) +$('search').addEventListener('input', e=>{ + const q = e.target.value.trim().toLowerCase(); + // filter announcements client-side (simple) + db.collection('announcements').orderBy('date','desc').get().then(snap=>{ + const docs = snap.docs.filter(d=>{ + const t = (d.data().title||'') + ' ' + (d.data().body||''); + return t.toLowerCase().includes(q); + }); + renderAnnouncements(docs); + }); +}); + +// initial tab +showTab('announcements'); diff --git a/data.json b/data.json new file mode 100644 index 0000000..83cc10d --- /dev/null +++ b/data.json @@ -0,0 +1,11 @@ +{ + "announcements": [ + {"id":1,"title":"مرحباً بكم في مدرسة النهضه الجديده","body":"نرحب بجميع الطلبة وأولياء الأمور في العام الدراسي الجديد.","date":"2026-01-02"} + ], + "classes": [ + {"id":1,"name":"الصف الأول","teacher":"أ. فاطمة"} + ], + "teachers": [ + {"id":1,"name":"أ. فاطمة","email":"fatima@nahda.edu"} + ] +} diff --git a/index.html b/index.html index 3e5d103..8bbe2df 100644 --- a/index.html +++ b/index.html @@ -1,58 +1,127 @@ - - + + - - - المكتبة المدرسية - نسخة تعليمية - + + + بوابة مدرسة النهضه الجديده + + - -
-

المكتبة المدرسية

-

نسخة تعليمية تجريبية ببيانات وهمية لأغراض التعلم فقط

+ +
+
+ +

مدرسة النهضه الجديده

+
+
-
-
- - -
-
- - -
-
- - -
-
- - -
- -
+
+
+
+ + +
+

الإعلانات

+
    +
    + + + + + + + + + + +
    -
    + + + + + - + - + + diff --git a/logo-192.svg b/logo-192.svg new file mode 100644 index 0000000..6560fd5 --- /dev/null +++ b/logo-192.svg @@ -0,0 +1,6 @@ + + + + + النهضه + diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..063b9f0 --- /dev/null +++ b/manifest.json @@ -0,0 +1,15 @@ +{ + "name": "بوابة مدرسة النهضه الجديده", + "short_name": "النهضه", + "start_url": ".", + "display": "standalone", + "background_color": "#ffffff", + "theme_color": "#c1121f", + "icons": [ + { + "src": "logo-192.svg", + "sizes": "192x192", + "type": "image/svg+xml" + } + ] +} diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..a5ac12a --- /dev/null +++ b/styles.css @@ -0,0 +1,26 @@ +:root{ + --bg:#fff; + --card:#fff; + --accent:#c1121f; /* أحمر قوي */ + --dark:#0b0b0b; /* أسود */ + --muted:#666; +} +*{box-sizing:border-box} +body{font-family:system-ui,Segoe UI,Arial; background:var(--bg); margin:0; color:var(--dark); line-height:1.4} +header{background:linear-gradient(90deg,var(--dark),var(--accent)); color:#fff; padding:12px} +.brand{display:flex;align-items:center;gap:10px} +.brand h1{margin:0;font-size:1.1rem} +nav{margin-top:8px;display:flex;gap:8px;flex-wrap:wrap} +nav button{background:transparent;color:#fff;border:1px solid rgba(255,255,255,.18);padding:6px 10px;border-radius:6px;cursor:pointer} +main{padding:12px} +.tab{background:var(--card);padding:12px;border-radius:8px;box-shadow:0 1px 6px rgba(0,0,0,.08);margin-bottom:12px} +.toolbar{display:flex;gap:8px;align-items:center;margin-bottom:8px} +input[type="text"],input[type="email"],input,textarea,select{width:100%;padding:8px;border:1px solid #ddd;border-radius:6px} +button{background:var(--accent);color:white;border:none;padding:8px 12px;border-radius:6px;cursor:pointer} +ul{list-style:none;padding:0;margin:0} +li{padding:10px;border-bottom:1px solid #eee} +.rtl{direction:rtl} +#att-log li,#hw-list li{font-size:0.95rem} +@media(min-width:800px){ + main{max-width:900px;margin:12px auto} +} diff --git a/sw.js b/sw.js new file mode 100644 index 0000000..bb7104e --- /dev/null +++ b/sw.js @@ -0,0 +1,8 @@ +const CACHE_NAME = 'nahda-cache-v1'; +const ASSETS = ['/', '/index.html', '/styles.css', '/app.js', '/manifest.json', '/logo-192.svg']; +self.addEventListener('install', e=>{ + e.waitUntil(caches.open(CACHE_NAME).then(c=>c.addAll(ASSETS))); +}); +self.addEventListener('fetch', e=>{ + e.respondWith(caches.match(e.request).then(r=>r||fetch(e.request))); +});