diff --git a/app/Http/Controllers/Auth/VerifyEmailController.php b/app/Http/Controllers/Auth/VerifyEmailController.php index 324b89d..e19d9eb 100644 --- a/app/Http/Controllers/Auth/VerifyEmailController.php +++ b/app/Http/Controllers/Auth/VerifyEmailController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; +use App\Support\CheckoutRoutes; use Illuminate\Foundation\Auth\EmailVerificationRequest; use Illuminate\Http\RedirectResponse; @@ -23,6 +24,7 @@ class VerifyEmailController extends Controller protected function redirectAfterVerification(EmailVerificationRequest $request): RedirectResponse { $redirectToCheckout = $request->session()->pull('checkout.verify_redirect'); + $preferredLocale = $request->session()->get('preferred_locale'); if (! $redirectToCheckout && $request->user()->pending_purchase) { $packageId = $request->session()->pull('checkout.pending_package_id'); @@ -35,7 +37,7 @@ class VerifyEmailController extends Controller } if ($packageId) { - $redirectToCheckout = route('checkout.show', ['package' => $packageId]); + $redirectToCheckout = CheckoutRoutes::wizardUrl($packageId, $preferredLocale); } } diff --git a/app/Http/Controllers/CheckoutController.php b/app/Http/Controllers/CheckoutController.php index ccb927c..8f74df3 100644 --- a/app/Http/Controllers/CheckoutController.php +++ b/app/Http/Controllers/CheckoutController.php @@ -7,6 +7,7 @@ use App\Models\AbandonedCheckout; use App\Models\Package; use App\Models\Tenant; use App\Models\User; +use App\Support\CheckoutRoutes; use App\Support\Concerns\PresentsPackages; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; @@ -22,7 +23,7 @@ class CheckoutController extends Controller { use PresentsPackages; - public function show(Package $package) + public function show(string $locale, string $checkoutSlug, Package $package): \Inertia\Response { $googleStatus = session()->pull('checkout_google_status'); $googleError = session()->pull('checkout_google_error'); @@ -52,7 +53,7 @@ class CheckoutController extends Controller ]); } - public function register(Request $request) + public function register(Request $request): \Illuminate\Http\JsonResponse { $validator = Validator::make($request->all(), [ 'email' => 'required|email|max:255|unique:users,email', @@ -143,7 +144,7 @@ class CheckoutController extends Controller Auth::login($user); $request->session()->put('checkout.pending_package_id', $package->id); - $redirectUrl = route('checkout.show', ['package' => $package->id]); + $redirectUrl = CheckoutRoutes::wizardUrl($package, $validated['locale'] ?? null); $request->session()->put('checkout.verify_redirect', $redirectUrl); $request->session()->put('url.intended', $redirectUrl); diff --git a/app/Http/Controllers/CheckoutGoogleController.php b/app/Http/Controllers/CheckoutGoogleController.php index bb67766..15a154a 100644 --- a/app/Http/Controllers/CheckoutGoogleController.php +++ b/app/Http/Controllers/CheckoutGoogleController.php @@ -5,6 +5,8 @@ namespace App\Http\Controllers; use App\Models\Package; use App\Models\Tenant; use App\Models\User; +use App\Support\CheckoutRoutes; +use App\Support\LocaleConfig; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; @@ -42,6 +44,7 @@ class CheckoutGoogleController extends Controller { $payload = $request->session()->get(self::SESSION_KEY, []); $packageId = $payload['package_id'] ?? null; + $locale = $payload['locale'] ?? null; try { $googleUser = Socialite::driver('google')->user(); @@ -49,14 +52,14 @@ class CheckoutGoogleController extends Controller Log::warning('Google checkout login failed', ['message' => $e->getMessage()]); $this->flashError($request, __('checkout.google_error_fallback')); - return $this->redirectBackToWizard($packageId); + return $this->redirectBackToWizard($packageId, $locale); } $email = $googleUser->getEmail(); if (! $email) { $this->flashError($request, __('checkout.google_missing_email')); - return $this->redirectBackToWizard($packageId); + return $this->redirectBackToWizard($packageId, $locale); } $raw = $googleUser->getRaw(); @@ -83,7 +86,7 @@ class CheckoutGoogleController extends Controller $request->session()->put('checkout_google_status', 'prefill'); - return $this->redirectBackToWizard($packageId); + return $this->redirectBackToWizard($packageId, $locale); } $user = DB::transaction(function () use ($existing, $googleUser, $email) { @@ -114,7 +117,7 @@ class CheckoutGoogleController extends Controller $this->ensurePackageAttached($user, (int) $packageId); } - return $this->redirectBackToWizard($packageId); + return $this->redirectBackToWizard($packageId, $locale); } private function createTenantForUser(User $user, ?string $displayName, string $email): Tenant @@ -188,19 +191,19 @@ class CheckoutGoogleController extends Controller ]); } - private function redirectBackToWizard(?int $packageId): RedirectResponse + private function redirectBackToWizard(?int $packageId, ?string $locale = null): RedirectResponse { if ($packageId) { - return redirect()->route('purchase.wizard', ['package' => $packageId]); + return redirect()->to(CheckoutRoutes::wizardUrl($packageId, $locale)); } $firstPackageId = Package::query()->orderBy('price')->value('id'); if ($firstPackageId) { - return redirect()->route('purchase.wizard', ['package' => $firstPackageId]); + return redirect()->to(CheckoutRoutes::wizardUrl($firstPackageId, $locale)); } return redirect()->route('packages', [ - 'locale' => app()->getLocale(), + 'locale' => LocaleConfig::canonicalize($locale ?? app()->getLocale()), ]); } diff --git a/app/Support/CheckoutRoutes.php b/app/Support/CheckoutRoutes.php new file mode 100644 index 0000000..924ce44 --- /dev/null +++ b/app/Support/CheckoutRoutes.php @@ -0,0 +1,28 @@ +getLocale()); + + return $normalized === 'en' ? 'checkout' : 'bestellen'; + } + + public static function wizardUrl(Package|int $package, ?string $locale = null): string + { + $normalized = LocaleConfig::canonicalize($locale ?? app()->getLocale()); + $slug = self::slugForLocale($normalized); + $packageId = $package instanceof Package ? $package->getKey() : $package; + + return route('checkout.show', [ + 'locale' => $normalized, + 'checkoutSlug' => $slug, + 'package' => $packageId, + ]); + } +} diff --git a/playwright-report/data/5178eafb1d619d71ea69fb93e7880ef9fb70cf4e.md b/playwright-report/data/5178eafb1d619d71ea69fb93e7880ef9fb70cf4e.md deleted file mode 100644 index b76649a..0000000 --- a/playwright-report/data/5178eafb1d619d71ea69fb93e7880ef9fb70cf4e.md +++ /dev/null @@ -1,183 +0,0 @@ -# Page snapshot - -```yaml -- generic [ref=e3]: - - banner [ref=e4]: - - generic [ref=e5]: - - link "Fotospiel App Logo Die Fotospiel App" [ref=e6] [cursor=pointer]: - - /url: /de - - img "Fotospiel App Logo" [ref=e7] - - generic [ref=e8]: Die Fotospiel App - - navigation [ref=e9]: - - link "So funktioniert's" [ref=e10] [cursor=pointer]: - - /url: /de/so-funktionierts - - link "Packages" [ref=e11] [cursor=pointer]: - - /url: /de/packages - - generic [ref=e13]: - - text: Anlässe - - img [ref=e14] - - link "Blog" [ref=e16] [cursor=pointer]: - - /url: /de/blog - - link "Kontakt" [ref=e17] [cursor=pointer]: - - /url: /de/kontakt - - generic [ref=e18]: - - link "Jetzt ausprobieren" [ref=e19] [cursor=pointer]: - - /url: /de/demo - - button "Einstellungen" [ref=e20]: - - img - - generic [ref=e21]: Einstellungen - - main [ref=e22]: - - generic [ref=e25]: - - generic [ref=e26]: - - button "Weiter" [disabled] - - generic [ref=e27]: - - progressbar [ref=e28] - - generic [ref=e30]: - - generic [ref=e31]: - - generic [ref=e32]: "1" - - generic [ref=e33]: - - paragraph [ref=e34]: Paket wählen - - paragraph [ref=e35]: Auswahl und Vergleich - - generic [ref=e36]: - - generic [ref=e37]: "2" - - generic [ref=e38]: - - paragraph [ref=e39]: Konto - - paragraph [ref=e40]: Anmelden oder Registrieren - - paragraph [ref=e41]: Erstellen Sie ein Konto oder melden Sie sich an, um mit dem Kauf fortzufahren. - - generic [ref=e42]: - - generic [ref=e43]: "3" - - generic [ref=e44]: - - paragraph [ref=e45]: Zahlung - - paragraph [ref=e46]: Sichere Zahlung - - generic [ref=e47]: - - generic [ref=e48]: "4" - - generic [ref=e49]: - - paragraph [ref=e50]: Bestätigung - - paragraph [ref=e51]: Alles erledigt! - - generic [ref=e53]: - - generic [ref=e55]: - - button "Registrieren" [ref=e56] - - button "Anmelden" [ref=e57] - - generic [ref=e58]: - - button "Mit Google fortfahren" [ref=e59]: - - img - - text: Mit Google fortfahren - - button "Warum Google?" [ref=e60]: - - text: Warum Google? - - img [ref=e61] - - generic [ref=e64]: - - generic [ref=e65]: - - generic [ref=e66]: - - generic [ref=e67]: Vorname * - - generic [ref=e68]: - - img [ref=e69] - - textbox "Vorname *" [ref=e72]: - - /placeholder: Vorname - - text: Play - - generic [ref=e73]: - - generic [ref=e74]: Nachname * - - generic [ref=e75]: - - img [ref=e76] - - textbox "Nachname *" [ref=e79]: - - /placeholder: Nachname - - text: Wright - - generic [ref=e80]: - - generic [ref=e81]: E-Mail-Adresse * - - generic [ref=e82]: - - img [ref=e83] - - textbox "E-Mail-Adresse *" [ref=e86]: - - /placeholder: beispiel@email.de - - text: playwright-buyer@example.com - - generic [ref=e87]: - - generic [ref=e88]: Adresse * - - generic [ref=e89]: - - img [ref=e90] - - textbox "Adresse *" [ref=e93]: - - /placeholder: Straße Hausnummer, PLZ Ort - - text: Teststrasse 1, 12345 Berlin - - generic [ref=e94]: - - generic [ref=e95]: Telefonnummer * - - generic [ref=e96]: - - img [ref=e97] - - textbox "Telefonnummer *" [ref=e99]: - - /placeholder: +49 170 1234567 - - text: "+49123456789" - - generic [ref=e100]: - - generic [ref=e101]: Username * - - generic [ref=e102]: - - img [ref=e103] - - textbox "Username *" [ref=e106]: - - /placeholder: z. B. hochzeit_julia - - text: playwright-buyer - - generic [ref=e107]: - - generic [ref=e108]: Passwort * - - generic [ref=e109]: - - img [ref=e110] - - textbox "Passwort *" [ref=e113]: - - /placeholder: Mindestens 8 Zeichen - - text: Password123! - - generic [ref=e114]: - - generic [ref=e115]: Passwort bestätigen * - - generic [ref=e116]: - - img [ref=e117] - - textbox "Passwort bestätigen *" [active] [ref=e120]: - - /placeholder: Passwort erneut eingeben - - text: Password123! - - generic [ref=e121]: - - checkbox "Ich stimme der Datenschutzerklärung zu und akzeptiere die Verarbeitung meiner persönlichen Daten. Datenschutzerklärung ." [ref=e122] - - generic [ref=e123]: - - text: Ich stimme der Datenschutzerklärung zu und akzeptiere die Verarbeitung meiner persönlichen Daten. - - button "Datenschutzerklärung" [ref=e124] [cursor=pointer] - - text: . - - button "Registrieren" [disabled] [ref=e125] - - generic [ref=e126]: - - button "Zurück" [ref=e127] - - button "Weiter" [disabled] - - contentinfo [ref=e128]: - - generic [ref=e129]: - - generic [ref=e130]: - - generic [ref=e131]: - - generic [ref=e132]: - - img "Fotospiel App Logo" [ref=e133] - - generic [ref=e134]: - - link "Die Fotospiel App" [ref=e135] [cursor=pointer]: - - /url: /de - - paragraph [ref=e136]: S.E.B. Fotografie - - generic [ref=e137]: - - paragraph [ref=e138]: Gutscheine - - link "Gutscheine" [ref=e139] [cursor=pointer]: - - /url: /de/gutschein - - generic [ref=e140]: - - heading "Rechtliches" [level=3] [ref=e141] - - list [ref=e142]: - - listitem [ref=e143]: - - link "Impressum" [ref=e144] [cursor=pointer]: - - /url: /de/impressum - - listitem [ref=e145]: - - link "Datenschutzerklärung" [ref=e146] [cursor=pointer]: - - /url: /de/datenschutz - - listitem [ref=e147]: - - link "Allgemeine Geschäftsbedingungen" [ref=e148] [cursor=pointer]: - - /url: /de/agb - - listitem [ref=e149]: - - link "Widerrufsbelehrung" [ref=e150] [cursor=pointer]: - - /url: /de/widerrufsbelehrung - - listitem [ref=e151]: - - button "Cookie-Einstellungen" [ref=e152] - - generic [ref=e153]: - - heading "Social" [level=3] [ref=e154] - - list [ref=e155]: - - listitem [ref=e156]: - - link "Kontakt" [ref=e157] [cursor=pointer]: - - /url: /de/kontakt - - listitem [ref=e158]: - - link "Instagram" [ref=e159] [cursor=pointer]: - - /url: "#" - - listitem [ref=e160]: - - link "Facebook" [ref=e161] [cursor=pointer]: - - /url: "#" - - listitem [ref=e162]: - - link "YouTube" [ref=e163] [cursor=pointer]: - - /url: "#" - - generic [ref=e164]: © 2025 Die Fotospiel App – Alle Rechte vorbehalten. -``` \ No newline at end of file diff --git a/playwright-report/data/5c5c999ecdc2c5044c78e0bc5111b537bb29f8ea.webm b/playwright-report/data/5c5c999ecdc2c5044c78e0bc5111b537bb29f8ea.webm deleted file mode 100644 index 2bf036b..0000000 Binary files a/playwright-report/data/5c5c999ecdc2c5044c78e0bc5111b537bb29f8ea.webm and /dev/null differ diff --git a/playwright-report/data/6240a68b897dd5f45413f9c5c6fa24e3a5cc05fa.png b/playwright-report/data/6240a68b897dd5f45413f9c5c6fa24e3a5cc05fa.png deleted file mode 100644 index 45f7029..0000000 Binary files a/playwright-report/data/6240a68b897dd5f45413f9c5c6fa24e3a5cc05fa.png and /dev/null differ diff --git a/playwright-report/index.html b/playwright-report/index.html index 8ca3daf..74977ee 100644 --- a/playwright-report/index.html +++ b/playwright-report/index.html @@ -82,4 +82,4 @@ Error generating stack: `+n.message+`