orderBy('sort_order') ->take(6) ->get(); $featuredProducts = Product::with('category') ->published() ->where('is_featured', true) ->latest() ->take(6) ->get(); $materials = Material::where('is_active', true)->get(); return view('shop.index', compact('categories', 'featuredProducts', 'materials')); } public function catalog(Request $request) { $query = Product::with('category')->published(); // Filter op categorie if ($request->filled('category')) { $query->whereHas('category', function ($q) use ($request) { $q->where('slug', $request->category); }); } // Filter op materiaal if ($request->filled('material')) { $query->whereJsonContains('available_materials', $request->material); } // Zoekfunctie if ($request->filled('q')) { $search = $request->q; $query->where(function ($q) use ($search) { $q->where('name', 'like', "%{$search}%") ->orWhere('short_description', 'like', "%{$search}%") ->orWhere('description', 'like', "%{$search}%"); }); } // Sortering $sort = $request->get('sort', 'newest'); if ($sort === 'price_asc') { $query->orderBy('base_price', 'asc'); } elseif ($sort === 'price_desc') { $query->orderBy('base_price', 'desc'); } else { $query->latest(); } $products = $query->paginate(12)->withQueryString(); $categories = Category::orderBy('name')->get(); $materials = Material::where('is_active', true)->get(); return view('shop.catalog', compact('products', 'categories', 'materials')); } public function show($slug) { $product = Product::with('category')->published()->where('slug', $slug)->firstOrFail(); $allMaterials = Material::where('is_active', true)->get()->keyBy('code'); $allColors = Color::where('in_stock', true)->get(); $relatedProducts = Product::published() ->where('id', '!=', $product->id) ->where('category_id', $product->category_id) ->take(3) ->get(); return view('shop.show', compact('product', 'allMaterials', 'allColors', 'relatedProducts')); } public function customRequest() { $materials = Material::where('is_active', true)->get(); $colors = Color::where('in_stock', true)->get(); return view('shop.custom', compact('materials', 'colors')); } public function storeCustomRequest(Request $request) { $validated = $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|email|max:255', 'phone' => 'nullable|string|max:50', 'description' => 'required|string|max:2000', 'preferred_material' => 'nullable|string|max:50', 'preferred_color' => 'nullable|string|max:50', 'dimensions' => 'nullable|string|max:100', 'model_file' => 'nullable|file|extensions:stl,3mf,obj,step,stp,zip|max:51200', // max 50MB (stl, step, obj, zip) ]); $filePath = null; $originalName = null; if ($request->hasFile('model_file')) { $file = $request->file('model_file'); $originalName = $file->getClientOriginalName(); $filePath = $file->store('custom_models', 'public'); } CustomRequest::create([ 'name' => $validated['name'], 'email' => $validated['email'], 'phone' => $validated['phone'] ?? null, 'description' => $validated['description'], 'preferred_material' => $validated['preferred_material'] ?? null, 'preferred_color' => $validated['preferred_color'] ?? null, 'dimensions' => $validated['dimensions'] ?? null, 'file_path' => $filePath, 'original_filename' => $originalName, 'status' => 'nieuw', ]); return redirect()->route('custom.request')->with('success', 'Bedankt! Jouw 3D print aanvraag is succesvol ontvangen. We beoordelen je model en sturen binnen 24 uur een vrijblijvende prijsopgave.'); } }