From d1a50fce96b2567035f12568002c4c194e2f919c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 09:09:29 +0000 Subject: [PATCH 1/2] Initial plan From c0f074025183c618cf3a236ad34ef4bb097dab4e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 09:26:23 +0000 Subject: [PATCH 2/2] Translate topup blade views and replace hardcoded strings in Vue components - Create Laravel translation files for topup views (en, nl, fr, de, es) - Replace hardcoded Dutch/English strings in all topup blade templates with __() calls - Add locale detection to TopupController (Accept-Language and ?lang= query param) - Update order layout to use dynamic locale in html lang attribute - Replace hardcoded string in QrScanner.vue with $t() call - Replace hardcoded strings in Hello.vue and Home.vue with $t() calls - Add new i18n keys to all Vue translation files Agent-Logs-Url: https://github.com/CatLabInteractive/catlab-drinks/sessions/5fa19d47-a1bb-4298-9cf5-5db2874d9116 Co-authored-by: daedeloth <1168599+daedeloth@users.noreply.github.com> --- app/Http/Controllers/TopupController.php | 36 +++++++++++++++++--- resources/lang/de/topup.php | 18 ++++++++++ resources/lang/en/topup.php | 18 ++++++++++ resources/lang/es/topup.php | 18 ++++++++++ resources/lang/fr/topup.php | 18 ++++++++++ resources/lang/nl/topup.php | 18 ++++++++++ resources/pos/js/components/QrScanner.vue | 2 +- resources/shared/js/i18n/de.js | 6 ++++ resources/shared/js/i18n/en.js | 6 ++++ resources/shared/js/i18n/es.js | 6 ++++ resources/shared/js/i18n/fr.js | 6 ++++ resources/shared/js/i18n/nl.js | 6 ++++ resources/shared/js/views/Hello.vue | 4 +-- resources/shared/js/views/Home.vue | 4 +-- resources/views/layouts/order.blade.php | 2 +- resources/views/topup/index.blade.php | 4 +-- resources/views/topup/notAvailable.blade.php | 6 ++-- resources/views/topup/status.blade.php | 14 ++++---- resources/views/topup/topupForm.blade.php | 14 ++++---- 19 files changed, 176 insertions(+), 30 deletions(-) create mode 100644 resources/lang/de/topup.php create mode 100644 resources/lang/en/topup.php create mode 100644 resources/lang/es/topup.php create mode 100644 resources/lang/fr/topup.php create mode 100644 resources/lang/nl/topup.php diff --git a/app/Http/Controllers/TopupController.php b/app/Http/Controllers/TopupController.php index 859bf5c1..08f96e70 100644 --- a/app/Http/Controllers/TopupController.php +++ b/app/Http/Controllers/TopupController.php @@ -27,6 +27,7 @@ use App\Models\OrganisationPaymentGateway; use App\Models\Topup; use Illuminate\Database\Eloquent\ModelNotFoundException; +use Illuminate\Http\Request; use Omnipay\Common\Exception\InvalidRequestException; use Omnipay\Omnipay; use Omnipay\Paynl\Gateway; @@ -41,6 +42,7 @@ class TopupController extends Controller { private $minTopup; private $maxTopup; + private static $supportedLocales = ['en', 'nl', 'fr', 'de', 'es']; public function __construct() { @@ -48,12 +50,36 @@ public function __construct() $this->maxTopup = config('payment.maxTopup', 250); } + /** + * Detect and set the locale from the request. + * + * @param Request $request + */ + protected function detectLocale(Request $request) + { + $lang = $request->query('lang') ?? $request->query('language'); + + if ($lang) { + $lang = strtolower(explode('-', $lang)[0]); + if (in_array($lang, self::$supportedLocales)) { + app()->setLocale($lang); + } + } elseif ($request->hasHeader('Accept-Language')) { + $preferred = $request->getPreferredLanguage(self::$supportedLocales); + if ($preferred) { + app()->setLocale($preferred); + } + } + } + /** * @param $cardUid * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ - public function topupForm($cardUid) + public function topupForm(Request $request, $cardUid) { + $this->detectLocale($request); + $card = $this->getCard($cardUid); $gateway = $this->createPayNLGateway($card->organisation); if (!$gateway) { @@ -120,9 +146,9 @@ public function processTopup(\Illuminate\Http\Request $request, $cardUid) * @param $topupUid * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View|string|void */ - public function notification($cardUid, $topupUid) + public function notification(Request $request, $cardUid, $topupUid) { - return $this->status($cardUid, $topupUid, true); + return $this->status($request, $cardUid, $topupUid, true); } /** @@ -131,8 +157,10 @@ public function notification($cardUid, $topupUid) * @param bool $isApiRequest * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Foundation\Application|\Illuminate\View\View|string|void */ - public function status($cardUid, $topupUid, $isApiRequest = false) + public function status(Request $request, $cardUid, $topupUid, $isApiRequest = false) { + $this->detectLocale($request); + $card = $this->getCard($cardUid); /** @var Topup $topup */ diff --git a/resources/lang/de/topup.php b/resources/lang/de/topup.php new file mode 100644 index 00000000..6f636f4c --- /dev/null +++ b/resources/lang/de/topup.php @@ -0,0 +1,18 @@ + 'Karte aufladen', + 'scan_qr' => 'Bitte scannen Sie den QR-Code auf der Karte, um eine Aufladung zu starten.', + 'current_balance' => 'Aktuelles Guthaben', + 'choose_amount' => 'Wählen Sie den gewünschten Betrag (ab :min €).', + 'amount_label' => 'Betrag', + 'amount_placeholder' => 'Betrag', + 'submit' => 'Aufladen', + 'not_available' => 'Online-Aufladung ist noch nicht verfügbar.', + 'payment_failed' => 'Die Zahlung ist fehlgeschlagen.', + 'retry' => 'Erneut versuchen', + 'payment_pending' => 'Vielen Dank für die Zahlung! Wir haben noch keine Zahlungsbestätigung erhalten, aber das kann einige Minuten dauern. Wenn die Aufladung nach 10 Minuten noch nicht erfolgreich war, wenden Sie sich bitte an einen Mitarbeiter und wir prüfen das.', + 'payment_success' => 'Die Zahlung war erfolgreich, Ihre Karte wurde um :amount aufgeladen.', + +]; diff --git a/resources/lang/en/topup.php b/resources/lang/en/topup.php new file mode 100644 index 00000000..58415edb --- /dev/null +++ b/resources/lang/en/topup.php @@ -0,0 +1,18 @@ + 'Card top-up', + 'scan_qr' => 'Please scan the QR code on the card to initiate a top-up.', + 'current_balance' => 'Current balance', + 'choose_amount' => 'Choose the desired amount (starting from €:min).', + 'amount_label' => 'Amount', + 'amount_placeholder' => 'Amount', + 'submit' => 'Top up', + 'not_available' => 'Online top-up is not yet available.', + 'payment_failed' => 'The payment has failed.', + 'retry' => 'Try again', + 'payment_pending' => 'Thank you for the payment! We have not yet received a payment confirmation, but this may take a few minutes. If the top-up has not succeeded after 10 minutes, please contact a staff member and we will look into it.', + 'payment_success' => 'The payment was successful, your card has been topped up by :amount.', + +]; diff --git a/resources/lang/es/topup.php b/resources/lang/es/topup.php new file mode 100644 index 00000000..d1885be9 --- /dev/null +++ b/resources/lang/es/topup.php @@ -0,0 +1,18 @@ + 'Recargar tarjeta', + 'scan_qr' => 'Escanee el código QR de la tarjeta para iniciar una recarga.', + 'current_balance' => 'Saldo actual', + 'choose_amount' => 'Elija el monto deseado (a partir de :min €).', + 'amount_label' => 'Monto', + 'amount_placeholder' => 'Monto', + 'submit' => 'Recargar', + 'not_available' => 'La recarga en línea aún no está disponible.', + 'payment_failed' => 'El pago ha fallado.', + 'retry' => 'Intentar de nuevo', + 'payment_pending' => '¡Gracias por el pago! Aún no hemos recibido una confirmación de pago, pero esto puede tardar unos minutos. Si la recarga no se ha completado después de 10 minutos, contacte a un miembro del personal y lo revisaremos.', + 'payment_success' => 'El pago fue exitoso, su tarjeta ha sido recargada por :amount.', + +]; diff --git a/resources/lang/fr/topup.php b/resources/lang/fr/topup.php new file mode 100644 index 00000000..2753ffff --- /dev/null +++ b/resources/lang/fr/topup.php @@ -0,0 +1,18 @@ + 'Recharger la carte', + 'scan_qr' => 'Veuillez scanner le code QR sur la carte pour initier un rechargement.', + 'current_balance' => 'Solde actuel', + 'choose_amount' => 'Choisissez le montant souhaité (à partir de :min €).', + 'amount_label' => 'Montant', + 'amount_placeholder' => 'Montant', + 'submit' => 'Recharger', + 'not_available' => 'Le rechargement en ligne n\'est pas encore disponible.', + 'payment_failed' => 'Le paiement a échoué.', + 'retry' => 'Réessayer', + 'payment_pending' => 'Merci pour le paiement ! Nous n\'avons pas encore reçu de confirmation de paiement, mais cela peut prendre quelques minutes. Si le rechargement n\'a pas réussi après 10 minutes, veuillez contacter un membre du personnel et nous vérifierons.', + 'payment_success' => 'Le paiement a réussi, votre carte a été rechargée de :amount.', + +]; diff --git a/resources/lang/nl/topup.php b/resources/lang/nl/topup.php new file mode 100644 index 00000000..c5f18075 --- /dev/null +++ b/resources/lang/nl/topup.php @@ -0,0 +1,18 @@ + 'Kaart opladen', + 'scan_qr' => 'Scan de QR-code op de kaart om een opwaardering te starten.', + 'current_balance' => 'Huidige balans', + 'choose_amount' => 'Kies het gewenste bedrag (vanaf €:min).', + 'amount_label' => 'Bedrag', + 'amount_placeholder' => 'Bedrag', + 'submit' => 'Opladen', + 'not_available' => 'Online herladen is nog niet beschikbaar.', + 'payment_failed' => 'De betaling is mislukt.', + 'retry' => 'Probeer het opnieuw', + 'payment_pending' => 'Dank voor de betaling! We hebben nog geen bevestiging van betaling ontvangen, maar dat kan enkele minuten duren. Is het opladen na 10 minuten nog steeds niet gelukt, contacteer dan een medewerker en we kijken het na.', + 'payment_success' => 'De betaling is gelukt, je kaart is voor :amount herladen.', + +]; diff --git a/resources/pos/js/components/QrScanner.vue b/resources/pos/js/components/QrScanner.vue index 01a1dff0..df5c34cd 100644 --- a/resources/pos/js/components/QrScanner.vue +++ b/resources/pos/js/components/QrScanner.vue @@ -24,7 +24,7 @@

{{ cameraError }}

-

Point your camera at the QR code

+

{{ $t('Point your camera at the QR code') }}

diff --git a/resources/shared/js/i18n/de.js b/resources/shared/js/i18n/de.js index 267bfdb4..b715e768 100644 --- a/resources/shared/js/i18n/de.js +++ b/resources/shared/js/i18n/de.js @@ -415,4 +415,10 @@ export default { // Language toggle 'Language': 'Sprache', + + // Placeholder pages + 'Hello world': 'Hallo Welt', + 'This is the hello world.': 'Dies ist die Hallo-Welt.', + 'Home': 'Startseite', + 'This is the home.': 'Dies ist die Startseite.', }; diff --git a/resources/shared/js/i18n/en.js b/resources/shared/js/i18n/en.js index 4cbb2f95..cf511327 100644 --- a/resources/shared/js/i18n/en.js +++ b/resources/shared/js/i18n/en.js @@ -415,4 +415,10 @@ export default { // Language toggle 'Language': 'Language', + + // Placeholder pages + 'Hello world': 'Hello world', + 'This is the hello world.': 'This is the hello world.', + 'Home': 'Home', + 'This is the home.': 'This is the home.', }; diff --git a/resources/shared/js/i18n/es.js b/resources/shared/js/i18n/es.js index 957a5989..624a0862 100644 --- a/resources/shared/js/i18n/es.js +++ b/resources/shared/js/i18n/es.js @@ -415,4 +415,10 @@ export default { // Language toggle 'Language': 'Idioma', + + // Placeholder pages + 'Hello world': 'Hola mundo', + 'This is the hello world.': 'Esta es la página hola mundo.', + 'Home': 'Inicio', + 'This is the home.': 'Esta es la página de inicio.', }; diff --git a/resources/shared/js/i18n/fr.js b/resources/shared/js/i18n/fr.js index 325292d7..3b1a3e8c 100644 --- a/resources/shared/js/i18n/fr.js +++ b/resources/shared/js/i18n/fr.js @@ -415,4 +415,10 @@ export default { // Language toggle 'Language': 'Langue', + + // Placeholder pages + 'Hello world': 'Bonjour le monde', + 'This is the hello world.': 'Ceci est le bonjour le monde.', + 'Home': 'Accueil', + 'This is the home.': 'Ceci est la page d\'accueil.', }; diff --git a/resources/shared/js/i18n/nl.js b/resources/shared/js/i18n/nl.js index ec893554..0e9c27ce 100644 --- a/resources/shared/js/i18n/nl.js +++ b/resources/shared/js/i18n/nl.js @@ -415,4 +415,10 @@ export default { // Language toggle 'Language': 'Taal', + + // Placeholder pages + 'Hello world': 'Hallo wereld', + 'This is the hello world.': 'Dit is de hallo wereld.', + 'Home': 'Startpagina', + 'This is the home.': 'Dit is de startpagina.', }; diff --git a/resources/shared/js/views/Hello.vue b/resources/shared/js/views/Hello.vue index 5cd9bb82..7bcaea76 100644 --- a/resources/shared/js/views/Hello.vue +++ b/resources/shared/js/views/Hello.vue @@ -23,8 +23,8 @@ -

Hello world

-

This is the hello world.

+

{{ $t('Hello world') }}

+

{{ $t('This is the hello world.') }}

diff --git a/resources/shared/js/views/Home.vue b/resources/shared/js/views/Home.vue index 52c6e9e0..4ed70753 100644 --- a/resources/shared/js/views/Home.vue +++ b/resources/shared/js/views/Home.vue @@ -23,8 +23,8 @@ -

Home

-

This is the home.

+

{{ $t('Home') }}

+

{{ $t('This is the home.') }}

diff --git a/resources/views/layouts/order.blade.php b/resources/views/layouts/order.blade.php index 084d5d4a..4c5364fc 100644 --- a/resources/views/layouts/order.blade.php +++ b/resources/views/layouts/order.blade.php @@ -1,5 +1,5 @@ - + diff --git a/resources/views/topup/index.blade.php b/resources/views/topup/index.blade.php index 25a57103..3da53130 100644 --- a/resources/views/topup/index.blade.php +++ b/resources/views/topup/index.blade.php @@ -4,8 +4,8 @@ @section('content')
-

CatLab Drinks: topup

-

Please scan the QR code on the card to initiate a topup.

+

{{ __('topup.title') }}

+

{{ __('topup.scan_qr') }}

@endsection diff --git a/resources/views/topup/notAvailable.blade.php b/resources/views/topup/notAvailable.blade.php index 705121a8..cf52df47 100644 --- a/resources/views/topup/notAvailable.blade.php +++ b/resources/views/topup/notAvailable.blade.php @@ -3,10 +3,10 @@ @section('content')
- -

Kaart opladen

+ +

{{ __('topup.title') }}

- Online herladen is nog niet beschikbaar. + {{ __('topup.not_available') }}
diff --git a/resources/views/topup/status.blade.php b/resources/views/topup/status.blade.php index 88a30993..7ddb7cc3 100644 --- a/resources/views/topup/status.blade.php +++ b/resources/views/topup/status.blade.php @@ -3,23 +3,21 @@ @section('content')
- -

Kaart opladen

+ +

{{ __('topup.title') }}

@if($topup->isCancelled())
- De betaling is mislukt.
- Probeer het opnieuw + {{ __('topup.payment_failed') }}
+ {{ __('topup.retry') }}
@elseif($topup->isPending())
- Dank voor de betaling! We hebben nog geen bevestiging van betaling ontvangen, maar dat kan enkele - minuten duren. Is het opladen na 10 minuten nog steeds niet gelukt, contacteer dan een medewerker - en we kijken het na. + {{ __('topup.payment_pending') }}
@elseif($topup->isSuccess())
- De betaling is gelukt, je kaart is voor {{ $topup->amount }} herladen. + {{ __('topup.payment_success', ['amount' => $topup->amount]) }}
@endif diff --git a/resources/views/topup/topupForm.blade.php b/resources/views/topup/topupForm.blade.php index 8d82e132..cd4fe7c1 100644 --- a/resources/views/topup/topupForm.blade.php +++ b/resources/views/topup/topupForm.blade.php @@ -4,14 +4,14 @@
- + -

Huidige balans

+

{{ __('topup.current_balance') }}

€ {{ $balance }}

-

Kaart opladen

+

{{ __('topup.title') }}

@if ($errors->any())
@@ -23,15 +23,15 @@
@endif -

Kies het gewenste bedrag (vanaf €10,00).

+

{{ __('topup.choose_amount', ['min' => $minTopup]) }}

@csrf
- - + +
- +