-
-
-
-
-
-
-
-
- {#each sessions as session}
-
-
-
- {#each session.slots || [] as slot}
-
- {slot.start_time}-{slot.end_time}
-
-
- {/each}
-
-
- {/each}
-
+
+
+
+
+
+
+
Neue Sitzung anlegen
+
+
+
+
+
+
+ {#if sessions.length === 0}
+
+ Noch keine Sitzungen angelegt.
+
+ {:else}
+
+ {#each sessions as session}
+
+
+
+ W{String(session.week_nr).padStart(2, '0')}
+ {session.date}
+
+
+
+
+ {#if (session.slots ?? []).length === 0}
+
+ Noch kein Slot für diese Sitzung.
+
+ {:else}
+
+
+ {#each session.slots ?? [] as slot, i}
+
+ |
+ {slot.start_time}–{slot.end_time}
+ |
+ |
+
+ {#if slot.code}
+ {slot.code}
+ {:else}
+ —
+ {/if}
+ |
+
+
+ {#if slot.status === 'open' || slot.status === 'locked'}
+ Anzeigen
+ {/if}
+
+
+ |
+
+ {/each}
+
+
+ {/if}
+
+ {/each}
+
+ {/if}
-
+
+{#if selectedSessionId !== null}
+ {@const sess = sessions.find((s: Session) => s.id === selectedSessionId)}
+
+{/if}
diff --git a/frontend/src/routes/s/[code]/+page.svelte b/frontend/src/routes/s/[code]/+page.svelte
index 84e778e..80458a0 100644
--- a/frontend/src/routes/s/[code]/+page.svelte
+++ b/frontend/src/routes/s/[code]/+page.svelte
@@ -1,124 +1,385 @@
-
- {#if loading}
-
Loading...
- {:else if error}
-
{error}
- {:else if slot}
-
Check-in: {slot.start_time} - {slot.end_time}
-
- {#if slot.status === 'locked'}
-
Check-in is currently locked by the tutor.
- {/if}
+
- {#if !myAttendance && slot.status === 'open'}
-
-
-
-
- {:else if myAttendance}
-
You are checked in as {students.find(s => s.id === myAttendance.student_id)?.name || 'Student'}
- {/if}
+ {#if step === 'loading'}
+
+ Wird geladen…
+
-
-
Select a seat to check in:
-
+ {:else if step === 'error'}
+
+
+ {:else if step === 'locked'}
+
+
+
Anwesenheit
+
+ Erfassung abgeschlossen
- {/if}
-
+
+
+ {#if myAttendance}
+
✓ ANWESEND
+
Du wurdest als anwesend eingetragen.
+ {:else}
+
Der Check-in-Link ist nicht mehr aktiv.
+
Wende dich an deine:n Tutor:in.
+ {/if}
+
+ {#if slot}
+
{slot.start_time}–{slot.end_time}
+ {/if}
+
-
+ {:else if !isDesktop}
+
+
+ {#if step === 'name'}
+
+
+
Check-in
+
Wer bist du?
+
Wähle deinen Namen aus der Liste.
+
+
+ {#if errorMsg}
+
+ {errorMsg}
+
+ {/if}
+
+
+
+
+
+ {#if slot}
+
{slot.start_time}–{slot.end_time}
+ {/if}
+
+
+ {:else if step === 'seat' && selectedStudent}
+
+
+
Hallo, {selectedStudent.name.split(' ')[0]} 👋
+
Wähle deinen Sitz
+
Tippe auf einen freien Platz.
+
+
+ {#if errorMsg}
+
+ {errorMsg}
+
+ {/if}
+
+
+ checkin(seat.id)}
+ />
+
+
+
+
+ Dein Platz
+
+
+ Belegt
+
+
+ Frei
+
+
+
+
+
+
+ {:else if step === 'confirmed' && (myAttendance || selectedStudent)}
+
+
+
+ Du sitzt auf Platz {myAttendance?.seat_id ?? '—'}
+
+
+
+
+
✓ ANWESEND
+
Eingecheckt um {myAttendance?.checked_in_at?.slice(11, 16) ?? '—'} Uhr
+
+
+
+
+
+
+
+
+ {/if}
+
+ {:else}
+
+
+ {#if step === 'name'}
+
+
+
Check-in
+
Wer bist du?
+
Wähle deinen Namen aus der Liste.
+
+
+ {#if errorMsg}
+
+ {errorMsg}
+
+ {/if}
+
+
+
+
+
+
+ {:else if step === 'seat' && selectedStudent}
+
+
+
+
+
Hallo, {selectedStudent.name.split(' ')[0]} 👋
+
Wähle deinen Sitz
+
+
+ {#if errorMsg}
+
+ {errorMsg}
+
+ {/if}
+
+
checkin(seat.id)}
+ />
+
+
+
+ Dein Platz
+
+
+ Belegt
+
+
+ Frei
+
+
+
+
+
+
+
+
Sitzung
+ {#if slot}
+
{slot.start_time}–{slot.end_time}
+ {/if}
+
+
+
+
+
Anwesend
+
{attendances.length}
+
von {students.length} Studierenden
+
+
+
+
+
+
+ {:else if step === 'confirmed'}
+
+
+
+
+
Eingecheckt
+
+ Du sitzt auf Platz {myAttendance?.seat_id ?? '—'}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
✓ ANWESEND
+
+ {myAttendance?.checked_in_at?.slice(11, 16) ?? '—'} Uhr
+
+
+
+ {#if slot}
+
+
Sitzung
+
{slot.start_time}–{slot.end_time}
+
+ {/if}
+
+
+
Anwesende
+
{attendances.length} / {students.length}
+
+
+
+ {/if}
+ {/if}
+
+