From 694a1cd1a52c0bf8e6f22c3d512ade7068e508b2 Mon Sep 17 00:00:00 2001 From: Samir Boulahtit Date: Fri, 13 Mar 2026 19:53:17 +0100 Subject: [PATCH] feat(loyalty): add full i18n support for all loyalty module pages Replace hardcoded English strings across all 22 templates, 10 JS files, and 4 locale files (en/fr/de/lb) with ~300 translation keys per language. Uses server-side _() for Jinja2 templates and I18n.t() for JS toast messages and dynamic Alpine.js expressions. Co-Authored-By: Claude Opus 4.6 --- app/modules/loyalty/locales/de.json | 584 ++++++++++++++++++ app/modules/loyalty/locales/en.json | 584 ++++++++++++++++++ app/modules/loyalty/locales/fr.json | 584 ++++++++++++++++++ app/modules/loyalty/locales/lb.json | 584 ++++++++++++++++++ .../admin/js/loyalty-merchant-detail.js | 12 +- .../admin/js/loyalty-merchant-settings.js | 4 +- .../static/admin/js/loyalty-program-edit.js | 10 +- .../static/admin/js/loyalty-programs.js | 8 +- .../static/merchant/js/loyalty-settings.js | 8 +- .../static/shared/js/loyalty-program-form.js | 2 +- .../loyalty/static/store/js/loyalty-enroll.js | 2 +- .../static/store/js/loyalty-settings.js | 10 +- .../static/store/js/loyalty-terminal.js | 34 +- .../static/storefront/js/loyalty-enroll.js | 6 +- .../static/storefront/js/loyalty-history.js | 14 +- .../templates/loyalty/admin/analytics.html | 54 +- .../loyalty/admin/merchant-detail.html | 60 +- .../loyalty/admin/merchant-settings.html | 56 +- .../templates/loyalty/admin/program-edit.html | 18 +- .../templates/loyalty/admin/programs.html | 80 +-- .../templates/loyalty/merchant/analytics.html | 22 +- .../loyalty/merchant/program-edit.html | 18 +- .../templates/loyalty/merchant/program.html | 16 +- .../loyalty/shared/analytics-stats.html | 62 +- .../loyalty/shared/program-form.html | 100 +-- .../loyalty/shared/program-view.html | 74 +-- .../templates/loyalty/store/analytics.html | 26 +- .../templates/loyalty/store/card-detail.html | 48 +- .../templates/loyalty/store/cards.html | 48 +- .../templates/loyalty/store/enroll.html | 50 +- .../templates/loyalty/store/program.html | 20 +- .../templates/loyalty/store/settings.html | 24 +- .../templates/loyalty/store/terminal.html | 100 +-- .../loyalty/storefront/dashboard.html | 56 +- .../loyalty/storefront/enroll-success.html | 27 +- .../templates/loyalty/storefront/enroll.html | 44 +- .../templates/loyalty/storefront/history.html | 30 +- 37 files changed, 2916 insertions(+), 563 deletions(-) diff --git a/app/modules/loyalty/locales/de.json b/app/modules/loyalty/locales/de.json index 84076705..3e0aa0d7 100644 --- a/app/modules/loyalty/locales/de.json +++ b/app/modules/loyalty/locales/de.json @@ -96,5 +96,589 @@ "title": "Treueprogramm erstellen", "description": "Erstellen Sie Ihr erstes Stempel- oder Punkteprogramm" } + }, + "enrollment": { + "title": "Treten Sie unserem Prämienprogramm bei!", + "subtitle": "Verdienen Sie {points} Punkt pro ausgegebenem EUR", + "not_available_title": "Programm nicht verfügbar", + "not_available_message": "Dieser Shop hat noch kein Treueprogramm eingerichtet.", + "welcome_bonus": "Erhalten Sie {points} Bonuspunkte bei der Anmeldung!", + "already_member": "Bereits Mitglied? Ihre Punkte sind mit Ihrer E-Mail verknüpft.", + "form": { + "email": "E-Mail", + "first_name": "Vorname", + "last_name": "Nachname", + "phone": "Telefon (optional)", + "birthday": "Geburtstag (optional)", + "birthday_hint": "Für besondere Geburtstagsbelohnungen", + "terms_agree": "Ich stimme den", + "terms": "Allgemeinen Geschäftsbedingungen", + "marketing_consent": "Neuigkeiten und Sonderangebote senden", + "joining": "Anmeldung läuft...", + "join_button": "Beitreten & {points} Punkte erhalten" + }, + "privacy_policy": "Datenschutzrichtlinie", + "close": "Schließen", + "success": { + "title": "Willkommen!", + "message": "Sie sind jetzt Mitglied unseres Prämienprogramms.", + "card_number": "Ihre Kartennummer", + "wallet_prompt": "Speichern Sie Ihre Karte auf Ihrem Handy für einfachen Zugriff:", + "next_steps_title": "Wie geht es weiter?", + "step_earn": "Zeigen Sie Ihre Kartennummer beim Einkauf, um Punkte zu sammeln", + "step_balance": "Prüfen Sie Ihren Kontostand online oder in der App", + "step_redeem": "Lösen Sie Punkte gegen Prämien an allen unseren Standorten ein", + "view_dashboard": "Mein Treue-Dashboard anzeigen", + "continue_shopping": "Weiter einkaufen" + }, + "errors": { + "load_failed": "Programminformationen konnten nicht geladen werden", + "email_exists": "Diese E-Mail ist bereits in unserem Treueprogramm registriert.", + "failed": "Anmeldung fehlgeschlagen. Bitte versuchen Sie es erneut." + } + }, + "common": { + "active": "Aktiv", + "inactive": "Inaktiv", + "cancel": "Abbrechen", + "save": "Speichern", + "delete": "Löschen", + "confirm": "Bestätigen", + "refresh": "Aktualisieren", + "loading": "Laden...", + "saving": "Speichern...", + "view": "Anzeigen", + "edit": "Bearbeiten", + "yes": "Ja", + "no": "Nein", + "none": "Keine", + "never": "Nie", + "total": "GESAMT", + "continue": "Weiter", + "back": "Zurück", + "points": "Punkte", + "minutes": "Minuten", + "or": "oder", + "at": "bei" + }, + "transactions": { + "card_created": "Angemeldet", + "welcome_bonus": "Willkommensbonus", + "stamp_earned": "Stempel erhalten", + "stamp_redeemed": "Stempel eingelöst", + "stamp_voided": "Stempel storniert", + "stamp_adjustment": "Stempel angepasst", + "points_earned": "Punkte verdient", + "points_redeemed": "Punkte eingelöst", + "points_voided": "Punkte storniert", + "points_adjustment": "Punkte angepasst", + "points_expired": "Punkte verfallen", + "card_deactivated": "Deaktiviert", + "reward_redeemed": "Prämie eingelöst" + }, + "shared": { + "analytics": { + "total_programs": "Programme insgesamt", + "total_members": "Mitglieder insgesamt", + "active_members": "Aktive Mitglieder", + "points_issued_30d": "Punkte vergeben (30T)", + "transactions_30d": "Transaktionen (30T)", + "x_active": "{count} aktiv", + "points_overview": "Punkteübersicht", + "points_issued_vs_redeemed": "Punkte vergeben vs eingelöst (30T)", + "issued": "Vergeben:", + "redeemed": "Eingelöst:", + "redemption_rate": "Einlösungsrate", + "outstanding_balance": "Ausstehender Saldo", + "member_activity": "Mitgliederaktivität", + "active_members_30d": "Aktive Mitglieder (30T)", + "new_this_month": "Neu diesen Monat", + "merchants_with_programs": "Händler mit Programmen", + "avg_points_per_member": "Durchschn. Punkte pro Mitglied", + "all_time_statistics": "Gesamtstatistiken", + "total_points_issued": "Punkte insgesamt vergeben", + "total_points_redeemed": "Punkte insgesamt eingelöst", + "points_redeemed_30d": "Punkte eingelöst (30T)", + "outstanding_liability": "Ausstehende Verbindlichkeit", + "location_breakdown": "Aufschlüsselung nach Standort", + "store": "Geschäft", + "enrolled": "Angemeldet", + "points_earned": "Punkte verdient", + "points_redeemed": "Punkte eingelöst" + }, + "program_view": { + "program_configuration": "Programmkonfiguration", + "program_name": "Programmname", + "card_name": "Kartenname", + "stamps_configuration": "Stempelkonfiguration", + "stamps_target": "Stempelziel", + "reward_description": "Prämienbeschreibung", + "reward_value": "Prämienwert", + "points_configuration": "Punktekonfiguration", + "points_per_eur": "Punkte pro EUR", + "welcome_bonus": "Willkommensbonus", + "x_points": "{count} Punkte", + "minimum_redemption": "Mindesteinlösung", + "minimum_purchase": "Mindesteinkauf", + "points_expiration": "Punkteverfall", + "x_days_inactivity": "{days} Tage Inaktivität", + "redemption_rewards": "Einlösungsprämien", + "reward": "Prämie", + "points_required": "Benötigte Punkte", + "description": "Beschreibung", + "anti_fraud": "Betrugsschutz", + "cooldown": "Wartezeit", + "x_minutes": "{count} Minuten", + "max_daily_stamps": "Max. Stempel pro Tag", + "staff_pin_required": "Mitarbeiter-PIN erforderlich", + "branding": "Branding", + "primary_color": "Primärfarbe", + "secondary_color": "Sekundärfarbe", + "logo_url": "Logo-URL", + "hero_image_url": "Hintergrundbild-URL", + "terms_privacy": "AGB & Datenschutz", + "terms_conditions": "Allgemeine Geschäftsbedingungen", + "privacy_policy_url": "Datenschutzrichtlinien-URL" + }, + "program_form": { + "program_type": "Programmtyp", + "points_type_desc": "Punkte pro ausgegebenem EUR verdienen", + "stamps_type_desc": "N Stempel sammeln, Prämie erhalten", + "hybrid_type_desc": "Stempel und Punkte kombiniert", + "stamps_configuration": "Stempelkonfiguration", + "stamps_target": "Stempelziel", + "stamps_target_help": "Anzahl der Stempel für die Prämie", + "reward_description": "Prämienbeschreibung", + "reward_value_cents": "Prämienwert (Cent)", + "points_configuration": "Punktekonfiguration", + "points_per_eur": "Punkte pro ausgegebenem EUR", + "eur_equals_points": "1 EUR = {points} Punkt(e)", + "welcome_bonus_points": "Willkommensbonuspunkte", + "welcome_bonus_help": "Bonuspunkte bei der Anmeldung", + "minimum_redemption_points": "Mindesteinlösungspunkte", + "minimum_purchase_cents": "Mindesteinkauf (Cent)", + "minimum_purchase_help": "Mindesteinkaufsbetrag zum Punktesammeln (0 = kein Minimum)", + "points_expiration_days": "Punkteverfall (Tage)", + "points_expiration_help": "Tage der Inaktivität bis zum Punkteverfall (0 = nie)", + "redemption_rewards": "Einlösungsprämien", + "add_reward": "Prämie hinzufügen", + "no_rewards_configured": "Keine Prämien konfiguriert. Fügen Sie eine Prämie hinzu, damit Kunden Punkte einlösen können.", + "reward_name": "Prämienname", + "points_required": "Benötigte Punkte", + "description": "Beschreibung", + "anti_fraud_settings": "Betrugsschutz-Einstellungen", + "cooldown_minutes": "Wartezeit (Minuten)", + "cooldown_help": "Zeit zwischen Stempeln derselben Karte", + "max_daily_stamps": "Max. Stempel pro Tag", + "max_daily_stamps_help": "Maximale Stempel pro Karte pro Tag", + "require_staff_pin": "Mitarbeiter-PIN verlangen", + "branding": "Branding", + "card_name": "Kartenname", + "primary_color": "Primärfarbe", + "secondary_color": "Sekundärfarbe", + "logo_url": "Logo-URL", + "logo_url_help": "Erforderlich für Google Wallet-Integration. Muss eine öffentlich zugängliche Bild-URL sein (PNG oder JPG).", + "hero_image_url": "Hintergrundbild-URL", + "terms_privacy": "AGB & Datenschutz", + "terms_conditions": "Allgemeine Geschäftsbedingungen", + "privacy_policy_url": "Datenschutzrichtlinien-URL", + "program_status": "Programmstatus", + "program_active": "Programm aktiv", + "program_active_help": "Deaktiviert können Kunden weder sammeln noch einlösen", + "delete_program": "Programm löschen", + "create_program": "Programm erstellen", + "save_changes": "Änderungen speichern" + } + }, + "admin": { + "programs": { + "title": "Treueprogramme", + "create_program": "Programm erstellen", + "loading": "Treueprogramme werden geladen...", + "error_loading": "Fehler beim Laden der Treueprogramme", + "total_programs": "Programme insgesamt", + "active": "Aktiv", + "total_members": "Mitglieder insgesamt", + "transactions_30d": "Transaktionen (30T)", + "search_placeholder": "Nach Händlername suchen...", + "all_status": "Alle Status", + "table_merchant": "Händler", + "table_program_type": "Programmtyp", + "table_members": "Mitglieder", + "table_points_issued": "Punkte vergeben", + "table_status": "Status", + "table_created": "Erstellt", + "table_actions": "Aktionen", + "no_programs": "Keine Treueprogramme gefunden", + "adjust_filters": "Versuchen Sie, Ihre Suche oder Filter anzupassen", + "no_merchants_yet": "Noch keine Händler haben Treueprogramme erstellt", + "x_active": "({count} aktiv)", + "x_redeemed": "{count} eingelöst", + "pt_per_eur": "Pkt/EUR", + "delete_title": "Treueprogramm löschen", + "delete_message": "Treueprogramm für \"{name}\" löschen? Alle zugehörigen Daten (Karten, Transaktionen, Prämien) werden dauerhaft gelöscht. Dies kann nicht rückgängig gemacht werden.", + "delete_confirm": "Programm löschen", + "create_title": "Treueprogramm erstellen", + "create_description": "Wählen Sie einen Händler, um ein Treueprogramm zu erstellen.", + "search_merchant": "Händler suchen", + "type_merchant_name": "Händlername eingeben...", + "no_merchants_found": "Keine Händler gefunden", + "existing_program_warning": "Dieser Händler hat bereits ein Treueprogramm.", + "view_edit_existing": "Bestehendes Programm anzeigen / bearbeiten" + }, + "merchant_detail": { + "title": "Händler-Treuedetails", + "loading": "Treuedetails werden geladen...", + "error_loading": "Fehler beim Laden der Händlertreue", + "program_active": "Treueprogramm aktiv", + "no_program_subtitle": "Kein Treueprogramm", + "quick_actions": "Schnellaktionen", + "edit_program": "Programm bearbeiten", + "admin_policy": "Admin-Richtlinie", + "view_merchant": "Händler anzeigen", + "total_members": "Mitglieder insgesamt", + "active_30d": "Aktiv (30T)", + "points_issued_30d": "Punkte vergeben (30T)", + "points_redeemed_30d": "Punkte eingelöst (30T)", + "no_program": "Kein Treueprogramm", + "no_program_desc": "Dieser Händler hat noch kein Treueprogramm eingerichtet.", + "create_program": "Programm erstellen", + "delete_title": "Treueprogramm löschen", + "delete_message": "Das Treueprogramm und alle zugehörigen Daten werden dauerhaft gelöscht. Dies kann nicht rückgängig gemacht werden.", + "delete_confirm": "Programm löschen", + "location_breakdown": "Aufschlüsselung nach Standort", + "table_location": "Standort", + "table_enrolled": "Angemeldet", + "table_points_earned": "Punkte verdient", + "table_points_redeemed": "Punkte eingelöst", + "table_transactions_30d": "Transaktionen (30T)", + "admin_policy_settings": "Admin-Richtlinieneinstellungen", + "staff_pin_policy": "Mitarbeiter-PIN-Richtlinie", + "self_enrollment": "Selbstanmeldung", + "cross_location_redemption": "Standortübergreifende Einlösung", + "allowed": "Erlaubt", + "disabled": "Deaktiviert", + "modify_policy": "Admin-Richtlinie ändern" + }, + "merchant_settings": { + "title": "Händler-Treueeinstellungen", + "loading": "Einstellungen werden geladen...", + "error_loading": "Fehler beim Laden der Einstellungen", + "admin_controlled": "Admin-kontrollierte Einstellungen für das Treueprogramm dieses Händlers", + "staff_pin_policy": "Mitarbeiter-PIN-Richtlinie", + "staff_pin_description": "Legen Sie fest, ob Mitarbeiter einen PIN eingeben müssen, um Treuetransaktionen zu verarbeiten.", + "required": "Erforderlich", + "required_desc": "Mitarbeiter müssen ihren PIN bei jeder Transaktion eingeben. Empfohlen für die Sicherheit.", + "optional": "Optional", + "optional_desc": "Geschäfte können wählen, ob PINs erforderlich sind.", + "pin_disabled": "Deaktiviert", + "pin_disabled_desc": "Mitarbeiter-PINs werden nicht verwendet. Jeder Mitarbeiter kann Transaktionen verarbeiten.", + "pin_lockout_settings": "PIN-Sperreinstellungen", + "max_failed_attempts": "Max. Fehlversuche", + "max_failed_attempts_help": "Anzahl falscher Versuche vor Sperrung (3-10)", + "lockout_duration": "Sperrdauer (Minuten)", + "lockout_duration_help": "Sperrdauer nach Fehlversuchen (5-120 Minuten)", + "enrollment_settings": "Anmeldeeinstellungen", + "allow_self_enrollment": "Selbstanmeldung erlauben", + "self_enrollment_desc": "Kunden können sich per QR-Code ohne Personal anmelden", + "transaction_settings": "Transaktionseinstellungen", + "allow_cross_location": "Standortübergreifende Einlösung erlauben", + "cross_location_desc": "Kunden können Punkte an allen Standorten des Händlers einlösen", + "allow_void": "Stornierungen erlauben", + "void_desc": "Mitarbeiter können Punkte/Stempel bei Rückgaben stornieren", + "save_settings": "Einstellungen speichern" + }, + "analytics": { + "title": "Treue-Analytik", + "subtitle": "Plattformweite Treueprogramm-Statistiken", + "loading": "Analytik wird geladen...", + "error_loading": "Fehler beim Laden der Analytik", + "filter_by_merchant": "Nach Händler filtern", + "search_merchants_placeholder": "Händler nach Name suchen...", + "showing_stats_for": "Statistiken für:", + "wallet_status": "Wallet-Integrationsstatus", + "google_wallet": "Google Wallet", + "apple_wallet": "Apple Wallet", + "connected": "Verbunden", + "error": "Fehler", + "not_configured": "Nicht konfiguriert", + "issuer_id": "Aussteller-ID", + "project": "Projekt", + "wallet_objects": "Wallet-Objekte", + "loyalty_classes": "Treueklassen", + "pass_type_id": "Pass-Typ-ID", + "team_id": "Team-ID", + "active_passes": "Aktive Pässe", + "quick_actions": "Schnellaktionen", + "view_all_programs": "Alle Programme anzeigen", + "manage_merchants": "Händler verwalten" + }, + "program_edit": { + "title": "Programmkonfiguration", + "loading": "Konfiguration wird geladen...", + "error_loading": "Fehler beim Laden der Programmkonfiguration", + "create_subtitle": "Treueprogramm für diesen Händler erstellen", + "edit_subtitle": "Programmkonfiguration bearbeiten", + "delete_title": "Treueprogramm löschen", + "delete_message": "Das Treueprogramm und alle zugehörigen Daten (Karten, Transaktionen, Prämien) werden dauerhaft gelöscht. Dies kann nicht rückgängig gemacht werden.", + "delete_confirm": "Programm löschen" + } + }, + "merchant": { + "program": { + "title": "Treueprogramm", + "subtitle": "Ihre Treueprogramm-Konfiguration.", + "edit_program": "Programm bearbeiten", + "no_program": "Kein Treueprogramm", + "no_program_desc": "Ihr Treueprogramm wurde noch nicht eingerichtet. Erstellen Sie eines, um Ihre Kunden zu belohnen.", + "create_program": "Programm erstellen" + }, + "program_edit": { + "title": "Treue-Einstellungen", + "page_title": "Treueprogramm-Einstellungen", + "subtitle": "Konfigurieren Sie Ihr Treueprogramm", + "loading": "Einstellungen werden geladen...", + "error_loading": "Fehler beim Laden der Einstellungen", + "delete_title": "Treueprogramm löschen", + "delete_message": "Ihr Treueprogramm und alle zugehörigen Daten (Karten, Transaktionen, Prämien) werden dauerhaft gelöscht. Dies kann nicht rückgängig gemacht werden.", + "delete_confirm": "Programm löschen" + }, + "analytics": { + "title": "Treue-Analytik", + "subtitle": "Treueprogramm-Statistiken für alle Ihre Geschäfte", + "loading": "Analytik wird geladen...", + "error_loading": "Fehler beim Laden der Analytik", + "no_program": "Kein Treueprogramm", + "no_program_desc": "Richten Sie ein Treueprogramm ein, um hier Analytik zu sehen.", + "create_program": "Programm erstellen", + "quick_actions": "Schnellaktionen", + "view_program": "Programm anzeigen", + "edit_program": "Programm bearbeiten" + } + }, + "store": { + "terminal": { + "title": "Treue-Terminal", + "subtitle": "Treuetransaktionen verarbeiten", + "members": "Mitglieder", + "analytics": "Analytik", + "loading": "Treue-Terminal wird geladen...", + "error_loading": "Fehler beim Laden des Terminals", + "not_setup": "Treueprogramm nicht eingerichtet", + "not_setup_desc": "Ihr Händler hat noch kein Treueprogramm konfiguriert.", + "setup_program": "Treueprogramm einrichten", + "contact_admin": "Kontaktieren Sie Ihren Administrator, um die Einrichtung abzuschließen.", + "find_customer": "Kunde finden", + "search_placeholder": "E-Mail, Telefon oder Kartennummer...", + "looking_up": "Suche läuft...", + "look_up_customer": "Kunde suchen", + "enroll_new_customer": "Neuen Kunden anmelden", + "customer_found": "Kunde gefunden", + "points_balance": "Punktestand", + "stamps": "Stempel", + "x_more_for_reward": "Noch {count} für Prämie", + "ready_to_redeem": "Bereit zum Einlösen!", + "add_stamp": "Stempel hinzufügen", + "current": "Aktuell:", + "cooldown_active": "Wartezeit aktiv", + "redeem_stamps": "Stempel einlösen", + "not_enough_stamps": "Noch nicht genug Stempel", + "earn_points": "Punkte sammeln", + "purchase_amount": "Einkaufsbetrag", + "points_to_award": "Zu vergebende Punkte:", + "award_points": "Punkte vergeben", + "redeem_reward": "Prämie einlösen", + "select_reward": "Prämie auswählen", + "select_reward_placeholder": "Prämie auswählen...", + "points_after": "Punkte danach:", + "search_to_process": "Suchen Sie einen Kunden, um eine Transaktion zu verarbeiten", + "recent_transactions": "Letzte Transaktionen an diesem Standort", + "table_time": "Zeit", + "table_customer": "Kunde", + "table_type": "Typ", + "table_points": "Punkte", + "table_notes": "Notizen", + "no_recent_transactions": "Keine aktuellen Transaktionen", + "enter_staff_pin": "Mitarbeiter-PIN eingeben", + "pin_authorize": "Geben Sie Ihren Mitarbeiter-PIN ein, um diese Transaktion zu autorisieren.", + "clear": "Löschen", + "processing": "Verarbeitung...", + "customer_not_found": "Kunde nicht gefunden. Sie können ihn als neues Mitglied anmelden.", + "error_lookup": "Fehler bei der Kundensuche: {message}", + "transaction_failed": "Transaktion fehlgeschlagen: {message}", + "stamp_added": "Stempel hinzugefügt!", + "stamps_redeemed": "Stempel eingelöst! Prämie erhalten.", + "x_points_awarded": "{points} Punkte vergeben!", + "reward_redeemed": "Prämie eingelöst: {name}" + }, + "cards": { + "title": "Treue-Mitglieder", + "subtitle": "Mitglieder Ihres Treueprogramms anzeigen und verwalten", + "enroll_new": "Anmelden", + "loading": "Mitglieder werden geladen...", + "error_loading": "Fehler beim Laden der Mitglieder", + "total_members": "Mitglieder insgesamt", + "active_30d": "Aktiv (30T)", + "new_this_month": "Neu diesen Monat", + "total_points_balance": "Gesamtpunktestand", + "search_placeholder": "Nach Name, E-Mail, Telefon oder Karte suchen...", + "all_status": "Alle Status", + "table_member": "Mitglied", + "table_card_number": "Kartennummer", + "table_points_balance": "Punktestand", + "table_last_activity": "Letzte Aktivität", + "table_status": "Status", + "table_actions": "Aktionen", + "no_members": "Keine Mitglieder gefunden", + "adjust_search": "Versuchen Sie, Ihre Suche anzupassen", + "enroll_first": "Melden Sie Ihren ersten Kunden an" + }, + "card_detail": { + "title": "Mitgliederdetails", + "loading": "Mitgliederdetails werden geladen...", + "error_loading": "Fehler beim Laden des Mitglieds", + "points_balance": "Punktestand", + "total_earned": "Insgesamt verdient", + "total_redeemed": "Insgesamt eingelöst", + "member_since": "Mitglied seit", + "customer_information": "Kundeninformation", + "name": "Name", + "email": "E-Mail", + "phone": "Telefon", + "birthday": "Geburtstag", + "card_details": "Kartendetails", + "card_number": "Kartennummer", + "status": "Status", + "last_activity": "Letzte Aktivität", + "enrolled_at": "Angemeldet am", + "transaction_history": "Transaktionsverlauf", + "table_date": "Datum", + "table_type": "Typ", + "table_points": "Punkte", + "table_location": "Standort", + "table_notes": "Notizen", + "no_transactions": "Noch keine Transaktionen" + }, + "enroll": { + "title": "Kunde anmelden", + "page_title": "Neuen Kunden anmelden", + "subtitle": "Neues Mitglied zu Ihrem Treueprogramm hinzufügen", + "loading": "Laden...", + "error_loading": "Fehler beim Laden des Anmeldeformulars", + "customer_information": "Kundeninformation", + "first_name": "Vorname", + "last_name": "Nachname", + "email": "E-Mail", + "phone": "Telefon", + "birthday": "Geburtstag", + "birthday_help": "Für Geburtstagsbelohnungen (optional)", + "communication_preferences": "Kommunikationseinstellungen", + "send_emails": "Werbe-E-Mails senden", + "send_sms": "Werbe-SMS senden", + "welcome_bonus": "Willkommensbonus", + "welcome_bonus_desc": "Kunde erhält {points} Bonuspunkte!", + "enroll_customer": "Kunde anmelden", + "enrolling": "Anmeldung...", + "customer_enrolled": "Kunde angemeldet!", + "starting_balance": "Anfangssaldo:", + "x_points": "{count} Punkte", + "back_to_terminal": "Zurück zum Terminal", + "enroll_another": "Weiteren anmelden", + "enrollment_failed": "Anmeldung fehlgeschlagen: {message}" + }, + "analytics": { + "title": "Treue-Analytik", + "subtitle": "Verfolgen Sie die Leistung Ihres Treueprogramms", + "loading": "Analytik wird geladen...", + "error_loading": "Fehler beim Laden der Analytik", + "quick_actions": "Schnellaktionen", + "open_terminal": "Terminal öffnen", + "view_members": "Mitglieder anzeigen", + "view_program": "Programm anzeigen" + }, + "program": { + "title": "Treueprogramm", + "subtitle": "Ihre Treueprogramm-Konfiguration", + "edit_program": "Programm bearbeiten", + "loading": "Programm wird geladen...", + "error_loading": "Fehler beim Laden des Programms", + "no_program": "Kein Treueprogramm", + "no_program_desc": "Ihr Händler hat noch kein Treueprogramm konfiguriert.", + "create_program": "Programm erstellen", + "contact_admin": "Kontaktieren Sie Ihren Administrator, um ein Treueprogramm einzurichten." + }, + "settings": { + "title": "Treue-Einstellungen", + "page_title": "Treueprogramm-Einstellungen", + "subtitle": "Konfigurieren Sie Ihr Treueprogramm", + "back_to_program": "Zurück zum Programm", + "loading": "Einstellungen werden geladen...", + "error_loading": "Fehler beim Laden der Einstellungen", + "access_restricted": "Zugriff eingeschränkt", + "owner_only": "Nur der Geschäftsinhaber kann die Treueprogramm-Einstellungen verwalten.", + "delete_title": "Treueprogramm löschen", + "delete_message": "Das Treueprogramm und alle zugehörigen Daten (Karten, Transaktionen, Prämien) werden dauerhaft gelöscht. Dies kann nicht rückgängig gemacht werden.", + "delete_confirm": "Programm löschen", + "program_created": "Programm erfolgreich erstellt", + "program_updated": "Programm erfolgreich aktualisiert", + "program_deleted": "Treueprogramm gelöscht", + "save_failed": "Speichern fehlgeschlagen: {message}", + "delete_failed": "Löschen fehlgeschlagen: {message}" + } + }, + "storefront": { + "dashboard": { + "back_to_account": "Zurück zum Konto", + "my_loyalty": "Meine Treue", + "join_title": "Treten Sie unserem Prämienprogramm bei!", + "join_subtitle": "Sammeln Sie Punkte bei jedem Einkauf und lösen Sie sie gegen Prämien ein.", + "join_now": "Jetzt beitreten", + "points_balance": "Punktestand", + "card_number": "Kartennummer", + "show_card": "Karte anzeigen", + "total_earned": "Insgesamt verdient", + "total_redeemed": "Insgesamt eingelöst", + "available_rewards": "Verfügbare Prämien", + "no_rewards_yet": "Noch keine Prämien verfügbar", + "ready_to_redeem": "Bereit zum Einlösen", + "x_more_to_go": "Noch {count}", + "redeem_hint": "Zeigen Sie Ihre Karte dem Personal, um Prämien im Geschäft einzulösen.", + "recent_activity": "Letzte Aktivität", + "view_all": "Alle anzeigen", + "no_transactions": "Noch keine Transaktionen. Machen Sie einen Einkauf, um Punkte zu sammeln!", + "earn_redeem_locations": "Sammel- & Einlöse-Standorte", + "your_loyalty_card": "Ihre Treuekarte", + "show_to_staff": "Zeigen Sie dies dem Personal beim Einkauf oder Einlösen von Prämien." + }, + "history": { + "back_to_loyalty": "Zurück zur Treue", + "title": "Transaktionsverlauf", + "subtitle": "Alle Ihre Treuepunkttransaktionen anzeigen", + "current_balance": "Aktueller Saldo", + "total_earned": "Insgesamt verdient", + "total_redeemed": "Insgesamt eingelöst", + "no_transactions": "Noch keine Transaktionen", + "balance": "Saldo:", + "previous": "Zurück", + "next": "Weiter", + "page_x_of_y": "Seite {page} von {pages}" + } + }, + "toasts": { + "program_activated": "Programm erfolgreich aktiviert", + "program_deactivated": "Programm erfolgreich deaktiviert", + "activate_failed": "Programm konnte nicht aktiviert werden: {message}", + "deactivate_failed": "Programm konnte nicht deaktiviert werden: {message}", + "program_deleted": "Programm erfolgreich gelöscht", + "delete_failed": "Programm konnte nicht gelöscht werden: {message}", + "program_created": "Programm erfolgreich erstellt", + "program_updated": "Programm erfolgreich aktualisiert", + "loyalty_program_created": "Treueprogramm erstellt", + "loyalty_program_deleted": "Treueprogramm gelöscht", + "settings_saved": "Einstellungen erfolgreich gespeichert", + "save_failed": "Speichern fehlgeschlagen: {message}", + "settings_save_failed": "Einstellungen konnten nicht gespeichert werden: {message}", + "create_failed": "Programm konnte nicht erstellt werden: {message}", + "logo_required": "Logo-URL ist für die Wallet-Integration erforderlich." } } diff --git a/app/modules/loyalty/locales/en.json b/app/modules/loyalty/locales/en.json index 8f5d1c9c..73385dbd 100644 --- a/app/modules/loyalty/locales/en.json +++ b/app/modules/loyalty/locales/en.json @@ -97,5 +97,589 @@ "title": "Create a loyalty program", "description": "Set up your first stamp or points program" } + }, + "enrollment": { + "title": "Join Our Rewards Program!", + "subtitle": "Earn {points} point for every EUR you spend", + "not_available_title": "Program Not Available", + "not_available_message": "This store doesn't have a loyalty program set up yet.", + "welcome_bonus": "Get {points} bonus points when you join!", + "already_member": "Already a member? Your points are linked to your email.", + "form": { + "email": "Email", + "first_name": "First Name", + "last_name": "Last Name", + "phone": "Phone (optional)", + "birthday": "Birthday (optional)", + "birthday_hint": "For special birthday rewards", + "terms_agree": "I agree to the", + "terms": "Terms & Conditions", + "marketing_consent": "Send me news and special offers", + "joining": "Joining...", + "join_button": "Join & Get {points} Points" + }, + "privacy_policy": "Privacy Policy", + "close": "Close", + "success": { + "title": "Welcome!", + "message": "You're now a member of our rewards program.", + "card_number": "Your Card Number", + "wallet_prompt": "Save your card to your phone for easy access:", + "next_steps_title": "What's Next?", + "step_earn": "Show your card number when making purchases to earn points", + "step_balance": "Check your balance online or in the app", + "step_redeem": "Redeem points for rewards at any of our locations", + "view_dashboard": "View My Loyalty Dashboard", + "continue_shopping": "Continue Shopping" + }, + "errors": { + "load_failed": "Failed to load program information", + "email_exists": "This email is already registered in our loyalty program.", + "failed": "Enrollment failed. Please try again." + } + }, + "common": { + "active": "Active", + "inactive": "Inactive", + "cancel": "Cancel", + "save": "Save", + "delete": "Delete", + "confirm": "Confirm", + "refresh": "Refresh", + "loading": "Loading...", + "saving": "Saving...", + "view": "View", + "edit": "Edit", + "yes": "Yes", + "no": "No", + "none": "None", + "never": "Never", + "total": "TOTAL", + "continue": "Continue", + "back": "Back", + "points": "points", + "minutes": "minutes", + "or": "or", + "at": "at" + }, + "transactions": { + "card_created": "Enrolled", + "welcome_bonus": "Welcome Bonus", + "stamp_earned": "Stamp Earned", + "stamp_redeemed": "Stamp Redeemed", + "stamp_voided": "Stamp Voided", + "stamp_adjustment": "Stamp Adjusted", + "points_earned": "Points Earned", + "points_redeemed": "Points Redeemed", + "points_voided": "Points Voided", + "points_adjustment": "Points Adjusted", + "points_expired": "Points Expired", + "card_deactivated": "Deactivated", + "reward_redeemed": "Reward Redeemed" + }, + "shared": { + "analytics": { + "total_programs": "Total Programs", + "total_members": "Total Members", + "active_members": "Active Members", + "points_issued_30d": "Points Issued (30d)", + "transactions_30d": "Transactions (30d)", + "x_active": "{count} active", + "points_overview": "Points Overview", + "points_issued_vs_redeemed": "Points Issued vs Redeemed (30d)", + "issued": "Issued:", + "redeemed": "Redeemed:", + "redemption_rate": "Redemption Rate", + "outstanding_balance": "Outstanding Balance", + "member_activity": "Member Activity", + "active_members_30d": "Active Members (30d)", + "new_this_month": "New This Month", + "merchants_with_programs": "Merchants with Programs", + "avg_points_per_member": "Avg Points Per Member", + "all_time_statistics": "All-Time Statistics", + "total_points_issued": "Total Points Issued", + "total_points_redeemed": "Total Points Redeemed", + "points_redeemed_30d": "Points Redeemed (30d)", + "outstanding_liability": "Outstanding Liability", + "location_breakdown": "Location Breakdown", + "store": "Store", + "enrolled": "Enrolled", + "points_earned": "Points Earned", + "points_redeemed": "Points Redeemed" + }, + "program_view": { + "program_configuration": "Program Configuration", + "program_name": "Program Name", + "card_name": "Card Name", + "stamps_configuration": "Stamps Configuration", + "stamps_target": "Stamps Target", + "reward_description": "Reward Description", + "reward_value": "Reward Value", + "points_configuration": "Points Configuration", + "points_per_eur": "Points per EUR", + "welcome_bonus": "Welcome Bonus", + "x_points": "{count} points", + "minimum_redemption": "Minimum Redemption", + "minimum_purchase": "Minimum Purchase", + "points_expiration": "Points Expiration", + "x_days_inactivity": "{days} days of inactivity", + "redemption_rewards": "Redemption Rewards", + "reward": "Reward", + "points_required": "Points Required", + "description": "Description", + "anti_fraud": "Anti-Fraud", + "cooldown": "Cooldown", + "x_minutes": "{count} minutes", + "max_daily_stamps": "Max Daily Stamps", + "staff_pin_required": "Staff PIN Required", + "branding": "Branding", + "primary_color": "Primary Color", + "secondary_color": "Secondary Color", + "logo_url": "Logo URL", + "hero_image_url": "Hero Image URL", + "terms_privacy": "Terms & Privacy", + "terms_conditions": "Terms & Conditions", + "privacy_policy_url": "Privacy Policy URL" + }, + "program_form": { + "program_type": "Program Type", + "points_type_desc": "Earn points per EUR spent", + "stamps_type_desc": "Collect N stamps, get reward", + "hybrid_type_desc": "Both stamps and points", + "stamps_configuration": "Stamps Configuration", + "stamps_target": "Stamps Target", + "stamps_target_help": "Number of stamps needed for reward", + "reward_description": "Reward Description", + "reward_value_cents": "Reward Value (cents)", + "points_configuration": "Points Configuration", + "points_per_eur": "Points per EUR spent", + "eur_equals_points": "1 EUR = {points} point(s)", + "welcome_bonus_points": "Welcome Bonus Points", + "welcome_bonus_help": "Bonus points awarded on enrollment", + "minimum_redemption_points": "Minimum Redemption Points", + "minimum_purchase_cents": "Minimum Purchase (cents)", + "minimum_purchase_help": "Minimum purchase amount to earn points (0 = no minimum)", + "points_expiration_days": "Points Expiration (days)", + "points_expiration_help": "Days of inactivity before points expire (0 = never)", + "redemption_rewards": "Redemption Rewards", + "add_reward": "Add Reward", + "no_rewards_configured": "No rewards configured. Add a reward to allow customers to redeem points.", + "reward_name": "Reward Name", + "points_required": "Points Required", + "description": "Description", + "anti_fraud_settings": "Anti-Fraud Settings", + "cooldown_minutes": "Cooldown (minutes)", + "cooldown_help": "Time between stamps from the same card", + "max_daily_stamps": "Max Daily Stamps", + "max_daily_stamps_help": "Maximum stamps per card per day", + "require_staff_pin": "Require Staff PIN", + "branding": "Branding", + "card_name": "Card Name", + "primary_color": "Primary Color", + "secondary_color": "Secondary Color", + "logo_url": "Logo URL", + "logo_url_help": "Required for Google Wallet integration. Must be a publicly accessible image URL (PNG or JPG).", + "hero_image_url": "Hero Image URL", + "terms_privacy": "Terms & Privacy", + "terms_conditions": "Terms & Conditions", + "privacy_policy_url": "Privacy Policy URL", + "program_status": "Program Status", + "program_active": "Program Active", + "program_active_help": "When disabled, customers cannot earn or redeem", + "delete_program": "Delete Program", + "create_program": "Create Program", + "save_changes": "Save Changes" + } + }, + "admin": { + "programs": { + "title": "Loyalty Programs", + "create_program": "Create Program", + "loading": "Loading loyalty programs...", + "error_loading": "Error loading loyalty programs", + "total_programs": "Total Programs", + "active": "Active", + "total_members": "Total Members", + "transactions_30d": "Transactions (30d)", + "search_placeholder": "Search by merchant name...", + "all_status": "All Status", + "table_merchant": "Merchant", + "table_program_type": "Program Type", + "table_members": "Members", + "table_points_issued": "Points Issued", + "table_status": "Status", + "table_created": "Created", + "table_actions": "Actions", + "no_programs": "No loyalty programs found", + "adjust_filters": "Try adjusting your search or filters", + "no_merchants_yet": "No merchants have set up loyalty programs yet", + "x_active": "({count} active)", + "x_redeemed": "{count} redeemed", + "pt_per_eur": "pt/EUR", + "delete_title": "Delete Loyalty Program", + "delete_message": "Delete the loyalty program for \"{name}\"? This will permanently remove all associated data (cards, transactions, rewards). This cannot be undone.", + "delete_confirm": "Delete Program", + "create_title": "Create Loyalty Program", + "create_description": "Select a merchant to create a loyalty program for.", + "search_merchant": "Search Merchant", + "type_merchant_name": "Type merchant name...", + "no_merchants_found": "No merchants found", + "existing_program_warning": "This merchant already has a loyalty program.", + "view_edit_existing": "View / Edit existing program" + }, + "merchant_detail": { + "title": "Merchant Loyalty Details", + "loading": "Loading merchant loyalty details...", + "error_loading": "Error loading merchant loyalty", + "program_active": "Loyalty Program Active", + "no_program_subtitle": "No Loyalty Program", + "quick_actions": "Quick Actions", + "edit_program": "Edit Program", + "admin_policy": "Admin Policy", + "view_merchant": "View Merchant", + "total_members": "Total Members", + "active_30d": "Active (30d)", + "points_issued_30d": "Points Issued (30d)", + "points_redeemed_30d": "Points Redeemed (30d)", + "no_program": "No Loyalty Program", + "no_program_desc": "This merchant has not set up a loyalty program yet.", + "create_program": "Create Program", + "delete_title": "Delete Loyalty Program", + "delete_message": "This will permanently delete the loyalty program and all associated data. This action cannot be undone.", + "delete_confirm": "Delete Program", + "location_breakdown": "Location Breakdown", + "table_location": "Location", + "table_enrolled": "Enrolled", + "table_points_earned": "Points Earned", + "table_points_redeemed": "Points Redeemed", + "table_transactions_30d": "Transactions (30d)", + "admin_policy_settings": "Admin Policy Settings", + "staff_pin_policy": "Staff PIN Policy", + "self_enrollment": "Self Enrollment", + "cross_location_redemption": "Cross-Location Redemption", + "allowed": "Allowed", + "disabled": "Disabled", + "modify_policy": "Modify admin policy" + }, + "merchant_settings": { + "title": "Merchant Loyalty Settings", + "loading": "Loading settings...", + "error_loading": "Error loading settings", + "admin_controlled": "Admin-controlled settings for this merchant's loyalty program", + "staff_pin_policy": "Staff PIN Policy", + "staff_pin_description": "Control whether staff members at this merchant's locations must enter a PIN to process loyalty transactions.", + "required": "Required", + "required_desc": "Staff must enter their PIN for every transaction. Recommended for security.", + "optional": "Optional", + "optional_desc": "Stores can choose whether to require PINs at their locations.", + "pin_disabled": "Disabled", + "pin_disabled_desc": "Staff PINs are not used. Any staff member can process transactions.", + "pin_lockout_settings": "PIN Lockout Settings", + "max_failed_attempts": "Max Failed Attempts", + "max_failed_attempts_help": "Number of wrong attempts before lockout (3-10)", + "lockout_duration": "Lockout Duration (minutes)", + "lockout_duration_help": "How long to lock out after failed attempts (5-120 minutes)", + "enrollment_settings": "Enrollment Settings", + "allow_self_enrollment": "Allow Self-Service Enrollment", + "self_enrollment_desc": "Customers can sign up via QR code without staff assistance", + "transaction_settings": "Transaction Settings", + "allow_cross_location": "Allow Cross-Location Redemption", + "cross_location_desc": "Customers can redeem points at any merchant location", + "allow_void": "Allow Void Transactions", + "void_desc": "Staff can void points/stamps for returns", + "save_settings": "Save Settings" + }, + "analytics": { + "title": "Loyalty Analytics", + "subtitle": "Platform-wide loyalty program statistics", + "loading": "Loading analytics...", + "error_loading": "Error loading analytics", + "filter_by_merchant": "Filter by Merchant", + "search_merchants_placeholder": "Search merchants by name...", + "showing_stats_for": "Showing stats for:", + "wallet_status": "Wallet Integration Status", + "google_wallet": "Google Wallet", + "apple_wallet": "Apple Wallet", + "connected": "Connected", + "error": "Error", + "not_configured": "Not Configured", + "issuer_id": "Issuer ID", + "project": "Project", + "wallet_objects": "Wallet Objects", + "loyalty_classes": "Loyalty Classes", + "pass_type_id": "Pass Type ID", + "team_id": "Team ID", + "active_passes": "Active Passes", + "quick_actions": "Quick Actions", + "view_all_programs": "View All Programs", + "manage_merchants": "Manage Merchants" + }, + "program_edit": { + "title": "Program Configuration", + "loading": "Loading program configuration...", + "error_loading": "Error loading program configuration", + "create_subtitle": "Create a loyalty program for this merchant", + "edit_subtitle": "Edit program configuration", + "delete_title": "Delete Loyalty Program", + "delete_message": "This will permanently delete the loyalty program and all associated data (cards, transactions, rewards). This action cannot be undone.", + "delete_confirm": "Delete Program" + } + }, + "merchant": { + "program": { + "title": "Loyalty Program", + "subtitle": "Your loyalty program configuration.", + "edit_program": "Edit Program", + "no_program": "No Loyalty Program", + "no_program_desc": "Your loyalty program hasn't been set up yet. Create one to start rewarding your customers.", + "create_program": "Create Program" + }, + "program_edit": { + "title": "Loyalty Settings", + "page_title": "Loyalty Program Settings", + "subtitle": "Configure your loyalty program", + "loading": "Loading settings...", + "error_loading": "Error loading settings", + "delete_title": "Delete Loyalty Program", + "delete_message": "This will permanently delete your loyalty program and all associated data (cards, transactions, rewards). This action cannot be undone.", + "delete_confirm": "Delete Program" + }, + "analytics": { + "title": "Loyalty Analytics", + "subtitle": "Loyalty program statistics across all your stores", + "loading": "Loading analytics...", + "error_loading": "Error loading analytics", + "no_program": "No Loyalty Program", + "no_program_desc": "Set up a loyalty program to see analytics here.", + "create_program": "Create Program", + "quick_actions": "Quick Actions", + "view_program": "View Program", + "edit_program": "Edit Program" + } + }, + "store": { + "terminal": { + "title": "Loyalty Terminal", + "subtitle": "Process loyalty transactions", + "members": "Members", + "analytics": "Analytics", + "loading": "Loading loyalty terminal...", + "error_loading": "Error loading terminal", + "not_setup": "Loyalty Program Not Set Up", + "not_setup_desc": "Your merchant doesn't have a loyalty program configured yet.", + "setup_program": "Set Up Loyalty Program", + "contact_admin": "Contact your administrator to complete the setup.", + "find_customer": "Find Customer", + "search_placeholder": "Email, phone, or card number...", + "looking_up": "Looking up...", + "look_up_customer": "Look Up Customer", + "enroll_new_customer": "Enroll New Customer", + "customer_found": "Customer Found", + "points_balance": "Points Balance", + "stamps": "Stamps", + "x_more_for_reward": "{count} more for reward", + "ready_to_redeem": "Ready to redeem!", + "add_stamp": "Add Stamp", + "current": "Current:", + "cooldown_active": "Cooldown active", + "redeem_stamps": "Redeem Stamps", + "not_enough_stamps": "Not enough stamps yet", + "earn_points": "Earn Points", + "purchase_amount": "Purchase Amount", + "points_to_award": "Points to award:", + "award_points": "Award Points", + "redeem_reward": "Redeem Reward", + "select_reward": "Select Reward", + "select_reward_placeholder": "Select reward...", + "points_after": "Points after:", + "search_to_process": "Search for a customer to process a transaction", + "recent_transactions": "Recent Transactions at This Location", + "table_time": "Time", + "table_customer": "Customer", + "table_type": "Type", + "table_points": "Points", + "table_notes": "Notes", + "no_recent_transactions": "No recent transactions", + "enter_staff_pin": "Enter Staff PIN", + "pin_authorize": "Enter your staff PIN to authorize this transaction.", + "clear": "Clear", + "processing": "Processing...", + "customer_not_found": "Customer not found. You can enroll them as a new member.", + "error_lookup": "Error looking up customer: {message}", + "transaction_failed": "Transaction failed: {message}", + "stamp_added": "Stamp added!", + "stamps_redeemed": "Stamps redeemed! Reward earned.", + "x_points_awarded": "{points} points awarded!", + "reward_redeemed": "Reward redeemed: {name}" + }, + "cards": { + "title": "Loyalty Members", + "subtitle": "View and manage your loyalty program members", + "enroll_new": "Enroll New", + "loading": "Loading members...", + "error_loading": "Error loading members", + "total_members": "Total Members", + "active_30d": "Active (30d)", + "new_this_month": "New This Month", + "total_points_balance": "Total Points Balance", + "search_placeholder": "Search by name, email, phone, or card...", + "all_status": "All Status", + "table_member": "Member", + "table_card_number": "Card Number", + "table_points_balance": "Points Balance", + "table_last_activity": "Last Activity", + "table_status": "Status", + "table_actions": "Actions", + "no_members": "No members found", + "adjust_search": "Try adjusting your search", + "enroll_first": "Enroll your first customer to get started" + }, + "card_detail": { + "title": "Member Details", + "loading": "Loading member details...", + "error_loading": "Error loading member", + "points_balance": "Points Balance", + "total_earned": "Total Earned", + "total_redeemed": "Total Redeemed", + "member_since": "Member Since", + "customer_information": "Customer Information", + "name": "Name", + "email": "Email", + "phone": "Phone", + "birthday": "Birthday", + "card_details": "Card Details", + "card_number": "Card Number", + "status": "Status", + "last_activity": "Last Activity", + "enrolled_at": "Enrolled At", + "transaction_history": "Transaction History", + "table_date": "Date", + "table_type": "Type", + "table_points": "Points", + "table_location": "Location", + "table_notes": "Notes", + "no_transactions": "No transactions yet" + }, + "enroll": { + "title": "Enroll Customer", + "page_title": "Enroll New Customer", + "subtitle": "Add a new member to your loyalty program", + "loading": "Loading...", + "error_loading": "Error loading enrollment form", + "customer_information": "Customer Information", + "first_name": "First Name", + "last_name": "Last Name", + "email": "Email", + "phone": "Phone", + "birthday": "Birthday", + "birthday_help": "For birthday rewards (optional)", + "communication_preferences": "Communication Preferences", + "send_emails": "Send promotional emails", + "send_sms": "Send promotional SMS", + "welcome_bonus": "Welcome Bonus", + "welcome_bonus_desc": "Customer will receive {points} bonus points!", + "enroll_customer": "Enroll Customer", + "enrolling": "Enrolling...", + "customer_enrolled": "Customer Enrolled!", + "starting_balance": "Starting Balance:", + "x_points": "{count} points", + "back_to_terminal": "Back to Terminal", + "enroll_another": "Enroll Another", + "enrollment_failed": "Enrollment failed: {message}" + }, + "analytics": { + "title": "Loyalty Analytics", + "subtitle": "Track your loyalty program performance", + "loading": "Loading analytics...", + "error_loading": "Error loading analytics", + "quick_actions": "Quick Actions", + "open_terminal": "Open Terminal", + "view_members": "View Members", + "view_program": "View Program" + }, + "program": { + "title": "Loyalty Program", + "subtitle": "Your loyalty program configuration", + "edit_program": "Edit Program", + "loading": "Loading program...", + "error_loading": "Error loading program", + "no_program": "No Loyalty Program", + "no_program_desc": "Your merchant doesn't have a loyalty program configured yet.", + "create_program": "Create Program", + "contact_admin": "Contact your administrator to set up a loyalty program." + }, + "settings": { + "title": "Loyalty Settings", + "page_title": "Loyalty Program Settings", + "subtitle": "Configure your loyalty program", + "back_to_program": "Back to Program", + "loading": "Loading settings...", + "error_loading": "Error loading settings", + "access_restricted": "Access Restricted", + "owner_only": "Only the merchant owner can manage loyalty program settings.", + "delete_title": "Delete Loyalty Program", + "delete_message": "This will permanently delete the loyalty program and all associated data (cards, transactions, rewards). This action cannot be undone.", + "delete_confirm": "Delete Program", + "program_created": "Program created successfully", + "program_updated": "Program updated successfully", + "program_deleted": "Loyalty program deleted", + "save_failed": "Failed to save: {message}", + "delete_failed": "Failed to delete: {message}" + } + }, + "storefront": { + "dashboard": { + "back_to_account": "Back to Account", + "my_loyalty": "My Loyalty", + "join_title": "Join Our Rewards Program!", + "join_subtitle": "Earn points on every purchase and redeem for rewards.", + "join_now": "Join Now", + "points_balance": "Points Balance", + "card_number": "Card Number", + "show_card": "Show Card", + "total_earned": "Total Earned", + "total_redeemed": "Total Redeemed", + "available_rewards": "Available Rewards", + "no_rewards_yet": "No rewards available yet", + "ready_to_redeem": "Ready to redeem", + "x_more_to_go": "{count} more to go", + "redeem_hint": "Show your card to staff to redeem rewards in-store.", + "recent_activity": "Recent Activity", + "view_all": "View All", + "no_transactions": "No transactions yet. Make a purchase to start earning points!", + "earn_redeem_locations": "Earn & Redeem Locations", + "your_loyalty_card": "Your Loyalty Card", + "show_to_staff": "Show this to staff when making a purchase or redeeming rewards." + }, + "history": { + "back_to_loyalty": "Back to Loyalty", + "title": "Transaction History", + "subtitle": "View all your loyalty point transactions", + "current_balance": "Current Balance", + "total_earned": "Total Earned", + "total_redeemed": "Total Redeemed", + "no_transactions": "No transactions yet", + "balance": "Balance:", + "previous": "Previous", + "next": "Next", + "page_x_of_y": "Page {page} of {pages}" + } + }, + "toasts": { + "program_activated": "Program activated successfully", + "program_deactivated": "Program deactivated successfully", + "activate_failed": "Failed to activate program: {message}", + "deactivate_failed": "Failed to deactivate program: {message}", + "program_deleted": "Program deleted successfully", + "delete_failed": "Failed to delete program: {message}", + "program_created": "Program created successfully", + "program_updated": "Program updated successfully", + "loyalty_program_created": "Loyalty program created", + "loyalty_program_deleted": "Loyalty program deleted", + "settings_saved": "Settings saved successfully", + "save_failed": "Failed to save: {message}", + "settings_save_failed": "Failed to save settings: {message}", + "create_failed": "Failed to create program: {message}", + "logo_required": "Logo URL is required for wallet integration." } } diff --git a/app/modules/loyalty/locales/fr.json b/app/modules/loyalty/locales/fr.json index 71896325..1942bd70 100644 --- a/app/modules/loyalty/locales/fr.json +++ b/app/modules/loyalty/locales/fr.json @@ -97,5 +97,589 @@ "title": "Créer un programme de fidélité", "description": "Créez votre premier programme de tampons ou de points" } + }, + "enrollment": { + "title": "Rejoignez notre programme de récompenses !", + "subtitle": "Gagnez {points} point pour chaque EUR dépensé", + "not_available_title": "Programme non disponible", + "not_available_message": "Ce magasin n'a pas encore de programme de fidélité.", + "welcome_bonus": "Obtenez {points} points bonus en vous inscrivant !", + "already_member": "Déjà membre ? Vos points sont liés à votre e-mail.", + "form": { + "email": "E-mail", + "first_name": "Prénom", + "last_name": "Nom", + "phone": "Téléphone (facultatif)", + "birthday": "Date de naissance (facultatif)", + "birthday_hint": "Pour des récompenses d'anniversaire spéciales", + "terms_agree": "J'accepte les", + "terms": "Conditions Générales", + "marketing_consent": "M'envoyer des nouvelles et offres spéciales", + "joining": "Inscription en cours...", + "join_button": "S'inscrire et obtenir {points} points" + }, + "privacy_policy": "Politique de confidentialité", + "close": "Fermer", + "success": { + "title": "Bienvenue !", + "message": "Vous êtes maintenant membre de notre programme de récompenses.", + "card_number": "Votre numéro de carte", + "wallet_prompt": "Enregistrez votre carte sur votre téléphone pour un accès facile :", + "next_steps_title": "Et maintenant ?", + "step_earn": "Présentez votre numéro de carte lors de vos achats pour gagner des points", + "step_balance": "Consultez votre solde en ligne ou dans l'application", + "step_redeem": "Échangez vos points contre des récompenses dans tous nos points de vente", + "view_dashboard": "Voir mon tableau de bord fidélité", + "continue_shopping": "Continuer mes achats" + }, + "errors": { + "load_failed": "Impossible de charger les informations du programme", + "email_exists": "Cet e-mail est déjà inscrit dans notre programme de fidélité.", + "failed": "L'inscription a échoué. Veuillez réessayer." + } + }, + "common": { + "active": "Actif", + "inactive": "Inactif", + "cancel": "Annuler", + "save": "Enregistrer", + "delete": "Supprimer", + "confirm": "Confirmer", + "refresh": "Actualiser", + "loading": "Chargement...", + "saving": "Enregistrement...", + "view": "Voir", + "edit": "Modifier", + "yes": "Oui", + "no": "Non", + "none": "Aucun", + "never": "Jamais", + "total": "TOTAL", + "continue": "Continuer", + "back": "Retour", + "points": "points", + "minutes": "minutes", + "or": "ou", + "at": "à" + }, + "transactions": { + "card_created": "Inscrit", + "welcome_bonus": "Bonus de bienvenue", + "stamp_earned": "Tampon obtenu", + "stamp_redeemed": "Tampon échangé", + "stamp_voided": "Tampon annulé", + "stamp_adjustment": "Tampon ajusté", + "points_earned": "Points gagnés", + "points_redeemed": "Points échangés", + "points_voided": "Points annulés", + "points_adjustment": "Points ajustés", + "points_expired": "Points expirés", + "card_deactivated": "Désactivé", + "reward_redeemed": "Récompense échangée" + }, + "shared": { + "analytics": { + "total_programs": "Programmes au total", + "total_members": "Membres au total", + "active_members": "Membres actifs", + "points_issued_30d": "Points émis (30j)", + "transactions_30d": "Transactions (30j)", + "x_active": "{count} actifs", + "points_overview": "Aperçu des points", + "points_issued_vs_redeemed": "Points émis vs échangés (30j)", + "issued": "Émis :", + "redeemed": "Échangés :", + "redemption_rate": "Taux d'échange", + "outstanding_balance": "Solde restant", + "member_activity": "Activité des membres", + "active_members_30d": "Membres actifs (30j)", + "new_this_month": "Nouveaux ce mois", + "merchants_with_programs": "Commerçants avec programmes", + "avg_points_per_member": "Moy. points par membre", + "all_time_statistics": "Statistiques globales", + "total_points_issued": "Total points émis", + "total_points_redeemed": "Total points échangés", + "points_redeemed_30d": "Points échangés (30j)", + "outstanding_liability": "Passif en cours", + "location_breakdown": "Répartition par point de vente", + "store": "Magasin", + "enrolled": "Inscrits", + "points_earned": "Points gagnés", + "points_redeemed": "Points échangés" + }, + "program_view": { + "program_configuration": "Configuration du programme", + "program_name": "Nom du programme", + "card_name": "Nom de la carte", + "stamps_configuration": "Configuration des tampons", + "stamps_target": "Objectif de tampons", + "reward_description": "Description de la récompense", + "reward_value": "Valeur de la récompense", + "points_configuration": "Configuration des points", + "points_per_eur": "Points par EUR", + "welcome_bonus": "Bonus de bienvenue", + "x_points": "{count} points", + "minimum_redemption": "Échange minimum", + "minimum_purchase": "Achat minimum", + "points_expiration": "Expiration des points", + "x_days_inactivity": "{days} jours d'inactivité", + "redemption_rewards": "Récompenses d'échange", + "reward": "Récompense", + "points_required": "Points requis", + "description": "Description", + "anti_fraud": "Anti-fraude", + "cooldown": "Temps d'attente", + "x_minutes": "{count} minutes", + "max_daily_stamps": "Tampons max par jour", + "staff_pin_required": "PIN personnel requis", + "branding": "Image de marque", + "primary_color": "Couleur principale", + "secondary_color": "Couleur secondaire", + "logo_url": "URL du logo", + "hero_image_url": "URL de l'image principale", + "terms_privacy": "Conditions & Confidentialité", + "terms_conditions": "Conditions Générales", + "privacy_policy_url": "URL politique de confidentialité" + }, + "program_form": { + "program_type": "Type de programme", + "points_type_desc": "Gagner des points par EUR dépensé", + "stamps_type_desc": "Collecter N tampons, obtenir une récompense", + "hybrid_type_desc": "Tampons et points combinés", + "stamps_configuration": "Configuration des tampons", + "stamps_target": "Objectif de tampons", + "stamps_target_help": "Nombre de tampons nécessaires pour la récompense", + "reward_description": "Description de la récompense", + "reward_value_cents": "Valeur de la récompense (centimes)", + "points_configuration": "Configuration des points", + "points_per_eur": "Points par EUR dépensé", + "eur_equals_points": "1 EUR = {points} point(s)", + "welcome_bonus_points": "Points bonus de bienvenue", + "welcome_bonus_help": "Points bonus attribués à l'inscription", + "minimum_redemption_points": "Points minimum d'échange", + "minimum_purchase_cents": "Achat minimum (centimes)", + "minimum_purchase_help": "Montant minimum d'achat pour gagner des points (0 = pas de minimum)", + "points_expiration_days": "Expiration des points (jours)", + "points_expiration_help": "Jours d'inactivité avant expiration des points (0 = jamais)", + "redemption_rewards": "Récompenses d'échange", + "add_reward": "Ajouter une récompense", + "no_rewards_configured": "Aucune récompense configurée. Ajoutez une récompense pour permettre aux clients d'échanger des points.", + "reward_name": "Nom de la récompense", + "points_required": "Points requis", + "description": "Description", + "anti_fraud_settings": "Paramètres anti-fraude", + "cooldown_minutes": "Temps d'attente (minutes)", + "cooldown_help": "Temps entre les tampons d'une même carte", + "max_daily_stamps": "Tampons max par jour", + "max_daily_stamps_help": "Maximum de tampons par carte par jour", + "require_staff_pin": "Exiger le PIN du personnel", + "branding": "Image de marque", + "card_name": "Nom de la carte", + "primary_color": "Couleur principale", + "secondary_color": "Couleur secondaire", + "logo_url": "URL du logo", + "logo_url_help": "Requis pour l'intégration Google Wallet. Doit être une URL d'image publique (PNG ou JPG).", + "hero_image_url": "URL de l'image principale", + "terms_privacy": "Conditions & Confidentialité", + "terms_conditions": "Conditions Générales", + "privacy_policy_url": "URL politique de confidentialité", + "program_status": "Statut du programme", + "program_active": "Programme actif", + "program_active_help": "Désactivé, les clients ne peuvent ni gagner ni échanger", + "delete_program": "Supprimer le programme", + "create_program": "Créer le programme", + "save_changes": "Enregistrer les modifications" + } + }, + "admin": { + "programs": { + "title": "Programmes de fidélité", + "create_program": "Créer un programme", + "loading": "Chargement des programmes de fidélité...", + "error_loading": "Erreur de chargement des programmes de fidélité", + "total_programs": "Programmes au total", + "active": "Actifs", + "total_members": "Membres au total", + "transactions_30d": "Transactions (30j)", + "search_placeholder": "Rechercher par nom de commerçant...", + "all_status": "Tous les statuts", + "table_merchant": "Commerçant", + "table_program_type": "Type de programme", + "table_members": "Membres", + "table_points_issued": "Points émis", + "table_status": "Statut", + "table_created": "Créé", + "table_actions": "Actions", + "no_programs": "Aucun programme de fidélité trouvé", + "adjust_filters": "Essayez d'ajuster votre recherche ou vos filtres", + "no_merchants_yet": "Aucun commerçant n'a encore créé de programme de fidélité", + "x_active": "({count} actifs)", + "x_redeemed": "{count} échangés", + "pt_per_eur": "pt/EUR", + "delete_title": "Supprimer le programme de fidélité", + "delete_message": "Supprimer le programme de fidélité de \"{name}\" ? Cela supprimera définitivement toutes les données associées (cartes, transactions, récompenses). Cette action est irréversible.", + "delete_confirm": "Supprimer le programme", + "create_title": "Créer un programme de fidélité", + "create_description": "Sélectionnez un commerçant pour créer un programme de fidélité.", + "search_merchant": "Rechercher un commerçant", + "type_merchant_name": "Tapez le nom du commerçant...", + "no_merchants_found": "Aucun commerçant trouvé", + "existing_program_warning": "Ce commerçant a déjà un programme de fidélité.", + "view_edit_existing": "Voir / Modifier le programme existant" + }, + "merchant_detail": { + "title": "Détails fidélité du commerçant", + "loading": "Chargement des détails de fidélité...", + "error_loading": "Erreur de chargement de la fidélité du commerçant", + "program_active": "Programme de fidélité actif", + "no_program_subtitle": "Aucun programme de fidélité", + "quick_actions": "Actions rapides", + "edit_program": "Modifier le programme", + "admin_policy": "Politique admin", + "view_merchant": "Voir le commerçant", + "total_members": "Membres au total", + "active_30d": "Actifs (30j)", + "points_issued_30d": "Points émis (30j)", + "points_redeemed_30d": "Points échangés (30j)", + "no_program": "Aucun programme de fidélité", + "no_program_desc": "Ce commerçant n'a pas encore configuré de programme de fidélité.", + "create_program": "Créer un programme", + "delete_title": "Supprimer le programme de fidélité", + "delete_message": "Cela supprimera définitivement le programme de fidélité et toutes les données associées. Cette action est irréversible.", + "delete_confirm": "Supprimer le programme", + "location_breakdown": "Répartition par point de vente", + "table_location": "Point de vente", + "table_enrolled": "Inscrits", + "table_points_earned": "Points gagnés", + "table_points_redeemed": "Points échangés", + "table_transactions_30d": "Transactions (30j)", + "admin_policy_settings": "Paramètres de politique admin", + "staff_pin_policy": "Politique PIN du personnel", + "self_enrollment": "Auto-inscription", + "cross_location_redemption": "Échange inter-points de vente", + "allowed": "Autorisé", + "disabled": "Désactivé", + "modify_policy": "Modifier la politique admin" + }, + "merchant_settings": { + "title": "Paramètres de fidélité du commerçant", + "loading": "Chargement des paramètres...", + "error_loading": "Erreur de chargement des paramètres", + "admin_controlled": "Paramètres contrôlés par l'admin pour le programme de fidélité de ce commerçant", + "staff_pin_policy": "Politique PIN du personnel", + "staff_pin_description": "Contrôlez si les membres du personnel doivent saisir un PIN pour traiter les transactions de fidélité.", + "required": "Obligatoire", + "required_desc": "Le personnel doit saisir son PIN pour chaque transaction. Recommandé pour la sécurité.", + "optional": "Facultatif", + "optional_desc": "Les magasins peuvent choisir d'exiger ou non les PINs.", + "pin_disabled": "Désactivé", + "pin_disabled_desc": "Les PINs du personnel ne sont pas utilisés. Tout membre du personnel peut traiter les transactions.", + "pin_lockout_settings": "Paramètres de verrouillage PIN", + "max_failed_attempts": "Tentatives échouées max", + "max_failed_attempts_help": "Nombre de tentatives erronées avant verrouillage (3-10)", + "lockout_duration": "Durée de verrouillage (minutes)", + "lockout_duration_help": "Durée du verrouillage après échecs (5-120 minutes)", + "enrollment_settings": "Paramètres d'inscription", + "allow_self_enrollment": "Autoriser l'auto-inscription", + "self_enrollment_desc": "Les clients peuvent s'inscrire via QR code sans aide du personnel", + "transaction_settings": "Paramètres de transaction", + "allow_cross_location": "Autoriser l'échange inter-points de vente", + "cross_location_desc": "Les clients peuvent échanger des points dans tous les points de vente du commerçant", + "allow_void": "Autoriser les annulations", + "void_desc": "Le personnel peut annuler des points/tampons pour les retours", + "save_settings": "Enregistrer les paramètres" + }, + "analytics": { + "title": "Analytique fidélité", + "subtitle": "Statistiques de fidélité à l'échelle de la plateforme", + "loading": "Chargement des analytiques...", + "error_loading": "Erreur de chargement des analytiques", + "filter_by_merchant": "Filtrer par commerçant", + "search_merchants_placeholder": "Rechercher des commerçants par nom...", + "showing_stats_for": "Statistiques pour :", + "wallet_status": "Statut de l'intégration Wallet", + "google_wallet": "Google Wallet", + "apple_wallet": "Apple Wallet", + "connected": "Connecté", + "error": "Erreur", + "not_configured": "Non configuré", + "issuer_id": "ID émetteur", + "project": "Projet", + "wallet_objects": "Objets Wallet", + "loyalty_classes": "Classes de fidélité", + "pass_type_id": "ID type de pass", + "team_id": "ID équipe", + "active_passes": "Pass actifs", + "quick_actions": "Actions rapides", + "view_all_programs": "Voir tous les programmes", + "manage_merchants": "Gérer les commerçants" + }, + "program_edit": { + "title": "Configuration du programme", + "loading": "Chargement de la configuration...", + "error_loading": "Erreur de chargement de la configuration du programme", + "create_subtitle": "Créer un programme de fidélité pour ce commerçant", + "edit_subtitle": "Modifier la configuration du programme", + "delete_title": "Supprimer le programme de fidélité", + "delete_message": "Cela supprimera définitivement le programme de fidélité et toutes les données associées (cartes, transactions, récompenses). Cette action est irréversible.", + "delete_confirm": "Supprimer le programme" + } + }, + "merchant": { + "program": { + "title": "Programme de fidélité", + "subtitle": "Configuration de votre programme de fidélité.", + "edit_program": "Modifier le programme", + "no_program": "Aucun programme de fidélité", + "no_program_desc": "Votre programme de fidélité n'a pas encore été configuré. Créez-en un pour commencer à récompenser vos clients.", + "create_program": "Créer un programme" + }, + "program_edit": { + "title": "Paramètres de fidélité", + "page_title": "Paramètres du programme de fidélité", + "subtitle": "Configurez votre programme de fidélité", + "loading": "Chargement des paramètres...", + "error_loading": "Erreur de chargement des paramètres", + "delete_title": "Supprimer le programme de fidélité", + "delete_message": "Cela supprimera définitivement votre programme de fidélité et toutes les données associées (cartes, transactions, récompenses). Cette action est irréversible.", + "delete_confirm": "Supprimer le programme" + }, + "analytics": { + "title": "Analytique fidélité", + "subtitle": "Statistiques de fidélité pour tous vos magasins", + "loading": "Chargement des analytiques...", + "error_loading": "Erreur de chargement des analytiques", + "no_program": "Aucun programme de fidélité", + "no_program_desc": "Configurez un programme de fidélité pour voir les analytiques ici.", + "create_program": "Créer un programme", + "quick_actions": "Actions rapides", + "view_program": "Voir le programme", + "edit_program": "Modifier le programme" + } + }, + "store": { + "terminal": { + "title": "Terminal de fidélité", + "subtitle": "Traiter les transactions de fidélité", + "members": "Membres", + "analytics": "Analytique", + "loading": "Chargement du terminal de fidélité...", + "error_loading": "Erreur de chargement du terminal", + "not_setup": "Programme de fidélité non configuré", + "not_setup_desc": "Votre commerçant n'a pas encore configuré de programme de fidélité.", + "setup_program": "Configurer le programme de fidélité", + "contact_admin": "Contactez votre administrateur pour terminer la configuration.", + "find_customer": "Trouver un client", + "search_placeholder": "E-mail, téléphone ou numéro de carte...", + "looking_up": "Recherche en cours...", + "look_up_customer": "Rechercher un client", + "enroll_new_customer": "Inscrire un nouveau client", + "customer_found": "Client trouvé", + "points_balance": "Solde de points", + "stamps": "Tampons", + "x_more_for_reward": "Encore {count} pour la récompense", + "ready_to_redeem": "Prêt à échanger !", + "add_stamp": "Ajouter un tampon", + "current": "Actuel :", + "cooldown_active": "Temps d'attente actif", + "redeem_stamps": "Échanger les tampons", + "not_enough_stamps": "Pas assez de tampons encore", + "earn_points": "Gagner des points", + "purchase_amount": "Montant de l'achat", + "points_to_award": "Points à attribuer :", + "award_points": "Attribuer des points", + "redeem_reward": "Échanger une récompense", + "select_reward": "Sélectionner une récompense", + "select_reward_placeholder": "Sélectionner une récompense...", + "points_after": "Points après :", + "search_to_process": "Recherchez un client pour traiter une transaction", + "recent_transactions": "Transactions récentes dans ce point de vente", + "table_time": "Heure", + "table_customer": "Client", + "table_type": "Type", + "table_points": "Points", + "table_notes": "Notes", + "no_recent_transactions": "Aucune transaction récente", + "enter_staff_pin": "Saisir le PIN du personnel", + "pin_authorize": "Saisissez votre PIN personnel pour autoriser cette transaction.", + "clear": "Effacer", + "processing": "Traitement...", + "customer_not_found": "Client introuvable. Vous pouvez l'inscrire comme nouveau membre.", + "error_lookup": "Erreur de recherche du client : {message}", + "transaction_failed": "Transaction échouée : {message}", + "stamp_added": "Tampon ajouté !", + "stamps_redeemed": "Tampons échangés ! Récompense obtenue.", + "x_points_awarded": "{points} points attribués !", + "reward_redeemed": "Récompense échangée : {name}" + }, + "cards": { + "title": "Membres fidélité", + "subtitle": "Voir et gérer les membres de votre programme de fidélité", + "enroll_new": "Inscrire", + "loading": "Chargement des membres...", + "error_loading": "Erreur de chargement des membres", + "total_members": "Membres au total", + "active_30d": "Actifs (30j)", + "new_this_month": "Nouveaux ce mois", + "total_points_balance": "Solde total de points", + "search_placeholder": "Rechercher par nom, e-mail, téléphone ou carte...", + "all_status": "Tous les statuts", + "table_member": "Membre", + "table_card_number": "Numéro de carte", + "table_points_balance": "Solde de points", + "table_last_activity": "Dernière activité", + "table_status": "Statut", + "table_actions": "Actions", + "no_members": "Aucun membre trouvé", + "adjust_search": "Essayez d'ajuster votre recherche", + "enroll_first": "Inscrivez votre premier client pour commencer" + }, + "card_detail": { + "title": "Détails du membre", + "loading": "Chargement des détails du membre...", + "error_loading": "Erreur de chargement du membre", + "points_balance": "Solde de points", + "total_earned": "Total gagné", + "total_redeemed": "Total échangé", + "member_since": "Membre depuis", + "customer_information": "Informations client", + "name": "Nom", + "email": "E-mail", + "phone": "Téléphone", + "birthday": "Date de naissance", + "card_details": "Détails de la carte", + "card_number": "Numéro de carte", + "status": "Statut", + "last_activity": "Dernière activité", + "enrolled_at": "Inscrit le", + "transaction_history": "Historique des transactions", + "table_date": "Date", + "table_type": "Type", + "table_points": "Points", + "table_location": "Point de vente", + "table_notes": "Notes", + "no_transactions": "Aucune transaction" + }, + "enroll": { + "title": "Inscrire un client", + "page_title": "Inscrire un nouveau client", + "subtitle": "Ajouter un nouveau membre à votre programme de fidélité", + "loading": "Chargement...", + "error_loading": "Erreur de chargement du formulaire d'inscription", + "customer_information": "Informations client", + "first_name": "Prénom", + "last_name": "Nom", + "email": "E-mail", + "phone": "Téléphone", + "birthday": "Date de naissance", + "birthday_help": "Pour les récompenses d'anniversaire (facultatif)", + "communication_preferences": "Préférences de communication", + "send_emails": "Envoyer des e-mails promotionnels", + "send_sms": "Envoyer des SMS promotionnels", + "welcome_bonus": "Bonus de bienvenue", + "welcome_bonus_desc": "Le client recevra {points} points bonus !", + "enroll_customer": "Inscrire le client", + "enrolling": "Inscription...", + "customer_enrolled": "Client inscrit !", + "starting_balance": "Solde initial :", + "x_points": "{count} points", + "back_to_terminal": "Retour au terminal", + "enroll_another": "Inscrire un autre", + "enrollment_failed": "Inscription échouée : {message}" + }, + "analytics": { + "title": "Analytique fidélité", + "subtitle": "Suivez les performances de votre programme de fidélité", + "loading": "Chargement des analytiques...", + "error_loading": "Erreur de chargement des analytiques", + "quick_actions": "Actions rapides", + "open_terminal": "Ouvrir le terminal", + "view_members": "Voir les membres", + "view_program": "Voir le programme" + }, + "program": { + "title": "Programme de fidélité", + "subtitle": "Configuration de votre programme de fidélité", + "edit_program": "Modifier le programme", + "loading": "Chargement du programme...", + "error_loading": "Erreur de chargement du programme", + "no_program": "Aucun programme de fidélité", + "no_program_desc": "Votre commerçant n'a pas encore configuré de programme de fidélité.", + "create_program": "Créer un programme", + "contact_admin": "Contactez votre administrateur pour configurer un programme de fidélité." + }, + "settings": { + "title": "Paramètres de fidélité", + "page_title": "Paramètres du programme de fidélité", + "subtitle": "Configurez votre programme de fidélité", + "back_to_program": "Retour au programme", + "loading": "Chargement des paramètres...", + "error_loading": "Erreur de chargement des paramètres", + "access_restricted": "Accès restreint", + "owner_only": "Seul le propriétaire du commerce peut gérer les paramètres du programme de fidélité.", + "delete_title": "Supprimer le programme de fidélité", + "delete_message": "Cela supprimera définitivement le programme de fidélité et toutes les données associées (cartes, transactions, récompenses). Cette action est irréversible.", + "delete_confirm": "Supprimer le programme", + "program_created": "Programme créé avec succès", + "program_updated": "Programme mis à jour avec succès", + "program_deleted": "Programme de fidélité supprimé", + "save_failed": "Échec de l'enregistrement : {message}", + "delete_failed": "Échec de la suppression : {message}" + } + }, + "storefront": { + "dashboard": { + "back_to_account": "Retour au compte", + "my_loyalty": "Ma fidélité", + "join_title": "Rejoignez notre programme de récompenses !", + "join_subtitle": "Gagnez des points à chaque achat et échangez-les contre des récompenses.", + "join_now": "Rejoindre maintenant", + "points_balance": "Solde de points", + "card_number": "Numéro de carte", + "show_card": "Afficher la carte", + "total_earned": "Total gagné", + "total_redeemed": "Total échangé", + "available_rewards": "Récompenses disponibles", + "no_rewards_yet": "Aucune récompense disponible pour le moment", + "ready_to_redeem": "Prêt à échanger", + "x_more_to_go": "Encore {count}", + "redeem_hint": "Montrez votre carte au personnel pour échanger des récompenses en magasin.", + "recent_activity": "Activité récente", + "view_all": "Tout voir", + "no_transactions": "Aucune transaction. Faites un achat pour commencer à gagner des points !", + "earn_redeem_locations": "Points de vente partenaires", + "your_loyalty_card": "Votre carte de fidélité", + "show_to_staff": "Montrez ceci au personnel lors d'un achat ou d'un échange de récompense." + }, + "history": { + "back_to_loyalty": "Retour à la fidélité", + "title": "Historique des transactions", + "subtitle": "Voir toutes vos transactions de points de fidélité", + "current_balance": "Solde actuel", + "total_earned": "Total gagné", + "total_redeemed": "Total échangé", + "no_transactions": "Aucune transaction", + "balance": "Solde :", + "previous": "Précédent", + "next": "Suivant", + "page_x_of_y": "Page {page} sur {pages}" + } + }, + "toasts": { + "program_activated": "Programme activé avec succès", + "program_deactivated": "Programme désactivé avec succès", + "activate_failed": "Échec de l'activation du programme : {message}", + "deactivate_failed": "Échec de la désactivation du programme : {message}", + "program_deleted": "Programme supprimé avec succès", + "delete_failed": "Échec de la suppression du programme : {message}", + "program_created": "Programme créé avec succès", + "program_updated": "Programme mis à jour avec succès", + "loyalty_program_created": "Programme de fidélité créé", + "loyalty_program_deleted": "Programme de fidélité supprimé", + "settings_saved": "Paramètres enregistrés avec succès", + "save_failed": "Échec de l'enregistrement : {message}", + "settings_save_failed": "Échec de l'enregistrement des paramètres : {message}", + "create_failed": "Échec de la création du programme : {message}", + "logo_required": "L'URL du logo est requise pour l'intégration wallet." } } diff --git a/app/modules/loyalty/locales/lb.json b/app/modules/loyalty/locales/lb.json index b993f40c..683d8f3a 100644 --- a/app/modules/loyalty/locales/lb.json +++ b/app/modules/loyalty/locales/lb.json @@ -96,5 +96,589 @@ "title": "Treieprogramm erstellen", "description": "Erstellt Äert éischt Stempel- oder Punkteprogramm" } + }, + "enrollment": { + "title": "Gitt Member vun eisem Belounungsprogramm!", + "subtitle": "Verdéngt {points} Punkt pro ausgegoenen EUR", + "not_available_title": "Programm net verfügbar", + "not_available_message": "Dëse Buttek huet nach kee Treieprogramm ageriicht.", + "welcome_bonus": "Kritt {points} Bonuspunkten wann Dir Iech umellt!", + "already_member": "Schonn Member? Är Punkten sinn mat Ärer E-Mail verlinkt.", + "form": { + "email": "E-Mail", + "first_name": "Virnumm", + "last_name": "Nonumm", + "phone": "Telefon (fakultativ)", + "birthday": "Gebuertsdag (fakultativ)", + "birthday_hint": "Fir speziell Gebuertsdagsbelounungen", + "terms_agree": "Ech akzeptéieren d'", + "terms": "Allgemeng Geschäftsbedingungen", + "marketing_consent": "Mir Neiegkeeten an Sonderoffere schécken", + "joining": "Umeldung leeft...", + "join_button": "Bäitrieden & {points} Punkten kréien" + }, + "privacy_policy": "Dateschutzrichtlinn", + "close": "Zoumaachen", + "success": { + "title": "Wëllkomm!", + "message": "Dir sidd elo Member vun eisem Belounungsprogramm.", + "card_number": "Är Kaartnummer", + "wallet_prompt": "Späichert Är Kaart op Ärem Handy fir einfachen Zougang:", + "next_steps_title": "Wéi geet et weider?", + "step_earn": "Weist Är Kaartnummer beim Akaf fir Punkten ze sammelen", + "step_balance": "Préift Äre Kontostand online oder an der App", + "step_redeem": "Léist Punkten géint Belounungen an all eise Standuerter an", + "view_dashboard": "Mäin Treie-Dashboard kucken", + "continue_shopping": "Weider akafen" + }, + "errors": { + "load_failed": "Programminformatiounen konnten net gelueden ginn", + "email_exists": "Dës E-Mail ass schonn an eisem Treieprogramm registréiert.", + "failed": "Umeldung feelgeschloen. Probéiert w.e.g. nach eng Kéier." + } + }, + "common": { + "active": "Aktiv", + "inactive": "Inaktiv", + "cancel": "Ofbriechen", + "save": "Späicheren", + "delete": "Läschen", + "confirm": "Bestätegen", + "refresh": "Aktualiséieren", + "loading": "Lueden...", + "saving": "Späicheren...", + "view": "Kucken", + "edit": "Beaarbechten", + "yes": "Jo", + "no": "Neen", + "none": "Keen", + "never": "Ni", + "total": "TOTAL", + "continue": "Weider", + "back": "Zréck", + "points": "Punkten", + "minutes": "Minutten", + "or": "oder", + "at": "bei" + }, + "transactions": { + "card_created": "Ageschriwwen", + "welcome_bonus": "Wëllkommensbonus", + "stamp_earned": "Stempel kritt", + "stamp_redeemed": "Stempel agelées", + "stamp_voided": "Stempel stornéiert", + "stamp_adjustment": "Stempel ugepasst", + "points_earned": "Punkten verdéngt", + "points_redeemed": "Punkten agelées", + "points_voided": "Punkten stornéiert", + "points_adjustment": "Punkten ugepasst", + "points_expired": "Punkten ofgelaf", + "card_deactivated": "Deaktivéiert", + "reward_redeemed": "Belounung agelées" + }, + "shared": { + "analytics": { + "total_programs": "Programmer insgesamt", + "total_members": "Memberen insgesamt", + "active_members": "Aktiv Memberen", + "points_issued_30d": "Punkten vergi (30D)", + "transactions_30d": "Transaktiounen (30D)", + "x_active": "{count} aktiv", + "points_overview": "Punkteniwwersiicht", + "points_issued_vs_redeemed": "Punkten vergi vs agelées (30D)", + "issued": "Vergi:", + "redeemed": "Agelées:", + "redemption_rate": "Aléisungsquot", + "outstanding_balance": "Ausstehende Solde", + "member_activity": "Memberaktivitéit", + "active_members_30d": "Aktiv Memberen (30D)", + "new_this_month": "Nei dëse Mount", + "merchants_with_programs": "Händler mat Programmer", + "avg_points_per_member": "Durchschn. Punkten pro Member", + "all_time_statistics": "Gesamtstatistiken", + "total_points_issued": "Total Punkten vergi", + "total_points_redeemed": "Total Punkten agelées", + "points_redeemed_30d": "Punkten agelées (30D)", + "outstanding_liability": "Ausstehend Verbindlechkeet", + "location_breakdown": "Opschlësselung no Standuert", + "store": "Geschäft", + "enrolled": "Ageschriwwen", + "points_earned": "Punkten verdéngt", + "points_redeemed": "Punkten agelées" + }, + "program_view": { + "program_configuration": "Programmkonfiguratioun", + "program_name": "Programmnumm", + "card_name": "Kaartnumm", + "stamps_configuration": "Stempelkonfiguratioun", + "stamps_target": "Stempelzil", + "reward_description": "Belounungsbeschreiwung", + "reward_value": "Belounungswäert", + "points_configuration": "Punktekonfiguratioun", + "points_per_eur": "Punkten pro EUR", + "welcome_bonus": "Wëllkommensbonus", + "x_points": "{count} Punkten", + "minimum_redemption": "Mindest-Aléisung", + "minimum_purchase": "Mindest-Akaf", + "points_expiration": "Punktenoflaaf", + "x_days_inactivity": "{days} Deeg Inaktivitéit", + "redemption_rewards": "Aléisungsbelounungen", + "reward": "Belounung", + "points_required": "Néideg Punkten", + "description": "Beschreiwung", + "anti_fraud": "Betrugsschutz", + "cooldown": "Waardezäit", + "x_minutes": "{count} Minutten", + "max_daily_stamps": "Max. Stempelen pro Dag", + "staff_pin_required": "Personal-PIN erfuerderlech", + "branding": "Branding", + "primary_color": "Haaptfaarf", + "secondary_color": "Secondärfaarf", + "logo_url": "Logo-URL", + "hero_image_url": "Hannergrondbild-URL", + "terms_privacy": "AGB & Dateschutz", + "terms_conditions": "Allgemeng Geschäftsbedingungen", + "privacy_policy_url": "Dateschutzrichtlinn-URL" + }, + "program_form": { + "program_type": "Programmtyp", + "points_type_desc": "Punkten pro ausgegoenen EUR verdéngen", + "stamps_type_desc": "N Stempelen sammelen, Belounung kréien", + "hybrid_type_desc": "Stempelen a Punkten kombinéiert", + "stamps_configuration": "Stempelkonfiguratioun", + "stamps_target": "Stempelzil", + "stamps_target_help": "Unzuel vun de Stempelen fir d'Belounung", + "reward_description": "Belounungsbeschreiwung", + "reward_value_cents": "Belounungswäert (Cent)", + "points_configuration": "Punktekonfiguratioun", + "points_per_eur": "Punkten pro ausgegoenen EUR", + "eur_equals_points": "1 EUR = {points} Punkt(en)", + "welcome_bonus_points": "Wëllkommensbonuspunkten", + "welcome_bonus_help": "Bonuspunkten bei der Umeldung", + "minimum_redemption_points": "Mindest-Aléisungspunkten", + "minimum_purchase_cents": "Mindest-Akaf (Cent)", + "minimum_purchase_help": "Mindestakafsbetrag fir Punkten ze sammelen (0 = kee Minimum)", + "points_expiration_days": "Punktenoflaaf (Deeg)", + "points_expiration_help": "Deeg vun Inaktivitéit bis zum Punktenoflaaf (0 = ni)", + "redemption_rewards": "Aléisungsbelounungen", + "add_reward": "Belounung derbäisetzen", + "no_rewards_configured": "Keng Belounungen konfiguréiert. Setzt eng Belounung derbäi fir datt Clienten Punkten aléise kënnen.", + "reward_name": "Belounungsnumm", + "points_required": "Néideg Punkten", + "description": "Beschreiwung", + "anti_fraud_settings": "Betrugsschutz-Astellungen", + "cooldown_minutes": "Waardezäit (Minutten)", + "cooldown_help": "Zäit tëschent Stempelen vun der selwechter Kaart", + "max_daily_stamps": "Max. Stempelen pro Dag", + "max_daily_stamps_help": "Maximal Stempelen pro Kaart pro Dag", + "require_staff_pin": "Personal-PIN verlaangen", + "branding": "Branding", + "card_name": "Kaartnumm", + "primary_color": "Haaptfaarf", + "secondary_color": "Secondärfaarf", + "logo_url": "Logo-URL", + "logo_url_help": "Erfuerderlech fir Google Wallet-Integratioun. Muss eng ëffentlech zougänglech Bild-URL sinn (PNG oder JPG).", + "hero_image_url": "Hannergrondbild-URL", + "terms_privacy": "AGB & Dateschutz", + "terms_conditions": "Allgemeng Geschäftsbedingungen", + "privacy_policy_url": "Dateschutzrichtlinn-URL", + "program_status": "Programmstatus", + "program_active": "Programm aktiv", + "program_active_help": "Deaktivéiert kënne Clienten net sammelen oder aléisen", + "delete_program": "Programm läschen", + "create_program": "Programm erstellen", + "save_changes": "Ännerunge späicheren" + } + }, + "admin": { + "programs": { + "title": "Treieprogrammer", + "create_program": "Programm erstellen", + "loading": "Treieprogrammer gi gelueden...", + "error_loading": "Feeler beim Luede vun den Treieprogrammer", + "total_programs": "Programmer insgesamt", + "active": "Aktiv", + "total_members": "Memberen insgesamt", + "transactions_30d": "Transaktiounen (30D)", + "search_placeholder": "No Händlernumm sichen...", + "all_status": "All Status", + "table_merchant": "Händler", + "table_program_type": "Programmtyp", + "table_members": "Memberen", + "table_points_issued": "Punkten vergi", + "table_status": "Status", + "table_created": "Erstellt", + "table_actions": "Aktiounen", + "no_programs": "Keng Treieprogrammer fonnt", + "adjust_filters": "Probéiert Är Sich oder Filter unzepassen", + "no_merchants_yet": "Nach kee Händler huet en Treieprogramm erstellt", + "x_active": "({count} aktiv)", + "x_redeemed": "{count} agelées", + "pt_per_eur": "Pkt/EUR", + "delete_title": "Treieprogramm läschen", + "delete_message": "Treieprogramm fir \"{name}\" läschen? All verbonnen Daten (Kaarten, Transaktiounen, Belounungen) ginn dauerhaft geläscht. Dëst kann net réckgängeg gemaach ginn.", + "delete_confirm": "Programm läschen", + "create_title": "Treieprogramm erstellen", + "create_description": "Wielt en Händler fir en Treieprogramm ze erstellen.", + "search_merchant": "Händler sichen", + "type_merchant_name": "Händlernumm aginn...", + "no_merchants_found": "Keen Händler fonnt", + "existing_program_warning": "Dësen Händler huet schonn en Treieprogramm.", + "view_edit_existing": "Bestehend Programm kucken / beaarbechten" + }, + "merchant_detail": { + "title": "Händler-Treiedetailer", + "loading": "Treiedetailer gi gelueden...", + "error_loading": "Feeler beim Luede vun der Händlertreie", + "program_active": "Treieprogramm aktiv", + "no_program_subtitle": "Keen Treieprogramm", + "quick_actions": "Schnellaktiounen", + "edit_program": "Programm beaarbechten", + "admin_policy": "Admin-Richtlinn", + "view_merchant": "Händler kucken", + "total_members": "Memberen insgesamt", + "active_30d": "Aktiv (30D)", + "points_issued_30d": "Punkten vergi (30D)", + "points_redeemed_30d": "Punkten agelées (30D)", + "no_program": "Keen Treieprogramm", + "no_program_desc": "Dësen Händler huet nach keen Treieprogramm ageriicht.", + "create_program": "Programm erstellen", + "delete_title": "Treieprogramm läschen", + "delete_message": "D'Treieprogramm an all verbonnen Daten ginn dauerhaft geläscht. Dëst kann net réckgängeg gemaach ginn.", + "delete_confirm": "Programm läschen", + "location_breakdown": "Opschlësselung no Standuert", + "table_location": "Standuert", + "table_enrolled": "Ageschriwwen", + "table_points_earned": "Punkten verdéngt", + "table_points_redeemed": "Punkten agelées", + "table_transactions_30d": "Transaktiounen (30D)", + "admin_policy_settings": "Admin-Richtlinn-Astellungen", + "staff_pin_policy": "Personal-PIN-Richtlinn", + "self_enrollment": "Selbstumeldung", + "cross_location_redemption": "Standuertiwergreifend Aléisung", + "allowed": "Erlaabt", + "disabled": "Deaktivéiert", + "modify_policy": "Admin-Richtlinn änneren" + }, + "merchant_settings": { + "title": "Händler-Treieastelllungen", + "loading": "Astellunge gi gelueden...", + "error_loading": "Feeler beim Luede vun den Astellungen", + "admin_controlled": "Admin-kontrolléiert Astellungen fir d'Treieprogramm vun dësem Händler", + "staff_pin_policy": "Personal-PIN-Richtlinn", + "staff_pin_description": "Bestëmmt ob Mataarbechter e PIN aginn mussen fir Treietransaktiounen ze veraarbechten.", + "required": "Erfuerderlech", + "required_desc": "Personal muss säin PIN bei all Transaktioun aginn. Recommandéiert fir d'Sécherheet.", + "optional": "Fakultativ", + "optional_desc": "Geschäfter kënne wielen ob PINe verlaangt ginn.", + "pin_disabled": "Deaktivéiert", + "pin_disabled_desc": "Personal-PINe ginn net benotzt. All Mataarbechter kann Transaktiounen veraarbechten.", + "pin_lockout_settings": "PIN-Sparrastellungen", + "max_failed_attempts": "Max. Fehlversich", + "max_failed_attempts_help": "Unzuel vu falschen Versich virun der Spär (3-10)", + "lockout_duration": "Spärauer (Minutten)", + "lockout_duration_help": "Wéi laang d'Spär no Fehlversich dauert (5-120 Minutten)", + "enrollment_settings": "Umeldungsastellungen", + "allow_self_enrollment": "Selbstumeldung erlaben", + "self_enrollment_desc": "Clienten kënne sech per QR-Code ouni Personal umellen", + "transaction_settings": "Transaktiouns-Astellungen", + "allow_cross_location": "Standuertiwergreifend Aléisung erlaben", + "cross_location_desc": "Clienten kënne Punkten an all Standuerter vum Händler aléisen", + "allow_void": "Stornéierungen erlaben", + "void_desc": "Personal kann Punkten/Stempelen bei Réckgaben stornéieren", + "save_settings": "Astellunge späicheren" + }, + "analytics": { + "title": "Treie-Analytik", + "subtitle": "Plattformwäit Treieprogramm-Statistiken", + "loading": "Analytik gëtt gelueden...", + "error_loading": "Feeler beim Luede vun der Analytik", + "filter_by_merchant": "No Händler filtréieren", + "search_merchants_placeholder": "Händler no Numm sichen...", + "showing_stats_for": "Statistike fir:", + "wallet_status": "Wallet-Integratiounsstatus", + "google_wallet": "Google Wallet", + "apple_wallet": "Apple Wallet", + "connected": "Verbonnen", + "error": "Feeler", + "not_configured": "Net konfiguréiert", + "issuer_id": "Aussteller-ID", + "project": "Projet", + "wallet_objects": "Wallet-Objeten", + "loyalty_classes": "Treieklassen", + "pass_type_id": "Pass-Typ-ID", + "team_id": "Team-ID", + "active_passes": "Aktiv Päss", + "quick_actions": "Schnellaktiounen", + "view_all_programs": "All Programmer kucken", + "manage_merchants": "Händler verwalten" + }, + "program_edit": { + "title": "Programmkonfiguratioun", + "loading": "Konfiguratioun gëtt gelueden...", + "error_loading": "Feeler beim Luede vun der Programmkonfiguratioun", + "create_subtitle": "Treieprogramm fir dësen Händler erstellen", + "edit_subtitle": "Programmkonfiguratioun beaarbechten", + "delete_title": "Treieprogramm läschen", + "delete_message": "D'Treieprogramm an all verbonnen Daten (Kaarten, Transaktiounen, Belounungen) ginn dauerhaft geläscht. Dëst kann net réckgängeg gemaach ginn.", + "delete_confirm": "Programm läschen" + } + }, + "merchant": { + "program": { + "title": "Treieprogramm", + "subtitle": "Är Treieprogramm-Konfiguratioun.", + "edit_program": "Programm beaarbechten", + "no_program": "Keen Treieprogramm", + "no_program_desc": "Ärt Treieprogramm gouf nach net ageriicht. Erstellt eent fir Är Clienten ze belounegen.", + "create_program": "Programm erstellen" + }, + "program_edit": { + "title": "Treie-Astellungen", + "page_title": "Treieprogramm-Astellungen", + "subtitle": "Konfiguréiert Ärt Treieprogramm", + "loading": "Astellunge gi gelueden...", + "error_loading": "Feeler beim Luede vun den Astellungen", + "delete_title": "Treieprogramm läschen", + "delete_message": "Ärt Treieprogramm an all verbonnen Daten (Kaarten, Transaktiounen, Belounungen) ginn dauerhaft geläscht. Dëst kann net réckgängeg gemaach ginn.", + "delete_confirm": "Programm läschen" + }, + "analytics": { + "title": "Treie-Analytik", + "subtitle": "Treieprogramm-Statistiken fir all Är Geschäfter", + "loading": "Analytik gëtt gelueden...", + "error_loading": "Feeler beim Luede vun der Analytik", + "no_program": "Keen Treieprogramm", + "no_program_desc": "Riicht en Treieprogramm an fir hei Analytik ze gesinn.", + "create_program": "Programm erstellen", + "quick_actions": "Schnellaktiounen", + "view_program": "Programm kucken", + "edit_program": "Programm beaarbechten" + } + }, + "store": { + "terminal": { + "title": "Treie-Terminal", + "subtitle": "Treietransaktiounen veraarbechten", + "members": "Memberen", + "analytics": "Analytik", + "loading": "Treie-Terminal gëtt gelueden...", + "error_loading": "Feeler beim Luede vum Terminal", + "not_setup": "Treieprogramm net ageriicht", + "not_setup_desc": "Ären Händler huet nach keen Treieprogramm konfiguréiert.", + "setup_program": "Treieprogramm ariichten", + "contact_admin": "Kontaktéiert Ären Administrateur fir d'Ariichtung ofzeschléissen.", + "find_customer": "Client fannen", + "search_placeholder": "E-Mail, Telefon oder Kaartnummer...", + "looking_up": "Sich leeft...", + "look_up_customer": "Client sichen", + "enroll_new_customer": "Neie Client umellen", + "customer_found": "Client fonnt", + "points_balance": "Punktestand", + "stamps": "Stempelen", + "x_more_for_reward": "Nach {count} fir d'Belounung", + "ready_to_redeem": "Prett fir anzeléisen!", + "add_stamp": "Stempel derbäisetzen", + "current": "Aktuell:", + "cooldown_active": "Waardezäit aktiv", + "redeem_stamps": "Stempelen aléisen", + "not_enough_stamps": "Nach net genuch Stempelen", + "earn_points": "Punkten sammelen", + "purchase_amount": "Akafsbetrag", + "points_to_award": "Punkten ze verginn:", + "award_points": "Punkten verginn", + "redeem_reward": "Belounung aléisen", + "select_reward": "Belounung wielen", + "select_reward_placeholder": "Belounung wielen...", + "points_after": "Punkten duerno:", + "search_to_process": "Sicht e Client fir eng Transaktioun ze veraarbechten", + "recent_transactions": "Rezent Transaktiounen un dësem Standuert", + "table_time": "Zäit", + "table_customer": "Client", + "table_type": "Typ", + "table_points": "Punkten", + "table_notes": "Notizen", + "no_recent_transactions": "Keng rezent Transaktiounen", + "enter_staff_pin": "Personal-PIN aginn", + "pin_authorize": "Gitt Äre Personal-PIN an fir dës Transaktioun ze autoriséieren.", + "clear": "Läschen", + "processing": "Veraarbechtung...", + "customer_not_found": "Client net fonnt. Dir kënnt hien als neit Member umellen.", + "error_lookup": "Feeler bei der Clientesich: {message}", + "transaction_failed": "Transaktioun feelgeschloen: {message}", + "stamp_added": "Stempel derbäigesat!", + "stamps_redeemed": "Stempelen agelées! Belounung kritt.", + "x_points_awarded": "{points} Punkten vergi!", + "reward_redeemed": "Belounung agelées: {name}" + }, + "cards": { + "title": "Treie-Memberen", + "subtitle": "Memberen vun Ärem Treieprogramm kucken a verwalten", + "enroll_new": "Umellen", + "loading": "Membere gi gelueden...", + "error_loading": "Feeler beim Luede vun de Memberen", + "total_members": "Memberen insgesamt", + "active_30d": "Aktiv (30D)", + "new_this_month": "Nei dëse Mount", + "total_points_balance": "Gesamtpunktestand", + "search_placeholder": "No Numm, E-Mail, Telefon oder Kaart sichen...", + "all_status": "All Status", + "table_member": "Member", + "table_card_number": "Kaartnummer", + "table_points_balance": "Punktestand", + "table_last_activity": "Lescht Aktivitéit", + "table_status": "Status", + "table_actions": "Aktiounen", + "no_members": "Keng Membere fonnt", + "adjust_search": "Probéiert Är Sich unzepassen", + "enroll_first": "Mellt Ären éischte Client un" + }, + "card_detail": { + "title": "Memberdetailer", + "loading": "Memberdetailer gi gelueden...", + "error_loading": "Feeler beim Luede vum Member", + "points_balance": "Punktestand", + "total_earned": "Insgesamt verdéngt", + "total_redeemed": "Insgesamt agelées", + "member_since": "Member zënter", + "customer_information": "Clienteninformatioun", + "name": "Numm", + "email": "E-Mail", + "phone": "Telefon", + "birthday": "Gebuertsdag", + "card_details": "Kaartdetailer", + "card_number": "Kaartnummer", + "status": "Status", + "last_activity": "Lescht Aktivitéit", + "enrolled_at": "Ugemellt um", + "transaction_history": "Transaktiounsverlaf", + "table_date": "Datum", + "table_type": "Typ", + "table_points": "Punkten", + "table_location": "Standuert", + "table_notes": "Notizen", + "no_transactions": "Nach keng Transaktiounen" + }, + "enroll": { + "title": "Client umellen", + "page_title": "Neie Client umellen", + "subtitle": "Neit Member bei Ärem Treieprogramm derbäisetzen", + "loading": "Lueden...", + "error_loading": "Feeler beim Luede vum Umeldungsformular", + "customer_information": "Clienteninformatioun", + "first_name": "Virnumm", + "last_name": "Nonumm", + "email": "E-Mail", + "phone": "Telefon", + "birthday": "Gebuertsdag", + "birthday_help": "Fir Gebuertsdagsbelounungen (fakultativ)", + "communication_preferences": "Kommunikatiounsastellungen", + "send_emails": "Promotiounsmaile schécken", + "send_sms": "Promotiounssms schécken", + "welcome_bonus": "Wëllkommensbonus", + "welcome_bonus_desc": "Client kritt {points} Bonuspunkten!", + "enroll_customer": "Client umellen", + "enrolling": "Umeldung...", + "customer_enrolled": "Client ugemellt!", + "starting_balance": "Ufankssolde:", + "x_points": "{count} Punkten", + "back_to_terminal": "Zréck zum Terminal", + "enroll_another": "Weider umellen", + "enrollment_failed": "Umeldung feelgeschloen: {message}" + }, + "analytics": { + "title": "Treie-Analytik", + "subtitle": "Verfollegt d'Performance vun Ärem Treieprogramm", + "loading": "Analytik gëtt gelueden...", + "error_loading": "Feeler beim Luede vun der Analytik", + "quick_actions": "Schnellaktiounen", + "open_terminal": "Terminal opmaachen", + "view_members": "Membere kucken", + "view_program": "Programm kucken" + }, + "program": { + "title": "Treieprogramm", + "subtitle": "Är Treieprogramm-Konfiguratioun", + "edit_program": "Programm beaarbechten", + "loading": "Programm gëtt gelueden...", + "error_loading": "Feeler beim Luede vum Programm", + "no_program": "Keen Treieprogramm", + "no_program_desc": "Ären Händler huet nach keen Treieprogramm konfiguréiert.", + "create_program": "Programm erstellen", + "contact_admin": "Kontaktéiert Ären Administrateur fir en Treieprogramm anzerichten." + }, + "settings": { + "title": "Treie-Astellungen", + "page_title": "Treieprogramm-Astellungen", + "subtitle": "Konfiguréiert Ärt Treieprogramm", + "back_to_program": "Zréck zum Programm", + "loading": "Astellunge gi gelueden...", + "error_loading": "Feeler beim Luede vun den Astellungen", + "access_restricted": "Zougang ageschränkt", + "owner_only": "Nëmmen den Geschäftseigentümer kann d'Treieprogramm-Astellungen verwalten.", + "delete_title": "Treieprogramm läschen", + "delete_message": "D'Treieprogramm an all verbonnen Daten (Kaarten, Transaktiounen, Belounungen) ginn dauerhaft geläscht. Dëst kann net réckgängeg gemaach ginn.", + "delete_confirm": "Programm läschen", + "program_created": "Programm erfollegräich erstellt", + "program_updated": "Programm erfollegräich aktualiséiert", + "program_deleted": "Treieprogramm geläscht", + "save_failed": "Späichere feelgeschloen: {message}", + "delete_failed": "Läsche feelgeschloen: {message}" + } + }, + "storefront": { + "dashboard": { + "back_to_account": "Zréck zum Kont", + "my_loyalty": "Meng Treie", + "join_title": "Gitt Member vun eisem Belounungsprogramm!", + "join_subtitle": "Sammelt Punkten bei all Akaf an léist se géint Belounungen an.", + "join_now": "Elo bäitrieden", + "points_balance": "Punktestand", + "card_number": "Kaartnummer", + "show_card": "Kaart weisen", + "total_earned": "Insgesamt verdéngt", + "total_redeemed": "Insgesamt agelées", + "available_rewards": "Verfügbar Belounungen", + "no_rewards_yet": "Nach keng Belounungen verfügbar", + "ready_to_redeem": "Prett fir anzeléisen", + "x_more_to_go": "Nach {count}", + "redeem_hint": "Weist Är Kaart dem Personal fir Belounungen am Geschäft anzeléisen.", + "recent_activity": "Rezent Aktivitéit", + "view_all": "Alles kucken", + "no_transactions": "Nach keng Transaktiounen. Maacht en Akaf fir Punkten ze sammelen!", + "earn_redeem_locations": "Sammel- & Aléisungs-Standuerter", + "your_loyalty_card": "Är Treiekaart", + "show_to_staff": "Weist dëst dem Personal beim Akaf oder beim Aléise vu Belounungen." + }, + "history": { + "back_to_loyalty": "Zréck zur Treie", + "title": "Transaktiounsverlaf", + "subtitle": "All Är Treiepunkttransaktiounen kucken", + "current_balance": "Aktuell Solde", + "total_earned": "Insgesamt verdéngt", + "total_redeemed": "Insgesamt agelées", + "no_transactions": "Nach keng Transaktiounen", + "balance": "Solde:", + "previous": "Zréck", + "next": "Weider", + "page_x_of_y": "Säit {page} vun {pages}" + } + }, + "toasts": { + "program_activated": "Programm erfollegräich aktivéiert", + "program_deactivated": "Programm erfollegräich deaktivéiert", + "activate_failed": "Programm konnt net aktivéiert ginn: {message}", + "deactivate_failed": "Programm konnt net deaktivéiert ginn: {message}", + "program_deleted": "Programm erfollegräich geläscht", + "delete_failed": "Programm konnt net geläscht ginn: {message}", + "program_created": "Programm erfollegräich erstellt", + "program_updated": "Programm erfollegräich aktualiséiert", + "loyalty_program_created": "Treieprogramm erstellt", + "loyalty_program_deleted": "Treieprogramm geläscht", + "settings_saved": "Astellungen erfollegräich gespäichert", + "save_failed": "Späichere feelgeschloen: {message}", + "settings_save_failed": "Astellunge konnten net gespäichert ginn: {message}", + "create_failed": "Programm konnt net erstellt ginn: {message}", + "logo_required": "Logo-URL ass erfuerderlech fir d'Wallet-Integratioun." } } diff --git a/app/modules/loyalty/static/admin/js/loyalty-merchant-detail.js b/app/modules/loyalty/static/admin/js/loyalty-merchant-detail.js index e785b580..5804f1b7 100644 --- a/app/modules/loyalty/static/admin/js/loyalty-merchant-detail.js +++ b/app/modules/loyalty/static/admin/js/loyalty-merchant-detail.js @@ -190,12 +190,12 @@ function adminLoyaltyMerchantDetail() { }; const response = await apiClient.post(`/admin/loyalty/merchants/${this.merchantId}/program`, data); this.program = response; - Utils.showToast('Loyalty program created', 'success'); + Utils.showToast(I18n.t('loyalty.toasts.program_created'), 'success'); loyaltyMerchantDetailLog.info('Program created for merchant', this.merchantId); // Reload stats await this.loadStats(); } catch (error) { - Utils.showToast(`Failed to create program: ${error.message}`, 'error'); + Utils.showToast(I18n.t('loyalty.toasts.create_failed', {message: error.message}), 'error'); loyaltyMerchantDetailLog.error('Failed to create program:', error); } }, @@ -207,10 +207,10 @@ function adminLoyaltyMerchantDetail() { try { const response = await apiClient.post(`/admin/loyalty/programs/${this.program.id}/${action}`); this.program.is_active = response.is_active; - Utils.showToast(`Program ${action}d successfully`, 'success'); + Utils.showToast(I18n.t(`loyalty.toasts.program_${action}d`), 'success'); loyaltyMerchantDetailLog.info(`Program ${action}d`); } catch (error) { - Utils.showToast(`Failed to ${action} program: ${error.message}`, 'error'); + Utils.showToast(I18n.t(`loyalty.toasts.${action}_failed`, {message: error.message}), 'error'); loyaltyMerchantDetailLog.error(`Failed to ${action} program:`, error); } }, @@ -227,12 +227,12 @@ function adminLoyaltyMerchantDetail() { await apiClient.delete(`/admin/loyalty/programs/${this.program.id}`); this.program = null; this.showDeleteModal = false; - Utils.showToast('Loyalty program deleted', 'success'); + Utils.showToast(I18n.t('loyalty.toasts.program_deleted'), 'success'); loyaltyMerchantDetailLog.info('Program deleted'); // Reload stats await this.loadStats(); } catch (error) { - Utils.showToast(`Failed to delete program: ${error.message}`, 'error'); + Utils.showToast(I18n.t('loyalty.toasts.delete_failed', {message: error.message}), 'error'); loyaltyMerchantDetailLog.error('Failed to delete program:', error); this.showDeleteModal = false; } diff --git a/app/modules/loyalty/static/admin/js/loyalty-merchant-settings.js b/app/modules/loyalty/static/admin/js/loyalty-merchant-settings.js index 1e25fbbe..d3818553 100644 --- a/app/modules/loyalty/static/admin/js/loyalty-merchant-settings.js +++ b/app/modules/loyalty/static/admin/js/loyalty-merchant-settings.js @@ -150,14 +150,14 @@ function adminLoyaltyMerchantSettings() { if (response) { loyaltyMerchantSettingsLog.info('Settings saved successfully'); - Utils.showToast('Settings saved successfully', 'success'); + Utils.showToast(I18n.t('loyalty.toasts.settings_saved'), 'success'); // Navigate back to merchant detail window.location.href = this.backUrl; } } catch (error) { loyaltyMerchantSettingsLog.error('Failed to save settings:', error); - Utils.showToast(`Failed to save settings: ${error.message}`, 'error'); + Utils.showToast(I18n.t('loyalty.toasts.settings_save_failed', {message: error.message}), 'error'); } finally { this.saving = false; } diff --git a/app/modules/loyalty/static/admin/js/loyalty-program-edit.js b/app/modules/loyalty/static/admin/js/loyalty-program-edit.js index fd3b97c7..74f03ac3 100644 --- a/app/modules/loyalty/static/admin/js/loyalty-program-edit.js +++ b/app/modules/loyalty/static/admin/js/loyalty-program-edit.js @@ -109,19 +109,19 @@ function adminLoyaltyProgramEdit() { ); this.programId = response.id; this.isNewProgram = false; - Utils.showToast('Program created successfully', 'success'); + Utils.showToast(I18n.t('loyalty.toasts.program_created'), 'success'); } else { await apiClient.patch( `/admin/loyalty/programs/${this.programId}`, payload ); - Utils.showToast('Program updated successfully', 'success'); + Utils.showToast(I18n.t('loyalty.toasts.program_updated'), 'success'); } loyaltyProgramEditLog.info('Program saved'); window.location.href = this.backUrl; } catch (error) { - Utils.showToast(`Failed to save: ${error.message}`, 'error'); + Utils.showToast(I18n.t('loyalty.toasts.save_failed', {message: error.message}), 'error'); loyaltyProgramEditLog.error('Save failed:', error); } finally { this.saving = false; @@ -134,11 +134,11 @@ function adminLoyaltyProgramEdit() { try { await apiClient.delete(`/admin/loyalty/programs/${this.programId}`); - Utils.showToast('Program deleted', 'success'); + Utils.showToast(I18n.t('loyalty.toasts.program_deleted'), 'success'); loyaltyProgramEditLog.info('Program deleted'); window.location.href = this.backUrl; } catch (error) { - Utils.showToast(`Failed to delete: ${error.message}`, 'error'); + Utils.showToast(I18n.t('loyalty.toasts.delete_failed', {message: error.message}), 'error'); loyaltyProgramEditLog.error('Delete failed:', error); } finally { this.deleting = false; diff --git a/app/modules/loyalty/static/admin/js/loyalty-programs.js b/app/modules/loyalty/static/admin/js/loyalty-programs.js index 4b182a90..95fdf8ca 100644 --- a/app/modules/loyalty/static/admin/js/loyalty-programs.js +++ b/app/modules/loyalty/static/admin/js/loyalty-programs.js @@ -249,10 +249,10 @@ function adminLoyaltyPrograms() { try { const response = await apiClient.post(`/admin/loyalty/programs/${program.id}/${action}`); program.is_active = response.is_active; - Utils.showToast(`Program ${action}d successfully`, 'success'); + Utils.showToast(I18n.t(`loyalty.toasts.program_${action}d`), 'success'); loyaltyProgramsLog.info(`Program ${program.id} ${action}d`); } catch (error) { - Utils.showToast(`Failed to ${action} program: ${error.message}`, 'error'); + Utils.showToast(I18n.t(`loyalty.toasts.${action}_failed`, {message: error.message}), 'error'); loyaltyProgramsLog.error(`Failed to ${action} program:`, error); } }, @@ -267,13 +267,13 @@ function adminLoyaltyPrograms() { if (!this.deletingProgram) return; try { await apiClient.delete(`/admin/loyalty/programs/${this.deletingProgram.id}`); - Utils.showToast('Program deleted successfully', 'success'); + Utils.showToast(I18n.t('loyalty.toasts.program_deleted'), 'success'); loyaltyProgramsLog.info('Program deleted:', this.deletingProgram.id); this.showDeleteModal = false; this.deletingProgram = null; await Promise.all([this.loadPrograms(), this.loadStats()]); } catch (error) { - Utils.showToast(`Failed to delete program: ${error.message}`, 'error'); + Utils.showToast(I18n.t('loyalty.toasts.delete_failed', {message: error.message}), 'error'); loyaltyProgramsLog.error('Failed to delete program:', error); this.showDeleteModal = false; this.deletingProgram = null; diff --git a/app/modules/loyalty/static/merchant/js/loyalty-settings.js b/app/modules/loyalty/static/merchant/js/loyalty-settings.js index 0cf29711..0e121526 100644 --- a/app/modules/loyalty/static/merchant/js/loyalty-settings.js +++ b/app/modules/loyalty/static/merchant/js/loyalty-settings.js @@ -61,10 +61,10 @@ function merchantLoyaltySettings() { await apiClient.patch('/merchants/loyalty/program', payload); } - Utils.showToast('Settings saved successfully', 'success'); + Utils.showToast(I18n.t('loyalty.toasts.settings_saved'), 'success'); loyaltySettingsLog.info('Settings saved'); } catch (error) { - Utils.showToast(`Failed to save: ${error.message}`, 'error'); + Utils.showToast(I18n.t('loyalty.toasts.save_failed', {message: error.message}), 'error'); loyaltySettingsLog.error('Save failed:', error); } finally { this.saving = false; @@ -76,11 +76,11 @@ function merchantLoyaltySettings() { try { await apiClient.delete('/merchants/loyalty/program'); - Utils.showToast('Loyalty program deleted', 'success'); + Utils.showToast(I18n.t('loyalty.toasts.program_deleted'), 'success'); loyaltySettingsLog.info('Program deleted'); window.location.href = '/merchants/loyalty/program'; } catch (error) { - Utils.showToast(`Failed to delete: ${error.message}`, 'error'); + Utils.showToast(I18n.t('loyalty.toasts.delete_failed', {message: error.message}), 'error'); loyaltySettingsLog.error('Delete failed:', error); } finally { this.deleting = false; diff --git a/app/modules/loyalty/static/shared/js/loyalty-program-form.js b/app/modules/loyalty/static/shared/js/loyalty-program-form.js index 53244db6..c8e3663f 100644 --- a/app/modules/loyalty/static/shared/js/loyalty-program-form.js +++ b/app/modules/loyalty/static/shared/js/loyalty-program-form.js @@ -99,7 +99,7 @@ function createProgramFormMixin() { if (!payload.card_name) payload.card_name = null; if (!payload.card_secondary_color) payload.card_secondary_color = null; if (!payload.logo_url) { - this.error = 'Logo URL is required for wallet integration.'; + this.error = I18n.t('loyalty.toasts.logo_required'); return null; } if (!payload.hero_image_url) payload.hero_image_url = null; diff --git a/app/modules/loyalty/static/store/js/loyalty-enroll.js b/app/modules/loyalty/static/store/js/loyalty-enroll.js index 778b6154..0360ac78 100644 --- a/app/modules/loyalty/static/store/js/loyalty-enroll.js +++ b/app/modules/loyalty/static/store/js/loyalty-enroll.js @@ -80,7 +80,7 @@ function storeLoyaltyEnroll() { loyaltyEnrollLog.info('Customer enrolled successfully:', response.card_number); } } catch (error) { - Utils.showToast(`Enrollment failed: ${error.message}`, 'error'); + Utils.showToast(I18n.t('loyalty.store.enroll.enrollment_failed', {message: error.message}), 'error'); loyaltyEnrollLog.error('Enrollment failed:', error); } finally { this.enrolling = false; diff --git a/app/modules/loyalty/static/store/js/loyalty-settings.js b/app/modules/loyalty/static/store/js/loyalty-settings.js index 711878f6..adbc0b62 100644 --- a/app/modules/loyalty/static/store/js/loyalty-settings.js +++ b/app/modules/loyalty/static/store/js/loyalty-settings.js @@ -87,10 +87,10 @@ function loyaltySettings() { let response; if (this.isNewProgram) { response = await apiClient.post('/store/loyalty/program', payload); - Utils.showToast('Program created successfully', 'success'); + Utils.showToast(I18n.t('loyalty.store.settings.program_created'), 'success'); } else { response = await apiClient.put('/store/loyalty/program', payload); - Utils.showToast('Program updated successfully', 'success'); + Utils.showToast(I18n.t('loyalty.store.settings.program_updated'), 'success'); } this.populateSettings(response); @@ -98,7 +98,7 @@ function loyaltySettings() { loyaltySettingsLog.info('Program saved:', response.display_name); } catch (error) { - Utils.showToast(`Failed to save: ${error.message}`, 'error'); + Utils.showToast(I18n.t('loyalty.store.settings.save_failed', {message: error.message}), 'error'); loyaltySettingsLog.error('Save failed:', error); } finally { this.saving = false; @@ -110,13 +110,13 @@ function loyaltySettings() { try { await apiClient.delete('/store/loyalty/program'); - Utils.showToast('Loyalty program deleted', 'success'); + Utils.showToast(I18n.t('loyalty.store.settings.program_deleted'), 'success'); loyaltySettingsLog.info('Program deleted'); // Redirect to terminal page const storeCode = window.location.pathname.split('/')[2]; window.location.href = `/store/${storeCode}/loyalty/program`; } catch (error) { - Utils.showToast(`Failed to delete: ${error.message}`, 'error'); + Utils.showToast(I18n.t('loyalty.store.settings.delete_failed', {message: error.message}), 'error'); loyaltySettingsLog.error('Delete failed:', error); } finally { this.deleting = false; diff --git a/app/modules/loyalty/static/store/js/loyalty-terminal.js b/app/modules/loyalty/static/store/js/loyalty-terminal.js index 59f264f4..4f6abc84 100644 --- a/app/modules/loyalty/static/store/js/loyalty-terminal.js +++ b/app/modules/loyalty/static/store/js/loyalty-terminal.js @@ -136,9 +136,9 @@ function storeLoyaltyTerminal() { } } catch (error) { if (error.status === 404) { - Utils.showToast('Customer not found. You can enroll them as a new member.', 'warning'); + Utils.showToast(I18n.t('loyalty.store.terminal.customer_not_found'), 'warning'); } else { - Utils.showToast(`Error looking up customer: ${error.message}`, 'error'); + Utils.showToast(I18n.t('loyalty.store.terminal.error_lookup', {message: error.message}), 'error'); } loyaltyTerminalLog.error('Lookup failed:', error); } finally { @@ -213,7 +213,7 @@ function storeLoyaltyTerminal() { await this.loadRecentTransactions(); } catch (error) { - Utils.showToast(`Transaction failed: ${error.message}`, 'error'); + Utils.showToast(I18n.t('loyalty.store.terminal.transaction_failed', {message: error.message}), 'error'); loyaltyTerminalLog.error('Transaction failed:', error); } finally { this.processing = false; @@ -229,7 +229,7 @@ function storeLoyaltyTerminal() { staff_pin: this.pinDigits }); - Utils.showToast('Stamp added!', 'success'); + Utils.showToast(I18n.t('loyalty.store.terminal.stamp_added'), 'success'); }, // Redeem stamps @@ -241,7 +241,7 @@ function storeLoyaltyTerminal() { staff_pin: this.pinDigits }); - Utils.showToast('Stamps redeemed! Reward earned.', 'success'); + Utils.showToast(I18n.t('loyalty.store.terminal.stamps_redeemed'), 'success'); }, // Earn points @@ -255,7 +255,7 @@ function storeLoyaltyTerminal() { }); const pointsEarned = response.points_earned || Math.floor(this.earnAmount * (this.program?.points_per_euro || 1)); - Utils.showToast(`${pointsEarned} points awarded!`, 'success'); + Utils.showToast(I18n.t('loyalty.store.terminal.x_points_awarded', {points: pointsEarned}), 'success'); this.earnAmount = null; }, @@ -273,7 +273,7 @@ function storeLoyaltyTerminal() { staff_pin: this.pinDigits }); - Utils.showToast(`Reward redeemed: ${reward.name}`, 'success'); + Utils.showToast(I18n.t('loyalty.store.terminal.reward_redeemed', {name: reward.name}), 'success'); this.selectedReward = ''; }, @@ -292,21 +292,11 @@ function storeLoyaltyTerminal() { // Format number getTransactionLabel(tx) { - const labels = { - 'card_created': 'Enrolled', - 'welcome_bonus': 'Welcome Bonus', - 'stamp_earned': 'Stamp Earned', - 'stamp_redeemed': 'Stamp Redeemed', - 'stamp_voided': 'Stamp Voided', - 'stamp_adjustment': 'Stamp Adjusted', - 'points_earned': 'Points Earned', - 'points_redeemed': 'Points Redeemed', - 'points_voided': 'Points Voided', - 'points_adjustment': 'Points Adjusted', - 'points_expired': 'Points Expired', - 'card_deactivated': 'Deactivated', - }; - return labels[tx.transaction_type] || tx.transaction_type?.replace(/_/g, ' ') || 'Unknown'; + const type = tx.transaction_type; + if (type) { + return I18n.t('loyalty.transactions.' + type, {defaultValue: type.replace(/_/g, ' ')}); + } + return I18n.t('loyalty.common.unknown'); }, getTransactionColor(tx) { diff --git a/app/modules/loyalty/static/storefront/js/loyalty-enroll.js b/app/modules/loyalty/static/storefront/js/loyalty-enroll.js index 173bbe83..9e80dff8 100644 --- a/app/modules/loyalty/static/storefront/js/loyalty-enroll.js +++ b/app/modules/loyalty/static/storefront/js/loyalty-enroll.js @@ -46,7 +46,7 @@ function customerLoyaltyEnroll() { this.program = null; } else { console.error('Failed to load program:', error); - this.error = 'Failed to load program information'; + this.error = I18n.t('loyalty.enrollment.errors.load_failed'); } } finally { this.loading = false; @@ -89,9 +89,9 @@ function customerLoyaltyEnroll() { } catch (error) { console.error('Enrollment failed:', error); if (error.message?.includes('already')) { - this.error = 'This email is already registered in our loyalty program.'; + this.error = I18n.t('loyalty.enrollment.errors.email_exists'); } else { - this.error = error.message || 'Enrollment failed. Please try again.'; + this.error = error.message || I18n.t('loyalty.enrollment.errors.failed'); } } finally { this.enrolling = false; diff --git a/app/modules/loyalty/static/storefront/js/loyalty-history.js b/app/modules/loyalty/static/storefront/js/loyalty-history.js index cd837da3..68c5ab56 100644 --- a/app/modules/loyalty/static/storefront/js/loyalty-history.js +++ b/app/modules/loyalty/static/storefront/js/loyalty-history.js @@ -84,16 +84,10 @@ function customerLoyaltyHistory() { getTransactionLabel(tx) { const type = tx.transaction_type || ''; - const labels = { - 'points_earned': 'Points Earned', - 'points_redeemed': 'Reward Redeemed', - 'points_voided': 'Points Voided', - 'welcome_bonus': 'Welcome Bonus', - 'points_expired': 'Points Expired', - 'stamp_earned': 'Stamp Earned', - 'stamp_redeemed': 'Stamp Redeemed' - }; - return labels[type] || type.replace(/_/g, ' '); + if (type) { + return I18n.t('loyalty.transactions.' + type, {defaultValue: type.replace(/_/g, ' ')}); + } + return type; }, formatNumber(num) { diff --git a/app/modules/loyalty/templates/loyalty/admin/analytics.html b/app/modules/loyalty/templates/loyalty/admin/analytics.html index adac780b..e32777f4 100644 --- a/app/modules/loyalty/templates/loyalty/admin/analytics.html +++ b/app/modules/loyalty/templates/loyalty/admin/analytics.html @@ -4,12 +4,14 @@ {% from 'shared/macros/alerts.html' import loading_state, error_state %} {% from 'shared/macros/inputs.html' import search_autocomplete, selected_item_display %} -{% block title %}Loyalty Analytics{% endblock %} +{% block title %}{{ _('loyalty.admin.analytics.title') }}{% endblock %} + +{% block i18n_modules %}['loyalty']{% endblock %} {% block alpine_data %}adminLoyaltyAnalytics(){% endblock %} {% block content %} -{% call page_header_flex(title='Loyalty Analytics', subtitle='Platform-wide loyalty program statistics') %} +{% call page_header_flex(title=_('loyalty.admin.analytics.title'), subtitle=_('loyalty.admin.analytics.subtitle')) %}
{{ refresh_button(loading_var='loading', onclick='loadStats()', variant='secondary') }}
@@ -17,7 +19,7 @@
- +
{{ search_autocomplete( search_var='merchantSearch', @@ -28,20 +30,20 @@ select_action='selectMerchant(item)', display_field='merchant_name', secondary_field='loyalty_type', - placeholder='Search merchants by name...', + placeholder=_('loyalty.admin.analytics.search_merchants_placeholder'), ) }}
{{ selected_item_display( selected_var='selectedMerchant', display_field='merchant_name', clear_action='clearMerchantFilter()', - label='Showing stats for:' + label=_('loyalty.admin.analytics.showing_stats_for') ) }}
-{{ loading_state('Loading analytics...') }} +{{ loading_state(_('loyalty.admin.analytics.loading')) }} -{{ error_state('Error loading analytics') }} +{{ error_state(_('loyalty.admin.analytics.error_loading')) }}
@@ -54,42 +56,42 @@

- Wallet Integration Status + {{ _('loyalty.admin.analytics.wallet_status') }}

-

Google Wallet

+

{{ _('loyalty.admin.analytics.google_wallet') }}