diff --git a/frontend/src/routes/admin/+layout.svelte b/frontend/src/routes/admin/+layout.svelte
index 7bf33ac..d141dbf 100644
--- a/frontend/src/routes/admin/+layout.svelte
+++ b/frontend/src/routes/admin/+layout.svelte
@@ -1,65 +1,45 @@
{#if $token}
-
-
-
-
-
+
+ {#snippet children()}
+
+ {/snippet}
+
{/if}
-
-
diff --git a/frontend/src/routes/admin/+page.svelte b/frontend/src/routes/admin/+page.svelte
index 98791d3..801a9a3 100644
--- a/frontend/src/routes/admin/+page.svelte
+++ b/frontend/src/routes/admin/+page.svelte
@@ -1,147 +1,214 @@
-
-
-
-
-
-
-{#if loading && sessions.length === 0}
-
Loading sessions...
-{:else}
-
- {#each sessions as session}
-
-
Week {session.week_nr} - {session.date}
-
- {#if session.slots && session.slots.length > 0}
- {#each session.slots as slot}
-
-
- {slot.status}
- {slot.start_time} - {slot.end_time}
- {#if slot.code}
- {slot.code}
- {/if}
-
-
- {#if slot.status === 'closed'}
-
- {:else if slot.status === 'open'}
-
-
-
- {:else if slot.status === 'locked'}
-
-
- {/if}
-
-
- {/each}
- {:else}
-
No slots scheduled.
- {/if}
-
-
- {/each}
+
+
-
+
+
+ 0 ? `Code: ${openSlots[0].code ?? '—'}` : 'Kein Slot offen'}
+ accent={openSlots.length > 0 ? 'var(--green)' : undefined}
+ />
+
+
+
+
+
+
+
+
+
+ {#if loading && slotRows.length === 0}
+
+ Wird geladen…
+
+ {:else if slotRows.length === 0}
+
+ Noch keine Slots geplant.
+
+ {:else}
+
+
+
+ | Woche |
+ Datum |
+ Zeit |
+ Status |
+ Code |
+ Aktionen |
+
+
+
+ {#each slotRows as { slot, session }, i}
+
+ |
+ {weekLabel(session.week_nr)}
+ |
+ {session.date} |
+
+ {slot.start_time}–{slot.end_time}
+ |
+ |
+
+ {#if slot.code}
+ {slot.code}
+ {:else}
+ —
+ {/if}
+ |
+
+
+ {#if slot.status === 'closed'}
+
+ {:else if slot.status === 'open'}
+ {#if slot.code}
+
+ {/if}
+ Anzeigen
+
+ {:else if slot.status === 'locked'}
+ Anzeigen
+
+ {/if}
+
+ |
+
+ {/each}
+
+
+ {/if}
+
+
+
diff --git a/frontend/src/routes/admin/attendance/+page.svelte b/frontend/src/routes/admin/attendance/+page.svelte
index f3a24e4..f6235f2 100644
--- a/frontend/src/routes/admin/attendance/+page.svelte
+++ b/frontend/src/routes/admin/attendance/+page.svelte
@@ -1,111 +1,220 @@
-
Attendance Matrix
+
-
-
-
- {#if sessions.length > 0}
-
- {/if}
-
-
-{#if data}
-
-
-
-
- | Student |
- {#each data.slots as slot}
- {slot.start_time} |
- {/each}
-
-
-
- {#each data.students as student}
-
- | {student.name} |
- {#each data.slots as slot}
- {@const present = data.attendances.some(a => a.slot_id === slot.id && a.student_id === student.id)}
- toggleAttendance(slot.id, student.id)}>
- {present ? '✓' : ''}
- |
- {/each}
-
- {/each}
-
-
+
+
-
+
+
+
+
+ {#if loading}
+
Wird geladen…
+ {/if}
+
+
+ {#if students.length === 0}
+
+ Keine Studierenden gefunden.
+
+ {:else}
+
+
+
+
+ | # |
+ Studierende:r |
+ {#each sessions as session, i}
+
+ W{String(session.week_nr).padStart(2, '0')}
+ |
+ {/each}
+ Anwesend |
+ Bonus |
+
+
+
+ {#each students as student, i}
+
+ |
+ {i + 1}
+ |
+
+
+
+ {initials(student.name)}
+
+ {student.name}
+
+ |
+ {#each sessions as session}
+ {@const slotIds = (session.slots ?? []).map((sl: any) => sl.id)}
+ {@const sessionPresent = slotIds.some((sid: number) => isPresent(sid, student.id))}
+
+ {#if slotIds.length > 0}
+
+ {:else}
+ —
+ {/if}
+ |
+ {/each}
+
+ {presentCount(student.id)} / {allSlotIds.length}
+ |
+
+ {#if allSlotIds.length > 0}
+
+ {#if bonusEligible(student.id)}
+
+ {:else}
+ —
+ {/if}
+
+ {:else}
+ —
+ {/if}
+ |
+
+ {/each}
+
+
+
+ {/if}
+
+
+
diff --git a/frontend/src/routes/admin/login/+page.svelte b/frontend/src/routes/admin/login/+page.svelte
index 9fcc2fa..ecea79a 100644
--- a/frontend/src/routes/admin/login/+page.svelte
+++ b/frontend/src/routes/admin/login/+page.svelte
@@ -1,82 +1,72 @@
-
+
-
+
+
+
+ Tutor·manager
+
+
Anwesenheit & Notizen für Tutorien.
+
+
+
+
+
Anmeldung
+
Willkommen zurück
+
+
+
+
+
+ Nur für Tutor:innen. Studierende nutzen den Link der Tutor:in.
+
+
+
+
~ Donnerstags ab 14 Uhr ~
+
+
diff --git a/frontend/src/routes/admin/students/+page.svelte b/frontend/src/routes/admin/students/+page.svelte
index b49f46f..50a0f40 100644
--- a/frontend/src/routes/admin/students/+page.svelte
+++ b/frontend/src/routes/admin/students/+page.svelte
@@ -1,8 +1,158 @@
-
-
Studierende
-
Studierende
+
+
+
+
+
+
+
+ {#if filtered.length === 0}
+
+
+ {search ? 'Keine Treffer.' : 'Noch keine Studierenden.'}
+
+
+ {:else}
+
+
+
+ | # |
+ Name |
+ Aktionen |
+
+
+
+ {#each filtered as student, i}
+
+ |
+ {i + 1}
+ |
+
+
+
+ {initials(student.name)}
+
+ {student.name}
+
+ |
+
+
+ |
+
+ {/each}
+
+
+ {/if}
+
+