L4 Einsatz mobil: Mobile Shell und Einsatz-Oberfläche
- /m in eigene Route-Group (field)/m verschoben (emergency-Platzhalter mit),
Zugriffsprüfungen aus (app)/layout.tsx nach server/app-access.ts extrahiert
und von Backoffice- und Mobile-Shell gemeinsam genutzt
- Mobile Shell mit Bottom-Nav (Heute · Aufträge · Notdienst · Sync · Profil)
und Online/Offline-Badge; Startseite rollenabhängig (Feldrollen → /m),
Login-Default-Redirect auf /
- Heute, Auftragsliste mit Tabs, Auftragsdetail mit einer Primäraktion je
Zustand, Unterseiten Fotos (Kamera, Kompression, Upload-Fortschritt),
Notizen + Sprachaufnahme, Material mit Stepper, Checkliste, Zeiten mit
Korrektur, Profil; Sync-Platzhalter für L7
- Client-Wrapper submitOp (lib/field/client-ops.ts), Upload mit Fortschritt,
Bildkompression, Formatierung; Texte in messages/{de,en}/field.json
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,298 @@
|
||||
{
|
||||
"nav": {
|
||||
"label": "Einsatz-Navigation",
|
||||
"today": "Heute",
|
||||
"orders": "Aufträge",
|
||||
"emergency": "Notdienst",
|
||||
"sync": "Sync",
|
||||
"profile": "Profil"
|
||||
},
|
||||
"connection": {
|
||||
"online": "Online",
|
||||
"offline": "Offline"
|
||||
},
|
||||
"noAccess": "Die Einsatz-App ist für Ihre Rolle nicht freigeschaltet.",
|
||||
"today": {
|
||||
"title": "Heute",
|
||||
"greeting": "Hallo {name}",
|
||||
"count": "{count, plural, =0 {Keine Einsätze} one {# Einsatz} other {# Einsätze}}",
|
||||
"empty": "Heute stehen keine Einsätze an.",
|
||||
"allOrders": "Alle Aufträge ansehen"
|
||||
},
|
||||
"orders": {
|
||||
"title": "Aufträge",
|
||||
"tabs": {
|
||||
"upcoming": "Kommend",
|
||||
"running": "Laufend",
|
||||
"to_complete": "Abzuschließen",
|
||||
"past": "Vergangen"
|
||||
},
|
||||
"empty": "Keine Aufträge in dieser Liste."
|
||||
},
|
||||
"card": {
|
||||
"open": "Auftrag öffnen",
|
||||
"route": "Route",
|
||||
"noDate": "Ohne Termin",
|
||||
"emergency": "Notdienst",
|
||||
"urgent": "Dringend",
|
||||
"high": "Hoch"
|
||||
},
|
||||
"statusGroup": {
|
||||
"new": "Neu",
|
||||
"planned": "Geplant",
|
||||
"en_route": "Unterwegs",
|
||||
"in_progress": "In Arbeit",
|
||||
"documentation_incomplete": "Dokumentation unvollständig",
|
||||
"in_review": "Zur Prüfung",
|
||||
"ready_for_billing": "Bereit zur Abrechnung",
|
||||
"billed": "Abgerechnet",
|
||||
"cancelled": "Storniert"
|
||||
},
|
||||
"statusDetail": {
|
||||
"draft": "Entwurf",
|
||||
"review_required": "Prüfung erforderlich",
|
||||
"planned": "Geplant",
|
||||
"assigned": "Zugewiesen",
|
||||
"accepted": "Angenommen",
|
||||
"en_route": "In Anfahrt",
|
||||
"in_progress": "In Arbeit",
|
||||
"paused": "Pausiert",
|
||||
"waiting_material": "Wartet auf Material",
|
||||
"daily_report_created": "Tagesbericht erstellt",
|
||||
"technically_completed": "Technisch abgeschlossen",
|
||||
"signature_pending": "Unterschrift ausstehend",
|
||||
"in_review": "Zur Prüfung",
|
||||
"released_for_billing": "Bereit zur Abrechnung",
|
||||
"billed": "Abgerechnet",
|
||||
"cancelled": "Storniert"
|
||||
},
|
||||
"action": {
|
||||
"accept": "Annehmen",
|
||||
"travel": "Losfahren",
|
||||
"start": "Arbeit starten",
|
||||
"pause": "Pause",
|
||||
"resume": "Weiter",
|
||||
"complete": "Abschließen",
|
||||
"confirmComplete": "Jetzt abschließen",
|
||||
"confirmHint": "Zeiterfassung wird beendet und der Auftrag technisch abgeschlossen.",
|
||||
"saving": "Wird gespeichert …",
|
||||
"blocked": "Vor dem Abschluss noch offen:",
|
||||
"reportNext": "Bericht und Unterschrift folgen im nächsten Schritt.",
|
||||
"nothing": "Keine Aktion erforderlich."
|
||||
},
|
||||
"blocker": {
|
||||
"checklist_item": "Checkliste: {label}",
|
||||
"photo_requirement": "Pflichtfoto: {label}",
|
||||
"running_session": "Zeiterfassung eines Teammitglieds läuft noch",
|
||||
"missing_field": "Angabe fehlt: {label}"
|
||||
},
|
||||
"errors": {
|
||||
"not_found": "Nicht gefunden oder nicht freigegeben.",
|
||||
"forbidden": "Keine Berechtigung für diese Aktion.",
|
||||
"invalid": "Eingabe prüfen.",
|
||||
"conflict": "Der Auftrag wurde inzwischen geändert. Die Ansicht ist aktualisiert.",
|
||||
"blocked": "Pflichtangaben fehlen noch.",
|
||||
"internal": "Technischer Fehler. Bitte erneut versuchen.",
|
||||
"network": "Keine Verbindung. Bitte erneut versuchen.",
|
||||
"image": "Foto konnte nicht verarbeitet werden."
|
||||
},
|
||||
"detail": {
|
||||
"back": "Zurück",
|
||||
"backToOrder": "Zum Auftrag",
|
||||
"window": "Zeitfenster",
|
||||
"hints": "Hinweise für Monteure",
|
||||
"order": "Auftrag",
|
||||
"orderType": "Auftragsart",
|
||||
"externalNumber": "Kundenauftrag",
|
||||
"team": "Team",
|
||||
"scope": "Leistungsumfang",
|
||||
"description": "Beschreibung",
|
||||
"customer": "Kunde",
|
||||
"contact": "Ansprechpartner",
|
||||
"onSiteContact": "Vor Ort",
|
||||
"call": "Anrufen",
|
||||
"mail": "E-Mail",
|
||||
"site": "Objekt",
|
||||
"route": "Route öffnen",
|
||||
"access": "Zugang",
|
||||
"parking": "Parken",
|
||||
"safety": "Sicherheit",
|
||||
"technical": "Technik",
|
||||
"documents": "Dokumente",
|
||||
"noDocuments": "Keine Dokumente.",
|
||||
"siteDocument": "Objekt",
|
||||
"openDocument": "Öffnen",
|
||||
"history": "Objekt-Historie",
|
||||
"noHistory": "Keine freigegebenen Berichte am Objekt.",
|
||||
"reportType": {
|
||||
"daily": "Tagesbericht",
|
||||
"completion": "Abschlussbericht"
|
||||
},
|
||||
"checklist": "Checkliste",
|
||||
"checklistProgress": "{done} von {total} erledigt",
|
||||
"materials": "Material",
|
||||
"materialsProgress": "{done} von {total} Positionen erfasst",
|
||||
"materialsNone": "Kein Material geplant",
|
||||
"photos": "Fotos",
|
||||
"photosProgress": "{count} Fotos · {done} von {total} Pflichtfotos",
|
||||
"photosCount": "{count} Fotos",
|
||||
"notes": "Notizen",
|
||||
"notesCount": "{count, plural, =0 {Noch keine Notizen} one {# Notiz} other {# Notizen}}",
|
||||
"time": "Zeiten",
|
||||
"myTime": "Meine Arbeitszeit: {duration}",
|
||||
"quick": {
|
||||
"photo": "Foto",
|
||||
"note": "Notiz",
|
||||
"material": "Material",
|
||||
"checklist": "Checkliste",
|
||||
"time": "Zeiten"
|
||||
}
|
||||
},
|
||||
"photos": {
|
||||
"title": "Fotos",
|
||||
"camera": "Kamera",
|
||||
"gallery": "Galerie",
|
||||
"phaseLabel": "Zeitpunkt",
|
||||
"phase": {
|
||||
"before": "Vorher",
|
||||
"during": "Während",
|
||||
"after": "Nachher"
|
||||
},
|
||||
"requirement": "Pflichtfoto",
|
||||
"checklistItem": "Checklistenpunkt",
|
||||
"none": "Keine Zuordnung",
|
||||
"comment": "Kommentar",
|
||||
"location": "Standort mitsenden",
|
||||
"save": "Foto speichern",
|
||||
"discard": "Verwerfen",
|
||||
"preview": "Vorschau des Fotos",
|
||||
"compressing": "Foto wird verkleinert …",
|
||||
"uploading": "Hochladen … {percent} %",
|
||||
"saved": "Foto gespeichert.",
|
||||
"empty": "Noch keine Fotos.",
|
||||
"requirements": "Pflichtfotos",
|
||||
"missing": "Fehlt",
|
||||
"done": "Vorhanden"
|
||||
},
|
||||
"notes": {
|
||||
"title": "Notizen",
|
||||
"kindLabel": "Art",
|
||||
"kind": {
|
||||
"work_done": "Durchgeführt",
|
||||
"deviation": "Abweichung",
|
||||
"problem": "Problem",
|
||||
"additional_work": "Zusatzleistung",
|
||||
"not_executable": "Nicht ausführbar",
|
||||
"follow_up": "Folgearbeit",
|
||||
"recommendation": "Empfehlung",
|
||||
"customer_note": "Kundenhinweis",
|
||||
"general": "Allgemein"
|
||||
},
|
||||
"text": "Notiz",
|
||||
"placeholder": "Kurz beschreiben, was vor Ort passiert ist …",
|
||||
"save": "Notiz speichern",
|
||||
"saved": "Notiz gespeichert.",
|
||||
"draftKept": "Entwurf bleibt auf diesem Gerät erhalten.",
|
||||
"empty": "Noch keine Notizen."
|
||||
},
|
||||
"voice": {
|
||||
"title": "Sprachnotiz",
|
||||
"record": "Aufnahme starten",
|
||||
"stop": "Aufnahme beenden",
|
||||
"recording": "Aufnahme läuft · {time} von 5:00",
|
||||
"save": "Sprachnotiz speichern",
|
||||
"discard": "Verwerfen",
|
||||
"saved": "Sprachnotiz gespeichert.",
|
||||
"unsupported": "Sprachaufnahme wird auf diesem Gerät nicht unterstützt.",
|
||||
"denied": "Mikrofon ist nicht freigegeben.",
|
||||
"status": {
|
||||
"pending": "Transkription läuft",
|
||||
"done": "Transkribiert",
|
||||
"failed": "Transkription fehlgeschlagen",
|
||||
"disabled": "Ohne Transkription"
|
||||
}
|
||||
},
|
||||
"materials": {
|
||||
"title": "Material",
|
||||
"planned": "Geplant: {quantity} {unit}",
|
||||
"usage": {
|
||||
"fully_used": "Vollständig",
|
||||
"partially_used": "Teilweise",
|
||||
"not_used": "Nicht verwendet",
|
||||
"additional": "Zusätzlich"
|
||||
},
|
||||
"quantity": "Menge",
|
||||
"unit": "Einheit",
|
||||
"decrease": "Menge verringern",
|
||||
"increase": "Menge erhöhen",
|
||||
"reason": "Begründung der Abweichung",
|
||||
"reasonRequired": "Bei Abweichung ist eine Begründung Pflicht.",
|
||||
"save": "Speichern",
|
||||
"saved": "Gespeichert.",
|
||||
"recorded": "Erfasst: {quantity} {unit}",
|
||||
"open": "Noch offen",
|
||||
"noPlan": "Kein Material geplant.",
|
||||
"additionalTitle": "Zusatzmaterial",
|
||||
"additionalEmpty": "Kein Zusatzmaterial erfasst.",
|
||||
"name": "Bezeichnung",
|
||||
"articleNumber": "Artikelnummer (optional)",
|
||||
"additionalReason": "Grund",
|
||||
"add": "Zusatzmaterial speichern",
|
||||
"invalid": "Angaben unvollständig oder Menge passt nicht zum Status."
|
||||
},
|
||||
"checklist": {
|
||||
"title": "Checkliste",
|
||||
"required": "Pflicht",
|
||||
"photo": "Foto nötig",
|
||||
"done": "Erledigt",
|
||||
"open": "Offen",
|
||||
"comment": "Kommentar",
|
||||
"saveComment": "Kommentar speichern",
|
||||
"empty": "Für diesen Auftrag gibt es keine Checkliste."
|
||||
},
|
||||
"time": {
|
||||
"title": "Zeiten",
|
||||
"type": {
|
||||
"travel": "Anfahrt",
|
||||
"work": "Arbeitszeit",
|
||||
"break": "Pause",
|
||||
"material_procurement": "Materialbeschaffung",
|
||||
"return_travel": "Rückfahrt",
|
||||
"interruption": "Unterbrechung"
|
||||
},
|
||||
"session": {
|
||||
"en_route": "In Anfahrt",
|
||||
"running": "Läuft",
|
||||
"paused": "Pausiert",
|
||||
"ended": "Beendet"
|
||||
},
|
||||
"running": "läuft",
|
||||
"offlineStarted": "offline gestartet",
|
||||
"corrected": "Korrigiert: {reason}",
|
||||
"correct": "Korrigieren",
|
||||
"start": "Beginn",
|
||||
"end": "Ende",
|
||||
"reason": "Grund der Korrektur",
|
||||
"reasonHint": "Pflichtangabe, wird protokolliert.",
|
||||
"save": "Korrektur speichern",
|
||||
"saved": "Korrektur gespeichert.",
|
||||
"empty": "Noch keine Zeiten erfasst.",
|
||||
"totalWork": "Arbeitszeit gesamt: {duration}"
|
||||
},
|
||||
"profile": {
|
||||
"title": "Profil",
|
||||
"tenant": "Betrieb",
|
||||
"teams": "Team",
|
||||
"noTeam": "Keinem Team zugeordnet",
|
||||
"roles": "Rolle",
|
||||
"language": "Sprache",
|
||||
"logout": "Abmelden",
|
||||
"backoffice": "Zum Büro-Bereich"
|
||||
},
|
||||
"sync": {
|
||||
"title": "Synchronisation",
|
||||
"immediate": "Änderungen werden sofort an das Büro übertragen.",
|
||||
"offlineHint": "Ohne Verbindung können Eingaben noch nicht zwischengespeichert werden – die Offline-Warteschlange folgt.",
|
||||
"status": "Verbindung"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user