/** * Rahmen der Anwendung: Name, Navigation, Anmeldung, Übersicht, Zustand. * * Nach Bereichen getrennt, weil eine **Client-Komponente die ganze Datei ins * Bündel zieht**, in der ihr Text steht. Lägen alle Texte in einer, trüge jede * Ansicht die der ganzen Anwendung mit sich herum — das Budget aus * docs/09-performance-und-ux.md wäre nach wenigen Phasen aufgebraucht. * * Serverkomponenten nehmen weiter `de` aus `lib/i18n/de.ts`: was dorthin * gezogen wird, verlässt den Server nicht. */ export const appText = { name: 'AfiS-Aktensystem', shortName: 'AfiS', description: 'Fallakten, Personalakten und Ermittlungen der Abteilung für innere Sicherheit', } as const export const navText = { dashboard: 'Übersicht', cases: 'Fallakten', personnel: 'Personalakten', search: 'Suche', admin: 'Admin', skipToContent: 'Zum Inhalt springen', } as const export const authText = { signIn: 'Mit Discord anmelden', signOut: 'Abmelden', signedInAs: 'Angemeldet als', intro: 'Die Anmeldung läuft über Discord. Zugriff haben Mitglieder der Abteilung für innere Sicherheit.', reasons: { 'keine-mitgliedschaft': { title: 'Du bist nicht auf dem AfiS-Discord', body: 'Die Anmeldung setzt eine Mitgliedschaft auf dem Discord-Server voraus. Wende dich an die Abteilungsleitung.', }, 'keine-afis-rolle': { title: 'Keine Berechtigung für das Aktensystem', body: 'Du bist auf dem Server, trägst aber keine Rolle der Abteilung. Wende dich an die Abteilungsleitung.', }, 'discord-nicht-erreichbar': { title: 'Discord antwortet nicht', body: 'Die Mitgliedschaft war nicht prüfbar. In einigen Minuten erneut versuchen.', }, } as Record, sessionEnded: { title: 'Sitzung beendet', body: 'Deine Rollen haben sich geändert. Melde dich neu an.', }, error: { title: 'Anmeldung nicht möglich', body: 'Der Anmeldevorgang wurde abgebrochen. Erneut versuchen.', }, backToSignIn: 'Zurück zur Anmeldung', } as const export const dashboardText = { heading: 'Übersicht', mine: 'Meine Fälle', mineEmpty: 'Du bist an keiner offenen Akte beteiligt.', due: 'Fristen', dueEmpty: 'Nichts steht an.', dueAt: (datum: string) => `fällig ${datum}`, overdue: 'überfällig', unread: 'Ungelesen', unreadEmpty: 'Nichts Neues.', unreadCount: (n: number) => (n === 1 ? '1 Nachricht' : `${n} Nachrichten`), watched: 'Beobachtet', watchedEmpty: 'Keine Akte beobachtet.', recent: 'Zuletzt geändert', recentEmpty: 'Noch keine Akte.', opened: 'Zuletzt geöffnet', openedEmpty: 'Noch nichts geöffnet. Was du aufrufst, findest du hier wieder.', openedHint: 'Nur für dich. Niemand sonst sieht diese Liste.', openedClear: 'Liste leeren', access: 'Dein Zugang', } as const export const watchText = { watch: 'Beobachten', unwatch: 'Nicht mehr beobachten', hint: 'Beobachtete Akten stehen auf deiner Übersicht und melden sich, auch ohne Beteiligung.', } as const export const overviewText = { heading: 'Dein Zugang', intro: 'Was das System über dich weiss und was daraus folgt.', person: 'Person', discordId: 'Discord-Kennung', roles: 'Rollen auf dem Discord', clearance: 'Errechnete Freigabestufe', permissions: 'Rechte', noPermissions: 'Keine Rechte. Die Abteilungsleitung vergibt sie in der Rollenverwaltung.', noRoles: 'Keine Rollen.', bootstrapAdmin: 'Notfallzugang aus der Konfiguration, unabhängig vom Rollen-Mapping', unmapped: 'nicht zugeordnet', } as const export const healthText = { heading: 'Systemzustand', service: 'Dienst', state: 'Zustand', checkedAt: (when: string) => `Zustand der Dienste, abgefragt ${when}`, ok: 'Betriebsbereit', degraded: 'Eingeschränkt', down: 'Gestört', components: { database: 'Datenbank', discordGateway: 'Discord-Gateway', clamav: 'Virenprüfung', } as Record, } as const export const notifyText = { heading: 'Benachrichtigungen', intro: 'Discord erfährt nie den Inhalt einer Akte. Bei Akten ab Stufe 3 auch nicht den Titel — nur, dass sich etwas getan hat, und einen Link.', mode: 'Was soll dich erreichen?', save: 'Übernehmen', saved: 'Übernommen', modes: { ALL: 'Alles, was ich sehen darf', OWN_CASES: 'Nur meine Fälle', MENTIONS: 'Nur Erwähnungen', OFF: 'Nichts', } as Record, } as const export const searchText = { heading: 'Suche', placeholder: 'Aktenzeichen, Titel, Inhalt', kinds: { case: 'Fallakten', document: 'Dokumente', personnel: 'Personalakten', } as Record, filters: 'Filter', reset: 'Filter zurücksetzen', empty: 'Kein Treffer. Anderen Begriff oder weniger Filter versuchen.', emptyNoQuery: 'Begriff eingeben oder einen Filter wählen.', countLabel: (n: number) => (n === 1 ? '1 Treffer' : `${n} Treffer`), more: 'Weitere laden', truncated: 'Sehr viele Treffer. Angezeigt werden die besten; mit einem genaueren Begriff wird die Liste vollständig.', views: 'Ansichten', saveView: 'Ansicht speichern', saveViewName: 'Name der Ansicht', deleteView: 'Ansicht löschen', builtin: { mine: 'Meine Fälle', dueThisWeek: 'Wiedervorlage diese Woche', idle: 'Unbearbeitet seit 14 Tagen', open: 'Offene Fälle', sinceLastVisit: 'Seit deinem letzten Besuch geändert', } as Record, } as const export const paletteText = { open: 'Springen', placeholder: 'Aktenzeichen, Akte oder Seite', hint: 'Strg+K', empty: 'Nichts gefunden.', close: 'Schliessen', sections: { cases: 'Fallakten', personnel: 'Personalakten', pages: 'Seiten', recent: 'Zuletzt geöffnet', } as Record, /** * Die Sprungziele der Palette. Sie stehen hier und nicht in der Komponente, * weil sie Oberflächentext sind — die Adressen daneben sind es nicht. */ pages: [ { href: '/uebersicht', label: 'Übersicht' }, { href: '/faelle', label: 'Fallakten' }, { href: '/faelle/neu', label: 'Neue Fallakte' }, { href: '/personalakten', label: 'Personalakten' }, { href: '/suche', label: 'Suche' }, { href: '/einstellungen', label: 'Benachrichtigungen' }, ], } as const export const profileText = { open: 'Konto und Einstellungen', signedInAs: 'Angemeldet als', } as const export const searchBarText = { label: 'Suchen', placeholder: 'Aktenzeichen, Titel, Name', } as const export const themeText = { label: 'Thema', system: 'Wie das System', dark: 'Dunkel', light: 'Hell', } as const