name('home'); Route::get('/wallpapers', [WallpapersController::class, 'index'])->name('wallpapers'); Route::get('/murals', [MuralsController::class, 'index'])->name('murals'); Route::get('/fabrics', [FabricsController::class, 'index'])->name('fabrics'); // Product routes Route::get('/products/{product}', [ProductController::class, 'show'])->name('product-detail'); // Authentication routes Route::get('/login', function () { return view('auth.login'); })->name('auth.login'); Route::get('/auth/google', [GoogleAuthController::class, 'redirect'])->name('auth.google'); Route::get('/auth/google/callback', [GoogleAuthController::class, 'callback'])->name('auth.google.callback'); Route::post('/logout', [GoogleAuthController::class, 'logout'])->name('logout'); // Cart routes Route::get('/cart', [CartController::class, 'index'])->name('cart'); Route::post('/cart/add/{product}', [CartController::class, 'add'])->name('cart-add'); Route::post('/cart/sample/{product}', [CartController::class, 'orderSample'])->name('order-sample'); Route::post('/cart/update', [CartController::class, 'update'])->name('cart-update'); Route::post('/cart/remove', [CartController::class, 'remove'])->name('cart-remove'); Route::post('/cart/clear', [CartController::class, 'clear'])->name('cart-clear'); // Order routes Route::get('/checkout', [OrderController::class, 'checkout'])->name('checkout'); Route::post('/orders/process', [OrderController::class, 'process'])->name('order-process'); Route::get('/orders/success/{order:uuid}', [OrderController::class, 'success'])->name('order-success'); Route::get('/orders/history', [OrderController::class, 'history'])->name('order-history'); // Guest order tracking routes Route::get('/track-order', [OrderController::class, 'trackForm'])->name('track-order-form'); Route::post('/track-order', [OrderController::class, 'trackSearch'])->name('track-order-search'); // Yoco payment routes Route::get('/payment/yoco/{order:uuid}', [OrderController::class, 'yocoPayment'])->name('yoco-payment'); Route::get('/payment/yoco/success/{order:uuid}', [OrderController::class, 'yocoSuccess'])->name('yoco-success'); Route::get('/payment/yoco/cancel/{order:uuid}', [OrderController::class, 'yocoCancel'])->name('yoco-cancel'); Route::get('/payment/yoco/failure/{order:uuid}', [OrderController::class, 'yocoFailure'])->name('yoco-failure'); // Protected routes - authenticated users only Route::middleware('auth')->group(function () { Route::get('/my-account', 'App\Http\Controllers\AccountController@show')->name('my-account'); Route::post('/my-account', 'App\Http\Controllers\AccountController@update')->name('my-account.update'); Route::get('/my-orders', 'App\Http\Controllers\AccountController@orders')->name('my-orders'); Route::get('/my-orders/{order:uuid}', 'App\Http\Controllers\AccountController@orderDetail')->name('my-orders.detail'); Route::get('/custom-orders', [CustomOrderController::class, 'index'])->name('custom-orders.index'); Route::get('/custom-orders/create', 'App\Http\Controllers\CustomOrderController@create')->name('custom-orders.create'); Route::post('/custom-orders', 'App\Http\Controllers\CustomOrderController@store')->name('custom-orders.store'); Route::get('/custom-orders/{customOrder:uuid}', 'App\Http\Controllers\CustomOrderController@show')->name('custom-orders.show'); Route::post('/custom-orders/{customOrder:uuid}/approve-proof', [CustomOrderController::class, 'approveProof'])->name('custom-orders.approve-proof'); Route::post('/custom-orders/{customOrder:uuid}/request-changes', [CustomOrderController::class, 'requestChanges'])->name('custom-orders.request-changes'); Route::post('/custom-orders/{customOrder:uuid}/pay-balance', [CustomOrderController::class, 'markBalancePaid'])->name('custom-orders.pay-balance'); Route::post('/payment/yoco/custom/deposit', [CustomOrderController::class, 'depositPayment'])->name('yoco-custom-deposit'); Route::get('/payment/yoco/custom/deposit/success/{customOrder:uuid}', [CustomOrderController::class, 'depositSuccess'])->name('yoco-custom-deposit-success'); // Packing & Shipping routes (ops staff) Route::post('/orders/{order:uuid}/pack', [PackingController::class, 'confirmPacked'])->name('orders.pack'); Route::post('/custom-orders/{customOrder:uuid}/pack', [PackingController::class, 'confirmPacked'])->name('custom-orders.pack'); Route::post('/orders/{order:uuid}/ship', [ShippingController::class, 'createShipment'])->name('orders.ship'); // QR-based operations (ops interface) Route::post('/ops/orders/{order:uuid}/pack', [OpsController::class, 'confirmPacking'])->name('ops.order.pack'); Route::post('/ops/orders/{order:uuid}/inspection-passed', [OpsController::class, 'markInspectionPassed'])->name('ops.order.inspection-passed'); Route::post('/ops/orders/{order:uuid}/inspection-failed', [OpsController::class, 'flagInspectionIssue'])->name('ops.order.inspection-failed'); Route::get('/ops/orders/{order:uuid}/sticker/download', [OpsController::class, 'downloadSticker'])->name('ops.order.sticker.download'); Route::post('/ops/orders/{order:uuid}/redownload-pdfs', [OpsController::class, 'redownloadShipmentPdfs'])->name('ops.order.redownload-pdfs'); Route::post('/ops/orders/{order:uuid}/ready-for-collection', [OpsController::class, 'markReadyForCollection'])->name('ops.order.ready-for-collection'); Route::post('/custom-orders/{customOrder:uuid}/ship', [ShippingController::class, 'createShipment'])->name('custom-orders.ship'); }); // QR landing page (public but token-gated) Route::get('/ops/orders/{token}', [OpsController::class, 'showOrder'])->name('ops.order.show'); // Test routes (remove in production) Route::get('/test/sticker/{orderNumber}', function ($orderNumber) { $order = \App\Models\Order::where('order_number', $orderNumber)->first(); if (!$order) { return response()->json(['error' => 'Order not found'], 404); } $stickerPath = "qr-stickers/{$order->uuid}.pdf"; if (!\Illuminate\Support\Facades\Storage::disk('public')->exists($stickerPath)) { return response()->json([ 'error' => 'Sticker PDF not generated yet', 'order_uuid' => $order->uuid, 'regenerate_url' => route('test.sticker.regenerate', ['orderNumber' => $orderNumber]) ], 404); } $pdfUrl = \Illuminate\Support\Facades\Storage::disk('public')->url($stickerPath); return view('test.sticker-display', [ 'order' => $order, 'pdfUrl' => $pdfUrl, 'stickerPath' => $stickerPath, ]); })->name('test.sticker'); // Regenerate sticker PDF for testing Route::match(['get', 'post'], '/test/sticker/{orderNumber}/regenerate', function ($orderNumber) { $order = \App\Models\Order::where('order_number', $orderNumber)->first(); if (!$order) { return response('Order not found', 404); } try { // Ensure order has QR token if (!$order->qr_token) { $order->qr_token = \Illuminate\Support\Str::random(32); $order->qr_generated_at = now(); $order->save(); } // Generate sticker $service = new \App\Services\QrStickerService(); $paths = $service->generateSticker($order); // Return PDF inline for viewing $pdfPath = storage_path('app/public/' . $paths['pdf_path']); return response()->file($pdfPath, [ 'Content-Type' => 'application/pdf', 'Content-Disposition' => 'inline; filename="QR-' . $order->order_number . '.pdf"' ]); } catch (\Exception $e) { return response('Failed to generate sticker: ' . $e->getMessage(), 500); } })->name('test.sticker.regenerate'); // use Illuminate\Support\Facades\Route; Route::get('/font-test', function () { dd( file_exists(storage_path('fonts/AbrilFatface-Regular.ttf')), is_readable(storage_path('fonts/AbrilFatface-Regular.ttf')) ); }); // Test route for invoice generation (remove in production) require __DIR__ . '/test-invoice.php';