ungültige paket-IDs werden nun abgefangen
This commit is contained in:
@@ -23,8 +23,16 @@ class CheckoutController extends Controller
|
||||
{
|
||||
use PresentsPackages;
|
||||
|
||||
public function show(string $locale, string $checkoutSlug, Package $package): \Inertia\Response
|
||||
public function show(string $locale, string $checkoutSlug, string $package): \Inertia\Response|\Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$resolvedPackage = Package::query()->find($package);
|
||||
|
||||
if (! $resolvedPackage) {
|
||||
return redirect()
|
||||
->route('packages', ['locale' => $locale])
|
||||
->with('error', __('marketing.packages.package_not_found'));
|
||||
}
|
||||
|
||||
$googleStatus = session()->pull('checkout_google_status');
|
||||
$googleError = session()->pull('checkout_google_error');
|
||||
$googleProfile = session()->pull('checkout_google_profile');
|
||||
@@ -35,7 +43,7 @@ class CheckoutController extends Controller
|
||||
->all();
|
||||
|
||||
return Inertia::render('marketing/CheckoutWizardPage', [
|
||||
'package' => $this->presentPackage($package),
|
||||
'package' => $this->presentPackage($resolvedPackage),
|
||||
'packageOptions' => $packageOptions,
|
||||
'privacyHtml' => view('legal.datenschutz-partial')->render(),
|
||||
'auth' => [
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Support\LocaleConfig;
|
||||
use Illuminate\Foundation\Inspiring;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Middleware;
|
||||
use App\Support\LocaleConfig;
|
||||
|
||||
class HandleInertiaRequests extends Middleware
|
||||
{
|
||||
@@ -63,6 +63,8 @@ class HandleInertiaRequests extends Middleware
|
||||
'dashboard' => __('dashboard'),
|
||||
],
|
||||
'flash' => [
|
||||
'success' => fn () => $request->session()->get('success'),
|
||||
'error' => fn () => $request->session()->get('error'),
|
||||
'verification' => fn () => $request->session()->get('verification'),
|
||||
],
|
||||
];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect, useMemo, useRef, useLayoutEffect } from 'react';
|
||||
import { Link } from '@inertiajs/react';
|
||||
import { Link, usePage } from '@inertiajs/react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import type { TFunction } from 'i18next';
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
|
||||
@@ -16,6 +16,7 @@ import { useCtaExperiment } from '@/hooks/useCtaExperiment';
|
||||
import { useLocalizedRoutes } from '@/hooks/useLocalizedRoutes';
|
||||
import { useLocale } from '@/hooks/useLocale';
|
||||
import { ArrowRight, Check, Star } from 'lucide-react';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
interface Package {
|
||||
id: number;
|
||||
@@ -255,11 +256,18 @@ const Packages: React.FC<PackagesProps> = ({ endcustomerPackages, resellerPackag
|
||||
const locale = useLocale();
|
||||
const { t } = useTranslation('marketing');
|
||||
const { t: tCommon } = useTranslation('common');
|
||||
const { flash } = usePage<{ flash?: { error?: string } }>().props;
|
||||
const {
|
||||
variant: packagesHeroVariant,
|
||||
trackClick: trackPackagesHeroClick,
|
||||
} = useCtaExperiment('packages_hero_cta');
|
||||
|
||||
useEffect(() => {
|
||||
if (flash?.error) {
|
||||
toast.error(flash.error);
|
||||
}
|
||||
}, [flash?.error]);
|
||||
|
||||
useEffect(() => {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const packageId = urlParams.get('package_id');
|
||||
|
||||
@@ -66,6 +66,7 @@ return [
|
||||
'limits_label' => 'Limits & Kapazitäten',
|
||||
'paddle_not_configured' => 'Dieses Package ist noch nicht für den Paddle-Checkout konfiguriert. Bitte kontaktiere den Support.',
|
||||
'paddle_checkout_failed' => 'Der Paddle-Checkout konnte nicht gestartet werden. Bitte versuche es später erneut.',
|
||||
'package_not_found' => 'Dieses Package ist nicht verfügbar. Bitte wähle ein anderes aus.',
|
||||
],
|
||||
'nav' => [
|
||||
'home' => 'Startseite',
|
||||
|
||||
@@ -66,6 +66,7 @@ return [
|
||||
'limits_label' => 'Limits & Capacity',
|
||||
'paddle_not_configured' => 'This package is not ready for Paddle checkout. Please contact support.',
|
||||
'paddle_checkout_failed' => 'We could not start the Paddle checkout. Please try again later.',
|
||||
'package_not_found' => 'This package is no longer available. Please choose another one.',
|
||||
],
|
||||
'nav' => [
|
||||
'home' => 'Home',
|
||||
|
||||
@@ -160,10 +160,18 @@ Route::prefix('{locale}')
|
||||
->where('checkoutSlug', 'bestellen|checkout')
|
||||
->name('checkout.show');
|
||||
} else {
|
||||
Route::get('/{checkoutSlug}/{package}', function (string $locale, string $checkoutSlug, Package $package) {
|
||||
Route::get('/{checkoutSlug}/{package}', function (string $locale, string $checkoutSlug, string $package) {
|
||||
$resolvedPackage = Package::query()->find($package);
|
||||
|
||||
if (! $resolvedPackage) {
|
||||
return redirect()
|
||||
->route('packages', ['locale' => $locale])
|
||||
->with('error', __('marketing.packages.package_not_found'));
|
||||
}
|
||||
|
||||
return redirect()->route('packages', [
|
||||
'locale' => app()->getLocale(),
|
||||
'highlight' => $package->slug,
|
||||
'locale' => $locale,
|
||||
'highlight' => $resolvedPackage->slug,
|
||||
]);
|
||||
})
|
||||
->where('checkoutSlug', 'bestellen|checkout')
|
||||
@@ -325,16 +333,30 @@ Route::middleware('auth')->group(function () {
|
||||
->name('tenant.events.photos.archive');
|
||||
});
|
||||
|
||||
Route::get('/purchase-wizard/{package}', function (Request $request, Package $package) use ($determinePreferredLocale) {
|
||||
Route::get('/purchase-wizard/{package}', function (Request $request, string $package) use ($determinePreferredLocale) {
|
||||
$locale = $determinePreferredLocale($request);
|
||||
$resolvedPackage = Package::query()->find($package);
|
||||
|
||||
return redirect()->to(CheckoutRoutes::wizardUrl($package, $locale), 301);
|
||||
if (! $resolvedPackage) {
|
||||
return redirect()
|
||||
->route('packages', ['locale' => $locale])
|
||||
->with('error', __('marketing.packages.package_not_found'));
|
||||
}
|
||||
|
||||
return redirect()->to(CheckoutRoutes::wizardUrl($resolvedPackage, $locale), 301);
|
||||
});
|
||||
|
||||
Route::get('/checkout/{package}', function (Request $request, Package $package) use ($determinePreferredLocale) {
|
||||
Route::get('/checkout/{package}', function (Request $request, string $package) use ($determinePreferredLocale) {
|
||||
$locale = $determinePreferredLocale($request);
|
||||
$resolvedPackage = Package::query()->find($package);
|
||||
|
||||
return redirect()->to(CheckoutRoutes::wizardUrl($package, $locale), 301);
|
||||
if (! $resolvedPackage) {
|
||||
return redirect()
|
||||
->route('packages', ['locale' => $locale])
|
||||
->with('error', __('marketing.packages.package_not_found'));
|
||||
}
|
||||
|
||||
return redirect()->to(CheckoutRoutes::wizardUrl($resolvedPackage, $locale), 301);
|
||||
});
|
||||
Route::post('/checkout/login', [CheckoutController::class, 'login'])->name('checkout.login');
|
||||
Route::post('/checkout/register', [CheckoutController::class, 'register'])->name('checkout.register');
|
||||
|
||||
@@ -326,11 +326,13 @@ class CheckoutAuthTest extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function test_checkout_show_with_invalid_package_returns_404()
|
||||
public function test_checkout_show_with_invalid_package_redirects_to_packages()
|
||||
{
|
||||
$response = $this->get(CheckoutRoutes::wizardUrl(999, 'de'));
|
||||
|
||||
$response->assertStatus(404);
|
||||
$response
|
||||
->assertRedirect(route('packages', ['locale' => 'de']))
|
||||
->assertSessionHas('error', __('marketing.packages.package_not_found'));
|
||||
}
|
||||
|
||||
public function test_checkout_register_missing_required_fields()
|
||||
|
||||
Reference in New Issue
Block a user