middleware('locale'); // No {locale} prefix: the response is plain JSON with no locale-dependent // content, and boboko-core's Modules\Core\File\Http\Controllers\ // UploadFileController::store() (which CustomFieldUploadController // extends) has no concept of a locale route parameter at all — every // other action in the group below still needs $locale as its literal // first parameter (the ControllerDispatcher positional-args gotcha), so // this one route living outside the group avoids that entirely rather // than forcing this shared, locale-agnostic base class to accept one. Route::post('/custom-field-uploads', [CustomFieldUploadController::class, 'store']) ->middleware('throttle:20,1') ->name('custom-field-upload.store'); Route::prefix('{locale}') ->middleware('locale') ->group(function () { Route::get('/', [HomeController::class, 'index'])->name('home'); Route::get('/products', [ProductController::class, 'index'])->name('products'); Route::get('/products/{id}', [ProductController::class, 'show'])->name( 'product.show', ); Route::get('/products-stock-check', [ProductController::class, 'checkStock'])->name( 'product.stock-check', ); Route::post('/products/{product}/reviews', [ProductController::class, 'storeReview'])->name( 'product.reviews.store', ); Route::get('/category/{id}', [CategoryController::class, 'show'])->name( 'category.show', ); Route::get('/search', [SearchController::class, 'show'])->name('search'); Route::get('/contact', [ContactController::class, 'index'])->name('contact'); Route::post('/contact', [ContactController::class, 'send'])->name('contact.send'); Route::get('/terms-and-conditions', [LegalPageController::class, 'terms'])->name( 'legal.terms', ); Route::get('/shipping-returns', [LegalPageController::class, 'shippingReturns'])->name( 'legal.shipping-returns', ); Route::get('/privacy-policy', [LegalPageController::class, 'privacy'])->name( 'legal.privacy', ); Route::get('/cookies-policy', [LegalPageController::class, 'cookies'])->name( 'legal.cookies', ); // Passwordless login — also registration, see LoginController. POSTs are // throttled per IP on top of the controller's own per-email limits. Route::middleware('guest')->group(function () { Route::get('/login', [LoginController::class, 'create'])->name('login'); Route::post('/login', [LoginController::class, 'send']) ->middleware('throttle:10,1') ->name('login.send'); Route::get('/login/code', [LoginController::class, 'code'])->name('login.code'); Route::post('/login/code', [LoginController::class, 'verify']) ->middleware('throttle:10,1') ->name('login.verify'); Route::post('/login/code/resend', [LoginController::class, 'resend']) ->middleware('throttle:10,1') ->name('login.resend'); }); Route::post('/logout', [LoginController::class, 'destroy']) ->middleware('auth') ->name('logout'); // Heart button: works for guests too (cookie), merged into the account // on login — see App\Services\Wishlist. Route::get('/wishlist', [WishlistController::class, 'guest'])->name('wishlist'); Route::post('/wishlist/{productId}', [WishlistController::class, 'toggle']) ->whereNumber('productId') ->middleware('throttle:60,1') ->name('wishlist.toggle'); Route::middleware('auth')->prefix('/account')->group(function () { Route::get('/', [AccountController::class, 'show'])->name('account'); Route::put('/', [AccountController::class, 'update'])->name('account.update'); Route::delete('/', [AccountController::class, 'destroy'])->name('account.destroy'); Route::get('/wishlist', [WishlistController::class, 'index'])->name('account.wishlist'); Route::get('/orders', [OrderController::class, 'index'])->name('account.orders'); // {orderId}, not {order}: a global `order` binding would resolve any // order by id, skipping CustomerAccountService's ownership check. Route::get('/orders/{orderId}', [OrderController::class, 'show']) ->whereNumber('orderId') ->name('account.orders.show'); // Changing the login email: verified by a code sent to the new // address, see EmailController. Route::get('/email', [EmailController::class, 'edit'])->name('account.email.edit'); Route::post('/email', [EmailController::class, 'send']) ->middleware('throttle:10,1') ->name('account.email.send'); Route::get('/email/code', [EmailController::class, 'code'])->name('account.email.code'); Route::post('/email/code', [EmailController::class, 'verify']) ->middleware('throttle:10,1') ->name('account.email.verify'); Route::post('/email/code/resend', [EmailController::class, 'resend']) ->middleware('throttle:10,1') ->name('account.email.resend'); }); });