feat: add teacher system with approval flow
- Teacher registration requires subject selection; account starts pending - Admin approves/rejects via existing admin panel - Teacher panel (Materialien, Ankündigungen, Prüfungen, Noten) visible only to approved teachers - Students see class materials and announcements via sidebar overlays - Teachers can assign grades to students (scoped to own subject) - New tables: teacher_materials, teacher_announcements, teacher_exams, teacher_assigned_grades - subject column added to users; included in JWT and /api/me - requireTeacher middleware fetches fresh status+subject from DB on every request - Login hint: username is the part of the school email before the @
This commit is contained in:
+23
-6
@@ -212,6 +212,7 @@ footer a:hover { color: #2563eb; }
|
||||
<div class="field">
|
||||
<label for="l-user">Benutzername</label>
|
||||
<input type="text" id="l-user" autocomplete="username" placeholder="dein.name" required>
|
||||
<span style="font-size:11px;color:#9ca3af;margin-top:2px">Der Teil deiner Schul-E-Mail vor dem @</span>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="l-pass">Passwort</label>
|
||||
@@ -232,9 +233,22 @@ footer a:hover { color: #2563eb; }
|
||||
<div class="notice notice-amber" id="teacher-notice">
|
||||
<i data-lucide="info" aria-hidden="true"></i> Lehrerkonten werden nach der Registrierung von einem Administrator geprüft und freigeschaltet.
|
||||
</div>
|
||||
<div class="field" id="subject-field" style="display:none">
|
||||
<label for="r-subject">Lehrfach</label>
|
||||
<select id="r-subject" style="padding:9px 12px;border:1px solid #e5e7eb;border-radius:7px;font-size:14px;font-family:inherit;color:#111827;background:#fff;outline:none;transition:border-color .12s">
|
||||
<option value="">– Fach auswählen –</option>
|
||||
<option>Deutsch</option><option>Mathematik</option><option>Englisch</option>
|
||||
<option>Informatik</option><option>Wirtschaft</option><option>Buchführung</option>
|
||||
<option>BWL</option><option>VWL</option><option>Recht</option>
|
||||
<option>Rechnungswesen</option><option>Sport</option><option>Religion</option>
|
||||
<option>Geschichte</option><option>Gemeinschaftskunde</option><option>Physik</option>
|
||||
<option>Chemie</option><option>Biologie</option><option>Sozialkunde</option>
|
||||
<option>Ethik</option><option>Sonstiges</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="r-email">Schul E-Mail</label>
|
||||
<input type="email" id="r-email" autocomplete="email" placeholder="vorname.nachname@ifb-schulen.com" required>
|
||||
<input type="email" id="r-email" autocomplete="email" placeholder="Schul E-Mail-Adresse" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="r-pass">Passwort</label>
|
||||
@@ -265,6 +279,7 @@ function selectRole(r) {
|
||||
document.getElementById('role-teacher').classList.toggle('active', r === 'teacher');
|
||||
document.getElementById('role-teacher').classList.toggle('teacher', r === 'teacher');
|
||||
document.getElementById('teacher-notice').classList.toggle('show', r === 'teacher');
|
||||
document.getElementById('subject-field').style.display = r === 'teacher' ? '' : 'none';
|
||||
document.getElementById('reg-btn').textContent = r === 'teacher' ? 'Als Lehrer/in registrieren' : 'Account erstellen';
|
||||
}
|
||||
|
||||
@@ -292,12 +307,14 @@ async function doLogin(e) {
|
||||
|
||||
async function doRegister(e) {
|
||||
e.preventDefault(); clearErr('reg-err');
|
||||
const body = {
|
||||
email: document.getElementById('r-email').value,
|
||||
password: document.getElementById('r-pass').value,
|
||||
role: selectedRole,
|
||||
};
|
||||
if (selectedRole === 'teacher') body.subject = document.getElementById('r-subject').value;
|
||||
const r = await fetch('/api/register', { method:'POST', headers:{'Content-Type':'application/json'},
|
||||
body: JSON.stringify({
|
||||
email: document.getElementById('r-email').value,
|
||||
password: document.getElementById('r-pass').value,
|
||||
role: selectedRole
|
||||
}) });
|
||||
body: JSON.stringify(body) });
|
||||
const d = await r.json();
|
||||
if (!r.ok) { showErr('reg-err', d.error); return; }
|
||||
if (d.pending) {
|
||||
|
||||
Reference in New Issue
Block a user