diff --git a/frontend/src/i18n/locales/de.json b/frontend/src/i18n/locales/de.json index 21108ee9..d65a422d 100644 --- a/frontend/src/i18n/locales/de.json +++ b/frontend/src/i18n/locales/de.json @@ -1547,6 +1547,21 @@ "clients": { "title": "CRM", "description": "Hauptschalter für den CRM-Bereich in der Seitenleiste. Aus blendet den Bereich und alle Unterfunktionen aus, unabhängig von deren individuellen Schaltern – beim erneuten Einschalten wird der vorherige Zustand wiederhergestellt." + }, + "contracts": { + "title": "Verträge", + "description": "Erstellen Sie Verträge aus einer Bibliothek wiederverwendbarer Bausteine (Bildrechte, Geheimhaltung, Model-Release, Stornierung, Gerichtsstand …) und lassen Sie Kunden im Browser unterschreiben oder eine handsignierte PDF hochladen. Die vorausgefüllten Baustein-Texte sind NUR BEISPIELE — vor dem Versand mit Ihrem Anwalt prüfen.", + "sidebar": "Verträge" + }, + "crmDevelopment": { + "title": "CRM-Entwicklerwerkzeuge", + "description": "Interne Helfer zum Prüfen von CRM-Abläufen (z. B. die Admin-Zahlungsprüfungs-E-Mail sofort auslösen, Drosselungen umgehen). Erscheint als Unterreiter „Entwicklung“ unter Kunden. Strikt opt-in — löst echte Seiteneffekte aus, nur mit Testdaten verwenden.", + "sidebar": "Entwicklung" + }, + "hoursLogging": { + "title": "Stundenerfassung", + "description": "Zeiterfassung pro Kunde. Admin erfasst Datum + Start-/Endzeit + optionalen Satz-Override + Notiz. Kunden im Monatsmodus akkumulieren Stunden automatisch in den laufenden Monatsentwurf; Kunden pro Anlass sehen eine Schaltfläche „Entwurfsrechnung erstellen“, die eine eigenständige Entwurfsrechnung mit einer Zeile pro Eintrag erzeugt. Unabhängig von Rechnungen — Stunden erfassen, noch bevor die volle Abrechnungsoberfläche aktiviert ist.", + "sidebar": "Stunden" } }, "customerSurface": { @@ -1559,6 +1574,12 @@ "save": "Änderungen speichern", "saved": "Branding des Kundendashboards gespeichert", "error": "Einstellungen konnten nicht gespeichert werden" + }, + "businessProfile": { + "title": "Geschäftsprofil" + }, + "crm": { + "title": "CRM-Verhalten" } }, "branding": { @@ -3575,7 +3596,6 @@ "status": "Status", "dueDate": "Fällig", "total": "Gesamt", - "sourceQuote": "Vom Angebot", "issueDate": "Ausgestellt am", "dueDateOverrideOn": "Manuelles Fälligkeitsdatum — Häkchen entfernen, um es automatisch aus Versanddatum + Zahlungsziel zu berechnen", "dueDateOverrideOff": "Automatisch aus Versanddatum + Zahlungsziel — ankreuzen, um es manuell zu setzen", @@ -3798,7 +3818,11 @@ "quotes": "Angebote", "invoices": "Rechnungen", "paymentDefaults": "Standard-Zahlungsbedingungen", - "installmentDefaults": "Standard-Trigger für Teilzahlungen" + "installmentDefaults": "Standard-Trigger für Teilzahlungen", + "contracts": "Verträge", + "quotesTos": "AGB-Schritt", + "dashboardOverview": "CRM-Übersicht im Dashboard", + "dashboardOverviewHint": "CRM-Übersichtskacheln im Admin-Dashboard ausblenden. Alle Kacheln werden standardmäßig angezeigt; zum Ausblenden abwählen." }, "installmentDefaults": { "help": "Vorbelegung der Trigger für neue Zeilen im Teilzahlungs-Panel. Pro-Dokument-Anpassungen überschreiben; bestehende Dokumente behalten ihren gespeicherten Plan.", @@ -3873,6 +3897,48 @@ }, "crm_invoices_late_fee_enabled": { "label": "Mahngebühr aktivieren" + }, + "crm_quotes_tos_required": { + "label": "Kunden müssen „Ich akzeptiere die AGB“ ankreuzen, bevor sie annehmen können" + }, + "crm_quotes_tos_url": { + "label": "AGB-URL (optional)" + }, + "crm_quotes_tos_text": { + "label": "AGB-Text, der auf der Angebotsseite angezeigt wird", + "placeholder": "Fügen Sie hier die Vertragsbedingungen ein. Nur Text. Leer lassen, um nur Häkchen + URL anzuzeigen." + }, + "crm_contracts_pdf_attachment_enabled": { + "label": "Vertrags-PDF an E-Mail anhängen" + }, + "crm_contracts_require_drawn_signature": { + "label": "Gezeichnete Unterschrift verlangen (getippter Name allein genügt nicht)" + }, + "crm_contracts_allow_pdf_upload": { + "label": "Kunden erlauben, eine handsignierte PDF hochzuladen" + }, + "crm_contracts_store_ip": { + "label": "IP-Adresse des Unterzeichners speichern (empfohlen — stützendes Beweismittel in Zivilstreitigkeiten)", + "help": "Wenn deaktiviert, wird die IP-Adresse von Kunde und Admin zum Signaturzeitpunkt NICHT in der Vertragszeile oder der öffentlichen Signaturseiten-Bestätigung erfasst. Nach dem DSGVO-Grundsatz der Datenminimierung bevorzugen das manche Betreiber — die IP ist jedoch ein stützendes Identitätsmerkmal, falls der Vertrag angefochten wird, daher empfehlen wir, sie aktiviert zu lassen." + }, + "crm_contracts_default_valid_days": { + "label": "Unterzeichnungsfrist (Tage)" + }, + "crm_contracts_number_format": { + "label": "Vertragsnummern-Format", + "help": "Unterstützte Platzhalter: {YEAR}, {MONTH}, {SEQ:04d}. Beispiel: LBM-C-{YEAR}-{SEQ:04d} → LBM-C-2026-0001." + }, + "crm_overview_show_revenue": { + "label": "Umsatz-Kacheln (30 / 90 / 365 Tage)" + }, + "crm_overview_show_outstanding": { + "label": "Kachel offene Zahlungen" + }, + "crm_overview_show_quotes": { + "label": "Angebots-Pipeline (nach Status)" + }, + "crm_overview_show_invoices": { + "label": "Rechnungs-Pipeline (nach Status)" } }, "quoteResponse": { @@ -4017,6 +4083,43 @@ "actual": "tatsächlich", "error": "Integritätsprüfung fehlgeschlagen." } + }, + "editor": { + "back": "Zurück zur Liste", + "backToDetail": "Zurück zum Vertrag", + "create": "Entwurf erstellen", + "createdToast": "Vertrag erstellt.", + "customer": "Kunde", + "disclaimerBody": "Die vorausgefüllten Baustein-Texte sind NUR BEISPIELE — vom Maintainer verfasst, nicht von einem Anwalt. Lassen Sie jeden verwendeten Baustein von Ihrem eigenen Anwalt prüfen, bevor Sie den Vertrag versenden. Siehe docs/crm-disclaimers.md.", + "disclaimerTitle": "Anwaltliche Prüfung erforderlich", + "eventDate": "Anlassdatum", + "eventHelp": "Wird auf den Vertrag übernommen und an jeden daraus erzeugten Anlass / jede Rechnung weitergegeben. Setzen Sie dies, damit Kundenportal und Mahn-E-Mails die richtige Bezeichnung \"Hochzeit Doe / Müller\" anzeigen.", + "eventName": "Anlassname", + "eventNamePlaceholder": "z. B. Hochzeit Doe / Müller", + "eventSection": "Anlass (optional)", + "eventTimeEnd": "Ende", + "eventTimeStart": "Beginn", + "intro": "Einleitungstext (optional)", + "issueDate": "Ausstellungsdatum", + "language": "Sprache", + "locked": "Gesendete Verträge können nicht bearbeitet werden. Für Änderungen stornieren und einen neuen erstellen.", + "noBlocksInSection": "Noch keine Bausteine für diesen Abschnitt.", + "outro": "Schlusstext (optional)", + "popupBlocked": "Erlauben Sie Pop-ups für diese Seite, um die PDF-Vorschau anzuzeigen.", + "preview": "PDF-Vorschau", + "previewAfterSave": "Zuerst den Entwurf speichern, dann Vorschau anzeigen.", + "previewError": "Vorschau fehlgeschlagen", + "save": "Speichern", + "saveError": "Speichern fehlgeschlagen", + "savedToast": "Vertrag gespeichert.", + "schriftformWarning": "Signaturtyp: einfache elektronische Signatur (EES). Ausreichend für routinemäßige Fotografieverträge in CH / DE / AT / FL. NICHT ausreichend für Dokumente, die gesetzlich Schriftform / forme qualifiée verlangen: Bürgschaft (DE § 766 BGB), Verbraucherdarlehensvertrag (DE § 492 BGB), befristete Arbeitsverträge (DE § 14 Abs. 4 TzBfG) und Ähnliches. Dafür ist eine qualifizierte elektronische Signatur (QES) eines Vertrauensdiensteanbieters erforderlich — picpeak bietet keine QES.", + "searchCustomer": "Nach E-Mail suchen…", + "systemBadge": "System", + "titleEdit": "Vertrag bearbeiten", + "titleField": "Vertragstitel", + "titleNew": "Neuer Vertrag", + "titlePlaceholder": "z. B. Hochzeitsvertrag Doe / Müller", + "validUntil": "Unterzeichnen bis (optional)" } } } diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json index 2eb33882..2116e5b7 100644 --- a/frontend/src/i18n/locales/en.json +++ b/frontend/src/i18n/locales/en.json @@ -1186,6 +1186,21 @@ "clients": { "title": "CRM", "description": "Master switch for the CRM sidebar section. Off hides the section and every sub-feature below regardless of their individual toggles — re-enable to restore them to whatever you set last." + }, + "contracts": { + "title": "Contracts", + "description": "Compose contracts from a library of reusable blocks (image rights, NDA, model release, cancellation, jurisdiction…) and have customers sign in-browser or upload a wet-signed PDF. Seeded block bodies are EXAMPLES ONLY — review with your lawyer before sending.", + "sidebar": "Contracts" + }, + "crmDevelopment": { + "title": "CRM developer tools", + "description": "Internal helpers for verifying CRM flows (e.g. fire the admin payment-check email instantly, bypass throttles). Surfaces as a \"Development\" sub-tab under Clients. Strictly opt-in — fires real side effects, use against test data only.", + "sidebar": "Development" + }, + "hoursLogging": { + "title": "Hours logging", + "description": "Per-customer time tracking. Admin logs date + start/end times + optional rate override + note. Monthly-mode customers auto-accumulate hours into the running monthly draft; per-event customers see a \"Create draft invoice\" button that mints a standalone draft invoice with one line per entry. Independent of Bills — log hours even before turning the full billing surface on.", + "sidebar": "Hours" } }, "customerSurface": { @@ -1198,6 +1213,12 @@ "save": "Save changes", "saved": "Customer dashboard branding saved", "error": "Could not save settings" + }, + "businessProfile": { + "title": "Business profile" + }, + "crm": { + "title": "CRM behaviour" } }, "analytics": { @@ -3795,7 +3816,11 @@ "quotes": "Quotes", "invoices": "Invoices", "paymentDefaults": "Default payment conditions", - "installmentDefaults": "Default installment triggers" + "installmentDefaults": "Default installment triggers", + "contracts": "Contracts", + "quotesTos": "Terms of Service / AGB step", + "dashboardOverview": "Dashboard CRM overview", + "dashboardOverviewHint": "Hide CRM overview tiles on the admin dashboard. All tiles render by default; uncheck to hide." }, "paymentDefaults": { "help": "Pre-filled on every new quote and invoice. The editor still lets you pick a different combination per document.", @@ -3870,6 +3895,48 @@ }, "crm_invoices_late_fee_enabled": { "label": "Add a late fee on the second reminder" + }, + "crm_quotes_tos_required": { + "label": "Require customers to tick \"I accept the Terms of Service\" before accepting" + }, + "crm_quotes_tos_url": { + "label": "Terms of Service URL (optional)" + }, + "crm_quotes_tos_text": { + "label": "Inline Terms text shown on the quote page", + "placeholder": "Paste the contract terms here. Plain text. Leave empty to only show the checkbox + URL." + }, + "crm_contracts_pdf_attachment_enabled": { + "label": "Attach contract PDF to email" + }, + "crm_contracts_require_drawn_signature": { + "label": "Require drawn signature (typed name alone is not enough)" + }, + "crm_contracts_allow_pdf_upload": { + "label": "Allow customer to upload a wet-signed PDF" + }, + "crm_contracts_store_ip": { + "label": "Store signer's IP address (recommended — corroborating evidence in civil disputes)", + "help": "When off, the customer's and admin's IP at signing time is NOT recorded into the contract row or the public sign-page audit confirmation. Per GDPR data-minimisation principle some operators prefer this — but IP is corroborating identity evidence if the contract is challenged, so we recommend keeping it on." + }, + "crm_contracts_default_valid_days": { + "label": "Signing window (days)" + }, + "crm_contracts_number_format": { + "label": "Contract number format", + "help": "Supported tokens: {YEAR}, {MONTH}, {SEQ:04d}. Example: LBM-C-{YEAR}-{SEQ:04d} → LBM-C-2026-0001." + }, + "crm_overview_show_revenue": { + "label": "Revenue tiles (30 / 90 / 365 days)" + }, + "crm_overview_show_outstanding": { + "label": "Outstanding payments tile" + }, + "crm_overview_show_quotes": { + "label": "Quotes pipeline (per-status)" + }, + "crm_overview_show_invoices": { + "label": "Invoices pipeline (per-status)" } }, "quoteResponse": { @@ -4014,6 +4081,43 @@ "actual": "actual", "error": "Integrity check failed." } + }, + "editor": { + "back": "Back to list", + "backToDetail": "Back to contract", + "create": "Create draft", + "createdToast": "Contract created.", + "customer": "Customer", + "disclaimerBody": "The seeded block bodies are EXAMPLES ONLY — written by the maintainer, not by a lawyer. Have your own lawyer review every block you include before sending the contract. See docs/crm-disclaimers.md.", + "disclaimerTitle": "Lawyer review required", + "eventDate": "Event date", + "eventHelp": "Snapshotted onto the contract and propagated to any event / invoice generated from it. Set this so the customer portal and dunning emails show the right \"Wedding Doe / Müller\" label.", + "eventName": "Event name", + "eventNamePlaceholder": "e.g. Wedding Doe / Müller", + "eventSection": "Event (optional)", + "eventTimeEnd": "End", + "eventTimeStart": "Start", + "intro": "Intro text (optional)", + "issueDate": "Issue date", + "language": "Language", + "locked": "Sent contracts cannot be edited. Cancel and create a fresh one for amendments.", + "noBlocksInSection": "No blocks for this section yet.", + "outro": "Closing text (optional)", + "popupBlocked": "Allow pop-ups for this site to preview the PDF.", + "preview": "Preview PDF", + "previewAfterSave": "Save the draft first, then preview.", + "previewError": "Preview failed", + "save": "Save", + "saveError": "Save failed", + "savedToast": "Contract saved.", + "schriftformWarning": "Signature type: simple electronic signature (SES). Sufficient for routine photography contracts in CH / DE / AT / FL. NOT sufficient for documents that legally require Schriftform / form qualifiée: Bürgschaft (DE § 766 BGB), Verbraucherdarlehensvertrag (DE § 492 BGB), befristete Arbeitsverträge (DE § 14 Abs. 4 TzBfG), and similar. For those, a qualified electronic signature (QES) from a Trust Service Provider is required — picpeak does not provide QES.", + "searchCustomer": "Search by email…", + "systemBadge": "System", + "titleEdit": "Edit contract", + "titleField": "Contract title", + "titleNew": "New contract", + "titlePlaceholder": "e.g. Wedding contract Doe / Müller", + "validUntil": "Sign by (optional)" } } }