feat: extend event toolkit and polish guest pwa

This commit is contained in:
Codex Agent
2025-10-28 18:28:22 +01:00
parent f29067f570
commit a7bbf230fd
45 changed files with 3809 additions and 351 deletions

View File

@@ -16,8 +16,8 @@ export const messages: Record<LocaleCode, NestedMessages> = {
common: {
hi: 'Hi',
actions: {
close: 'Schliessen',
loading: 'Laedt...',
close: 'Schließen',
loading: 'Lädt...',
},
},
navigation: {
@@ -30,34 +30,34 @@ export const messages: Record<LocaleCode, NestedMessages> = {
loading: 'Lade Event...',
stats: {
online: 'online',
tasksSolved: 'Aufgaben geloest',
tasksSolved: 'Aufgaben gelöst',
},
},
eventAccess: {
loading: {
title: 'Wir pruefen deinen Zugang...',
title: 'Wir prüfen deinen Zugang...',
subtitle: 'Einen Moment bitte.',
},
error: {
invalid_token: {
title: 'Zugriffscode ungueltig',
title: 'Zugriffscode ungültig',
description: 'Der eingegebene Code konnte nicht verifiziert werden.',
ctaLabel: 'Neuen Code anfordern',
},
token_revoked: {
title: 'Zugriffscode deaktiviert',
description: 'Dieser Code wurde zurueckgezogen. Bitte fordere einen neuen Code an.',
description: 'Dieser Code wurde zurückgezogen. Bitte fordere einen neuen Code an.',
ctaLabel: 'Neuen Code anfordern',
},
token_expired: {
title: 'Zugriffscode abgelaufen',
description: 'Der Code ist nicht mehr gueltig. Aktualisiere deinen Code, um fortzufahren.',
description: 'Der Code ist nicht mehr gültig. Aktualisiere deinen Code, um fortzufahren.',
ctaLabel: 'Code aktualisieren',
},
token_rate_limited: {
title: 'Zu viele Versuche',
description: 'Es gab zu viele Eingaben in kurzer Zeit. Warte kurz und versuche es erneut.',
hint: 'Tipp: Eine erneute Eingabe ist in wenigen Minuten moeglich.',
hint: 'Tipp: Eine erneute Eingabe ist in wenigen Minuten möglich.',
},
access_rate_limited: {
title: 'Zu viele Aufrufe',
@@ -65,22 +65,22 @@ export const messages: Record<LocaleCode, NestedMessages> = {
hint: 'Tipp: Du kannst es gleich noch einmal versuchen.',
},
gallery_expired: {
title: 'Galerie nicht mehr verfuegbar',
description: 'Die Galerie zu diesem Event ist nicht mehr zugaenglich.',
title: 'Galerie nicht mehr verfügbar',
description: 'Die Galerie zu diesem Event ist nicht mehr zugänglich.',
ctaLabel: 'Neuen Code anfordern',
},
event_not_public: {
title: 'Event nicht oeffentlich',
description: 'Dieses Event ist aktuell nicht oeffentlich zugaenglich.',
title: 'Event nicht öffentlich',
description: 'Dieses Event ist aktuell nicht öffentlich zugänglich.',
hint: 'Nimm Kontakt mit den Veranstalter:innen auf, um Zugang zu erhalten.',
},
network_error: {
title: 'Verbindungsproblem',
description: 'Wir konnten keine Verbindung zum Server herstellen. Pruefe deine Internetverbindung und versuche es erneut.',
description: 'Wir konnten keine Verbindung zum Server herstellen. Prüfe deine Internetverbindung und versuche es erneut.',
},
server_error: {
title: 'Server nicht erreichbar',
description: 'Der Server reagiert derzeit nicht. Versuche es spaeter erneut.',
description: 'Der Server reagiert derzeit nicht. Versuche es später erneut.',
},
default: {
title: 'Event nicht erreichbar',
@@ -93,10 +93,10 @@ export const messages: Record<LocaleCode, NestedMessages> = {
loading: 'Lade Event...',
error: {
default: 'Event nicht gefunden.',
backToStart: 'Zurueck zur Startseite',
backToStart: 'Zurück zur Startseite',
},
card: {
description: 'Fange den schoensten Moment ein!',
description: 'Fange den schönsten Moment ein!',
},
form: {
label: 'Dein Name (z.B. Anna)',
@@ -108,12 +108,12 @@ export const messages: Record<LocaleCode, NestedMessages> = {
landing: {
pageTitle: 'Willkommen bei der Fotobox!',
headline: 'Willkommen bei der Fotobox!',
subheadline: 'Dein Schluessel zu unvergesslichen Momenten.',
subheadline: 'Dein Schlüssel zu unvergesslichen Momenten.',
join: {
title: 'Event beitreten',
description: 'Scanne den QR-Code oder gib den Code manuell ein.',
button: 'Event beitreten',
buttonLoading: 'Pruefe...',
buttonLoading: 'Prüfe...',
},
scan: {
start: 'QR-Code scannen',
@@ -125,7 +125,7 @@ export const messages: Record<LocaleCode, NestedMessages> = {
},
errors: {
eventClosed: 'Event nicht gefunden oder geschlossen.',
network: 'Netzwerkfehler. Bitte spaeter erneut versuchen.',
network: 'Netzwerkfehler. Bitte später erneut versuchen.',
camera: 'Kamera-Zugriff fehlgeschlagen. Bitte erlaube den Zugriff und versuche es erneut.',
},
},
@@ -134,27 +134,27 @@ export const messages: Record<LocaleCode, NestedMessages> = {
hero: {
subtitle: 'Willkommen zur Party',
title: 'Hey {name}!',
description: 'Du bist bereit fuer "{eventName}". Fang die Highlights des Events ein und teile sie mit allen Gaesten.',
description: 'Du bist bereit für "{eventName}". Fang die Highlights des Events ein und teile sie mit allen Gästen.',
progress: {
some: 'Schon {count} Aufgaben erledigt - weiter so!',
none: 'Starte mit deiner ersten Aufgabe - wir zaehlen auf dich!',
some: 'Schon {count} Aufgaben erledigt weiter so!',
none: 'Starte mit deiner ersten Aufgabe wir zählen auf dich!',
},
defaultEventName: 'Dein Event',
},
stats: {
online: 'Gleichzeitig online',
tasksSolved: 'Aufgaben geloest',
tasksSolved: 'Aufgaben gelöst',
lastUpload: 'Letzter Upload',
completedTasks: 'Deine erledigten Aufgaben',
},
actions: {
title: 'Deine Aktionen',
subtitle: 'Waehle aus, womit du starten willst',
subtitle: 'Wähle aus, womit du starten willst',
queueButton: 'Uploads in Warteschlange ansehen',
items: {
tasks: {
label: 'Aufgabe ziehen',
description: 'Hol dir deine naechste Challenge',
description: 'Hol dir deine nächste Challenge',
},
upload: {
label: 'Direkt hochladen',
@@ -168,10 +168,10 @@ export const messages: Record<LocaleCode, NestedMessages> = {
},
checklist: {
title: 'Dein Fortschritt',
description: 'Halte dich an diese drei kurzen Schritte fuer die besten Ergebnisse.',
description: 'Halte dich an diese drei kurzen Schritte für die besten Ergebnisse.',
steps: {
first: 'Aufgabe auswaehlen oder starten',
second: 'Emotion festhalten und Foto schiessen',
first: 'Aufgabe auswählen oder starten',
second: 'Emotion festhalten und Foto schießen',
third: 'Bild hochladen und Credits sammeln',
},
},
@@ -225,35 +225,35 @@ export const messages: Record<LocaleCode, NestedMessages> = {
retry: 'Nochmal versuchen',
},
primer: {
title: 'Bereit fuer dein Shooting?',
title: 'Bereit für dein Shooting?',
body: {
part1: 'Lass uns sicherstellen, dass alles sitzt: pruefe das Licht, wisch die Kamera sauber und richte alle Personen im Bild aus.',
part2: 'Du kannst zwischen Front- und Rueckkamera wechseln und bei Bedarf ein Raster aktivieren.',
part1: 'Lass uns sicherstellen, dass alles sitzt: prüfe das Licht, wisch die Kamera sauber und richte alle Personen im Bild aus.',
part2: 'Du kannst zwischen Front- und Rückkamera wechseln und bei Bedarf ein Raster aktivieren.',
},
dismiss: 'Verstanden',
},
cameraUnsupported: {
title: 'Kamera nicht verfuegbar',
message: 'Dein Geraet unterstuetzt keine Kameravorschau im Browser. Du kannst stattdessen Fotos aus deiner Galerie hochladen.',
openGallery: 'Foto aus Galerie waehlen',
title: 'Kamera nicht verfügbar',
message: 'Dein Gerät unterstützt keine Kameravorschau im Browser. Du kannst stattdessen Fotos aus deiner Galerie hochladen.',
openGallery: 'Foto aus Galerie wählen',
},
cameraDenied: {
title: 'Kamera-Zugriff verweigert',
explanation: 'Du musst den Zugriff auf die Kamera erlauben, um Fotos aufnehmen zu koennen.',
reopenPrompt: 'Systemdialog erneut oeffnen',
chooseFile: 'Foto aus Galerie waehlen',
prompt: 'Wir brauchen Zugriff auf deine Kamera. Erlaube die Anfrage oder waehle alternativ ein Foto aus deiner Galerie.',
explanation: 'Du musst den Zugriff auf die Kamera erlauben, um Fotos aufnehmen zu können.',
reopenPrompt: 'Systemdialog erneut öffnen',
chooseFile: 'Foto aus Galerie wählen',
prompt: 'Wir brauchen Zugriff auf deine Kamera. Erlaube die Anfrage oder wähle alternativ ein Foto aus deiner Galerie.',
},
cameraError: {
title: 'Kamera konnte nicht gestartet werden',
explanation: 'Wir konnten keine Verbindung zur Kamera herstellen. Pruefe die Berechtigungen oder starte dein Geraet neu.',
explanation: 'Wir konnten keine Verbindung zur Kamera herstellen. Prüfe die Berechtigungen oder starte dein Gerät neu.',
tryAgain: 'Nochmals versuchen',
},
readyOverlay: {
title: 'Kamera bereit',
message: 'Wenn alle im Bild sind, kannst du den Countdown starten oder ein vorhandenes Foto waehlen.',
message: 'Wenn alle im Bild sind, kannst du den Countdown starten oder ein vorhandenes Foto wählen.',
start: 'Countdown starten',
chooseFile: 'Foto auswaehlen',
chooseFile: 'Foto auswählen',
},
taskInfo: {
countdown: 'Countdown',
@@ -266,7 +266,7 @@ export const messages: Record<LocaleCode, NestedMessages> = {
},
timeEstimate: '{count} Min',
fallbackTitle: 'Aufgabe {id}',
fallbackDescription: 'Halte den Moment fest und teile ihn mit allen Gaesten.',
fallbackDescription: 'Halte den Moment fest und teile ihn mit allen Gästen.',
fallbackInstructions: 'Positioniere alle im Bild, starte den Countdown und lass die Emotion wirken.',
badge: 'Aufgabe #{id}',
},
@@ -276,7 +276,7 @@ export const messages: Record<LocaleCode, NestedMessages> = {
review: {
retake: 'Nochmal aufnehmen',
keep: 'Foto verwenden',
readyAnnouncement: 'Foto aufgenommen. Bitte Vorschau pruefen.',
readyAnnouncement: 'Foto aufgenommen. Bitte Vorschau prüfen.',
},
status: {
saving: 'Speichere Foto...',
@@ -289,23 +289,23 @@ export const messages: Record<LocaleCode, NestedMessages> = {
controls: {
toggleGrid: 'Raster umschalten',
toggleCountdown: 'Countdown umschalten',
toggleMirror: 'Spiegelung fuer Frontkamera umschalten',
toggleFlash: 'Blitzpraeferenz umschalten',
toggleMirror: 'Spiegelung für Frontkamera umschalten',
toggleFlash: 'Blitzpräferenz umschalten',
capture: 'Foto aufnehmen',
switchCamera: 'Kamera wechseln',
chooseFile: 'Foto auswaehlen',
chooseFile: 'Foto auswählen',
},
limitReached: 'Upload-Limit erreicht ({used} / {max} Fotos). Bitte kontaktiere die Veranstalter fuer ein Upgrade.',
limitReached: 'Upload-Limit erreicht ({used} / {max} Fotos). Bitte kontaktiere die Veranstalter für ein Upgrade.',
limitUnlimited: 'unbegrenzt',
cameraInactive: 'Kamera ist nicht aktiv. {hint}',
cameraInactiveHint: 'Tippe auf "{label}", um loszulegen.',
captureError: 'Foto konnte nicht erstellt werden.',
feedError: 'Kamera liefert kein Bild. Bitte starte die Kamera neu.',
canvasError: 'Canvas konnte nicht initialisiert werden.',
limitCheckError: 'Fehler beim Pruefen des Upload-Limits. Upload deaktiviert.',
limitCheckError: 'Fehler beim Prüfen des Upload-Limits. Upload deaktiviert.',
galleryPickError: 'Auswahl fehlgeschlagen. Bitte versuche es erneut.',
captureButton: 'Foto aufnehmen',
galleryButton: 'Foto aus Galerie waehlen',
galleryButton: 'Foto aus Galerie wählen',
switchCamera: 'Kamera wechseln',
countdownLabel: 'Countdown: {seconds}s',
countdownReady: 'Bereit machen ...',
@@ -319,7 +319,7 @@ export const messages: Record<LocaleCode, NestedMessages> = {
subtitle: 'Verwalte deinen Gastzugang, rechtliche Dokumente und lokale Daten.',
language: {
title: 'Sprache',
description: 'Waehle deine bevorzugte Sprache fuer diese Veranstaltung.',
description: 'Wähle deine bevorzugte Sprache für diese Veranstaltung.',
activeBadge: 'aktiv',
option: {
de: 'Deutsch',
@@ -328,12 +328,12 @@ export const messages: Record<LocaleCode, NestedMessages> = {
},
name: {
title: 'Dein Name',
description: 'Passe an, wie wir dich im Event begruessen. Der Name wird nur lokal gespeichert.',
description: 'Passe an, wie wir dich im Event begrüßen. Der Name wird nur lokal gespeichert.',
label: 'Anzeigename',
placeholder: 'z.B. Anna',
save: 'Name speichern',
saving: 'Speichere...',
reset: 'Zuruecksetzen',
reset: 'Zurücksetzen',
saved: 'Gespeichert (ok)',
loading: 'Lade gespeicherten Namen...',
},
@@ -341,7 +341,7 @@ export const messages: Record<LocaleCode, NestedMessages> = {
title: 'Rechtliches',
description: 'Die rechtlich verbindlichen Texte sind jederzeit hier abrufbar.',
loading: 'Dokument wird geladen...',
error: 'Das Dokument konnte nicht geladen werden. Bitte versuche es spaeter erneut.',
error: 'Das Dokument konnte nicht geladen werden. Bitte versuche es später erneut.',
fallbackTitle: 'Rechtlicher Hinweis',
section: {
impressum: 'Impressum',
@@ -350,19 +350,19 @@ export const messages: Record<LocaleCode, NestedMessages> = {
},
},
cache: {
title: 'Offline Cache',
description: 'Loesche lokale Daten, falls Inhalte veraltet erscheinen oder Uploads haengen bleiben.',
title: 'Offline-Cache',
description: 'Lösche lokale Daten, falls Inhalte veraltet erscheinen oder Uploads hängen bleiben.',
clear: 'Cache leeren',
clearing: 'Leere Cache...',
cleared: 'Cache geloescht.',
note: 'Dies betrifft nur diesen Browser und muss pro Geraet erneut ausgefuehrt werden.',
cleared: 'Cache gelöscht.',
note: 'Dies betrifft nur diesen Browser und muss pro Gerät erneut ausgeführt werden.',
},
footer: {
notice: 'Gastbereich - Daten werden lokal im Browser gespeichert.',
},
sheet: {
openLabel: 'Einstellungen oeffnen',
backLabel: 'Zurueck',
openLabel: 'Einstellungen öffnen',
backLabel: 'Zurück',
legalDescription: 'Rechtlicher Hinweis',
},
},