Refine design (less clunky, fully mobile-friendly), seed only Fidget Toys, Pokemon & Film popculture, and add direct custom model ordering
This commit is contained in:
@@ -89,6 +89,80 @@ class CartController extends Controller
|
||||
return redirect()->route('cart.index')->with('success', "{$product->name} is toegevoegd aan je winkelwagen!");
|
||||
}
|
||||
|
||||
public function addCustom(Request $request)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'model_name' => 'nullable|string|max:255',
|
||||
'model_url' => 'nullable|url|max:1000',
|
||||
'model_file' => 'nullable|file|max:51200', // 50MB
|
||||
'size' => 'required|in:klein,medium,groot',
|
||||
'material' => 'required|string',
|
||||
'color' => 'required|string',
|
||||
'infill' => 'nullable|string',
|
||||
'notes' => 'nullable|string|max:1000',
|
||||
'quantity' => 'required|integer|min:1|max:20',
|
||||
]);
|
||||
|
||||
if (! $request->hasFile('model_file') && empty($validated['model_url'])) {
|
||||
return back()->withInput()->with('error', 'Upload een 3D-bestand (.stl, .3mf, .obj, .step) of vul een MakerWorld/Printables link in.');
|
||||
}
|
||||
|
||||
$filePath = null;
|
||||
$originalName = null;
|
||||
if ($request->hasFile('model_file')) {
|
||||
$file = $request->file('model_file');
|
||||
$originalName = $file->getClientOriginalName();
|
||||
$filePath = $file->store('custom_models', 'public');
|
||||
}
|
||||
|
||||
$material = Material::where('code', $validated['material'])->first();
|
||||
|
||||
// Basisprijs op basis van formaat
|
||||
$sizePrices = [
|
||||
'klein' => 9.95, // tot 8 cm
|
||||
'medium' => 16.95, // tot 15 cm
|
||||
'groot' => 24.95, // tot 22 cm
|
||||
];
|
||||
$unitPrice = $sizePrices[$validated['size']] ?? 16.95;
|
||||
|
||||
if ($material) {
|
||||
$unitPrice *= $material->price_multiplier;
|
||||
}
|
||||
|
||||
$unitPrice = round($unitPrice, 2);
|
||||
|
||||
$name = ! empty($validated['model_name'])
|
||||
? $validated['model_name']
|
||||
: ($originalName ?: 'Eigen 3D Model');
|
||||
|
||||
$cartKey = md5('custom_'.($filePath ?: ($validated['model_url'] ?? '')).'_'.$validated['material'].'_'.$validated['color'].'_'.$validated['size']);
|
||||
|
||||
$cart = session()->get('cart', []);
|
||||
|
||||
$cart[$cartKey] = [
|
||||
'id' => null,
|
||||
'is_custom' => true,
|
||||
'name' => 'Custom Print: '.$name,
|
||||
'slug' => 'custom-3d-print',
|
||||
'image_url' => 'https://images.unsplash.com/photo-1581092160607-ee22621dd758?auto=format&fit=crop&w=400&q=80',
|
||||
'material' => $material ? $material->name : $validated['material'],
|
||||
'material_code' => $validated['material'],
|
||||
'color' => $validated['color'],
|
||||
'scale' => ucfirst($validated['size']),
|
||||
'infill' => $validated['infill'] ?? 'Standaard (20%)',
|
||||
'price' => $unitPrice,
|
||||
'quantity' => (int) $validated['quantity'],
|
||||
'custom_file_path' => $filePath,
|
||||
'custom_file_name' => $originalName,
|
||||
'custom_model_url' => $validated['model_url'] ?? null,
|
||||
'custom_notes' => $validated['notes'] ?? null,
|
||||
];
|
||||
|
||||
session()->put('cart', $cart);
|
||||
|
||||
return redirect()->route('cart.index')->with('success', "Jouw eigen 3D model '{$name}' is direct toegevoegd aan je winkelwagen!");
|
||||
}
|
||||
|
||||
public function update(Request $request)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
|
||||
@@ -78,10 +78,18 @@ class CheckoutController extends Controller
|
||||
]);
|
||||
|
||||
foreach ($cart as $item) {
|
||||
$productName = $item['name'];
|
||||
if (! empty($item['custom_model_url'])) {
|
||||
$productName .= ' (Link: '.$item['custom_model_url'].')';
|
||||
}
|
||||
if (! empty($item['custom_file_name'])) {
|
||||
$productName .= ' [Bestand: '.$item['custom_file_name'].']';
|
||||
}
|
||||
|
||||
OrderItem::create([
|
||||
'order_id' => $order->id,
|
||||
'product_id' => $item['id'],
|
||||
'product_name' => $item['name'],
|
||||
'product_id' => $item['id'] ?? null,
|
||||
'product_name' => $productName,
|
||||
'material' => $item['material'] ?? null,
|
||||
'color' => $item['color'] ?? null,
|
||||
'scale' => $item['scale'] ?? '100%',
|
||||
|
||||
+230
-132
@@ -15,32 +15,32 @@ class DatabaseSeeder extends Seeder
|
||||
// 1. Materialen
|
||||
$materials = [
|
||||
[
|
||||
'name' => 'PLA+ Premium',
|
||||
'name' => 'Bio-PLA+ (Kindvriendelijk)',
|
||||
'code' => 'pla',
|
||||
'description' => 'Milieuvriendelijk, vormvast en strakke printlagen. Dé universele keuze voor interieur, houders en decoratie.',
|
||||
'description' => 'Plantaardig, biologisch afbreekbaar en geurloos. Dé ideale keuze voor speelgoed, fidgets en gedetailleerde figuren.',
|
||||
'badge_color' => 'emerald',
|
||||
'price_multiplier' => 1.00,
|
||||
],
|
||||
[
|
||||
'name' => 'PETG Tough',
|
||||
'name' => 'PETG Tough (Extra Sterk)',
|
||||
'code' => 'petg',
|
||||
'description' => 'Hittebestendig tot 75°C, slagvast en waterbestendig. Ideaal voor zwaarder belaste gereedschappen en buitentoepassingen.',
|
||||
'description' => 'Slagvast, kan tegen een stootje en waterdicht. Perfect voor intensief speelgoed en plantenpotjes.',
|
||||
'badge_color' => 'blue',
|
||||
'price_multiplier' => 1.20,
|
||||
],
|
||||
[
|
||||
'name' => 'TPU 95A Flexibel',
|
||||
'name' => 'TPU Flexibel (Rubberachtig)',
|
||||
'code' => 'tpu',
|
||||
'description' => 'Rubberachtig elastomeer. Schokabsorberend, slijtvast en nagenoeg onverwoestbaar.',
|
||||
'description' => 'Buigzaam, onbreekbaar elastomeer. Heerlijk zacht en kneedbaar voor fidget gadgets.',
|
||||
'badge_color' => 'amber',
|
||||
'price_multiplier' => 1.35,
|
||||
],
|
||||
[
|
||||
'name' => 'Resin Ultra-Detail',
|
||||
'code' => 'resin',
|
||||
'description' => 'Vloeibare fotopolymeer hars voor spuitgietkwaliteit met microscopische laaglijnen en perfecte details.',
|
||||
'name' => 'Silk / Regenboog Glans',
|
||||
'code' => 'silk',
|
||||
'description' => 'Extra glanzende zijdelook met sprankelende kleurwisselingen bij lichtinval.',
|
||||
'badge_color' => 'purple',
|
||||
'price_multiplier' => 1.50,
|
||||
'price_multiplier' => 1.25,
|
||||
],
|
||||
];
|
||||
|
||||
@@ -50,168 +50,266 @@ class DatabaseSeeder extends Seeder
|
||||
|
||||
// 2. Kleuren
|
||||
$colors = [
|
||||
['name' => 'Mat Zwart', 'hex' => '#171717', 'in_stock' => true],
|
||||
['name' => 'Zon Geel (Pikachu)', 'hex' => '#FBBF24', 'in_stock' => true],
|
||||
['name' => 'Vurig Rood (Charizard)', 'hex' => '#EF4444', 'in_stock' => true],
|
||||
['name' => 'Hemelsblauw (Squirtle)', 'hex' => '#38BDF8', 'in_stock' => true],
|
||||
['name' => 'Muntgroen (Bulbasaur)', 'hex' => '#34D399', 'in_stock' => true],
|
||||
['name' => 'Spooky Paars (Gengar)', 'hex' => '#A855F7', 'in_stock' => true],
|
||||
['name' => 'Koper Zijdeglans', 'hex' => '#D97706', 'in_stock' => true],
|
||||
['name' => 'Regenboog Multi-Color', 'hex' => '#EC4899', 'in_stock' => true],
|
||||
['name' => 'Mat Zwart', 'hex' => '#1E293B', 'in_stock' => true],
|
||||
['name' => 'Sneeuwwit', 'hex' => '#F8FAFC', 'in_stock' => true],
|
||||
['name' => 'Galaxy Grijs', 'hex' => '#475569', 'in_stock' => true],
|
||||
['name' => 'Signaal Oranje', 'hex' => '#EA580C', 'in_stock' => true],
|
||||
['name' => 'Bamboe Groen', 'hex' => '#16A34A', 'in_stock' => true],
|
||||
['name' => 'Kobaltblauw', 'hex' => '#2563EB', 'in_stock' => true],
|
||||
['name' => 'Koper Zijdeglans', 'hex' => '#B45309', 'in_stock' => true],
|
||||
['name' => 'Vurig Rood', 'hex' => '#DC2626', 'in_stock' => true],
|
||||
];
|
||||
|
||||
foreach ($colors as $c) {
|
||||
Color::updateOrCreate(['name' => $c['name']], $c);
|
||||
}
|
||||
|
||||
// 3. Categorieën
|
||||
$catInterieur = Category::updateOrCreate(['slug' => 'home-interieur'], [
|
||||
'name' => 'Home & Interieur',
|
||||
'slug' => 'home-interieur',
|
||||
'description' => 'Stijlvolle geometrische vazen, wanddecoratie en functioneel design voor in huis.',
|
||||
'icon' => 'home',
|
||||
// 3. Categorieën (Alleen Fidget Toys, Pokémon, Film & Popculture, Eigen Model)
|
||||
$catFidget = Category::updateOrCreate(['slug' => 'fidget-toys'], [
|
||||
'name' => 'Fidget Toys & Sensory',
|
||||
'slug' => 'fidget-toys',
|
||||
'description' => 'Articulated draken, wriemel slakken, oneindige kubussen en bevredigende clickers.',
|
||||
'icon' => 'sparkles',
|
||||
'is_featured' => true,
|
||||
'sort_order' => 1,
|
||||
]);
|
||||
|
||||
$catBureau = Category::updateOrCreate(['slug' => 'bureau-tech'], [
|
||||
'name' => 'Bureau & Tech Accessoires',
|
||||
'slug' => 'bureau-tech',
|
||||
'description' => 'Organizers, telefoonstandaarden, hoofdtelefoonhouders en kabelmanagement.',
|
||||
'icon' => 'laptop',
|
||||
$catPokemon = Category::updateOrCreate(['slug' => 'pokemon-3d'], [
|
||||
'name' => 'Pokémon 3D Prints',
|
||||
'slug' => 'pokemon-3d',
|
||||
'description' => 'Beweegbare Charizards, Pikachu potjes, Pokéballs en iconische figuren.',
|
||||
'icon' => 'zap',
|
||||
'is_featured' => true,
|
||||
'sort_order' => 2,
|
||||
]);
|
||||
|
||||
$catTools = Category::updateOrCreate(['slug' => 'gereedschap-werkplaats'], [
|
||||
'name' => 'Gereedschap & Werkplaats',
|
||||
'slug' => 'gereedschap-werkplaats',
|
||||
'description' => 'Robuuste houders, borensets, meetgereedschap en handige garage-hulpstukken.',
|
||||
'icon' => 'wrench',
|
||||
'is_featured' => false,
|
||||
$catFilm = Category::updateOrCreate(['slug' => 'film-popculture'], [
|
||||
'name' => 'Film, Popculture & Gaming',
|
||||
'slug' => 'film-popculture',
|
||||
'description' => 'Star Wars Grogu & Lightsabers, Marvel Mjolnir, Harry Potter en anime prints.',
|
||||
'icon' => 'film',
|
||||
'is_featured' => true,
|
||||
'sort_order' => 3,
|
||||
]);
|
||||
|
||||
$catGadgets = Category::updateOrCreate(['slug' => 'gadgets-speelgoed'], [
|
||||
'name' => 'Gadgets & Speelgoed',
|
||||
'slug' => 'gadgets-speelgoed',
|
||||
'description' => 'Articulated beweegbare figuren, fidget gadgets en unieke giveaways.',
|
||||
'icon' => 'sparkles',
|
||||
$catCustom = Category::updateOrCreate(['slug' => 'eigen-model'], [
|
||||
'name' => 'Eigen 3D Model Printen',
|
||||
'slug' => 'eigen-model',
|
||||
'description' => 'Upload jouw eigen STL of 3MF bestand en bestel direct online op maat.',
|
||||
'icon' => 'printer',
|
||||
'is_featured' => true,
|
||||
'sort_order' => 4,
|
||||
]);
|
||||
|
||||
$catCustom = Category::updateOrCreate(['slug' => 'custom-printservice'], [
|
||||
'name' => 'Custom Printservice',
|
||||
'slug' => 'custom-printservice',
|
||||
'description' => 'Laat jouw eigen STL- of CAD-ontwerp professioneel printen op maat.',
|
||||
'icon' => 'printer',
|
||||
'is_featured' => true,
|
||||
'sort_order' => 5,
|
||||
]);
|
||||
// Verwijder oude niet-relevante categorieën
|
||||
Category::whereNotIn('slug', ['fidget-toys', 'pokemon-3d', 'film-popculture', 'eigen-model'])->delete();
|
||||
|
||||
// 4. Producten (Verwijder oude vazen, gereedschap, etc.)
|
||||
Product::truncate();
|
||||
|
||||
// 4. Producten
|
||||
$products = [
|
||||
// --- FIDGET TOYS ---
|
||||
[
|
||||
'category_id' => $catInterieur->id,
|
||||
'name' => 'Origami Geometrische Vaas',
|
||||
'slug' => 'origami-geometrische-vaas',
|
||||
'short_description' => 'Moderne vaas met scherpe facetten en minimalistische vouwlijnen. Een eyecatcher op elke tafel.',
|
||||
'description' => 'De Origami Vaas combineert traditionele vouwkunst met hypermoderne additieve fabricage. Geprint in spiralize vaasmodus of met versterkte wanden voor een 100% waterdichte afwerking bij keuze voor PETG. Ideaal voor droogbloemen of als sculptuur in je woonkamer.',
|
||||
'base_price' => 18.95,
|
||||
'sku' => 'J3D-VAS-001',
|
||||
'category_id' => $catFidget->id,
|
||||
'name' => 'Articulated Kristaldraak (Flexibel Beweegbaar)',
|
||||
'slug' => 'articulated-kristaldraak-flexibel',
|
||||
'short_description' => 'De virale 3D kristaldraak! Print-in-place scharnieren met tientallen soepele schakels.',
|
||||
'description' => 'Deze iconische kristaldraak wordt in één geheel geprint met ingenieuze scharnierverbindingen. De draak beweegt soepel en natuurlijk in je handen en maakt een heerlijk zacht klikkend geluid. Een ultieme fidget toy en een fantastisch pronkstuk voor op je bureau of kast.',
|
||||
'base_price' => 17.95,
|
||||
'sku' => 'J3D-FID-DRAAK',
|
||||
'is_featured' => true,
|
||||
'dimensions' => '11 x 11 x 22 cm',
|
||||
'weight_grams' => 140,
|
||||
'print_time_hours' => 5.5,
|
||||
'image_url' => 'https://images.unsplash.com/photo-1578749556568-bc2c40e68b61?auto=format&fit=crop&w=800&q=80',
|
||||
'available_materials' => ['pla', 'petg'],
|
||||
'available_colors' => ['Mat Zwart', 'Sneeuwwit', 'Galaxy Grijs', 'Koper Zijdeglans'],
|
||||
'dimensions' => '45 x 6 x 4 cm',
|
||||
'weight_grams' => 135,
|
||||
'print_time_hours' => 6.5,
|
||||
'image_url' => 'https://images.unsplash.com/photo-1563089145-599997674d42?auto=format&fit=crop&w=800&q=80',
|
||||
'available_materials' => ['pla', 'silk'],
|
||||
'available_colors' => ['Regenboog Multi-Color', 'Koper Zijdeglans', 'Spooky Paars (Gengar)', 'Hemelsblauw (Squirtle)', 'Mat Zwart'],
|
||||
],
|
||||
[
|
||||
'category_id' => $catBureau->id,
|
||||
'name' => 'Ergonomische MagSafe Telefoon- & Watchhouder',
|
||||
'slug' => 'ergonomische-magsafe-telefoonhouder',
|
||||
'short_description' => 'Strakke bureau-standaard met kabelgoot, geschikt voor iPhone MagSafe en smartwatch.',
|
||||
'description' => 'Houd je bureau opgeruimd en je smartphone in de perfecte 65-graden kijkhoek voor videocalls of StandBy-modus. Voorzien van antislip voetpads en een slimme verborgen kabelgoot.',
|
||||
'base_price' => 14.50,
|
||||
'sku' => 'J3D-DSK-002',
|
||||
'category_id' => $catFidget->id,
|
||||
'name' => 'Articulated Fidget Slug (Wriemel Slak)',
|
||||
'slug' => 'articulated-fidget-slug-wriemel-slak',
|
||||
'short_description' => 'Vrolijke scharnierende slak die rustgevend ratelt en beweegt. Perfect tegen stress en friemelen!',
|
||||
'description' => 'De originele 3D Fidget Slug is gemaakt van concentrische flexibele segmenten. Wanneer je hem schudt of vasthoudt, beweegt hij golvend en produceert hij een zacht, bevredigend ASMR-geluid. Zeer geliefd bij zowel kinderen als volwassenen!',
|
||||
'base_price' => 9.95,
|
||||
'sku' => 'J3D-FID-SLUG',
|
||||
'is_featured' => true,
|
||||
'dimensions' => '9 x 8 x 12 cm',
|
||||
'weight_grams' => 95,
|
||||
'dimensions' => '18 x 5 x 4 cm',
|
||||
'weight_grams' => 75,
|
||||
'print_time_hours' => 3.5,
|
||||
'image_url' => 'https://images.unsplash.com/photo-1586105251261-72a756497a11?auto=format&fit=crop&w=800&q=80',
|
||||
'image_url' => 'https://images.unsplash.com/photo-1607604276583-eef5d076aa5f?auto=format&fit=crop&w=800&q=80',
|
||||
'available_materials' => ['pla', 'silk'],
|
||||
'available_colors' => ['Zon Geel (Pikachu)', 'Muntgroen (Bulbasaur)', 'Hemelsblauw (Squirtle)', 'Regenboog Multi-Color'],
|
||||
],
|
||||
[
|
||||
'category_id' => $catFidget->id,
|
||||
'name' => 'Infinity Fidget Cube (Oneindige Kubus)',
|
||||
'slug' => 'infinity-fidget-cube-oneindige-kubus',
|
||||
'short_description' => 'Vouw hem oneindig in elkaar van rechthoek naar kubus. Ideaal voor focus tijdens werk of school.',
|
||||
'description' => 'Een precisie-geprinte kubus bestaande uit 8 onderling verbonden minikubussen. Vouw hem met één hand om en om terwijl je leert, belt of gamet. Compact formaat dat makkelijk in je broekzak past.',
|
||||
'base_price' => 11.50,
|
||||
'sku' => 'J3D-FID-CUBE',
|
||||
'is_featured' => false,
|
||||
'dimensions' => '4 x 4 x 4 cm',
|
||||
'weight_grams' => 50,
|
||||
'print_time_hours' => 2.5,
|
||||
'image_url' => 'https://images.unsplash.com/photo-1596461404969-9ae70f2830c1?auto=format&fit=crop&w=800&q=80',
|
||||
'available_materials' => ['pla', 'petg'],
|
||||
'available_colors' => ['Mat Zwart', 'Zon Geel (Pikachu)', 'Hemelsblauw (Squirtle)', 'Spooky Paars (Gengar)'],
|
||||
],
|
||||
[
|
||||
'category_id' => $catFidget->id,
|
||||
'name' => 'Gyroscope Tri-Ring Fidget Spinner',
|
||||
'slug' => 'gyroscope-tri-ring-fidget-spinner',
|
||||
'short_description' => 'Multi-axis gyroscoop met onafhankelijk draaiende ringen. Draait soepel in elke dimensie.',
|
||||
'description' => 'Drie concentrische ringen die in elkaar hangen en tegelijkertijd in verschillende richtingen kunnen tuimelen. Geeft een heerlijk gevoel van gewichtloosheid in je vingers.',
|
||||
'base_price' => 8.95,
|
||||
'sku' => 'J3D-FID-GYRO',
|
||||
'is_featured' => false,
|
||||
'dimensions' => '7 x 7 x 1 cm',
|
||||
'weight_grams' => 35,
|
||||
'print_time_hours' => 2.0,
|
||||
'image_url' => 'https://images.unsplash.com/photo-1508873696983-2df5293cb32f?auto=format&fit=crop&w=800&q=80',
|
||||
'available_materials' => ['pla', 'silk'],
|
||||
'available_colors' => ['Regenboog Multi-Color', 'Koper Zijdeglans', 'Zon Geel (Pikachu)'],
|
||||
],
|
||||
|
||||
// --- POKÉMON 3D PRINTS ---
|
||||
[
|
||||
'category_id' => $catPokemon->id,
|
||||
'name' => 'Low-Poly Pikachu Plantenpotje & Bureau-Organizer',
|
||||
'slug' => 'low-poly-pikachu-plantenpotje',
|
||||
'short_description' => 'Iconische vrolijke Pikachu met geometrische low-poly vlakken. Perfect voor vetplantjes of pennen!',
|
||||
'description' => 'Een absolute fan-favorite! Deze vrolijke Pikachu is ontworpen in een stijlvolle low-poly facetstijl. Bovenop bevindt zich een uitsparing van ca. 6 cm doorsnede, uitermate geschikt voor kleine vetplantjes, cactussen of pennen op je bureau.',
|
||||
'base_price' => 14.95,
|
||||
'sku' => 'J3D-POK-PIKA',
|
||||
'is_featured' => true,
|
||||
'dimensions' => '12 x 10 x 14 cm',
|
||||
'weight_grams' => 110,
|
||||
'print_time_hours' => 4.5,
|
||||
'image_url' => 'https://images.unsplash.com/photo-1613771404784-3a5686aa2be3?auto=format&fit=crop&w=800&q=80',
|
||||
'available_materials' => ['pla', 'petg'],
|
||||
'available_colors' => ['Zon Geel (Pikachu)', 'Sneeuwwit', 'Mat Zwart', 'Koper Zijdeglans'],
|
||||
],
|
||||
[
|
||||
'category_id' => $catPokemon->id,
|
||||
'name' => 'Articulated Beweegbare Charizard Draak',
|
||||
'slug' => 'articulated-beweegbare-charizard-draak',
|
||||
'short_description' => 'Volledig scharnierende Charizard met beweegbare vleugels, kop en vlamstaart. Print-in-place spektakel!',
|
||||
'description' => 'De ultieme vuurdraak in flexibele 3D print uitvoering! De segmenten van zijn staart, rug en nek bewegen soepel met elkaar mee. Geprint in vurige oranje/rode filamentkleuren of shiny zwart.',
|
||||
'base_price' => 22.50,
|
||||
'sku' => 'J3D-POK-CHAR',
|
||||
'is_featured' => true,
|
||||
'dimensions' => '32 x 20 x 8 cm',
|
||||
'weight_grams' => 160,
|
||||
'print_time_hours' => 7.5,
|
||||
'image_url' => 'https://images.unsplash.com/photo-1542751371-adc38448a05e?auto=format&fit=crop&w=800&q=80',
|
||||
'available_materials' => ['pla', 'silk'],
|
||||
'available_colors' => ['Vurig Rood (Charizard)', 'Mat Zwart', 'Koper Zijdeglans', 'Zon Geel (Pikachu)'],
|
||||
],
|
||||
[
|
||||
'category_id' => $catPokemon->id,
|
||||
'name' => 'Pokéball Opbergdoosje met Kliksluiting',
|
||||
'slug' => 'pokeball-opbergdoosje-met-kliksluiting',
|
||||
'short_description' => 'Functionele 3D geprinte Pokéball die echt open en dicht klikt! Ideaal voor kleine schatten of sieraden.',
|
||||
'description' => 'Geprint in meerdere losse kleuren en met precisie geassembleerd. Druk op de witte middenknop om de bal te openen. Voorzien van een stabiele bodem zodat hij netjes rechtop op je bureau staat.',
|
||||
'base_price' => 13.95,
|
||||
'sku' => 'J3D-POK-BALL',
|
||||
'is_featured' => false,
|
||||
'dimensions' => '8 x 8 x 8 cm',
|
||||
'weight_grams' => 85,
|
||||
'print_time_hours' => 4.0,
|
||||
'image_url' => 'https://images.unsplash.com/photo-1563089145-599997674d42?auto=format&fit=crop&w=800&q=80',
|
||||
'available_materials' => ['pla', 'petg'],
|
||||
'available_colors' => ['Vurig Rood (Charizard)', 'Spooky Paars (Gengar)', 'Hemelsblauw (Squirtle)'],
|
||||
],
|
||||
[
|
||||
'category_id' => $catPokemon->id,
|
||||
'name' => 'Bulbasaur Geometrisch Vetplant Potje',
|
||||
'slug' => 'bulbasaur-geometrisch-vetplant-potje',
|
||||
'short_description' => 'De klassieke Bulbasaur met plantenruimte op zijn rug. Schattig en super populair!',
|
||||
'description' => 'Zet een echt klein vetplantje op Bulbasaur zijn rug om zijn beroemde plantenknop na te bootsen! Voorzien van waterafvoergaatje aan de onderzijde bij gebruik met echte plantjes.',
|
||||
'base_price' => 14.95,
|
||||
'sku' => 'J3D-POK-BULBA',
|
||||
'is_featured' => false,
|
||||
'dimensions' => '13 x 10 x 9 cm',
|
||||
'weight_grams' => 105,
|
||||
'print_time_hours' => 4.0,
|
||||
'image_url' => 'https://images.unsplash.com/photo-1509198397868-475647b2a1e5?auto=format&fit=crop&w=800&q=80',
|
||||
'available_materials' => ['pla', 'petg'],
|
||||
'available_colors' => ['Muntgroen (Bulbasaur)', 'Sneeuwwit', 'Hemelsblauw (Squirtle)'],
|
||||
],
|
||||
[
|
||||
'category_id' => $catPokemon->id,
|
||||
'name' => 'Gengar Grijns Schaduw Figuur',
|
||||
'slug' => 'gengar-grijns-schaduw-figuur',
|
||||
'short_description' => 'De ondeugende Gengar met zijn beruchte brede grijns en puntige oren in paars filament.',
|
||||
'description' => 'Spooky en iconisch! Deze Gengar is met zorg gemodelleerd en heeft strakke detaillijnen. Prachtig in glanzend paars zijdefilament of spooky glow-in-the-dark effect.',
|
||||
'base_price' => 16.95,
|
||||
'sku' => 'J3D-POK-GENG',
|
||||
'is_featured' => true,
|
||||
'dimensions' => '11 x 11 x 10 cm',
|
||||
'weight_grams' => 120,
|
||||
'print_time_hours' => 5.0,
|
||||
'image_url' => 'https://images.unsplash.com/photo-1566576912321-d58ddd74b508?auto=format&fit=crop&w=800&q=80',
|
||||
'available_materials' => ['pla', 'silk'],
|
||||
'available_colors' => ['Spooky Paars (Gengar)', 'Mat Zwart', 'Sneeuwwit'],
|
||||
],
|
||||
|
||||
// --- FILM, POPCULTURE & GAMING ---
|
||||
[
|
||||
'category_id' => $catFilm->id,
|
||||
'name' => 'Grogu Baby Yoda 3D Bureaufiguur',
|
||||
'slug' => 'grogu-baby-yoda-3d-bureaufiguur',
|
||||
'short_description' => 'De schattigste Jedi uit het universum! Prachtig gedetailleerd beeldje van Grogu in zijn mantel.',
|
||||
'description' => 'This is the way! Schattig beeldje van Grogu (The Child) met zijn iconische grote oren en plooien in zijn gewaad. Geprint in hoge resolutie (0.12mm laaghoogte) voor maximale detailweergave.',
|
||||
'base_price' => 19.95,
|
||||
'sku' => 'J3D-POP-GROGU',
|
||||
'is_featured' => true,
|
||||
'dimensions' => '12 x 14 x 10 cm',
|
||||
'weight_grams' => 140,
|
||||
'print_time_hours' => 6.0,
|
||||
'image_url' => 'https://images.unsplash.com/photo-1608889175123-8ee362201f81?auto=format&fit=crop&w=800&q=80',
|
||||
'available_materials' => ['pla', 'petg'],
|
||||
'available_colors' => ['Muntgroen (Bulbasaur)', 'Sneeuwwit', 'Koper Zijdeglans', 'Mat Zwart'],
|
||||
],
|
||||
[
|
||||
'category_id' => $catFilm->id,
|
||||
'name' => 'Lightsaber Horizontale Bureaustandaard',
|
||||
'slug' => 'lightsaber-horizontale-bureaustandaard',
|
||||
'short_description' => 'Strakke displaystandaard met Star Wars thema om jouw lightsaber handvat horizontaal te tonen.',
|
||||
'description' => 'Laat jouw lightsaber hilt schitteren op je bureau of wandplank. Universele wieg-uitsparingen geschikt voor vrijwel elk verzamel- of FX-model.',
|
||||
'base_price' => 15.95,
|
||||
'sku' => 'J3D-POP-SABER',
|
||||
'is_featured' => false,
|
||||
'dimensions' => '22 x 7 x 8 cm',
|
||||
'weight_grams' => 100,
|
||||
'print_time_hours' => 4.0,
|
||||
'image_url' => 'https://images.unsplash.com/photo-1579783900882-c0d3dad7b119?auto=format&fit=crop&w=800&q=80',
|
||||
'available_materials' => ['pla', 'petg'],
|
||||
'available_colors' => ['Mat Zwart', 'Sneeuwwit', 'Galaxy Grijs'],
|
||||
],
|
||||
[
|
||||
'category_id' => $catBureau->id,
|
||||
'name' => 'Minimal Hoofdtelefoon Bureaustandaard',
|
||||
'slug' => 'minimal-hoofdtelefoon-standaard',
|
||||
'short_description' => 'Elegante boogstandaard om je headset veilig en vormvast op te bergen.',
|
||||
'description' => 'Geen rondslingerende hoofdtelefoons meer. Het brede steunvlak ontziet de hoofdband en voorkomt drukplekken in de kussens. Geprint met versterkte infill voor optimale stabiliteit.',
|
||||
'base_price' => 22.50,
|
||||
'sku' => 'J3D-DSK-003',
|
||||
'category_id' => $catFilm->id,
|
||||
'name' => "Marvel Thor's Mjolnir Pennen- & Toolhouder",
|
||||
'slug' => 'marvel-thors-mjolnir-pennenhouder',
|
||||
'short_description' => 'De mythische hamer gestoken in een rotssokkel met uitsparingen voor pennen en gadgets.',
|
||||
'description' => 'Alleen degenen die waardig zijn kunnen deze pen pakken! Een stoere bureau-organizer in de vorm van de iconische Mjolnir hamer in een rotsachtig plateau.',
|
||||
'base_price' => 18.50,
|
||||
'sku' => 'J3D-POP-THOR',
|
||||
'is_featured' => true,
|
||||
'dimensions' => '14 x 12 x 26 cm',
|
||||
'weight_grams' => 210,
|
||||
'print_time_hours' => 8.0,
|
||||
'image_url' => 'https://images.unsplash.com/photo-1546435770-a3e426bf472b?auto=format&fit=crop&w=800&q=80',
|
||||
'dimensions' => '14 x 12 x 15 cm',
|
||||
'weight_grams' => 175,
|
||||
'print_time_hours' => 6.5,
|
||||
'image_url' => 'https://images.unsplash.com/photo-1568605117036-5fe5e7bab0b7?auto=format&fit=crop&w=800&q=80',
|
||||
'available_materials' => ['pla', 'petg'],
|
||||
'available_colors' => ['Mat Zwart', 'Galaxy Grijs', 'Sneeuwwit'],
|
||||
],
|
||||
[
|
||||
'category_id' => $catGadgets->id,
|
||||
'name' => 'Articulated Flexibele Kristaldraak',
|
||||
'slug' => 'articulated-flexibele-kristaldraak',
|
||||
'short_description' => 'Print-in-place scharnierende draak met tientallen soepele schakels. Fascinerend fidget & decoratie-item.',
|
||||
'description' => 'In één stuk geprint zonder montage of schroeven! De schakels bewegen soepel en natuurlijk in je handen. Verkrijgbaar in zijdeglans en tweekleurige effecten.',
|
||||
'base_price' => 19.95,
|
||||
'sku' => 'J3D-GAD-004',
|
||||
'is_featured' => true,
|
||||
'dimensions' => '45 x 6 x 4 cm',
|
||||
'weight_grams' => 120,
|
||||
'print_time_hours' => 6.0,
|
||||
'image_url' => 'https://images.unsplash.com/photo-1563089145-599997674d42?auto=format&fit=crop&w=800&q=80',
|
||||
'available_materials' => ['pla'],
|
||||
'available_colors' => ['Koper Zijdeglans', 'Signaal Oranje', 'Bamboe Groen', 'Mat Zwart'],
|
||||
],
|
||||
[
|
||||
'category_id' => $catInterieur->id,
|
||||
'name' => 'Hexagon Modulaire Wandplankjes (Set van 3)',
|
||||
'slug' => 'hexagon-modulaire-wandplankjes',
|
||||
'short_description' => 'Honingraat wanddisplay voor kleine plantjes, miniaturen of edelstenen. Inclusief onzichtbare wandmontage.',
|
||||
'description' => 'Creëer je eigen geometrische wandpatroon. Eenvoudig op te hangen met dubbelzijdige montagepads of kleine spijkers. Robuust ontworpen om kleine vetplantjes en beeldjes moeiteloos te dragen.',
|
||||
'base_price' => 27.50,
|
||||
'sku' => 'J3D-HOM-005',
|
||||
'is_featured' => false,
|
||||
'dimensions' => '15 x 13 x 6 cm (per stuk)',
|
||||
'weight_grams' => 260,
|
||||
'print_time_hours' => 9.5,
|
||||
'image_url' => 'https://images.unsplash.com/photo-1513519245088-0e12902e5a38?auto=format&fit=crop&w=800&q=80',
|
||||
'available_materials' => ['pla', 'petg'],
|
||||
'available_colors' => ['Mat Zwart', 'Sneeuwwit', 'Koper Zijdeglans'],
|
||||
],
|
||||
[
|
||||
'category_id' => $catTools->id,
|
||||
'name' => 'Heavy-Duty Boorkophouder & Magnetische Bit Tray',
|
||||
'slug' => 'heavy-duty-boorkophouder-bit-tray',
|
||||
'short_description' => 'Georganiseerde opberger voor 1/4" hex bits en boorkoppen met krachtige Neodymium magneten.',
|
||||
'description' => 'Geprint in taai en chemicaliënbestendig PETG. Nooit meer losse schroefbits zoeken in je gereedschapskist. De magnetische bodem houdt al je metalen accessoires stevig op hun plek.',
|
||||
'base_price' => 16.95,
|
||||
'sku' => 'J3D-WRK-006',
|
||||
'is_featured' => false,
|
||||
'dimensions' => '16 x 7 x 3.5 cm',
|
||||
'weight_grams' => 110,
|
||||
'print_time_hours' => 4.0,
|
||||
'image_url' => 'https://images.unsplash.com/photo-1581783898377-1c85bf937427?auto=format&fit=crop&w=800&q=80',
|
||||
'available_materials' => ['petg', 'tpu'],
|
||||
'available_colors' => ['Mat Zwart', 'Signaal Oranje', 'Kobaltblauw'],
|
||||
'available_colors' => ['Mat Zwart', 'Koper Zijdeglans', 'Sneeuwwit'],
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($products as $p) {
|
||||
Product::updateOrCreate(['slug' => $p['slug']], $p);
|
||||
Product::create($p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-26
@@ -13,36 +13,22 @@
|
||||
font-family: var(--font-heading);
|
||||
}
|
||||
|
||||
/* Chunky playful toy block shadows */
|
||||
.toy-shadow-sm {
|
||||
box-shadow: 2px 2px 0px 0px #0f172a;
|
||||
/* Refined, smooth playful button */
|
||||
.playful-btn {
|
||||
transition: all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
}
|
||||
.toy-shadow {
|
||||
box-shadow: 4px 4px 0px 0px #0f172a;
|
||||
.playful-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.toy-shadow-lg {
|
||||
box-shadow: 6px 6px 0px 0px #0f172a;
|
||||
}
|
||||
.toy-shadow-amber {
|
||||
box-shadow: 4px 4px 0px 0px #b45309;
|
||||
}
|
||||
.toy-shadow-rose {
|
||||
box-shadow: 4px 4px 0px 0px #be123c;
|
||||
}
|
||||
.toy-shadow-indigo {
|
||||
box-shadow: 4px 4px 0px 0px #3730a3;
|
||||
.playful-btn:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
/* Chunky pressable button effect */
|
||||
.toy-btn {
|
||||
transition: all 0.12s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
/* Modern playful card */
|
||||
.playful-card {
|
||||
transition: all 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
}
|
||||
.toy-btn:hover {
|
||||
transform: translate(-2px, -2px);
|
||||
box-shadow: 6px 6px 0px 0px #0f172a;
|
||||
}
|
||||
.toy-btn:active {
|
||||
transform: translate(2px, 2px);
|
||||
box-shadow: 2px 2px 0px 0px #0f172a;
|
||||
.playful-card:hover {
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,70 +3,84 @@
|
||||
@section('title', 'Winkelwagen 🛒 | Jouwdriedee.nl')
|
||||
|
||||
@section('content')
|
||||
<div class="bg-amber-100 border-b-2 border-slate-900 py-6">
|
||||
<div class="bg-gradient-to-b from-amber-50 to-[#FFFDF9] border-b border-slate-200/80 py-5 sm:py-7">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<h1 class="font-heading text-3xl font-black text-slate-900 tracking-tight flex items-center space-x-2">
|
||||
<h1 class="font-heading text-2xl sm:text-3xl font-black text-slate-900 tracking-tight flex items-center space-x-2">
|
||||
<span>🛒</span>
|
||||
<span>Jouw Winkelwagen</span>
|
||||
</h1>
|
||||
<p class="text-xs font-bold text-slate-600 mt-1">Controleer jouw geselecteerde 3D prints, vrolijke kleuren en aantallen.</p>
|
||||
<p class="text-xs text-slate-500 mt-0.5">Controleer jouw geselecteerde 3D prints, custom bestanden en kleuren.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-10">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 sm:py-10">
|
||||
@if(empty($cart))
|
||||
<div class="p-12 text-center rounded-3xl bg-white border-2 border-slate-900 toy-shadow space-y-4 max-w-lg mx-auto">
|
||||
<div class="w-20 h-20 rounded-3xl bg-amber-100 border-2 border-slate-900 text-slate-900 flex items-center justify-center mx-auto text-4xl">
|
||||
<div class="p-8 sm:p-12 text-center rounded-3xl bg-white border border-slate-100 shadow-sm space-y-4 max-w-lg mx-auto">
|
||||
<div class="w-16 h-16 rounded-2xl bg-amber-50 text-slate-800 flex items-center justify-center mx-auto text-3xl">
|
||||
🧸
|
||||
</div>
|
||||
<h2 class="font-heading text-xl font-black text-slate-900">Je winkelwagen is nog leeg!</h2>
|
||||
<p class="text-xs text-slate-600 font-medium">Zoek een leuk speelgoedmodel, vaas of handige gadget uit onze collectie!</p>
|
||||
<div class="pt-3">
|
||||
<a href="{{ route('catalog') }}" class="toy-btn px-6 py-3.5 rounded-2xl bg-amber-400 hover:bg-amber-300 border-2 border-slate-900 toy-shadow-sm text-slate-950 font-black text-xs inline-flex items-center space-x-2">
|
||||
<h2 class="font-heading text-xl font-black text-slate-900">Je winkelmandje is nog leeg!</h2>
|
||||
<p class="text-xs text-slate-500 max-w-sm mx-auto">Bekijk onze vrolijke collectie fidget toys en Pokémon prints, of bestel direct je eigen 3D model.</p>
|
||||
<div class="pt-2 flex flex-col sm:flex-row items-center justify-center gap-2">
|
||||
<a href="{{ route('catalog') }}" class="playful-btn w-full sm:w-auto px-5 py-3 rounded-xl bg-amber-400 hover:bg-amber-300 text-slate-950 font-black text-xs inline-flex items-center justify-center space-x-1.5 shadow-xs">
|
||||
<span>Bekijk Alle Prints 🎁</span>
|
||||
<i data-lucide="arrow-right" class="w-4 h-4 stroke-[3]"></i>
|
||||
</a>
|
||||
<a href="{{ route('custom.request') }}" class="playful-btn w-full sm:w-auto px-5 py-3 rounded-xl bg-slate-100 hover:bg-slate-200 text-slate-800 font-bold text-xs inline-flex items-center justify-center space-x-1.5">
|
||||
<span>Eigen Model Bestellen 🚀</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-8">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-6 lg:gap-8">
|
||||
|
||||
<!-- Items Lijst -->
|
||||
<div class="lg:col-span-8 space-y-4">
|
||||
<div class="lg:col-span-8 space-y-3 sm:space-y-4">
|
||||
@foreach($cart as $key => $item)
|
||||
<div class="p-5 rounded-3xl bg-white border-2 border-slate-900 toy-shadow-sm flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
<div class="flex items-center space-x-4 w-full sm:w-auto">
|
||||
<div class="w-20 h-20 rounded-2xl bg-[#FFFDF7] border-2 border-slate-900 overflow-hidden flex-shrink-0">
|
||||
<div class="p-4 sm:p-5 rounded-2xl sm:rounded-3xl bg-white border border-slate-100 shadow-xs flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
<div class="flex items-center space-x-3.5 w-full sm:w-auto">
|
||||
<div class="w-16 h-16 sm:w-20 sm:h-20 rounded-2xl bg-slate-100 overflow-hidden flex-shrink-0 border border-slate-100">
|
||||
<img src="{{ $item['image_url'] }}" alt="{{ $item['name'] }}" class="w-full h-full object-cover">
|
||||
</div>
|
||||
<div class="space-y-1">
|
||||
<h3 class="font-heading text-base font-black text-slate-900">{{ $item['name'] }}</h3>
|
||||
<div class="flex flex-wrap items-center gap-2 text-xs">
|
||||
<span class="px-2 py-0.5 rounded-lg bg-sky-100 border border-slate-900 text-slate-900 font-black text-[10px]">{{ $item['material'] }}</span>
|
||||
<h3 class="font-heading text-sm sm:text-base font-black text-slate-900">{{ $item['name'] }}</h3>
|
||||
<div class="flex flex-wrap items-center gap-1.5 text-[11px] text-slate-500">
|
||||
<span class="px-2 py-0.2 rounded-md bg-rose-50 text-rose-700 font-bold">{{ $item['material'] }}</span>
|
||||
<span>•</span>
|
||||
<span class="font-bold text-slate-700">Kleur: {{ $item['color'] }}</span>
|
||||
<span class="font-semibold text-slate-700">Kleur: {{ $item['color'] }}</span>
|
||||
<span>•</span>
|
||||
<span class="font-mono font-bold text-slate-700">{{ $item['scale'] }}</span>
|
||||
<span class="font-mono text-slate-600">{{ $item['scale'] }}</span>
|
||||
</div>
|
||||
<div class="text-xs font-black text-slate-900 pt-1">
|
||||
@if(!empty($item['custom_file_name']))
|
||||
<div class="text-[10px] font-bold text-indigo-600 flex items-center space-x-1 pt-0.5">
|
||||
<span>📁</span>
|
||||
<span>Bestand: {{ $item['custom_file_name'] }}</span>
|
||||
</div>
|
||||
@endif
|
||||
@if(!empty($item['custom_model_url']))
|
||||
<div class="text-[10px] font-bold text-indigo-600 flex items-center space-x-1 pt-0.5">
|
||||
<span>🔗</span>
|
||||
<span class="truncate max-w-xs">{{ $item['custom_model_url'] }}</span>
|
||||
</div>
|
||||
@endif
|
||||
<div class="text-xs font-black text-slate-900 pt-0.5">
|
||||
€ {{ number_format($item['price'], 2, ',', '.') }} per stuk
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Aantal en acties -->
|
||||
<div class="flex items-center justify-between sm:justify-end space-x-4 w-full sm:w-auto pt-3 sm:pt-0 border-t sm:border-t-0 border-slate-100">
|
||||
<div class="flex items-center justify-between sm:justify-end space-x-3 w-full sm:w-auto pt-2 sm:pt-0 border-t sm:border-t-0 border-slate-100">
|
||||
<!-- Update Formulier -->
|
||||
<form action="{{ route('cart.update') }}" method="POST" class="flex items-center space-x-1">
|
||||
@csrf
|
||||
<input type="hidden" name="key" value="{{ $key }}">
|
||||
<input type="number" name="quantity" min="1" max="50" value="{{ $item['quantity'] }}" class="w-16 bg-[#FFFDF7] border-2 border-slate-900 rounded-xl px-2 py-1.5 text-xs text-center font-heading font-black text-slate-900 focus:outline-none">
|
||||
<button type="submit" class="p-2 rounded-xl text-slate-600 hover:text-slate-900 hover:bg-slate-100 transition" title="Bijwerken">
|
||||
<i data-lucide="refresh-cw" class="w-4 h-4"></i>
|
||||
<input type="number" name="quantity" min="1" max="50" value="{{ $item['quantity'] }}" class="w-14 bg-slate-50 border border-slate-200 rounded-lg px-2 py-1 text-xs text-center font-heading font-black text-slate-900 focus:outline-none">
|
||||
<button type="submit" class="p-1 rounded-lg text-slate-400 hover:text-slate-800 transition" title="Bijwerken">
|
||||
<i data-lucide="refresh-cw" class="w-3.5 h-3.5"></i>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<span class="font-heading text-base font-black text-slate-900 w-24 text-right">
|
||||
<span class="font-heading text-base font-black text-slate-900 w-20 text-right">
|
||||
€ {{ number_format($item['price'] * $item['quantity'], 2, ',', '.') }}
|
||||
</span>
|
||||
|
||||
@@ -74,8 +88,8 @@
|
||||
<form action="{{ route('cart.remove', $key) }}" method="POST">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="p-2 text-rose-500 hover:text-rose-700 transition cursor-pointer" title="Verwijderen">
|
||||
<i data-lucide="trash-2" class="w-5 h-5"></i>
|
||||
<button type="submit" class="p-1.5 text-slate-300 hover:text-rose-500 transition cursor-pointer" title="Verwijderen">
|
||||
<i data-lucide="trash-2" class="w-4 h-4"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@@ -83,47 +97,47 @@
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<!-- Samenvatting (Chunky Toy Box) -->
|
||||
<!-- Samenvatting -->
|
||||
<div class="lg:col-span-4">
|
||||
<div class="p-6 rounded-3xl bg-amber-100 border-2 border-slate-900 toy-shadow space-y-5 sticky top-24">
|
||||
<h3 class="font-heading text-sm font-black text-slate-900 uppercase tracking-wider pb-3 border-b-2 border-slate-900 flex items-center space-x-2">
|
||||
<div class="p-6 rounded-3xl bg-white border border-slate-100 shadow-md space-y-4 sticky top-24">
|
||||
<h3 class="font-heading text-sm font-black text-slate-900 uppercase tracking-wider pb-2.5 border-b border-slate-100 flex items-center space-x-1.5">
|
||||
<span>🧾</span>
|
||||
<span>Overzicht Bestelling</span>
|
||||
</h3>
|
||||
|
||||
<div class="space-y-3 text-xs font-bold">
|
||||
<div class="flex justify-between text-slate-700">
|
||||
<div class="space-y-2 text-xs font-bold">
|
||||
<div class="flex justify-between text-slate-600">
|
||||
<span>Subtotaal</span>
|
||||
<span class="font-heading text-sm font-black text-slate-900">€ {{ number_format($subtotal, 2, ',', '.') }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between text-slate-700">
|
||||
<div class="flex justify-between text-slate-600">
|
||||
<span>Verzendkosten</span>
|
||||
@if($shipping == 0)
|
||||
<span class="text-emerald-700 font-black bg-emerald-200 px-2 py-0.5 rounded-lg border border-slate-900">GRATIS 🎉</span>
|
||||
<span class="text-emerald-700 font-black bg-emerald-100 px-2 py-0.2 rounded-md">GRATIS 🎉</span>
|
||||
@else
|
||||
<span class="font-heading text-sm font-black text-slate-900">€ {{ number_format($shipping, 2, ',', '.') }}</span>
|
||||
@endif
|
||||
</div>
|
||||
@if($subtotal < 50)
|
||||
<p class="text-[11px] text-amber-900 bg-amber-200/90 p-3 rounded-2xl border-2 border-slate-900 font-black">
|
||||
💡 Tip: Bestel nog voor <strong>€ {{ number_format(50 - $subtotal, 2, ',', '.') }}</strong> en profiteer van gratis verzending!
|
||||
<p class="text-[11px] text-amber-900 bg-amber-50 p-2.5 rounded-xl border border-amber-200 font-bold">
|
||||
💡 Tip: Bestel nog voor <strong>€ {{ number_format(50 - $subtotal, 2, ',', '.') }}</strong> voor gratis verzending!
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="pt-4 border-t-2 border-slate-900 flex justify-between items-baseline">
|
||||
<span class="font-heading text-base font-black text-slate-900">Totaal (incl. btw)</span>
|
||||
<div class="pt-3 border-t border-slate-100 flex justify-between items-baseline">
|
||||
<span class="font-heading text-sm font-black text-slate-900">Totaal (incl. btw)</span>
|
||||
<span class="font-heading text-2xl font-black text-slate-900">€ {{ number_format($total, 2, ',', '.') }}</span>
|
||||
</div>
|
||||
|
||||
<a href="{{ route('checkout.index') }}" class="toy-btn w-full py-4 rounded-2xl bg-emerald-400 hover:bg-emerald-300 border-2 border-slate-900 toy-shadow text-slate-950 font-black text-xs uppercase tracking-wider transition flex items-center justify-center space-x-2">
|
||||
<a href="{{ route('checkout.index') }}" class="playful-btn w-full py-3.5 rounded-2xl bg-gradient-to-r from-amber-400 via-rose-400 to-rose-500 hover:opacity-95 text-slate-950 font-black text-xs uppercase tracking-wider transition shadow-md shadow-rose-500/20 flex items-center justify-center space-x-2">
|
||||
<span>Doorgaan Naar Afrekenen 🚀</span>
|
||||
</a>
|
||||
|
||||
<div class="flex items-center justify-center space-x-3 text-[11px] font-bold text-slate-600 pt-1">
|
||||
<span>🔒 Veilig betalen</span>
|
||||
<div class="flex items-center justify-center space-x-2 text-[11px] font-bold text-slate-400 pt-1">
|
||||
<span>🔒 Veilig betalen met iDEAL</span>
|
||||
<span>•</span>
|
||||
<span>📦 PostNL Track & Trace</span>
|
||||
<span>PostNL</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
<html lang="nl" class="h-full antialiased">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>@yield('title', 'Jouwdriedee.nl 🎨 Dé Speelse 3D Print Webshop')</title>
|
||||
<meta name="description" content="@yield('meta_description', 'Jouwdriedee.nl - Vrolijke 3D prints, tof speelgoed, hippe gadgets en op maat gemaakte 3D creaties direct uit de printer!')">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5">
|
||||
<title>@yield('title', 'Jouwdriedee.nl ✨ Dé 3D Print Webshop | Fidget Toys, Pokémon & Eigen Modellen')</title>
|
||||
<meta name="description" content="@yield('meta_description', 'Jouwdriedee.nl - Vrolijke 3D prints, toffe fidget toys, Pokémon figuren en film artikelen. Bestel ook direct jouw eigen 3D model!')">
|
||||
|
||||
<!-- Playful Google Fonts: Fredoka & Nunito -->
|
||||
<!-- Google Fonts: Fredoka & Nunito -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&family=Nunito:wght@400;600;700;800;900&display=swap" rel="stylesheet">
|
||||
@@ -22,134 +22,144 @@
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="min-h-full flex flex-col bg-[#FFFDF7] text-slate-900 selection:bg-amber-300 selection:text-slate-900" x-data="{ mobileMenuOpen: false }">
|
||||
<body class="min-h-full flex flex-col bg-[#FFFDF9] text-slate-800 selection:bg-amber-300 selection:text-slate-900" x-data="{ mobileMenuOpen: false }">
|
||||
|
||||
<!-- Top Playful Announcement Bar -->
|
||||
<div class="bg-amber-400 border-b-2 border-slate-900 text-slate-950 text-xs py-2 px-4 font-black">
|
||||
<!-- Top Announcement Bar (Vrolijk & Subtiel) -->
|
||||
<div class="bg-gradient-to-r from-amber-400 via-rose-400 to-indigo-500 text-slate-950 text-xs py-2 px-3 sm:px-4 font-black">
|
||||
<div class="max-w-7xl mx-auto flex items-center justify-between">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="inline-block animate-bounce">🎉</span>
|
||||
<span class="tracking-wide">Hoera! Jouw favoriete 3D prints & speelgoed vers uit onze printers!</span>
|
||||
<div class="flex items-center space-x-1.5 mx-auto sm:mx-0 text-center sm:text-left">
|
||||
<span class="inline-block animate-bounce">✨</span>
|
||||
<span>Fidget toys, Pokémon figuren & film gadgets vers 3D geprint!</span>
|
||||
</div>
|
||||
<div class="hidden md:flex items-center space-x-6 text-[12px]">
|
||||
<span class="flex items-center space-x-1.5 bg-amber-300/80 px-2.5 py-0.5 rounded-full border border-slate-900">
|
||||
<span>✨</span>
|
||||
<div class="hidden md:flex items-center space-x-5 text-[11px] font-bold text-slate-900">
|
||||
<span class="flex items-center space-x-1 bg-white/70 backdrop-blur-xs px-2.5 py-0.5 rounded-full shadow-2xs">
|
||||
<span>📦</span>
|
||||
<span>Gratis verzending vanaf € 50,-</span>
|
||||
</span>
|
||||
<span class="flex items-center space-x-1.5">
|
||||
<span class="flex items-center space-x-1 bg-white/70 backdrop-blur-xs px-2.5 py-0.5 rounded-full shadow-2xs">
|
||||
<span>🚀</span>
|
||||
<span>Snel verzonden via PostNL</span>
|
||||
</span>
|
||||
<span class="flex items-center space-x-1.5">
|
||||
<span>🌈</span>
|
||||
<span>Biologisch PLA & veilige materialen</span>
|
||||
<span>Binnen 2-3 werkdagen in huis</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Navigation Header -->
|
||||
<header class="sticky top-0 z-40 bg-white/95 backdrop-blur-md border-b-2 border-slate-900 shadow-sm">
|
||||
<header class="sticky top-0 z-40 bg-white/90 backdrop-blur-md border-b border-slate-200/80 shadow-xs">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex items-center justify-between h-20">
|
||||
<div class="flex items-center justify-between h-16 sm:h-20">
|
||||
|
||||
<!-- Logo & Brand (Fun Toy Mascot Box) -->
|
||||
<div class="flex items-center space-x-6">
|
||||
<a href="{{ route('home') }}" class="flex items-center space-x-3 group">
|
||||
<div class="w-12 h-12 rounded-2xl bg-gradient-to-br from-amber-400 via-rose-400 to-indigo-500 border-2 border-slate-900 toy-shadow-sm flex items-center justify-center text-white group-hover:scale-105 group-hover:-rotate-3 transition transform">
|
||||
<i data-lucide="sparkles" class="w-7 h-7 text-white stroke-[2.5]"></i>
|
||||
<!-- Logo & Brand -->
|
||||
<div class="flex items-center space-x-4 sm:space-x-8">
|
||||
<a href="{{ route('home') }}" class="flex items-center space-x-2.5 group">
|
||||
<div class="w-10 h-10 sm:w-11 sm:h-11 rounded-2xl bg-gradient-to-br from-amber-400 via-rose-400 to-indigo-500 flex items-center justify-center text-white shadow-md shadow-rose-500/20 group-hover:scale-105 group-hover:-rotate-3 transition transform">
|
||||
<i data-lucide="sparkles" class="w-5 h-5 sm:w-6 sm:h-6 stroke-[2.5]"></i>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex items-baseline space-x-1">
|
||||
<span class="font-heading text-2xl font-black tracking-tight text-slate-900">Jouw<span class="text-rose-500">driedee</span></span>
|
||||
<span class="text-xs font-black bg-indigo-500 text-white px-1.5 py-0.5 rounded-lg border border-slate-900">.NL</span>
|
||||
<span class="font-heading text-xl sm:text-2xl font-black tracking-tight text-slate-900">Jouw<span class="text-rose-500">driedee</span></span>
|
||||
<span class="text-[10px] font-black bg-indigo-500 text-white px-1.5 py-0.2 rounded-md">.NL</span>
|
||||
</div>
|
||||
<span class="text-[11px] font-extrabold text-amber-600 flex items-center space-x-1">
|
||||
<span>🧸</span>
|
||||
<span>De vrolijkste 3D print webshop</span>
|
||||
</span>
|
||||
<span class="text-[10px] font-bold text-amber-600 hidden sm:inline">🧸 3D Prints, Fidgets & Pokémon</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- Desktop Nav Links (Chunky Rounded Toy Pills) -->
|
||||
<nav class="hidden lg:flex items-center space-x-2 text-sm font-extrabold">
|
||||
<a href="{{ route('home') }}" class="px-4 py-2 rounded-2xl transition border-2 {{ request()->routeIs('home') ? 'bg-amber-300 border-slate-900 toy-shadow-sm text-slate-950 font-black' : 'border-transparent text-slate-700 hover:border-slate-900 hover:bg-slate-100/80' }}">
|
||||
<!-- Desktop Nav Links -->
|
||||
<nav class="hidden lg:flex items-center space-x-1 text-sm font-extrabold text-slate-700">
|
||||
<a href="{{ route('home') }}" class="px-3.5 py-2 rounded-xl transition {{ request()->routeIs('home') ? 'bg-amber-100 text-amber-900 font-black' : 'hover:bg-slate-100 text-slate-700' }}">
|
||||
Home 🏠
|
||||
</a>
|
||||
<a href="{{ route('catalog') }}" class="px-4 py-2 rounded-2xl transition border-2 {{ request()->routeIs('catalog*') ? 'bg-sky-200 border-slate-900 toy-shadow-sm text-slate-950 font-black' : 'border-transparent text-slate-700 hover:border-slate-900 hover:bg-slate-100/80' }}">
|
||||
Alle Prints 🎁
|
||||
<a href="{{ route('catalog', ['category' => 'fidget-toys']) }}" class="px-3.5 py-2 rounded-xl transition hover:bg-slate-100 text-slate-700">
|
||||
Fidget Toys 🌀
|
||||
</a>
|
||||
<a href="{{ route('custom.request') }}" class="px-4 py-2 rounded-2xl transition border-2 flex items-center space-x-1.5 {{ request()->routeIs('custom.request') ? 'bg-emerald-200 border-slate-900 toy-shadow-sm text-slate-950 font-black' : 'border-transparent text-slate-700 hover:border-slate-900 hover:bg-slate-100/80' }}">
|
||||
<span>Eigen Model Printen</span>
|
||||
<a href="{{ route('catalog', ['category' => 'pokemon-3d']) }}" class="px-3.5 py-2 rounded-xl transition hover:bg-slate-100 text-slate-700">
|
||||
Pokémon ⚡
|
||||
</a>
|
||||
<a href="{{ route('catalog', ['category' => 'film-popculture']) }}" class="px-3.5 py-2 rounded-xl transition hover:bg-slate-100 text-slate-700">
|
||||
Film & Gaming 🎬
|
||||
</a>
|
||||
<a href="{{ route('custom.request') }}" class="px-3.5 py-2 rounded-xl transition bg-rose-50 text-rose-600 hover:bg-rose-100 font-black flex items-center space-x-1">
|
||||
<span>Eigen Model Bestellen</span>
|
||||
<span>🚀</span>
|
||||
</a>
|
||||
<a href="{{ route('admin.makerworld.index') }}" class="px-4 py-2 rounded-2xl transition border-2 border-slate-900 bg-rose-500 text-white font-black toy-shadow-sm hover:bg-rose-600 flex items-center space-x-1.5">
|
||||
<i data-lucide="layers" class="w-4 h-4"></i>
|
||||
<span>MakerWorld Importer ✨</span>
|
||||
<a href="{{ route('admin.makerworld.index') }}" class="px-3 py-1.5 rounded-xl transition bg-slate-900 text-white text-xs font-bold hover:bg-slate-800 ml-2">
|
||||
<span>MakerWorld Importer</span>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Right Action Bar -->
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="flex items-center space-x-2 sm:space-x-3">
|
||||
|
||||
<!-- Search Bar in Header -->
|
||||
<!-- Search Bar in Header (Desktop) -->
|
||||
<form action="{{ route('catalog') }}" method="GET" class="hidden md:flex items-center relative">
|
||||
<input
|
||||
type="text"
|
||||
name="q"
|
||||
value="{{ request('q') }}"
|
||||
placeholder="Zoek speelgoed, gadgets, vazen..."
|
||||
class="w-60 bg-amber-50/60 border-2 border-slate-900 rounded-2xl pl-9 pr-3.5 py-2 text-xs font-bold text-slate-900 placeholder-slate-400 focus:bg-white focus:outline-none focus:ring-2 focus:ring-amber-400 transition"
|
||||
placeholder="Zoek fidget, Pokémon..."
|
||||
class="w-48 lg:w-56 bg-slate-100/80 border border-slate-200 rounded-xl pl-8 pr-3 py-2 text-xs font-bold text-slate-900 placeholder-slate-400 focus:bg-white focus:outline-none focus:ring-2 focus:ring-rose-400 transition"
|
||||
>
|
||||
<i data-lucide="search" class="w-4 h-4 text-slate-500 absolute left-3 pointer-events-none"></i>
|
||||
<i data-lucide="search" class="w-3.5 h-3.5 text-slate-400 absolute left-2.5 pointer-events-none"></i>
|
||||
</form>
|
||||
|
||||
<!-- Chunky Toy Cart Button -->
|
||||
<!-- Cart Button with Counter -->
|
||||
@php
|
||||
$cartItems = is_array(session('cart')) ? session('cart') : [];
|
||||
$cartCount = array_sum(array_column($cartItems, 'quantity'));
|
||||
@endphp
|
||||
<a href="{{ route('cart.index') }}" class="toy-btn relative px-4 py-2 rounded-2xl border-2 border-slate-900 bg-amber-300 hover:bg-amber-400 text-slate-950 toy-shadow flex items-center space-x-2 font-black group">
|
||||
<a href="{{ route('cart.index') }}" class="playful-btn relative px-3 sm:px-4 py-2 rounded-2xl bg-gradient-to-r from-amber-300 to-amber-400 hover:from-amber-400 hover:to-amber-500 text-slate-950 font-black text-xs flex items-center space-x-1.5 shadow-sm shadow-amber-500/20 group">
|
||||
<span class="text-base group-hover:scale-110 transition-transform">🛒</span>
|
||||
<span class="text-xs hidden sm:inline">Mandje</span>
|
||||
<span class="hidden sm:inline font-bold">Mandje</span>
|
||||
@if($cartCount > 0)
|
||||
<span class="inline-flex items-center justify-center px-2 py-0.5 text-xs font-black text-white bg-rose-500 border border-slate-900 rounded-full animate-bounce">
|
||||
<span class="inline-flex items-center justify-center px-1.5 py-0.5 text-[10px] font-black text-white bg-rose-500 rounded-full animate-bounce">
|
||||
{{ $cartCount }}
|
||||
</span>
|
||||
@endif
|
||||
</a>
|
||||
|
||||
<!-- Mobile Menu Trigger -->
|
||||
<button @click="mobileMenuOpen = !mobileMenuOpen" type="button" class="lg:hidden p-2.5 rounded-2xl border-2 border-slate-900 bg-white text-slate-900 hover:bg-slate-50">
|
||||
<i data-lucide="menu" class="w-5 h-5"></i>
|
||||
<button @click="mobileMenuOpen = !mobileMenuOpen" type="button" class="lg:hidden p-2 rounded-xl bg-slate-100 hover:bg-slate-200 text-slate-800 transition">
|
||||
<i data-lucide="menu" class="w-6 h-6"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mobile Menu Dropdown -->
|
||||
<div x-show="mobileMenuOpen" x-cloak class="lg:hidden border-t-2 border-slate-900 bg-[#FFFDF7] px-4 pt-4 pb-6 space-y-3">
|
||||
<form action="{{ route('catalog') }}" method="GET" class="flex items-center relative mb-3">
|
||||
<!-- Mobile Menu Drawer (100% Touch Friendly) -->
|
||||
<div x-show="mobileMenuOpen" x-cloak class="lg:hidden border-t border-slate-200 bg-white/98 backdrop-blur-md px-4 pt-3 pb-6 space-y-3 shadow-lg">
|
||||
<form action="{{ route('catalog') }}" method="GET" class="flex items-center relative mb-2">
|
||||
<input
|
||||
type="text"
|
||||
name="q"
|
||||
value="{{ request('q') }}"
|
||||
placeholder="Zoek speelgoed, vazen..."
|
||||
class="w-full bg-white border-2 border-slate-900 rounded-2xl pl-9 pr-3.5 py-2.5 text-xs font-bold placeholder-slate-400"
|
||||
placeholder="Zoek fidgets, Pokémon, figuren..."
|
||||
class="w-full bg-slate-100 border border-slate-200 rounded-xl pl-9 pr-3.5 py-2.5 text-xs font-bold placeholder-slate-400"
|
||||
>
|
||||
<i data-lucide="search" class="w-4 h-4 text-slate-500 absolute left-3"></i>
|
||||
<i data-lucide="search" class="w-4 h-4 text-slate-400 absolute left-3"></i>
|
||||
</form>
|
||||
<div class="flex flex-col space-y-2 font-black">
|
||||
<a href="{{ route('home') }}" class="px-4 py-2.5 rounded-2xl border-2 border-slate-900 bg-amber-300 text-sm">Home 🏠</a>
|
||||
<a href="{{ route('catalog') }}" class="px-4 py-2.5 rounded-2xl border-2 border-slate-900 bg-sky-200 text-sm">Alle 3D Prints 🎁</a>
|
||||
<a href="{{ route('custom.request') }}" class="px-4 py-2.5 rounded-2xl border-2 border-slate-900 bg-emerald-200 text-sm flex items-center space-x-2">
|
||||
<span>Eigen Model Printen</span>
|
||||
<div class="flex flex-col space-y-1.5 font-bold text-sm">
|
||||
<a href="{{ route('home') }}" class="px-3.5 py-2.5 rounded-xl hover:bg-slate-50 flex items-center justify-between">
|
||||
<span>Home 🏠</span>
|
||||
</a>
|
||||
<a href="{{ route('catalog', ['category' => 'fidget-toys']) }}" class="px-3.5 py-2.5 rounded-xl hover:bg-slate-50 flex items-center justify-between text-indigo-600">
|
||||
<span>Fidget Toys & Slugs 🌀</span>
|
||||
<span class="text-xs bg-indigo-50 px-2 py-0.5 rounded-md font-bold">Populier</span>
|
||||
</a>
|
||||
<a href="{{ route('catalog', ['category' => 'pokemon-3d']) }}" class="px-3.5 py-2.5 rounded-xl hover:bg-slate-50 flex items-center justify-between text-amber-600">
|
||||
<span>Pokémon 3D Prints ⚡</span>
|
||||
<span class="text-xs bg-amber-50 px-2 py-0.5 rounded-md font-bold">Trending</span>
|
||||
</a>
|
||||
<a href="{{ route('catalog', ['category' => 'film-popculture']) }}" class="px-3.5 py-2.5 rounded-xl hover:bg-slate-50 flex items-center justify-between text-rose-600">
|
||||
<span>Film, Gaming & Popculture 🎬</span>
|
||||
</a>
|
||||
<a href="{{ route('custom.request') }}" class="px-3.5 py-3 rounded-2xl bg-gradient-to-r from-rose-500 to-indigo-600 text-white font-black flex items-center justify-between shadow-sm shadow-rose-500/20">
|
||||
<span>Eigen 3D Model Bestellen (Upload STL)</span>
|
||||
<span>🚀</span>
|
||||
</a>
|
||||
<a href="{{ route('admin.makerworld.index') }}" class="px-4 py-2.5 rounded-2xl border-2 border-slate-900 bg-rose-500 text-white text-sm flex items-center space-x-2">
|
||||
<i data-lucide="layers" class="w-4 h-4"></i>
|
||||
<span>MakerWorld Importer ✨</span>
|
||||
<a href="{{ route('admin.makerworld.index') }}" class="px-3.5 py-2 text-xs font-bold text-slate-500 hover:text-slate-800 flex items-center space-x-1.5 pt-2 border-t border-slate-100">
|
||||
<i data-lucide="layers" class="w-3.5 h-3.5"></i>
|
||||
<span>MakerWorld Importer Beheer</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -157,21 +167,21 @@
|
||||
|
||||
<!-- Global Flash Alerts -->
|
||||
@if(session('success'))
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-5">
|
||||
<div class="p-4 rounded-3xl bg-emerald-300 border-2 border-slate-900 toy-shadow text-slate-950 text-sm font-extrabold flex items-center justify-between">
|
||||
<div class="flex items-center space-x-3">
|
||||
<span class="text-xl">🎉</span>
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-4">
|
||||
<div class="p-3.5 sm:p-4 rounded-2xl bg-emerald-50 border border-emerald-200 text-emerald-900 text-xs sm:text-sm font-bold flex items-center justify-between shadow-xs">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="text-lg">🎉</span>
|
||||
<span>{{ session('success') }}</span>
|
||||
</div>
|
||||
<a href="{{ route('cart.index') }}" class="px-3 py-1 bg-white border-2 border-slate-900 rounded-xl text-xs font-black hover:bg-slate-100 transition">Naar winkelwagen →</a>
|
||||
<a href="{{ route('cart.index') }}" class="px-3 py-1 bg-white border border-emerald-300 rounded-xl text-xs font-black text-emerald-800 hover:bg-emerald-100 transition">Winkelmandje →</a>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if(session('error'))
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-5">
|
||||
<div class="p-4 rounded-3xl bg-rose-300 border-2 border-slate-900 toy-shadow text-slate-950 text-sm font-extrabold flex items-center space-x-3">
|
||||
<span class="text-xl">⚠️</span>
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-4">
|
||||
<div class="p-3.5 sm:p-4 rounded-2xl bg-rose-50 border border-rose-200 text-rose-900 text-xs sm:text-sm font-bold flex items-center space-x-2 shadow-xs">
|
||||
<span class="text-lg">⚠️</span>
|
||||
<span>{{ session('error') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -182,90 +192,86 @@
|
||||
@yield('content')
|
||||
</main>
|
||||
|
||||
<!-- Playful Friendly Footer -->
|
||||
<footer class="bg-slate-900 text-white border-t-4 border-amber-400 pt-16 pb-12 mt-16 relative overflow-hidden">
|
||||
<!-- Playful Background Dots -->
|
||||
<div class="absolute inset-0 opacity-5 pointer-events-none" style="background-image: radial-gradient(#ffffff 2px, transparent 2px); background-size: 24px 24px;"></div>
|
||||
<!-- Refined Friendly Footer -->
|
||||
<footer class="bg-slate-900 text-white border-t-2 border-amber-400 pt-12 pb-10 mt-16">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-8 pb-10 border-b border-slate-800">
|
||||
|
||||
<div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-10 pb-12 border-b border-slate-800">
|
||||
|
||||
<!-- Col 1: Brand & Cheerful Info -->
|
||||
<div class="space-y-4 md:col-span-1">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="w-10 h-10 rounded-2xl bg-amber-400 border-2 border-white flex items-center justify-center text-slate-950 font-black">
|
||||
<!-- Col 1: Brand & Info -->
|
||||
<div class="space-y-3 sm:col-span-1">
|
||||
<div class="flex items-center space-x-2.5">
|
||||
<div class="w-9 h-9 rounded-xl bg-gradient-to-tr from-amber-400 to-rose-400 flex items-center justify-center text-white font-black text-sm">
|
||||
✨
|
||||
</div>
|
||||
<span class="font-heading text-2xl font-black text-white tracking-tight">Jouw<span class="text-rose-400">driedee</span>.nl</span>
|
||||
<span class="font-heading text-xl font-black text-white tracking-tight">Jouw<span class="text-rose-400">driedee</span>.nl</span>
|
||||
</div>
|
||||
<p class="text-xs text-slate-300 leading-relaxed font-medium">
|
||||
Dé vrolijke 3D print webshop voor origineel speelgoed, kleurrijke interieurdecoratie, handige bureaugadgets en maatwerk prints!
|
||||
Dé vrolijke 3D print webshop voor originele fidget toys, Pokémon creaties, popculture figuren en custom 3D prints op maat!
|
||||
</p>
|
||||
<div class="inline-flex items-center space-x-2 text-xs font-black text-emerald-300 bg-emerald-950/80 px-3 py-1.5 rounded-full border border-emerald-500/30">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-emerald-400 animate-pulse"></span>
|
||||
<span>Printers draaien op volle toeren! 🖨️</span>
|
||||
<div class="inline-flex items-center space-x-1.5 text-[11px] font-bold text-emerald-300 bg-emerald-950/60 px-2.5 py-1 rounded-full border border-emerald-500/30">
|
||||
<span class="w-2 h-2 rounded-full bg-emerald-400 animate-pulse"></span>
|
||||
<span>Printers online en print-klaar 🖨️</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Col 2: Snelle links -->
|
||||
<div class="space-y-3">
|
||||
<h3 class="font-heading text-sm font-black uppercase tracking-wider text-amber-300">🧸 Speelgoed & Prints</h3>
|
||||
<ul class="space-y-2 text-xs text-slate-300 font-bold">
|
||||
<li><a href="{{ route('catalog') }}" class="hover:text-amber-300 transition flex items-center space-x-1.5"><span>👉</span><span>Alle 3D Prints</span></a></li>
|
||||
<li><a href="{{ route('catalog', ['category' => 'gadgets-speelgoed']) }}" class="hover:text-amber-300 transition flex items-center space-x-1.5"><span>🎮</span><span>Gadgets & Speelgoed</span></a></li>
|
||||
<li><a href="{{ route('catalog', ['category' => 'home-interieur']) }}" class="hover:text-amber-300 transition flex items-center space-x-1.5"><span>🪴</span><span>Home & Vrolijke Vazen</span></a></li>
|
||||
<li><a href="{{ route('catalog', ['category' => 'bureau-tech']) }}" class="hover:text-amber-300 transition flex items-center space-x-1.5"><span>💻</span><span>Bureau & Tech Accessoires</span></a></li>
|
||||
<li><a href="{{ route('custom.request') }}" class="hover:text-amber-300 transition flex items-center space-x-1.5 text-rose-300"><span>🚀</span><span>Eigen CAD/STL Uploaden</span></a></li>
|
||||
<!-- Col 2: Categorieën -->
|
||||
<div class="space-y-2">
|
||||
<h3 class="font-heading text-xs font-black uppercase tracking-wider text-amber-300">🧸 Onze Collectie</h3>
|
||||
<ul class="space-y-1.5 text-xs text-slate-300 font-bold">
|
||||
<li><a href="{{ route('catalog', ['category' => 'fidget-toys']) }}" class="hover:text-amber-300 transition flex items-center space-x-1"><span>🌀</span><span>Fidget Toys & Slugs</span></a></li>
|
||||
<li><a href="{{ route('catalog', ['category' => 'pokemon-3d']) }}" class="hover:text-amber-300 transition flex items-center space-x-1"><span>⚡</span><span>Pokémon 3D Prints</span></a></li>
|
||||
<li><a href="{{ route('catalog', ['category' => 'film-popculture']) }}" class="hover:text-amber-300 transition flex items-center space-x-1"><span>🎬</span><span>Film & Gaming Items</span></a></li>
|
||||
<li><a href="{{ route('custom.request') }}" class="hover:text-amber-300 transition flex items-center space-x-1 text-rose-300 font-black"><span>🚀</span><span>Eigen STL Bestand Bestellen</span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Col 3: Veilige en Vrolijke Materialen -->
|
||||
<div class="space-y-3">
|
||||
<h3 class="font-heading text-sm font-black uppercase tracking-wider text-sky-300">🌈 Onze Materialen</h3>
|
||||
<ul class="space-y-2 text-xs text-slate-300 font-medium">
|
||||
<li class="flex items-center space-x-2">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-emerald-400"></span>
|
||||
<span><strong>Bio-PLA+</strong>: Plantaardig & kindvriendelijk</span>
|
||||
<!-- Col 3: Veilige Materialen -->
|
||||
<div class="space-y-2">
|
||||
<h3 class="font-heading text-xs font-black uppercase tracking-wider text-sky-300">🌈 Kwaliteit & Materialen</h3>
|
||||
<ul class="space-y-1.5 text-xs text-slate-300 font-medium">
|
||||
<li class="flex items-center space-x-1.5">
|
||||
<span class="w-2 h-2 rounded-full bg-emerald-400"></span>
|
||||
<span><strong>Bio-PLA+</strong> (Veilig voor kinderen)</span>
|
||||
</li>
|
||||
<li class="flex items-center space-x-2">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-sky-400"></span>
|
||||
<span><strong>PETG</strong>: Extra sterk & waterdicht</span>
|
||||
<li class="flex items-center space-x-1.5">
|
||||
<span class="w-2 h-2 rounded-full bg-sky-400"></span>
|
||||
<span><strong>PETG Tough</strong> (Slagvast)</span>
|
||||
</li>
|
||||
<li class="flex items-center space-x-2">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-amber-400"></span>
|
||||
<span><strong>Flex-TPU</strong>: Buigzaam en rubberachtig</span>
|
||||
<li class="flex items-center space-x-1.5">
|
||||
<span class="w-2 h-2 rounded-full bg-amber-400"></span>
|
||||
<span><strong>TPU Flex</strong> (Rubberachtig buigzaam)</span>
|
||||
</li>
|
||||
<li class="flex items-center space-x-2">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-purple-400"></span>
|
||||
<span><strong>Silk & Rainbow</strong>: Prachtige glanskleuren</span>
|
||||
<li class="flex items-center space-x-1.5">
|
||||
<span class="w-2 h-2 rounded-full bg-purple-400"></span>
|
||||
<span><strong>Silk Regenboog</strong> (Glanzend effect)</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Col 4: Contact & Klantenservice -->
|
||||
<div class="space-y-3">
|
||||
<h3 class="font-heading text-sm font-black uppercase tracking-wider text-rose-300">💌 Vragen of Ideeën?</h3>
|
||||
<p class="text-xs text-slate-300 font-medium">Wil je een speciale kleur, grotere afmetingen of een print op maat?</p>
|
||||
<div class="p-4 rounded-2xl bg-slate-800 border-2 border-slate-700 text-xs space-y-2 font-bold">
|
||||
<div class="flex items-center space-x-2 text-slate-200">
|
||||
<!-- Col 4: Contact -->
|
||||
<div class="space-y-2">
|
||||
<h3 class="font-heading text-xs font-black uppercase tracking-wider text-rose-300">💌 Service & Bezorging</h3>
|
||||
<p class="text-xs text-slate-300 font-medium">Heb je een speciale wens of custom print verzoek?</p>
|
||||
<div class="p-3 rounded-2xl bg-slate-800/80 border border-slate-700 text-xs space-y-1 font-bold">
|
||||
<div class="flex items-center space-x-1.5 text-slate-200">
|
||||
<span>📧</span>
|
||||
<span>info@jouwdriedee.nl</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2 text-slate-200">
|
||||
<span>🇳🇱</span>
|
||||
<span>Verzending in heel NL & België</span>
|
||||
<div class="flex items-center space-x-1.5 text-slate-200">
|
||||
<span>📦</span>
|
||||
<span>Verzending binnen 2-3 werkdagen</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="pt-8 flex flex-col sm:flex-row items-center justify-between text-xs text-slate-400 font-bold gap-4">
|
||||
<p>© {{ date('Y') }} Jouwdriedee.nl. Met ❤️ geprint in Nederland.</p>
|
||||
<div class="flex items-center space-x-4">
|
||||
<span>💳 Veilig betalen met iDEAL & Bancontact</span>
|
||||
<div class="pt-6 flex flex-col sm:flex-row items-center justify-between text-xs text-slate-400 font-bold gap-3 text-center sm:text-left">
|
||||
<p>© {{ date('Y') }} Jouwdriedee.nl. Alles vers 3D geprint in Nederland.</p>
|
||||
<div class="flex items-center space-x-3">
|
||||
<span>💳 iDEAL & Bancontact</span>
|
||||
<span>•</span>
|
||||
<span>📦 PostNL Track & Trace</span>
|
||||
<span>🚚 PostNL Track & Trace</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,68 +4,96 @@
|
||||
|
||||
@section('content')
|
||||
<!-- Page Header -->
|
||||
<div class="bg-amber-100 border-b-2 border-slate-900 py-8">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
||||
<div class="bg-gradient-to-b from-amber-50 to-[#FFFDF9] border-b border-slate-200/80 py-6 sm:py-8">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col sm:flex-row sm:items-center justify-between gap-3">
|
||||
<div>
|
||||
<div class="inline-flex items-center space-x-1.5 px-3 py-1 rounded-full bg-white border-2 border-slate-900 text-[11px] font-black text-rose-500 toy-shadow-sm mb-2">
|
||||
<div class="inline-flex items-center space-x-1.5 px-3 py-1 rounded-full bg-white border border-slate-200 text-[10px] sm:text-xs font-black text-rose-500 shadow-2xs mb-2">
|
||||
<span>🧸</span>
|
||||
<span>Onze Collectie 3D Prints</span>
|
||||
</div>
|
||||
<h1 class="font-heading text-3xl sm:text-4xl font-black text-slate-900 tracking-tight">Kies Jouw Favoriete Print! 🎁</h1>
|
||||
<p class="text-xs font-bold text-slate-600 mt-1">Filter op categorie of materiaal en bestel direct in jouw favoriete kleur.</p>
|
||||
<h1 class="font-heading text-2xl sm:text-4xl font-black text-slate-900 tracking-tight">Kies Jouw Favoriete Print! 🎁</h1>
|
||||
<p class="text-xs text-slate-500 mt-1">Fidget toys, Pokémon figuren en popculture collectibles vers uit de 3D printer.</p>
|
||||
</div>
|
||||
@if(request()->hasAny(['category', 'material', 'q', 'sort']))
|
||||
<a href="{{ route('catalog') }}" class="toy-btn px-4 py-2 rounded-2xl bg-white border-2 border-slate-900 toy-shadow-sm text-xs font-black text-rose-600 hover:bg-rose-50 flex items-center space-x-1.5 self-start">
|
||||
<a href="{{ route('catalog') }}" class="playful-btn px-3 py-1.5 rounded-xl bg-white border border-slate-200 text-xs font-bold text-rose-600 hover:bg-rose-50 flex items-center space-x-1 self-start shadow-2xs">
|
||||
<span>✕ Filters Wissen</span>
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-10">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-4 gap-8">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 sm:py-10" x-data="{ mobileFiltersOpen: false }">
|
||||
|
||||
<!-- Filters Sidebar (Chunky Toy Box) -->
|
||||
<aside class="space-y-6">
|
||||
<div class="p-6 rounded-3xl bg-white border-2 border-slate-900 toy-shadow space-y-6">
|
||||
<div class="flex items-center justify-between pb-3 border-b-2 border-slate-100">
|
||||
<span class="font-heading text-sm font-black text-slate-900 uppercase tracking-wider flex items-center space-x-2">
|
||||
<span>🔍</span>
|
||||
<span>Zoeken & Filters</span>
|
||||
<!-- Mobile Filter Toggle Bar (Zodat mobiele gebruikers niet 600px omlaag hoeven te scrollen!) -->
|
||||
<div class="lg:hidden mb-4 flex items-center justify-between gap-2">
|
||||
<button
|
||||
type="button"
|
||||
@click="mobileFiltersOpen = !mobileFiltersOpen"
|
||||
class="flex-1 py-2.5 px-4 rounded-xl bg-white border border-slate-200 text-slate-800 text-xs font-bold flex items-center justify-center space-x-2 shadow-2xs"
|
||||
>
|
||||
<i data-lucide="sliders-horizontal" class="w-4 h-4 text-rose-500"></i>
|
||||
<span x-text="mobileFiltersOpen ? 'Verberg Filters' : 'Filters & Categorieën'"></span>
|
||||
@if(request()->hasAny(['category', 'material', 'q']))
|
||||
<span class="w-2 h-2 rounded-full bg-rose-500"></span>
|
||||
@endif
|
||||
</button>
|
||||
|
||||
<!-- Snelle Sortering op Mobiel -->
|
||||
<form action="{{ route('catalog') }}" method="GET" class="w-40">
|
||||
@if(request('category')) <input type="hidden" name="category" value="{{ request('category') }}"> @endif
|
||||
@if(request('material')) <input type="hidden" name="material" value="{{ request('material') }}"> @endif
|
||||
@if(request('q')) <input type="hidden" name="q" value="{{ request('q') }}"> @endif
|
||||
<select name="sort" onchange="this.form.submit()" class="w-full bg-white border border-slate-200 rounded-xl px-2.5 py-2.5 text-xs font-bold text-slate-700 shadow-2xs">
|
||||
<option value="newest" {{ request('sort') === 'newest' ? 'selected' : '' }}>Nieuwste</option>
|
||||
<option value="price_asc" {{ request('sort') === 'price_asc' ? 'selected' : '' }}>Prijs ↑</option>
|
||||
<option value="price_desc" {{ request('sort') === 'price_desc' ? 'selected' : '' }}>Prijs ↓</option>
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-4 gap-6 lg:gap-8">
|
||||
|
||||
<!-- Filters Sidebar (Op mobiel inklapbaar via Alpine.js) -->
|
||||
<aside :class="mobileFiltersOpen ? 'block' : 'hidden lg:block'" class="space-y-4">
|
||||
<div class="p-5 sm:p-6 rounded-3xl bg-white border border-slate-100 shadow-sm space-y-5">
|
||||
<div class="flex items-center justify-between pb-3 border-b border-slate-100">
|
||||
<span class="font-heading text-xs font-black text-slate-900 uppercase tracking-wider flex items-center space-x-1.5">
|
||||
<i data-lucide="filter" class="w-3.5 h-3.5 text-rose-500"></i>
|
||||
<span>Filters & Zoeken</span>
|
||||
</span>
|
||||
@if(request()->hasAny(['category', 'material', 'q', 'sort']))
|
||||
<a href="{{ route('catalog') }}" class="text-[11px] font-black text-rose-500 hover:underline">Wissen</a>
|
||||
<a href="{{ route('catalog') }}" class="text-[11px] font-bold text-rose-500 hover:underline">Wissen</a>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Zoekveld -->
|
||||
<form action="{{ route('catalog') }}" method="GET" class="space-y-5">
|
||||
<form action="{{ route('catalog') }}" method="GET" class="space-y-4">
|
||||
@if(request('category')) <input type="hidden" name="category" value="{{ request('category') }}"> @endif
|
||||
@if(request('material')) <input type="hidden" name="material" value="{{ request('material') }}"> @endif
|
||||
|
||||
<div>
|
||||
<label class="block text-xs font-black text-slate-800 mb-1.5">Zoek op trefwoord</label>
|
||||
<label class="block text-xs font-bold text-slate-700 mb-1.5">Zoeken</label>
|
||||
<div class="relative">
|
||||
<input
|
||||
type="text"
|
||||
name="q"
|
||||
value="{{ request('q') }}"
|
||||
placeholder="Speelgoed, vaas, houder..."
|
||||
class="w-full bg-[#FFFDF7] border-2 border-slate-900 rounded-2xl pl-9 pr-3.5 py-2.5 text-xs font-bold text-slate-900 placeholder-slate-400 focus:bg-white focus:outline-none focus:ring-2 focus:ring-amber-400"
|
||||
placeholder="Draak, Pikachu, Grogu..."
|
||||
class="w-full bg-slate-50 border border-slate-200 rounded-xl pl-8 pr-3 py-2 text-xs font-bold text-slate-900 placeholder-slate-400 focus:bg-white focus:outline-none focus:ring-1 focus:ring-rose-400"
|
||||
>
|
||||
<i data-lucide="search" class="w-4 h-4 text-slate-400 absolute left-3 top-1/2 -translate-y-1/2"></i>
|
||||
<i data-lucide="search" class="w-3.5 h-3.5 text-slate-400 absolute left-2.5 top-1/2 -translate-y-1/2"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Categorie filter -->
|
||||
<div>
|
||||
<label class="block text-xs font-black text-slate-800 mb-2">Categorieën 🧸</label>
|
||||
<div class="space-y-1.5">
|
||||
<a href="{{ route('catalog', array_merge(request()->except('category', 'page'), [])) }}" class="flex items-center justify-between px-3.5 py-2 rounded-xl text-xs font-black transition border-2 {{ !request('category') ? 'bg-amber-300 border-slate-900 text-slate-950 toy-shadow-sm' : 'border-transparent text-slate-700 hover:bg-slate-100' }}">
|
||||
<label class="block text-xs font-bold text-slate-700 mb-2">Categorieën 🧸</label>
|
||||
<div class="space-y-1">
|
||||
<a href="{{ route('catalog', array_merge(request()->except('category', 'page'), [])) }}" class="flex items-center justify-between px-3 py-2 rounded-xl text-xs font-bold transition {{ !request('category') ? 'bg-amber-100 text-amber-950 font-black' : 'text-slate-600 hover:bg-slate-50' }}">
|
||||
<span>Alle categorieën</span>
|
||||
</a>
|
||||
@foreach($categories as $cat)
|
||||
<a href="{{ route('catalog', array_merge(request()->except('category', 'page'), ['category' => $cat->slug])) }}" class="flex items-center justify-between px-3.5 py-2 rounded-xl text-xs font-black transition border-2 {{ request('category') === $cat->slug ? 'bg-amber-300 border-slate-900 text-slate-950 toy-shadow-sm' : 'border-transparent text-slate-700 hover:bg-slate-100' }}">
|
||||
<a href="{{ route('catalog', array_merge(request()->except('category', 'page'), ['category' => $cat->slug])) }}" class="flex items-center justify-between px-3 py-2 rounded-xl text-xs font-bold transition {{ request('category') === $cat->slug ? 'bg-amber-100 text-amber-950 font-black' : 'text-slate-600 hover:bg-slate-50' }}">
|
||||
<span>{{ $cat->name }}</span>
|
||||
</a>
|
||||
@endforeach
|
||||
@@ -74,24 +102,23 @@
|
||||
|
||||
<!-- Materiaal filter -->
|
||||
<div>
|
||||
<label class="block text-xs font-black text-slate-800 mb-2">Materiaal 🌈</label>
|
||||
<div class="space-y-1.5">
|
||||
<a href="{{ route('catalog', array_merge(request()->except('material', 'page'), [])) }}" class="flex items-center justify-between px-3.5 py-2 rounded-xl text-xs font-black transition border-2 {{ !request('material') ? 'bg-sky-200 border-slate-900 text-slate-950 toy-shadow-sm' : 'border-transparent text-slate-700 hover:bg-slate-100' }}">
|
||||
<label class="block text-xs font-bold text-slate-700 mb-2">Materiaal 🌈</label>
|
||||
<div class="space-y-1">
|
||||
<a href="{{ route('catalog', array_merge(request()->except('material', 'page'), [])) }}" class="flex items-center justify-between px-3 py-1.5 rounded-xl text-xs font-bold transition {{ !request('material') ? 'bg-sky-100 text-sky-950 font-black' : 'text-slate-600 hover:bg-slate-50' }}">
|
||||
<span>Alle materialen</span>
|
||||
</a>
|
||||
@foreach($materials as $mat)
|
||||
<a href="{{ route('catalog', array_merge(request()->except('material', 'page'), ['material' => $mat->code])) }}" class="flex items-center justify-between px-3.5 py-2 rounded-xl text-xs font-black transition border-2 {{ request('material') === $mat->code ? 'bg-sky-200 border-slate-900 text-slate-950 toy-shadow-sm' : 'border-transparent text-slate-700 hover:bg-slate-100' }}">
|
||||
<a href="{{ route('catalog', array_merge(request()->except('material', 'page'), ['material' => $mat->code])) }}" class="flex items-center justify-between px-3 py-1.5 rounded-xl text-xs font-bold transition {{ request('material') === $mat->code ? 'bg-sky-100 text-sky-950 font-black' : 'text-slate-600 hover:bg-slate-50' }}">
|
||||
<span>{{ $mat->name }}</span>
|
||||
<span class="text-[10px] px-1.5 py-0.5 rounded bg-white border border-slate-300 font-mono">{{ strtoupper($mat->code) }}</span>
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sortering -->
|
||||
<div>
|
||||
<label class="block text-xs font-black text-slate-800 mb-1.5">Sorteren</label>
|
||||
<select name="sort" onchange="this.form.submit()" class="w-full bg-[#FFFDF7] border-2 border-slate-900 rounded-2xl px-3.5 py-2.5 text-xs font-bold text-slate-900 focus:bg-white focus:outline-none focus:ring-2 focus:ring-amber-400">
|
||||
<!-- Sortering Desktop -->
|
||||
<div class="hidden lg:block">
|
||||
<label class="block text-xs font-bold text-slate-700 mb-1.5">Sorteren</label>
|
||||
<select name="sort" onchange="this.form.submit()" class="w-full bg-slate-50 border border-slate-200 rounded-xl px-3 py-2 text-xs font-bold text-slate-700 focus:bg-white focus:outline-none">
|
||||
<option value="newest" {{ request('sort') === 'newest' ? 'selected' : '' }}>Nieuwste eerst ✨</option>
|
||||
<option value="price_asc" {{ request('sort') === 'price_asc' ? 'selected' : '' }}>Prijs: Laag naar hoog</option>
|
||||
<option value="price_desc" {{ request('sort') === 'price_desc' ? 'selected' : '' }}>Prijs: Hoog naar laag</option>
|
||||
@@ -101,60 +128,61 @@
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Producten Overzicht -->
|
||||
<!-- Producten Overzicht (2 kolommen op mobiel, 3 op desktop) -->
|
||||
<div class="lg:col-span-3 space-y-6">
|
||||
@if($products->isEmpty())
|
||||
<div class="p-12 text-center rounded-3xl bg-white border-2 border-slate-900 toy-shadow space-y-4">
|
||||
<div class="w-16 h-16 rounded-2xl bg-amber-100 border-2 border-slate-900 text-slate-900 flex items-center justify-center mx-auto text-2xl">
|
||||
<div class="p-10 text-center rounded-3xl bg-white border border-slate-100 shadow-sm space-y-3">
|
||||
<div class="w-14 h-14 rounded-2xl bg-amber-50 text-slate-800 flex items-center justify-center mx-auto text-3xl">
|
||||
🙈
|
||||
</div>
|
||||
<h3 class="font-heading text-lg font-black text-slate-900">Geen artikelen gevonden</h3>
|
||||
<p class="text-xs font-medium text-slate-600 max-w-sm mx-auto">Er zijn geen prints gevonden die voldoen aan je huidige filters. Probeer een andere zoekopdracht of bekijk alle prints!</p>
|
||||
<a href="{{ route('catalog') }}" class="toy-btn inline-flex px-6 py-3 rounded-2xl bg-amber-400 border-2 border-slate-900 toy-shadow-sm text-slate-950 text-xs font-black">Alle prints bekijken 🎁</a>
|
||||
<p class="text-xs text-slate-500 max-w-sm mx-auto">Er zijn geen prints gevonden die voldoen aan je huidige filters. Wis je filters of bekijk alle categorieën!</p>
|
||||
<a href="{{ route('catalog') }}" class="playful-btn inline-flex px-5 py-2.5 rounded-xl bg-amber-400 text-slate-950 text-xs font-black shadow-xs">Alle prints bekijken 🎁</a>
|
||||
</div>
|
||||
@else
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 gap-3 sm:gap-6">
|
||||
@foreach($products as $product)
|
||||
<div class="group rounded-3xl bg-[#FFFDF7] border-2 border-slate-900 toy-shadow overflow-hidden flex flex-col justify-between hover:-translate-y-1 transition duration-200">
|
||||
<div class="playful-card rounded-2xl sm:rounded-3xl bg-white border border-slate-100 shadow-xs hover:shadow-lg overflow-hidden flex flex-col justify-between group">
|
||||
<div>
|
||||
<div class="relative h-56 bg-slate-100 border-b-2 border-slate-900 overflow-hidden">
|
||||
<div class="relative h-40 sm:h-56 bg-slate-100 overflow-hidden">
|
||||
<img
|
||||
src="{{ $product->image_url }}"
|
||||
alt="{{ $product->name }}"
|
||||
class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
|
||||
loading="lazy"
|
||||
>
|
||||
@if($product->category)
|
||||
<span class="absolute top-3 left-3 px-2.5 py-1 rounded-xl bg-amber-300 border-2 border-slate-900 text-[10px] font-black text-slate-950 toy-shadow-sm">
|
||||
<span class="absolute top-2 left-2 sm:top-3 sm:left-3 px-2 py-0.5 rounded-md bg-white/90 backdrop-blur-xs text-[9px] sm:text-[10px] font-black text-slate-800 shadow-2xs">
|
||||
{{ $product->category->name }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
<div class="p-5">
|
||||
<h3 class="font-heading text-base font-black text-slate-900 group-hover:text-rose-600 transition">
|
||||
<div class="p-3 sm:p-4">
|
||||
<h3 class="font-heading text-xs sm:text-sm font-black text-slate-900 group-hover:text-rose-600 transition line-clamp-2">
|
||||
<a href="{{ route('product.show', $product->slug) }}">
|
||||
{{ $product->name }}
|
||||
</a>
|
||||
</h3>
|
||||
<p class="text-xs text-slate-600 mt-1 line-clamp-2 leading-relaxed font-medium">
|
||||
<p class="hidden sm:block text-xs text-slate-500 mt-1 line-clamp-2 leading-relaxed">
|
||||
{{ $product->short_description }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-5 pt-0 border-t-2 border-slate-100 mt-2 flex items-center justify-between">
|
||||
<div class="p-3 sm:p-4 pt-0 border-t border-slate-100/80 mt-1 flex items-center justify-between">
|
||||
<div>
|
||||
<span class="text-[10px] text-slate-500 block font-bold uppercase">Vanaf</span>
|
||||
<span class="font-heading text-lg font-black text-slate-900">{{ $product->formatted_price }}</span>
|
||||
<span class="text-[9px] sm:text-[10px] text-slate-400 block font-bold uppercase">Vanaf</span>
|
||||
<span class="font-heading text-sm sm:text-base font-black text-slate-900">{{ $product->formatted_price }}</span>
|
||||
</div>
|
||||
<a href="{{ route('product.show', $product->slug) }}" class="toy-btn px-4 py-2 rounded-2xl bg-amber-400 hover:bg-amber-300 border-2 border-slate-900 toy-shadow-sm text-slate-950 text-xs font-black transition flex items-center space-x-1">
|
||||
<span>Kies Kleur 🎨</span>
|
||||
<a href="{{ route('product.show', $product->slug) }}" class="playful-btn px-2.5 sm:px-3 py-1 sm:py-1.5 rounded-xl bg-amber-400 hover:bg-amber-300 text-slate-950 text-[10px] sm:text-xs font-black transition flex items-center space-x-1 shadow-2xs">
|
||||
<span>Kleur 🎨</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="pt-6">
|
||||
<div class="pt-4">
|
||||
{{ $products->links() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@@ -1,94 +1,296 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Eigen 3D Model Printen (STL / STEP Upload) | Jouwdriedee.nl')
|
||||
@section('title', 'Eigen 3D Model Bestellen (STL / 3MF Upload) 🚀 | Jouwdriedee.nl')
|
||||
|
||||
@section('content')
|
||||
<div class="bg-gradient-to-b from-slate-900 to-indigo-950 text-white py-12">
|
||||
<!-- Header Banner -->
|
||||
<div class="bg-gradient-to-b from-amber-50 to-[#FFFDF9] border-b border-slate-200/80 py-8 sm:py-12">
|
||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center space-y-3">
|
||||
<span class="px-3 py-1 rounded-full bg-indigo-500/20 text-indigo-300 border border-indigo-500/30 text-xs font-bold inline-flex items-center space-x-1.5">
|
||||
<i data-lucide="layers" class="w-3.5 h-3.5"></i>
|
||||
<span>3D Print op Aanvraag</span>
|
||||
<span class="px-3 py-1 rounded-full bg-rose-100 text-rose-700 text-xs font-black inline-flex items-center space-x-1.5 shadow-2xs">
|
||||
<span>🚀</span>
|
||||
<span>Direct 3D Printen op Bestelling</span>
|
||||
</span>
|
||||
<h1 class="text-3xl sm:text-4xl font-black tracking-tight">Upload Jouw Eigen 3D-Bestand</h1>
|
||||
<p class="text-xs sm:text-sm text-slate-300 max-w-xl mx-auto leading-relaxed">
|
||||
Heb je een STL, STEP of OBJ bestand van Thingiverse, Printables of je eigen CAD-ontwerp? Upload het hieronder en ontvang binnen 24 uur een vrijblijvende prijsopgave.
|
||||
<h1 class="font-heading text-3xl sm:text-5xl font-black text-slate-900 tracking-tight">Bestel Jouw Eigen 3D Model!</h1>
|
||||
<p class="text-xs sm:text-sm text-slate-600 max-w-xl mx-auto leading-relaxed font-medium">
|
||||
Heb je een gaaf 3D bestand gevonden op MakerWorld, Printables, Thingiverse of zelf ontworpen? Upload jouw bestand of plak de link, kies je kleur en bestel direct online!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 py-10">
|
||||
<div class="p-8 rounded-3xl bg-white border border-slate-200 shadow-md space-y-6">
|
||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-8 sm:py-12"
|
||||
x-data="{
|
||||
activeTab: 'direct', // 'direct' of 'offerte'
|
||||
selectedSize: 'medium',
|
||||
sizePrices: {
|
||||
'klein': 9.95, // tot 8 cm
|
||||
'medium': 16.95, // tot 15 cm
|
||||
'groot': 24.95 // tot 22 cm
|
||||
},
|
||||
selectedMaterial: 'pla',
|
||||
materialMultipliers: {
|
||||
@foreach($materials as $mat)
|
||||
'{{ $mat->code }}': {{ $mat->price_multiplier }},
|
||||
@endforeach
|
||||
},
|
||||
selectedColor: '{{ $colors[0]->name ?? 'Zon Geel (Pikachu)' }}',
|
||||
quantity: 1,
|
||||
|
||||
<form action="{{ route('custom.store') }}" method="POST" enctype="multipart/form-data" class="space-y-6">
|
||||
get calculatedTotal() {
|
||||
let base = this.sizePrices[this.selectedSize] || 16.95;
|
||||
let mult = this.materialMultipliers[this.selectedMaterial] || 1.0;
|
||||
return ((base * mult) * this.quantity).toFixed(2).replace('.', ',');
|
||||
},
|
||||
get unitPrice() {
|
||||
let base = this.sizePrices[this.selectedSize] || 16.95;
|
||||
let mult = this.materialMultipliers[this.selectedMaterial] || 1.0;
|
||||
return (base * mult).toFixed(2).replace('.', ',');
|
||||
}
|
||||
}">
|
||||
|
||||
<!-- Tab Selector -->
|
||||
<div class="flex items-center justify-center p-1.5 bg-slate-100 rounded-2xl max-w-md mx-auto mb-8">
|
||||
<button
|
||||
type="button"
|
||||
@click="activeTab = 'direct'"
|
||||
:class="activeTab === 'direct' ? 'bg-white text-slate-900 shadow-sm font-black' : 'text-slate-600 hover:text-slate-900 font-bold'"
|
||||
class="flex-1 py-2.5 px-4 rounded-xl text-xs transition flex items-center justify-center space-x-1.5"
|
||||
>
|
||||
<span>🛒</span>
|
||||
<span>Direct Bestellen & Afrekenen</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
@click="activeTab = 'offerte'"
|
||||
:class="activeTab === 'offerte' ? 'bg-white text-slate-900 shadow-sm font-black' : 'text-slate-600 hover:text-slate-900 font-bold'"
|
||||
class="flex-1 py-2.5 px-4 rounded-xl text-xs transition flex items-center justify-center space-x-1.5"
|
||||
>
|
||||
<span>💬</span>
|
||||
<span>Vrijblijvende Prijsopgave</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- TAB 1: DIRECT BESTELLEN EN IN WINKELWAGEN -->
|
||||
<div x-show="activeTab === 'direct'" class="p-6 sm:p-10 rounded-3xl bg-white border border-slate-100 shadow-xl shadow-slate-200/50 space-y-8">
|
||||
|
||||
<form action="{{ route('custom.cart.add') }}" method="POST" enctype="multipart/form-data" class="space-y-6">
|
||||
@csrf
|
||||
|
||||
<!-- 1. Model bron: Bestand of Link -->
|
||||
<div class="space-y-4">
|
||||
<div class="border-b border-slate-100 pb-3">
|
||||
<h3 class="font-heading text-base font-black text-slate-900 flex items-center space-x-2">
|
||||
<span>1️⃣</span>
|
||||
<span>Upload 3D Bestand of vul een Model-Link in</span>
|
||||
</h3>
|
||||
<p class="text-xs text-slate-500 mt-0.5">Ondersteunt STL, 3MF, STEP, OBJ of directe links van MakerWorld, Printables en Thingiverse.</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<!-- Bestand upload -->
|
||||
<div class="p-4 rounded-2xl bg-slate-50 border border-slate-200 hover:border-rose-400 transition">
|
||||
<label class="block text-xs font-black text-slate-800 mb-1 flex items-center space-x-1">
|
||||
<span>📁</span>
|
||||
<span>Bestand uploaden (.stl, .3mf, .step, .obj)</span>
|
||||
</label>
|
||||
<input type="file" name="model_file" accept=".stl,.step,.stp,.obj,.3mf,.zip" class="w-full text-xs text-slate-600 file:mr-3 file:py-1.5 file:px-3 file:rounded-xl file:border-0 file:text-xs file:font-bold file:bg-rose-500 file:text-white hover:file:bg-rose-600 cursor-pointer">
|
||||
<span class="text-[10px] text-slate-400 block mt-1">Max. 50MB</span>
|
||||
</div>
|
||||
|
||||
<!-- Of URL -->
|
||||
<div class="p-4 rounded-2xl bg-slate-50 border border-slate-200 hover:border-rose-400 transition">
|
||||
<label class="block text-xs font-black text-slate-800 mb-1 flex items-center space-x-1">
|
||||
<span>🔗</span>
|
||||
<span>Of plak een MakerWorld / Printables link</span>
|
||||
</label>
|
||||
<input type="url" name="model_url" placeholder="https://makerworld.com/nl/models/..." class="w-full bg-white border border-slate-200 rounded-xl px-3 py-2 text-xs font-medium placeholder-slate-400 focus:outline-none focus:ring-1 focus:ring-rose-400">
|
||||
<span class="text-[10px] text-slate-400 block mt-1">Wij halen het 3D model direct binnen</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-slate-700 mb-1">Naam of titel van het model (optioneel)</label>
|
||||
<input type="text" name="model_name" placeholder="Bijv. Pikachu sleutelhanger of Fidget Spinner" class="w-full bg-slate-50 border border-slate-200 rounded-xl px-3 py-2 text-xs font-medium text-slate-800 focus:bg-white focus:outline-none">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. Formaat & Afmeting -->
|
||||
<div class="space-y-3">
|
||||
<div class="border-b border-slate-100 pb-2">
|
||||
<h3 class="font-heading text-base font-black text-slate-900 flex items-center space-x-2">
|
||||
<span>2️⃣</span>
|
||||
<span>Kies het gewenste formaat</span>
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="size" x-model="selectedSize">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-3 gap-3">
|
||||
<button
|
||||
type="button"
|
||||
@click="selectedSize = 'klein'"
|
||||
:class="selectedSize === 'klein' ? 'border-rose-500 bg-rose-50 ring-2 ring-rose-400 font-black' : 'border-slate-200 hover:bg-slate-50 font-bold'"
|
||||
class="p-4 rounded-2xl border text-left transition cursor-pointer flex flex-col justify-between"
|
||||
>
|
||||
<div>
|
||||
<span class="text-xs font-black text-slate-900 block">Klein (tot 8 cm)</span>
|
||||
<span class="text-[11px] text-slate-500 block mt-0.5">Sleutelhangers, munten, miniatuurtjes</span>
|
||||
</div>
|
||||
<span class="font-heading text-base font-black text-rose-600 mt-2 block">€ 9,95</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
@click="selectedSize = 'medium'"
|
||||
:class="selectedSize === 'medium' ? 'border-rose-500 bg-rose-50 ring-2 ring-rose-400 font-black' : 'border-slate-200 hover:bg-slate-50 font-bold'"
|
||||
class="p-4 rounded-2xl border text-left transition cursor-pointer flex flex-col justify-between"
|
||||
>
|
||||
<div>
|
||||
<span class="text-xs font-black text-slate-900 block">Medium (tot 15 cm) 🔥</span>
|
||||
<span class="text-[11px] text-slate-500 block mt-0.5">Figuren, plantenpotjes, bureau-items</span>
|
||||
</div>
|
||||
<span class="font-heading text-base font-black text-rose-600 mt-2 block">€ 16,95</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
@click="selectedSize = 'groot'"
|
||||
:class="selectedSize === 'groot' ? 'border-rose-500 bg-rose-50 ring-2 ring-rose-400 font-black' : 'border-slate-200 hover:bg-slate-50 font-bold'"
|
||||
class="p-4 rounded-2xl border text-left transition cursor-pointer flex flex-col justify-between"
|
||||
>
|
||||
<div>
|
||||
<span class="text-xs font-black text-slate-900 block">Groot (tot 22 cm)</span>
|
||||
<span class="text-[11px] text-slate-500 block mt-0.5">Grote beelden, cosplay, vazen</span>
|
||||
</div>
|
||||
<span class="font-heading text-base font-black text-rose-600 mt-2 block">€ 24,95</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. Materiaal & Kleur -->
|
||||
<div class="space-y-4">
|
||||
<div class="border-b border-slate-100 pb-2">
|
||||
<h3 class="font-heading text-base font-black text-slate-900 flex items-center space-x-2">
|
||||
<span>3️⃣</span>
|
||||
<span>Kies Materiaal & Kleur</span>
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<!-- Materiaal -->
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-slate-700 mb-1.5">Materiaal</label>
|
||||
<select name="material" x-model="selectedMaterial" class="w-full bg-slate-50 border border-slate-200 rounded-xl px-3 py-2.5 text-xs font-bold text-slate-800 focus:bg-white focus:outline-none">
|
||||
@foreach($materials as $mat)
|
||||
<option value="{{ $mat->code }}">{{ $mat->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Kleur -->
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-slate-700 mb-1.5">Printkleur: <span class="text-rose-500 font-black" x-text="selectedColor"></span></label>
|
||||
<input type="hidden" name="color" x-model="selectedColor">
|
||||
<div class="flex flex-wrap gap-2 pt-1">
|
||||
@foreach($colors as $c)
|
||||
<button
|
||||
type="button"
|
||||
@click="selectedColor = '{{ $c->name }}'"
|
||||
:class="selectedColor === '{{ $c->name }}' ? 'ring-3 ring-rose-500 ring-offset-2 scale-110' : 'hover:scale-105 border-slate-300'"
|
||||
class="w-7 h-7 rounded-xl border shadow-2xs transition flex items-center justify-center cursor-pointer relative"
|
||||
style="background-color: {{ $c->hex }};"
|
||||
title="{{ $c->name }}"
|
||||
>
|
||||
<template x-if="selectedColor === '{{ $c->name }}'">
|
||||
<i data-lucide="check" class="w-3.5 h-3.5 {{ in_array($c->name, ['Sneeuwwit', 'Zon Geel (Pikachu)']) ? 'text-slate-950' : 'text-white' }} stroke-[3]"></i>
|
||||
</template>
|
||||
</button>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-slate-700 mb-1">Optionele opmerkingen / afmetingen</label>
|
||||
<textarea name="notes" rows="2" placeholder="Bijv. exact 12cm hoog maken, extra stevige infill gewenst, etc." class="w-full bg-slate-50 border border-slate-200 rounded-xl p-3 text-xs text-slate-800 focus:bg-white focus:outline-none"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. Prijs & Bestelknop -->
|
||||
<div class="p-5 rounded-2xl bg-gradient-to-r from-amber-50 via-rose-50 to-indigo-50 border border-amber-200/80 flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
<div>
|
||||
<span class="text-[10px] font-bold text-slate-500 uppercase tracking-wider block">Berekende Stukprijs</span>
|
||||
<div class="flex items-baseline space-x-2">
|
||||
<span class="font-heading text-3xl font-black text-slate-900">€ <span x-text="unitPrice"></span></span>
|
||||
<span class="text-xs text-slate-500">incl. btw & materiaal</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-3 w-full sm:w-auto">
|
||||
<!-- Aantal -->
|
||||
<div class="flex items-center border border-slate-200 rounded-xl bg-white overflow-hidden shadow-2xs">
|
||||
<button type="button" @click="if (quantity > 1) quantity--" class="px-3 py-2 text-slate-700 font-black cursor-pointer text-sm hover:bg-slate-100">-</button>
|
||||
<span class="px-3 py-2 font-heading font-black text-xs text-slate-900" x-text="quantity"></span>
|
||||
<input type="hidden" name="quantity" x-model="quantity">
|
||||
<button type="button" @click="if (quantity < 20) quantity++" class="px-3 py-2 text-slate-700 font-black cursor-pointer text-sm hover:bg-slate-100">+</button>
|
||||
</div>
|
||||
|
||||
<!-- Bestelknop -->
|
||||
<button type="submit" class="playful-btn flex-1 sm:flex-none px-6 py-3.5 rounded-2xl bg-gradient-to-r from-amber-400 via-rose-400 to-rose-500 text-slate-950 font-black text-xs sm:text-sm shadow-md shadow-rose-500/20 flex items-center justify-center space-x-2 cursor-pointer">
|
||||
<span>🛒</span>
|
||||
<span>In Winkelwagen • € <span x-text="calculatedTotal"></span></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- TAB 2: VRIJBLIJVENDE OFFERTE (VOOR MAATWERK & ADVIES) -->
|
||||
<div x-show="activeTab === 'offerte'" class="p-6 sm:p-10 rounded-3xl bg-white border border-slate-100 shadow-xl shadow-slate-200/50 space-y-6">
|
||||
<div class="border-b border-slate-100 pb-3">
|
||||
<h3 class="font-heading text-lg font-black text-slate-900">Vrijblijvende Prijsopgave & Maatwerk Advies</h3>
|
||||
<p class="text-xs text-slate-500 mt-1">Voor grotere series, mechanische onderdelen of technisch advies. We reageren binnen 24 uur met een scherpe offerte.</p>
|
||||
</div>
|
||||
|
||||
<form action="{{ route('custom.store') }}" method="POST" enctype="multipart/form-data" class="space-y-5">
|
||||
@csrf
|
||||
|
||||
<!-- Contactgegevens -->
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-1.5">Naam *</label>
|
||||
<input type="text" name="name" required value="{{ old('name') }}" placeholder="Bijv. Jan de Vries" class="w-full bg-slate-50 border border-slate-200 rounded-xl px-3.5 py-2.5 text-xs text-slate-900 focus:bg-white focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||
<label class="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-1">Naam *</label>
|
||||
<input type="text" name="name" required value="{{ old('name') }}" placeholder="Bijv. Jan de Vries" class="w-full bg-slate-50 border border-slate-200 rounded-xl px-3.5 py-2.5 text-xs text-slate-900 focus:bg-white focus:outline-none">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-1.5">E-mailadres *</label>
|
||||
<input type="email" name="email" required value="{{ old('email') }}" placeholder="jouw@email.nl" class="w-full bg-slate-50 border border-slate-200 rounded-xl px-3.5 py-2.5 text-xs text-slate-900 focus:bg-white focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||
<label class="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-1">E-mailadres *</label>
|
||||
<input type="email" name="email" required value="{{ old('email') }}" placeholder="jouw@email.nl" class="w-full bg-slate-50 border border-slate-200 rounded-xl px-3.5 py-2.5 text-xs text-slate-900 focus:bg-white focus:outline-none">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-1.5">Telefoonnummer (optioneel)</label>
|
||||
<input type="text" name="phone" value="{{ old('phone') }}" placeholder="06-12345678" class="w-full bg-slate-50 border border-slate-200 rounded-xl px-3.5 py-2.5 text-xs text-slate-900 focus:bg-white focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||
<label class="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-1">Telefoonnummer (optioneel)</label>
|
||||
<input type="text" name="phone" value="{{ old('phone') }}" placeholder="06-12345678" class="w-full bg-slate-50 border border-slate-200 rounded-xl px-3.5 py-2.5 text-xs text-slate-900 focus:bg-white focus:outline-none">
|
||||
</div>
|
||||
|
||||
<!-- Bestand Uploaden -->
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-1.5">3D Model Bestand (.stl, .step, .obj, .zip)</label>
|
||||
<div class="p-6 border-2 border-dashed border-slate-300 hover:border-indigo-500 rounded-2xl bg-slate-50/50 text-center transition cursor-pointer">
|
||||
<input type="file" name="model_file" accept=".stl,.step,.stp,.obj,.3mf,.zip" class="w-full text-xs text-slate-500 file:mr-4 file:py-2 file:px-4 file:rounded-xl file:border-0 file:text-xs file:font-bold file:bg-indigo-600 file:text-white hover:file:bg-indigo-500 cursor-pointer">
|
||||
<label class="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-1">3D Model Bestand (.stl, .step, .obj, .zip)</label>
|
||||
<div class="p-6 border-2 border-dashed border-slate-200 hover:border-rose-400 rounded-2xl bg-slate-50/60 text-center transition">
|
||||
<input type="file" name="model_file" accept=".stl,.step,.stp,.obj,.3mf,.zip" class="w-full text-xs text-slate-500 file:mr-4 file:py-2 file:px-4 file:rounded-xl file:border-0 file:text-xs file:font-bold file:bg-rose-500 file:text-white hover:file:bg-rose-600 cursor-pointer">
|
||||
<p class="text-[11px] text-slate-400 mt-2">Ondersteunde formaten: STL, STEP, OBJ, 3MF of ZIP (max 50 MB)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Voorkeuren -->
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-1.5">Gewenst Materiaal</label>
|
||||
<select name="preferred_material" class="w-full bg-slate-50 border border-slate-200 rounded-xl px-3.5 py-2.5 text-xs text-slate-900 focus:bg-white focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||
<option value="Weet ik niet (Adviseer mij)">Weet ik niet (Adviseer mij)</option>
|
||||
@foreach($materials as $mat)
|
||||
<option value="{{ $mat->name }}">{{ $mat->name }} ({{ strtoupper($mat->code) }})</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-1.5">Voorkeurskleur</label>
|
||||
<select name="preferred_color" class="w-full bg-slate-50 border border-slate-200 rounded-xl px-3.5 py-2.5 text-xs text-slate-900 focus:bg-white focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||
<option value="Geen voorkeur">Geen voorkeur / In overleg</option>
|
||||
@foreach($colors as $color)
|
||||
<option value="{{ $color->name }}">{{ $color->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Beschrijving & Wensen -->
|
||||
<div>
|
||||
<label class="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-1.5">Toelichting, Afmetingen & Aantal *</label>
|
||||
<textarea name="description" rows="4" required placeholder="Vermeld eventuele gewenste afmetingen (bv. 10cm hoog), gewenst aantal en toepassing (binnen, buiten, waterdicht, mechanisch belast)..." class="w-full bg-slate-50 border border-slate-200 rounded-xl p-3.5 text-xs text-slate-900 focus:bg-white focus:outline-none focus:ring-1 focus:ring-indigo-500"></textarea>
|
||||
<label class="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-1">Toelichting, Afmetingen & Aantal *</label>
|
||||
<textarea name="description" rows="4" required placeholder="Vermeld gewenste afmetingen, aantal en toepassing..." class="w-full bg-slate-50 border border-slate-200 rounded-xl p-3.5 text-xs text-slate-900 focus:bg-white focus:outline-none"></textarea>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="w-full py-4 rounded-2xl bg-indigo-600 hover:bg-indigo-500 text-white font-bold text-xs uppercase tracking-wider transition shadow-lg shadow-indigo-600/25 flex items-center justify-center space-x-2 cursor-pointer">
|
||||
<button type="submit" class="playful-btn w-full py-4 rounded-2xl bg-gradient-to-r from-rose-500 to-indigo-600 text-white font-black text-xs uppercase tracking-wider transition shadow-md shadow-rose-500/20 flex items-center justify-center space-x-2 cursor-pointer">
|
||||
<i data-lucide="send" class="w-4 h-4"></i>
|
||||
<span>Aanvraag Vrijblijvend Verzenden</span>
|
||||
<span>Aanvraag Vrijblijvend Verzenden ✨</span>
|
||||
</button>
|
||||
|
||||
<p class="text-center text-[11px] text-slate-400">
|
||||
🔒 Jouw bestanden en gegevens worden uitsluitend gebruikt voor de offerteberekening en niet gedeeld met derden.
|
||||
</p>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
|
||||
@@ -1,104 +1,104 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Jouwdriedee.nl 🎨 Dé Speelse 3D Print Webshop')
|
||||
@section('title', 'Jouwdriedee.nl ✨ Dé 3D Print Webshop voor Fidget Toys & Pokémon')
|
||||
|
||||
@section('content')
|
||||
<!-- Hero Section (Vrolijk & Speels) -->
|
||||
<section class="relative overflow-hidden bg-gradient-to-b from-amber-100 via-rose-50 to-[#FFFDF7] border-b-2 border-slate-900 pt-12 pb-20 lg:pt-16 lg:pb-28">
|
||||
<!-- Hero Section (Vrolijk, Modern & Niet Lomp) -->
|
||||
<section class="relative overflow-hidden bg-gradient-to-b from-amber-50/70 via-rose-50/40 to-[#FFFDF9] pt-8 pb-14 sm:pt-14 sm:pb-20 border-b border-slate-200/60">
|
||||
|
||||
<!-- Playful Floating Blobs / Shapes -->
|
||||
<div class="absolute top-10 left-8 w-24 h-24 bg-amber-300/60 rounded-full blur-xl pointer-events-none"></div>
|
||||
<div class="absolute top-1/2 right-12 w-40 h-40 bg-sky-300/50 rounded-full blur-2xl pointer-events-none"></div>
|
||||
<div class="absolute bottom-6 left-1/3 w-32 h-32 bg-rose-300/40 rounded-full blur-xl pointer-events-none"></div>
|
||||
<!-- Subtiele pastel bollen -->
|
||||
<div class="absolute top-6 left-6 w-32 h-32 bg-amber-200/40 rounded-full blur-2xl pointer-events-none"></div>
|
||||
<div class="absolute top-1/2 right-8 w-48 h-48 bg-rose-200/30 rounded-full blur-3xl pointer-events-none"></div>
|
||||
<div class="absolute bottom-4 left-1/3 w-40 h-40 bg-sky-200/30 rounded-full blur-2xl pointer-events-none"></div>
|
||||
|
||||
<div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-12 items-center">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12 items-center">
|
||||
|
||||
<!-- Left Hero Content -->
|
||||
<div class="lg:col-span-7 space-y-6 text-center lg:text-left">
|
||||
<div class="lg:col-span-7 space-y-4 sm:space-y-6 text-center lg:text-left">
|
||||
|
||||
<!-- Playful Pill Badge -->
|
||||
<div class="inline-flex items-center space-x-2 px-4 py-1.5 rounded-full bg-white border-2 border-slate-900 toy-shadow-sm text-slate-900 text-xs font-black">
|
||||
<span class="animate-spin text-sm">✨</span>
|
||||
<span class="tracking-wide">Dé gezelligste 3D printstudio van Nederland!</span>
|
||||
<span class="text-sm">🖨️</span>
|
||||
<!-- Pill Badge -->
|
||||
<div class="inline-flex items-center space-x-2 px-3.5 py-1.5 rounded-full bg-white/90 border border-amber-200 shadow-2xs text-slate-800 text-xs font-black">
|
||||
<span class="animate-pulse text-sm">✨</span>
|
||||
<span class="tracking-wide">Dé gezelligste 3D print webshop van Nederland!</span>
|
||||
</div>
|
||||
|
||||
<h1 class="font-heading text-4xl sm:text-5xl lg:text-6xl font-black tracking-tight text-slate-900 leading-[1.15]">
|
||||
<h1 class="font-heading text-3xl sm:text-5xl lg:text-6xl font-black tracking-tight text-slate-900 leading-[1.18]">
|
||||
Vrolijke 3D prints, <br class="hidden sm:inline">
|
||||
<span class="bg-clip-text text-transparent bg-gradient-to-r from-rose-500 via-purple-600 to-indigo-600">tof speelgoed</span> & gadgets! 🚀
|
||||
<span class="bg-clip-text text-transparent bg-gradient-to-r from-rose-500 via-amber-500 to-indigo-600">fidget toys & Pokémon!</span> 🌀⚡
|
||||
</h1>
|
||||
|
||||
<p class="text-base sm:text-lg text-slate-700 max-w-2xl mx-auto lg:mx-0 font-bold leading-relaxed">
|
||||
Op zoek naar origineel speelgoed, vrolijke woonaccessoires of coole gadgets? Kies jouw lievelingskleur en wij toveren het met onze 3D-printers tot leven! ✨
|
||||
<p class="text-sm sm:text-base text-slate-600 max-w-xl mx-auto lg:mx-0 font-medium leading-relaxed">
|
||||
Op zoek naar een soepel bewegende kristaldraak, een toffe Pikachu plantenbak of film collectibles? Kies je favoriete printkleur of bestel direct jouw eigen 3D model!
|
||||
</p>
|
||||
|
||||
<!-- Action CTA's (Chunky Pressable Toy Buttons) -->
|
||||
<div class="flex flex-col sm:flex-row items-center justify-center lg:justify-start gap-4 pt-3">
|
||||
<a href="{{ route('catalog') }}" class="toy-btn w-full sm:w-auto px-8 py-4 rounded-2xl bg-amber-400 hover:bg-amber-300 border-2 border-slate-900 toy-shadow text-slate-950 font-black text-sm flex items-center justify-center space-x-2">
|
||||
<!-- Action CTA's (Modern, Smooth & Touch Friendly) -->
|
||||
<div class="flex flex-col sm:flex-row items-center justify-center lg:justify-start gap-3 pt-2">
|
||||
<a href="{{ route('catalog') }}" class="playful-btn w-full sm:w-auto px-7 py-3.5 rounded-2xl bg-gradient-to-r from-amber-400 via-rose-400 to-rose-500 hover:opacity-95 text-slate-950 font-black text-sm flex items-center justify-center space-x-2 shadow-md shadow-rose-500/20">
|
||||
<span>Ontdek Alle Prints 🎁</span>
|
||||
<i data-lucide="arrow-right" class="w-4 h-4 stroke-[3]"></i>
|
||||
<i data-lucide="arrow-right" class="w-4 h-4 stroke-[2.5]"></i>
|
||||
</a>
|
||||
<a href="{{ route('custom.request') }}" class="toy-btn w-full sm:w-auto px-8 py-4 rounded-2xl bg-white hover:bg-sky-50 border-2 border-slate-900 toy-shadow text-slate-950 font-black text-sm flex items-center justify-center space-x-2">
|
||||
<span>Upload Eigen STL Model 🚀</span>
|
||||
<a href="{{ route('custom.request') }}" class="playful-btn w-full sm:w-auto px-7 py-3.5 rounded-2xl bg-white hover:bg-slate-50 border border-slate-200 text-slate-800 font-extrabold text-sm flex items-center justify-center space-x-2 shadow-xs">
|
||||
<span>Eigen Model Bestellen 🚀</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Live stats / Badges in Toy Blocks -->
|
||||
<div class="pt-6 grid grid-cols-3 gap-3 max-w-lg mx-auto lg:mx-0">
|
||||
<div class="p-3 bg-white border-2 border-slate-900 rounded-2xl toy-shadow-sm text-center">
|
||||
<div class="text-xl sm:text-2xl font-black text-rose-500 font-heading">100%</div>
|
||||
<div class="text-[11px] font-extrabold text-slate-600">Bio PLA & Veilig</div>
|
||||
<!-- USP badges -->
|
||||
<div class="pt-4 grid grid-cols-3 gap-2 sm:gap-3 max-w-md mx-auto lg:mx-0">
|
||||
<div class="p-2.5 sm:p-3 bg-white/90 border border-slate-100 rounded-2xl shadow-xs text-center">
|
||||
<div class="text-base sm:text-xl font-black text-rose-500 font-heading">100% Bio</div>
|
||||
<div class="text-[10px] sm:text-[11px] font-bold text-slate-500">Kindvriendelijk PLA</div>
|
||||
</div>
|
||||
<div class="p-3 bg-white border-2 border-slate-900 rounded-2xl toy-shadow-sm text-center">
|
||||
<div class="text-xl sm:text-2xl font-black text-indigo-600 font-heading">24+</div>
|
||||
<div class="text-[11px] font-extrabold text-slate-600">Vrolijke Kleuren</div>
|
||||
<div class="p-2.5 sm:p-3 bg-white/90 border border-slate-100 rounded-2xl shadow-xs text-center">
|
||||
<div class="text-base sm:text-xl font-black text-amber-500 font-heading">9+ Kleuren</div>
|
||||
<div class="text-[10px] sm:text-[11px] font-bold text-slate-500">Zijdeglans & Mat</div>
|
||||
</div>
|
||||
<div class="p-3 bg-white border-2 border-slate-900 rounded-2xl toy-shadow-sm text-center">
|
||||
<div class="text-xl sm:text-2xl font-black text-emerald-600 font-heading">2-3 Dagen</div>
|
||||
<div class="text-[11px] font-extrabold text-slate-600">Snel Bezorgd 📦</div>
|
||||
<div class="p-2.5 sm:p-3 bg-white/90 border border-slate-100 rounded-2xl shadow-xs text-center">
|
||||
<div class="text-base sm:text-xl font-black text-indigo-500 font-heading">PostNL</div>
|
||||
<div class="text-[10px] sm:text-[11px] font-bold text-slate-500">2-3 Dagen in huis</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Right Hero Card / Toy Showcase -->
|
||||
<!-- Right Hero Card / Showcase (Verfijnd & Speels) -->
|
||||
<div class="lg:col-span-5 relative">
|
||||
<div class="relative rounded-3xl bg-white border-3 border-slate-900 p-4 toy-shadow-lg transform rotate-1 hover:rotate-0 transition duration-300">
|
||||
<div class="relative rounded-3xl bg-white p-3 sm:p-4 border border-slate-100 shadow-xl shadow-slate-200/50">
|
||||
|
||||
<!-- Sticker in the corner -->
|
||||
<div class="absolute -top-4 -right-4 bg-rose-500 text-white font-black text-xs px-3.5 py-1.5 rounded-full border-2 border-slate-900 toy-shadow-sm rotate-6 z-10 flex items-center space-x-1">
|
||||
<div class="absolute -top-3 -right-2 bg-gradient-to-r from-rose-500 to-amber-500 text-white font-black text-[11px] px-3 py-1 rounded-full shadow-md z-10 flex items-center space-x-1">
|
||||
<span>🔥</span>
|
||||
<span>Favoriet!</span>
|
||||
<span>Favoriet</span>
|
||||
</div>
|
||||
|
||||
<div class="relative h-72 sm:h-80 rounded-2xl overflow-hidden bg-amber-50 border-2 border-slate-900">
|
||||
<div class="relative h-64 sm:h-80 rounded-2xl overflow-hidden bg-slate-100">
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1578749556568-bc2c40e68b61?auto=format&fit=crop&w=1000&q=80"
|
||||
alt="3D print vaas"
|
||||
src="https://images.unsplash.com/photo-1563089145-599997674d42?auto=format&fit=crop&w=1000&q=80"
|
||||
alt="3D Kristaldraak"
|
||||
class="w-full h-full object-cover object-center hover:scale-105 transition-transform duration-500"
|
||||
>
|
||||
|
||||
<div class="absolute bottom-3 left-3 right-3 p-3 rounded-xl bg-white/95 border-2 border-slate-900 toy-shadow-sm flex items-center justify-between">
|
||||
<div class="absolute bottom-2.5 left-2.5 right-2.5 p-3 rounded-xl bg-white/95 backdrop-blur-xs border border-slate-100 shadow-sm flex items-center justify-between">
|
||||
<div>
|
||||
<span class="text-[10px] font-black uppercase text-amber-600">✨ Uitgelichte Print</span>
|
||||
<h3 class="font-heading font-black text-slate-900 text-sm">Origami Speelse Vaas</h3>
|
||||
<span class="text-[10px] font-black uppercase text-amber-600 flex items-center space-x-1">
|
||||
<span>🌀</span>
|
||||
<span>Fidget & Sensory</span>
|
||||
</span>
|
||||
<h3 class="font-heading font-black text-slate-900 text-xs sm:text-sm">Articulated Kristaldraak</h3>
|
||||
</div>
|
||||
<div class="bg-amber-300 px-3 py-1 rounded-xl border border-slate-900 font-heading font-black text-slate-900 text-sm">
|
||||
€ 18,95
|
||||
<div class="bg-amber-100 text-amber-900 px-2.5 py-1 rounded-lg font-heading font-black text-xs sm:text-sm">
|
||||
€ 17,95
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Material tags preview -->
|
||||
<div class="mt-3 flex items-center justify-between text-xs font-bold text-slate-700">
|
||||
<div class="mt-3 flex items-center justify-between text-[11px] font-bold text-slate-500 px-1">
|
||||
<span class="flex items-center space-x-1">
|
||||
<span>🎨</span>
|
||||
<span>Kies jouw favoriete kleur</span>
|
||||
<span>Kies jouw gewenste kleur</span>
|
||||
</span>
|
||||
<span class="flex items-center space-x-1">
|
||||
<span>🌱</span>
|
||||
<span>Milieuvriendelijk PLA</span>
|
||||
<span>100% Veilig Bio-materiaal</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -108,153 +108,146 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Cheerful USP Bar (4 Colorful Toy Blocks) -->
|
||||
<section class="border-b-2 border-slate-900 bg-white py-8">
|
||||
<!-- Categorieën Grid (4 Duidelijke en Toegankelijke Blokken) -->
|
||||
<section class="py-10 sm:py-14 bg-white border-b border-slate-200/60">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
|
||||
<div class="p-4 rounded-2xl bg-amber-100 border-2 border-slate-900 toy-shadow-sm flex items-center space-x-3.5">
|
||||
<div class="text-3xl">🖨️</div>
|
||||
<div>
|
||||
<h4 class="font-heading text-sm font-black text-slate-900">Vers Geprint</h4>
|
||||
<p class="text-xs text-slate-700 font-bold mt-0.5">Speciaal voor jou op bestelling gemaakt.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-4 rounded-2xl bg-sky-100 border-2 border-slate-900 toy-shadow-sm flex items-center space-x-3.5">
|
||||
<div class="text-3xl">🌈</div>
|
||||
<div>
|
||||
<h4 class="font-heading text-sm font-black text-slate-900">Veel Kleuren</h4>
|
||||
<p class="text-xs text-slate-700 font-bold mt-0.5">Zijden glans, mat, pastel & regenboog!</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-4 rounded-2xl bg-emerald-100 border-2 border-slate-900 toy-shadow-sm flex items-center space-x-3.5">
|
||||
<div class="text-3xl">🚚</div>
|
||||
<div>
|
||||
<h4 class="font-heading text-sm font-black text-slate-900">Snelle Bezorging</h4>
|
||||
<p class="text-xs text-slate-700 font-bold mt-0.5">Binnen 2-3 werkdagen via PostNL.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-4 rounded-2xl bg-rose-100 border-2 border-slate-900 toy-shadow-sm flex items-center space-x-3.5">
|
||||
<div class="text-3xl">❤️</div>
|
||||
<div>
|
||||
<h4 class="font-heading text-sm font-black text-slate-900">Top Kwaliteit</h4>
|
||||
<p class="text-xs text-slate-700 font-bold mt-0.5">Met zorg gecontroleerd en afgewerkt.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Categorieën Grid (Chunky Colorful Toy Boxes) -->
|
||||
<section class="py-16 bg-[#FFFDF7]">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex flex-col sm:flex-row sm:items-end justify-between mb-8 gap-4">
|
||||
<div class="flex flex-col sm:flex-row sm:items-end justify-between mb-6 gap-2">
|
||||
<div>
|
||||
<span class="text-xs font-black uppercase tracking-wider text-rose-500 flex items-center space-x-1">
|
||||
<span>🧸</span>
|
||||
<span>Kies een speelse categorie</span>
|
||||
<span>Direct naar categorie</span>
|
||||
</span>
|
||||
<h2 class="font-heading text-3xl font-black text-slate-900 tracking-tight">Wat wil jij vandaag ontdekken?</h2>
|
||||
<h2 class="font-heading text-2xl sm:text-3xl font-black text-slate-900 tracking-tight">Kies jouw favoriete thema</h2>
|
||||
</div>
|
||||
<a href="{{ route('catalog') }}" class="toy-btn px-4 py-2 rounded-2xl bg-white border-2 border-slate-900 toy-shadow-sm text-xs font-black text-slate-900 flex items-center space-x-1.5 self-start sm:self-auto">
|
||||
<span>Alles bekijken</span>
|
||||
<i data-lucide="chevron-right" class="w-4 h-4"></i>
|
||||
<a href="{{ route('catalog') }}" class="text-xs font-bold text-rose-600 hover:text-rose-700 flex items-center space-x-1 self-start sm:self-auto">
|
||||
<span>Bekijk alle 3D prints</span>
|
||||
<i data-lucide="chevron-right" class="w-3.5 h-3.5"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-4">
|
||||
@php
|
||||
$bgColors = ['bg-amber-100', 'bg-rose-100', 'bg-sky-100', 'bg-emerald-100', 'bg-purple-100'];
|
||||
@endphp
|
||||
@foreach($categories as $index => $category)
|
||||
@php $colorClass = $bgColors[$index % count($bgColors)]; @endphp
|
||||
<a href="{{ route('catalog', ['category' => $category->slug]) }}" class="toy-btn group p-5 rounded-3xl {{ $colorClass }} border-2 border-slate-900 toy-shadow text-center flex flex-col items-center justify-between">
|
||||
<div class="w-16 h-16 rounded-2xl bg-white border-2 border-slate-900 flex items-center justify-center mb-3 toy-shadow-sm group-hover:scale-110 group-hover:rotate-3 transition transform text-indigo-600">
|
||||
<i data-lucide="{{ $category->icon }}" class="w-8 h-8 stroke-[2.2]"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-heading text-sm font-black text-slate-900 group-hover:text-rose-600 transition">{{ $category->name }}</h3>
|
||||
<p class="text-[11px] font-bold text-slate-600 mt-1 line-clamp-1">{{ $category->description }}</p>
|
||||
</div>
|
||||
</a>
|
||||
@endforeach
|
||||
<div class="grid grid-cols-2 sm:grid-cols-2 lg:grid-cols-4 gap-3 sm:gap-5">
|
||||
<!-- 1. Fidget Toys -->
|
||||
<a href="{{ route('catalog', ['category' => 'fidget-toys']) }}" class="playful-card p-4 sm:p-5 rounded-3xl bg-gradient-to-br from-indigo-50/80 to-purple-50/80 border border-indigo-100 hover:border-indigo-300 text-left flex flex-col justify-between group shadow-xs">
|
||||
<div class="w-12 h-12 rounded-2xl bg-white shadow-xs flex items-center justify-center mb-3 text-2xl group-hover:scale-110 transition transform">
|
||||
🌀
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-[10px] font-extrabold text-indigo-500 uppercase tracking-wider block">Beweegbaar & ASMR</span>
|
||||
<h3 class="font-heading text-base font-black text-slate-900 group-hover:text-indigo-600 transition">Fidget Toys</h3>
|
||||
<p class="text-[11px] text-slate-500 mt-0.5 line-clamp-1">Draken, slakken, cubes & spinners</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- 2. Pokémon -->
|
||||
<a href="{{ route('catalog', ['category' => 'pokemon-3d']) }}" class="playful-card p-4 sm:p-5 rounded-3xl bg-gradient-to-br from-amber-50/80 to-yellow-50/80 border border-amber-100 hover:border-amber-300 text-left flex flex-col justify-between group shadow-xs">
|
||||
<div class="w-12 h-12 rounded-2xl bg-white shadow-xs flex items-center justify-center mb-3 text-2xl group-hover:scale-110 transition transform">
|
||||
⚡
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-[10px] font-extrabold text-amber-600 uppercase tracking-wider block">Gotta Print 'Em All</span>
|
||||
<h3 class="font-heading text-base font-black text-slate-900 group-hover:text-amber-600 transition">Pokémon Prints</h3>
|
||||
<p class="text-[11px] text-slate-500 mt-0.5 line-clamp-1">Pikachu, Charizard, Pokéball & Gengar</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- 3. Film & Popculture -->
|
||||
<a href="{{ route('catalog', ['category' => 'film-popculture']) }}" class="playful-card p-4 sm:p-5 rounded-3xl bg-gradient-to-br from-rose-50/80 to-pink-50/80 border border-rose-100 hover:border-rose-300 text-left flex flex-col justify-between group shadow-xs">
|
||||
<div class="w-12 h-12 rounded-2xl bg-white shadow-xs flex items-center justify-center mb-3 text-2xl group-hover:scale-110 transition transform">
|
||||
🎬
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-[10px] font-extrabold text-rose-500 uppercase tracking-wider block">Iconische Items</span>
|
||||
<h3 class="font-heading text-base font-black text-slate-900 group-hover:text-rose-600 transition">Film & Gaming</h3>
|
||||
<p class="text-[11px] text-slate-500 mt-0.5 line-clamp-1">Star Wars Grogu, Thor Mjolnir & meer</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- 4. Eigen Model Bestellen -->
|
||||
<a href="{{ route('custom.request') }}" class="playful-card p-4 sm:p-5 rounded-3xl bg-gradient-to-br from-emerald-50/80 to-teal-50/80 border border-emerald-100 hover:border-emerald-300 text-left flex flex-col justify-between group shadow-xs">
|
||||
<div class="w-12 h-12 rounded-2xl bg-white shadow-xs flex items-center justify-center mb-3 text-2xl group-hover:scale-110 transition transform">
|
||||
🚀
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-[10px] font-extrabold text-emerald-600 uppercase tracking-wider block">Direct Online</span>
|
||||
<h3 class="font-heading text-base font-black text-slate-900 group-hover:text-emerald-600 transition">Eigen Model Printen</h3>
|
||||
<p class="text-[11px] text-slate-500 mt-0.5 line-clamp-1">Upload STL / 3MF en bestel direct</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Uitgelichte Prints / Product Showcase -->
|
||||
<section class="py-16 bg-white border-t-2 border-slate-900">
|
||||
<!-- Uitgelichte Prints Showcase (Mobile-First 2-koloms / Desktop 3-koloms) -->
|
||||
<section class="py-12 sm:py-16 bg-[#FFFDF9]">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex flex-col sm:flex-row sm:items-end justify-between mb-10 gap-4">
|
||||
<div class="flex flex-col sm:flex-row sm:items-end justify-between mb-8 gap-3">
|
||||
<div>
|
||||
<span class="text-xs font-black uppercase tracking-wider text-amber-600 flex items-center space-x-1">
|
||||
<span>🌟</span>
|
||||
<span>Favorieten uit de 3D studio</span>
|
||||
<span>Populairste Prints</span>
|
||||
</span>
|
||||
<h2 class="font-heading text-3xl font-black text-slate-900 tracking-tight">Populaire Prints & Modellen</h2>
|
||||
<p class="text-xs font-bold text-slate-600 mt-1">Kies jouw favoriet en stel hem helemaal samen in jouw gewenste kleur!</p>
|
||||
<h2 class="font-heading text-2xl sm:text-3xl font-black text-slate-900 tracking-tight">Direct te bestellen in jouw kleur</h2>
|
||||
<p class="text-xs text-slate-500 mt-1">Kies je favoriet, selecteer je lievelingskleur en wij starten de printer!</p>
|
||||
</div>
|
||||
<a href="{{ route('catalog') }}" class="toy-btn px-5 py-2.5 rounded-2xl bg-amber-300 hover:bg-amber-400 border-2 border-slate-900 toy-shadow-sm text-slate-950 text-xs font-black transition flex items-center space-x-1.5 self-start sm:self-auto">
|
||||
<span>Volledige Catalogus 🎁</span>
|
||||
<i data-lucide="arrow-right" class="w-3.5 h-3.5 stroke-[3]"></i>
|
||||
<a href="{{ route('catalog') }}" class="playful-btn px-4 py-2 rounded-xl bg-white border border-slate-200 text-slate-800 text-xs font-bold transition flex items-center space-x-1.5 self-start sm:self-auto shadow-2xs">
|
||||
<span>Alle prints bekijken</span>
|
||||
<i data-lucide="arrow-right" class="w-3.5 h-3.5"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
<!-- 2 Kolommen op mobiel, 3 op desktop -->
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 gap-3 sm:gap-6">
|
||||
@foreach($featuredProducts as $product)
|
||||
<div class="group rounded-3xl bg-[#FFFDF7] border-2 border-slate-900 toy-shadow overflow-hidden flex flex-col justify-between hover:-translate-y-1 transition duration-200">
|
||||
<div class="playful-card rounded-2xl sm:rounded-3xl bg-white border border-slate-100 shadow-xs hover:shadow-lg overflow-hidden flex flex-col justify-between group">
|
||||
|
||||
<!-- Afbeelding & Badges -->
|
||||
<div class="relative h-64 overflow-hidden bg-slate-100 border-b-2 border-slate-900">
|
||||
<div class="relative h-40 sm:h-60 overflow-hidden bg-slate-100">
|
||||
<img
|
||||
src="{{ $product->image_url }}"
|
||||
alt="{{ $product->name }}"
|
||||
class="w-full h-full object-cover object-center group-hover:scale-105 transition-transform duration-500"
|
||||
loading="lazy"
|
||||
>
|
||||
<div class="absolute top-3.5 left-3.5 flex flex-col gap-1.5">
|
||||
@if($product->category)
|
||||
<span class="px-3 py-1 rounded-xl bg-amber-300 border-2 border-slate-900 text-slate-950 text-[11px] font-black toy-shadow-sm">
|
||||
@if($product->category)
|
||||
<div class="absolute top-2 left-2 sm:top-3 sm:left-3">
|
||||
<span class="px-2 py-0.5 sm:px-2.5 sm:py-1 rounded-lg bg-white/90 backdrop-blur-xs text-slate-900 text-[9px] sm:text-[10px] font-black shadow-2xs">
|
||||
{{ $product->category->name }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if($product->print_time_hours)
|
||||
<div class="absolute bottom-3 left-3 px-2.5 py-1 rounded-xl bg-white border-2 border-slate-900 text-slate-900 text-[11px] font-black toy-shadow-sm flex items-center space-x-1">
|
||||
<div class="hidden sm:flex absolute bottom-2.5 left-2.5 px-2 py-0.5 rounded-md bg-slate-900/80 backdrop-blur-xs text-white text-[10px] font-bold items-center space-x-1">
|
||||
<span>⏱️</span>
|
||||
<span>{{ $product->print_time_hours }}u printtijd</span>
|
||||
<span>{{ $product->print_time_hours }}u</span>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Inhoud -->
|
||||
<div class="p-6 flex-1 flex flex-col justify-between space-y-4">
|
||||
<div class="p-3 sm:p-5 flex-1 flex flex-col justify-between space-y-3">
|
||||
<div>
|
||||
<h3 class="font-heading text-lg font-black text-slate-900 group-hover:text-rose-600 transition tracking-tight">
|
||||
<h3 class="font-heading text-xs sm:text-base font-black text-slate-900 group-hover:text-rose-600 transition tracking-tight line-clamp-2">
|
||||
<a href="{{ route('product.show', $product->slug) }}">
|
||||
{{ $product->name }}
|
||||
</a>
|
||||
</h3>
|
||||
<p class="text-xs font-medium text-slate-600 mt-1.5 line-clamp-2 leading-relaxed">
|
||||
<p class="hidden sm:block text-xs text-slate-500 mt-1 line-clamp-2 leading-relaxed">
|
||||
{{ $product->short_description }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Footer met prijs & actieknop -->
|
||||
<div class="pt-4 border-t-2 border-slate-200 flex items-center justify-between">
|
||||
<div class="pt-2 sm:pt-3 border-t border-slate-100 flex items-center justify-between">
|
||||
<div>
|
||||
<span class="text-[10px] text-slate-500 font-extrabold uppercase block">Vanaf</span>
|
||||
<span class="font-heading text-xl font-black text-slate-900">
|
||||
<span class="text-[9px] sm:text-[10px] text-slate-400 font-bold uppercase block">Vanaf</span>
|
||||
<span class="font-heading text-sm sm:text-lg font-black text-slate-900">
|
||||
{{ $product->formatted_price }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<a href="{{ route('product.show', $product->slug) }}" class="toy-btn px-4 py-2.5 rounded-2xl bg-amber-400 hover:bg-amber-300 border-2 border-slate-900 toy-shadow-sm text-slate-950 text-xs font-black transition flex items-center space-x-1.5">
|
||||
<span>Kies Kleur 🎨</span>
|
||||
<a href="{{ route('product.show', $product->slug) }}" class="playful-btn px-2.5 sm:px-3.5 py-1.5 sm:py-2 rounded-xl bg-amber-400 hover:bg-amber-300 text-slate-950 text-[10px] sm:text-xs font-black transition flex items-center space-x-1 shadow-2xs">
|
||||
<span>Kleur 🎨</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -265,25 +258,25 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Custom 3D STL Upload Banner Section (Speelse Creatieve Werkplaats) -->
|
||||
<section class="py-16 bg-amber-300 border-t-2 border-slate-900 relative overflow-hidden">
|
||||
<!-- Direct Eigen Model Bestellen Banner (Sleek & Duidelijk) -->
|
||||
<section class="py-12 sm:py-16 bg-gradient-to-r from-rose-500 via-amber-500 to-indigo-600 text-white relative overflow-hidden">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative">
|
||||
<div class="p-8 sm:p-12 rounded-3xl bg-white border-3 border-slate-900 toy-shadow-lg flex flex-col lg:flex-row items-center justify-between gap-8">
|
||||
<div class="space-y-4 max-w-2xl text-center lg:text-left">
|
||||
<span class="px-3.5 py-1.5 rounded-full bg-rose-100 text-rose-700 border-2 border-slate-900 text-xs font-black inline-flex items-center space-x-2">
|
||||
<div class="p-6 sm:p-10 rounded-3xl bg-white/10 backdrop-blur-md border border-white/20 flex flex-col lg:flex-row items-center justify-between gap-6 sm:gap-8">
|
||||
<div class="space-y-3 text-center lg:text-left max-w-2xl">
|
||||
<span class="px-3 py-1 rounded-full bg-white/20 text-white text-xs font-black inline-flex items-center space-x-1.5">
|
||||
<span>💡</span>
|
||||
<span>Heb je zelf een cool 3D-bestand gevonden?</span>
|
||||
<span>Zelf een gaaf model gevonden op MakerWorld of Printables?</span>
|
||||
</span>
|
||||
<h2 class="font-heading text-3xl sm:text-4xl font-black tracking-tight text-slate-900">
|
||||
Upload jouw eigen STL of MakerWorld model! 🚀
|
||||
<h2 class="font-heading text-2xl sm:text-4xl font-black tracking-tight">
|
||||
Bestel direct jouw eigen 3D bestand online! 🚀
|
||||
</h2>
|
||||
<p class="text-xs sm:text-sm text-slate-700 font-bold leading-relaxed">
|
||||
Heb je een gaaf speelgoedmodel, onderdeel of design gezien op MakerWorld, Printables of Thingiverse? Upload je bestand en wij printen het in hoge kwaliteit en in jouw favoriete kleur!
|
||||
<p class="text-xs sm:text-sm text-white/90 leading-relaxed font-medium">
|
||||
Upload jouw .STL, .3MF of .STEP bestand (of plak een MakerWorld link). Kies je formaat, materiaal en lievelingskleur en stop hem direct in je winkelmandje!
|
||||
</p>
|
||||
</div>
|
||||
<a href="{{ route('custom.request') }}" class="toy-btn px-8 py-4 rounded-2xl bg-rose-500 hover:bg-rose-400 border-2 border-slate-900 toy-shadow text-white font-black text-xs uppercase tracking-wider transition flex items-center space-x-2 flex-shrink-0">
|
||||
<i data-lucide="upload-cloud" class="w-4 h-4 stroke-[3]"></i>
|
||||
<span>Direct Bestand Uploaden ✨</span>
|
||||
<a href="{{ route('custom.request') }}" class="playful-btn px-8 py-4 rounded-2xl bg-white text-slate-950 hover:bg-slate-50 font-black text-xs uppercase tracking-wider transition shadow-lg flex items-center space-x-2 flex-shrink-0">
|
||||
<i data-lucide="upload-cloud" class="w-4 h-4 text-rose-500"></i>
|
||||
<span>Direct Eigen Model Bestellen ✨</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
@section('content')
|
||||
<!-- Breadcrumbs -->
|
||||
<div class="bg-amber-50 border-b-2 border-slate-900 py-3.5">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-xs font-bold text-slate-600 flex items-center space-x-2">
|
||||
<div class="bg-amber-50/50 border-b border-slate-200/80 py-2.5 sm:py-3">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-xs font-bold text-slate-500 flex items-center space-x-1.5 overflow-x-auto whitespace-nowrap">
|
||||
<a href="{{ route('home') }}" class="hover:text-rose-600">Home 🏠</a>
|
||||
<span>/</span>
|
||||
<a href="{{ route('catalog') }}" class="hover:text-rose-600">Catalogus 🎁</a>
|
||||
@@ -18,7 +18,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-10"
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 sm:py-10"
|
||||
x-data="{
|
||||
basePrice: {{ $product->base_price }},
|
||||
selectedMaterial: '{{ $product->available_materials[0] ?? 'pla' }}',
|
||||
@@ -27,7 +27,7 @@
|
||||
'{{ $code }}': {{ $mat->price_multiplier }},
|
||||
@endforeach
|
||||
},
|
||||
selectedColor: '{{ $product->available_colors[0] ?? 'Mat Zwart' }}',
|
||||
selectedColor: '{{ $product->available_colors[0] ?? 'Zon Geel (Pikachu)' }}',
|
||||
selectedScale: '100%',
|
||||
scaleMultipliers: {
|
||||
'100%': 1.0,
|
||||
@@ -51,88 +51,88 @@
|
||||
}
|
||||
}">
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-10">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12">
|
||||
|
||||
<!-- Linkerkant: Productgalerij & Speelse Specificaties -->
|
||||
<div class="lg:col-span-6 space-y-6">
|
||||
<div class="rounded-3xl bg-white border-3 border-slate-900 overflow-hidden toy-shadow-lg">
|
||||
<div class="relative h-96 sm:h-112 bg-[#FFFDF7] flex items-center justify-center overflow-hidden">
|
||||
<!-- Linkerkant: Productgalerij & Specificaties -->
|
||||
<div class="lg:col-span-6 space-y-4 sm:space-y-6">
|
||||
<div class="rounded-3xl bg-white border border-slate-100 overflow-hidden shadow-sm">
|
||||
<div class="relative h-72 sm:h-96 md:h-112 bg-slate-100 flex items-center justify-center overflow-hidden">
|
||||
<img
|
||||
src="{{ $product->image_url }}"
|
||||
alt="{{ $product->name }}"
|
||||
class="w-full h-full object-cover object-center"
|
||||
>
|
||||
<div class="absolute top-4 left-4 flex flex-col gap-2">
|
||||
<div class="absolute top-3 left-3 flex flex-col gap-1.5">
|
||||
@if($product->is_featured)
|
||||
<span class="px-3.5 py-1.5 rounded-full bg-rose-500 text-white font-heading text-xs font-black border-2 border-slate-900 toy-shadow-sm flex items-center space-x-1">
|
||||
<span class="px-3 py-1 rounded-full bg-gradient-to-r from-rose-500 to-amber-500 text-white font-heading text-xs font-black shadow-sm flex items-center space-x-1">
|
||||
<span>🔥</span>
|
||||
<span>Populair!</span>
|
||||
<span>Populair</span>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Print & Specificaties Card in Vrolijke Blokken -->
|
||||
<div class="p-6 rounded-3xl bg-white border-2 border-slate-900 toy-shadow space-y-4">
|
||||
<h3 class="font-heading text-sm font-black text-slate-900 uppercase tracking-wider flex items-center space-x-2">
|
||||
<!-- Print Specificaties Card (Minder lomp, verfijnd) -->
|
||||
<div class="p-4 sm:p-6 rounded-3xl bg-white border border-slate-100 shadow-xs space-y-3">
|
||||
<h3 class="font-heading text-xs font-black text-slate-900 uppercase tracking-wider flex items-center space-x-1.5">
|
||||
<span>🖨️</span>
|
||||
<span>Print Specificaties & Details</span>
|
||||
<span>Print Details & Formaat</span>
|
||||
</h3>
|
||||
|
||||
<div class="grid grid-cols-2 sm:grid-cols-4 gap-3 text-xs">
|
||||
<div class="p-3.5 rounded-2xl bg-amber-100 border-2 border-slate-900 text-center">
|
||||
<span class="text-slate-600 block text-[10px] uppercase font-black">📏 Formaat</span>
|
||||
<span class="font-black text-slate-900 mt-0.5 block font-heading">{{ $product->dimensions ?? 'Standaard' }}</span>
|
||||
<div class="grid grid-cols-2 sm:grid-cols-4 gap-2 sm:gap-3 text-xs">
|
||||
<div class="p-3 rounded-2xl bg-slate-50 text-center">
|
||||
<span class="text-slate-400 block text-[10px] uppercase font-bold">📏 Formaat</span>
|
||||
<span class="font-black text-slate-800 mt-0.5 block font-heading">{{ $product->dimensions ?? 'Standaard' }}</span>
|
||||
</div>
|
||||
|
||||
<div class="p-3.5 rounded-2xl bg-rose-100 border-2 border-slate-900 text-center">
|
||||
<span class="text-slate-600 block text-[10px] uppercase font-black">⚖️ Gewicht</span>
|
||||
<span class="font-black text-slate-900 mt-0.5 block font-heading">~{{ $product->weight_grams ?? '80' }}g</span>
|
||||
<div class="p-3 rounded-2xl bg-slate-50 text-center">
|
||||
<span class="text-slate-400 block text-[10px] uppercase font-bold">⚖️ Gewicht</span>
|
||||
<span class="font-black text-slate-800 mt-0.5 block font-heading">~{{ $product->weight_grams ?? '80' }}g</span>
|
||||
</div>
|
||||
|
||||
<div class="p-3.5 rounded-2xl bg-sky-100 border-2 border-slate-900 text-center">
|
||||
<span class="text-slate-600 block text-[10px] uppercase font-black">⏱️ Printtijd</span>
|
||||
<span class="font-black text-slate-900 mt-0.5 block font-heading">{{ $product->print_time_hours ?? '4.0' }} uur</span>
|
||||
<div class="p-3 rounded-2xl bg-slate-50 text-center">
|
||||
<span class="text-slate-400 block text-[10px] uppercase font-bold">⏱️ Printtijd</span>
|
||||
<span class="font-black text-slate-800 mt-0.5 block font-heading">{{ $product->print_time_hours ?? '4.0' }} uur</span>
|
||||
</div>
|
||||
|
||||
<div class="p-3.5 rounded-2xl bg-emerald-100 border-2 border-slate-900 text-center">
|
||||
<span class="text-slate-600 block text-[10px] uppercase font-black">🔍 Laaghoogte</span>
|
||||
<span class="font-black text-slate-900 mt-0.5 block font-heading">0.16 mm</span>
|
||||
<div class="p-3 rounded-2xl bg-slate-50 text-center">
|
||||
<span class="text-slate-400 block text-[10px] uppercase font-bold">🔍 Resolutie</span>
|
||||
<span class="font-black text-slate-800 mt-0.5 block font-heading">0.12 - 0.16 mm</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pt-3 flex flex-col sm:flex-row items-center justify-between text-xs text-slate-700 font-bold border-t-2 border-slate-100 gap-2">
|
||||
<span class="flex items-center space-x-1.5">
|
||||
<div class="pt-2 flex flex-col sm:flex-row items-center justify-between text-[11px] text-slate-500 font-bold border-t border-slate-100 gap-1.5">
|
||||
<span class="flex items-center space-x-1">
|
||||
<span>✨</span>
|
||||
<span>Geprint op hypermoderne Bambu Lab 3D printers</span>
|
||||
<span>Geprint op precisie Bambu Lab printers</span>
|
||||
</span>
|
||||
<span class="flex items-center space-x-1.5">
|
||||
<span>🧼</span>
|
||||
<span>Handmatig nagekeken en ontbraamd</span>
|
||||
<span class="flex items-center space-x-1">
|
||||
<span>🌱</span>
|
||||
<span>Veilig & biologisch afbreekbaar PLA</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Productomschrijving -->
|
||||
<div class="p-6 rounded-3xl bg-white border-2 border-slate-900 toy-shadow space-y-3">
|
||||
<h3 class="font-heading text-base font-black text-slate-900 flex items-center space-x-2">
|
||||
<div class="p-4 sm:p-6 rounded-3xl bg-white border border-slate-100 shadow-xs space-y-2">
|
||||
<h3 class="font-heading text-sm font-black text-slate-900 flex items-center space-x-1.5">
|
||||
<span>📝</span>
|
||||
<span>Over dit product</span>
|
||||
<span>Over deze 3D print</span>
|
||||
</h3>
|
||||
<div class="text-xs text-slate-700 leading-relaxed space-y-2 font-medium">
|
||||
<div class="text-xs text-slate-600 leading-relaxed space-y-1.5 font-medium">
|
||||
{!! nl2br($product->description) !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if($product->makerworld_id)
|
||||
<!-- MakerWorld Model Attributie -->
|
||||
<div class="p-4 rounded-2xl bg-sky-100 border-2 border-slate-900 toy-shadow-sm text-xs text-slate-800 flex items-center justify-between font-bold">
|
||||
<div class="p-4 rounded-2xl bg-indigo-50 border border-indigo-100 text-xs text-slate-700 flex items-center justify-between font-bold">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="px-2.5 py-1 rounded-xl bg-white border border-slate-900 text-indigo-700 font-black text-[10px]">MakerWorld 3D</span>
|
||||
<span>Gemaakt door <strong>{{ $product->makerworld_author ?? 'MakerWorld Maker' }}</strong></span>
|
||||
<span class="px-2.5 py-0.5 rounded-lg bg-indigo-100 text-indigo-700 font-black text-[10px]">MakerWorld Model</span>
|
||||
<span>Ontworpen door <strong>{{ $product->makerworld_author ?? 'MakerWorld Creator' }}</strong></span>
|
||||
</div>
|
||||
<a href="{{ $product->makerworld_url ?? 'https://makerworld.com/nl/models/' . $product->makerworld_id }}" target="_blank" class="text-indigo-700 hover:text-indigo-900 underline inline-flex items-center space-x-1">
|
||||
<a href="{{ $product->makerworld_url ?? 'https://makerworld.com/nl/models/' . $product->makerworld_id }}" target="_blank" class="text-indigo-600 hover:text-indigo-800 underline inline-flex items-center space-x-1">
|
||||
<span>Origineel bekijken</span>
|
||||
<i data-lucide="external-link" class="w-3 h-3"></i>
|
||||
</a>
|
||||
@@ -140,39 +140,39 @@
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Rechterkant: Interactive 3D Workshop / Configurator -->
|
||||
<!-- Rechterkant: Interactive Configurator & Bestelmodule -->
|
||||
<div class="lg:col-span-6 space-y-6">
|
||||
<div class="p-8 rounded-3xl bg-white border-3 border-slate-900 toy-shadow-lg space-y-6">
|
||||
<div class="p-5 sm:p-8 rounded-3xl bg-white border border-slate-100 shadow-lg shadow-slate-200/40 space-y-5 sm:space-y-6">
|
||||
|
||||
<div>
|
||||
@if($product->category)
|
||||
<span class="inline-block px-3 py-1 rounded-full bg-amber-300 border-2 border-slate-900 text-[11px] font-black text-slate-950 mb-2 toy-shadow-sm">
|
||||
<span class="inline-block px-2.5 py-0.5 rounded-full bg-amber-100 text-[10px] sm:text-xs font-black text-amber-900 mb-1.5">
|
||||
{{ $product->category->name }}
|
||||
</span>
|
||||
@endif
|
||||
<h1 class="font-heading text-2xl sm:text-3xl font-black text-slate-900 tracking-tight">{{ $product->name }}</h1>
|
||||
<p class="text-xs font-bold text-slate-600 mt-2 leading-relaxed">{{ $product->short_description }}</p>
|
||||
<h1 class="font-heading text-xl sm:text-3xl font-black text-slate-900 tracking-tight">{{ $product->name }}</h1>
|
||||
<p class="text-xs text-slate-500 mt-1 leading-relaxed">{{ $product->short_description }}</p>
|
||||
</div>
|
||||
|
||||
<!-- Live Prijs Display (Speelse Candy Box) -->
|
||||
<div class="p-4 rounded-2xl bg-amber-100 border-2 border-slate-900 toy-shadow-sm flex items-center justify-between">
|
||||
<!-- Prijs Display -->
|
||||
<div class="p-3.5 sm:p-4 rounded-2xl bg-gradient-to-r from-amber-50 to-rose-50 border border-amber-200/60 flex items-center justify-between">
|
||||
<div>
|
||||
<span class="text-[11px] text-slate-700 block font-black uppercase">Jouw stukprijs</span>
|
||||
<div class="flex items-baseline space-x-2">
|
||||
<span class="font-heading text-3xl font-black text-slate-900">€ <span x-text="unitPriceFormatted"></span></span>
|
||||
<span class="text-xs text-slate-600 font-bold">incl. btw</span>
|
||||
<span class="text-[10px] text-slate-500 block font-bold uppercase">Stukprijs</span>
|
||||
<div class="flex items-baseline space-x-1.5">
|
||||
<span class="font-heading text-2xl sm:text-3xl font-black text-slate-900">€ <span x-text="unitPriceFormatted"></span></span>
|
||||
<span class="text-xs text-slate-500 font-normal">incl. btw</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<span class="px-3 py-1.5 rounded-full bg-emerald-300 border-2 border-slate-900 text-slate-950 text-xs font-black inline-flex items-center space-x-1.5 toy-shadow-sm">
|
||||
<span>🚀</span>
|
||||
<span>Direct Print-klaar</span>
|
||||
<span class="px-2.5 py-1 rounded-full bg-emerald-100 text-emerald-800 text-[11px] font-black inline-flex items-center space-x-1">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500"></span>
|
||||
<span>Print-klaar</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bestelformulier met Customizer -->
|
||||
<form action="{{ route('cart.add') }}" method="POST" class="space-y-6">
|
||||
<form action="{{ route('cart.add') }}" method="POST" class="space-y-5">
|
||||
@csrf
|
||||
<input type="hidden" name="product_id" value="{{ $product->id }}">
|
||||
<input type="hidden" name="material" x-model="selectedMaterial">
|
||||
@@ -183,57 +183,51 @@
|
||||
|
||||
<!-- 1. Materiaal Keuze -->
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<label class="text-xs font-black text-slate-900 uppercase tracking-wider flex items-center space-x-1.5">
|
||||
<span>1️⃣</span>
|
||||
<span>Kies Materiaal / Filament</span>
|
||||
</label>
|
||||
<span class="text-xs font-black text-indigo-700 bg-indigo-50 px-2 py-0.5 rounded-lg border border-indigo-200" x-text="selectedMaterial.toUpperCase()"></span>
|
||||
<div class="flex items-center justify-between mb-1.5">
|
||||
<label class="text-xs font-black text-slate-800 uppercase tracking-wider">1. Kies Materiaal</label>
|
||||
<span class="text-xs font-black text-rose-500" x-text="selectedMaterial.toUpperCase()"></span>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 sm:grid-cols-3 gap-2.5">
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
@foreach($product->available_materials ?? ['pla'] as $matCode)
|
||||
@php $mat = $allMaterials[$matCode] ?? null; @endphp
|
||||
@if($mat)
|
||||
<button
|
||||
type="button"
|
||||
@click="selectedMaterial = '{{ $mat->code }}'"
|
||||
:class="selectedMaterial === '{{ $mat->code }}' ? 'border-slate-900 bg-amber-300 toy-shadow-sm font-black' : 'border-slate-200 bg-white hover:bg-slate-50 font-bold'"
|
||||
class="p-3 rounded-2xl border-2 text-left transition flex flex-col justify-between cursor-pointer"
|
||||
:class="selectedMaterial === '{{ $mat->code }}' ? 'border-amber-400 bg-amber-50 ring-2 ring-amber-400 font-black text-slate-950' : 'border-slate-200 bg-white hover:bg-slate-50 text-slate-700'"
|
||||
class="p-2.5 rounded-xl border text-left transition flex flex-col justify-between cursor-pointer"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-xs text-slate-900">{{ $mat->name }}</span>
|
||||
<span class="text-xs font-bold">{{ $mat->name }}</span>
|
||||
@if($mat->price_multiplier > 1.0)
|
||||
<span class="text-[10px] px-1.5 py-0.5 rounded bg-white border border-slate-900 text-slate-900 font-black">+{{ round(($mat->price_multiplier - 1) * 100) }}%</span>
|
||||
<span class="text-[9px] px-1 py-0.2 rounded bg-slate-100 font-mono text-slate-600">+{{ round(($mat->price_multiplier - 1) * 100) }}%</span>
|
||||
@endif
|
||||
</div>
|
||||
<p class="text-[10px] text-slate-600 mt-1 line-clamp-1">{{ $mat->description }}</p>
|
||||
<p class="text-[10px] text-slate-500 mt-0.5 line-clamp-1">{{ $mat->description }}</p>
|
||||
</button>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. Kleur Selectie (Swatches met vrolijke rand) -->
|
||||
<!-- 2. Kleur Selectie (Swatches met mooie afwerking) -->
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<label class="text-xs font-black text-slate-900 uppercase tracking-wider flex items-center space-x-1.5">
|
||||
<span>2️⃣</span>
|
||||
<span>Kies Jouw Lievelingskleur</span>
|
||||
</label>
|
||||
<span class="text-xs font-black text-rose-600 bg-rose-50 px-2.5 py-0.5 rounded-lg border border-rose-200" x-text="selectedColor"></span>
|
||||
<div class="flex items-center justify-between mb-1.5">
|
||||
<label class="text-xs font-black text-slate-800 uppercase tracking-wider">2. Kies Jouw Kleur</label>
|
||||
<span class="text-xs font-bold text-rose-600" x-text="selectedColor"></span>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2.5">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
@foreach($allColors as $c)
|
||||
<button
|
||||
type="button"
|
||||
@click="selectedColor = '{{ $c->name }}'"
|
||||
:class="selectedColor === '{{ $c->name }}' ? 'ring-4 ring-amber-400 scale-110' : 'hover:scale-105 border-slate-900'"
|
||||
class="w-9 h-9 rounded-2xl border-2 shadow-xs transition flex items-center justify-center cursor-pointer relative"
|
||||
:class="selectedColor === '{{ $c->name }}' ? 'ring-3 ring-rose-500 ring-offset-2 scale-110' : 'hover:scale-105 border-slate-300'"
|
||||
class="w-8 h-8 rounded-xl border shadow-xs transition flex items-center justify-center cursor-pointer relative"
|
||||
style="background-color: {{ $c->hex }};"
|
||||
title="{{ $c->name }}"
|
||||
>
|
||||
<template x-if="selectedColor === '{{ $c->name }}'">
|
||||
<i data-lucide="check" class="w-4 h-4 {{ in_array($c->name, ['Sneeuwwit', 'Galaxy Grijs', 'Zon Geel']) ? 'text-slate-950' : 'text-white' }} stroke-[3]"></i>
|
||||
<i data-lucide="check" class="w-4 h-4 {{ in_array($c->name, ['Sneeuwwit', 'Zon Geel (Pikachu)']) ? 'text-slate-950' : 'text-white' }} stroke-[3]"></i>
|
||||
</template>
|
||||
</button>
|
||||
@endforeach
|
||||
@@ -242,35 +236,32 @@
|
||||
|
||||
<!-- 3. Formaat & Schaal -->
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<label class="text-xs font-black text-slate-900 uppercase tracking-wider flex items-center space-x-1.5">
|
||||
<span>3️⃣</span>
|
||||
<span>Grootte / Schaal</span>
|
||||
</label>
|
||||
<span class="text-xs font-black text-slate-800" x-text="selectedScale"></span>
|
||||
<div class="flex items-center justify-between mb-1.5">
|
||||
<label class="text-xs font-black text-slate-800 uppercase tracking-wider">3. Formaat / Schaal</label>
|
||||
<span class="text-xs font-bold text-slate-700" x-text="selectedScale"></span>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-2 text-xs">
|
||||
<button
|
||||
type="button"
|
||||
@click="selectedScale = '100%'"
|
||||
:class="selectedScale === '100%' ? 'border-slate-900 bg-sky-200 toy-shadow-sm font-black' : 'border-slate-200 font-bold hover:bg-slate-50'"
|
||||
class="p-3 rounded-2xl border-2 text-center transition cursor-pointer"
|
||||
:class="selectedScale === '100%' ? 'border-rose-400 bg-rose-50 ring-2 ring-rose-300 font-black text-slate-900' : 'border-slate-200 font-bold hover:bg-slate-50'"
|
||||
class="p-2.5 rounded-xl border text-center transition cursor-pointer"
|
||||
>
|
||||
<span>100% (Normaal)</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
@click="selectedScale = '150%'"
|
||||
:class="selectedScale === '150%' ? 'border-slate-900 bg-sky-200 toy-shadow-sm font-black' : 'border-slate-200 font-bold hover:bg-slate-50'"
|
||||
class="p-3 rounded-2xl border-2 text-center transition cursor-pointer"
|
||||
:class="selectedScale === '150%' ? 'border-rose-400 bg-rose-50 ring-2 ring-rose-300 font-black text-slate-900' : 'border-slate-200 font-bold hover:bg-slate-50'"
|
||||
class="p-2.5 rounded-xl border text-center transition cursor-pointer"
|
||||
>
|
||||
<span>150% (+45%)</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
@click="selectedScale = '200%'"
|
||||
:class="selectedScale === '200%' ? 'border-slate-900 bg-sky-200 toy-shadow-sm font-black' : 'border-slate-200 font-bold hover:bg-slate-50'"
|
||||
class="p-3 rounded-2xl border-2 text-center transition cursor-pointer"
|
||||
:class="selectedScale === '200%' ? 'border-rose-400 bg-rose-50 ring-2 ring-rose-300 font-black text-slate-900' : 'border-slate-200 font-bold hover:bg-slate-50'"
|
||||
class="p-2.5 rounded-xl border text-center transition cursor-pointer"
|
||||
>
|
||||
<span>200% (+95%)</span>
|
||||
</button>
|
||||
@@ -278,32 +269,26 @@
|
||||
</div>
|
||||
|
||||
<!-- Aantal en Toevoegen Knop -->
|
||||
<div class="pt-4 border-t-2 border-slate-200 space-y-4">
|
||||
<div class="flex items-center space-x-3">
|
||||
<!-- Chunky Toy Stepper -->
|
||||
<div class="flex items-center border-2 border-slate-900 rounded-2xl bg-[#FFFDF7] toy-shadow-sm overflow-hidden">
|
||||
<button type="button" @click="if (quantity > 1) quantity--" class="px-4 py-3 hover:bg-amber-100 transition text-slate-900 font-black cursor-pointer text-sm">-</button>
|
||||
<span class="px-4 py-3 font-heading font-black text-sm text-slate-900" x-text="quantity"></span>
|
||||
<button type="button" @click="if (quantity < 50) quantity++" class="px-4 py-3 hover:bg-amber-100 transition text-slate-900 font-black cursor-pointer text-sm">+</button>
|
||||
<div class="pt-3 border-t border-slate-100 space-y-3">
|
||||
<div class="flex items-center space-x-2.5">
|
||||
<!-- Stepper -->
|
||||
<div class="flex items-center border border-slate-200 rounded-xl bg-slate-50 overflow-hidden">
|
||||
<button type="button" @click="if (quantity > 1) quantity--" class="px-3 py-2.5 hover:bg-slate-200 transition text-slate-700 font-black cursor-pointer text-sm">-</button>
|
||||
<span class="px-3.5 py-2.5 font-heading font-black text-xs text-slate-900" x-text="quantity"></span>
|
||||
<button type="button" @click="if (quantity < 50) quantity++" class="px-3 py-2.5 hover:bg-slate-200 transition text-slate-700 font-black cursor-pointer text-sm">+</button>
|
||||
</div>
|
||||
|
||||
<!-- Chunky Add to Cart CTA -->
|
||||
<button type="submit" class="toy-btn flex-1 py-4 px-6 rounded-2xl bg-amber-400 hover:bg-amber-300 border-2 border-slate-900 toy-shadow text-slate-950 font-black text-sm transition flex items-center justify-center space-x-2 cursor-pointer">
|
||||
<!-- Knop Desktop -->
|
||||
<button type="submit" class="playful-btn flex-1 py-3 px-5 rounded-2xl bg-gradient-to-r from-amber-400 to-rose-400 hover:from-amber-500 hover:to-rose-500 text-slate-950 font-black text-xs sm:text-sm transition flex items-center justify-center space-x-1.5 shadow-md shadow-rose-500/20 cursor-pointer">
|
||||
<span>🛒</span>
|
||||
<span>In Winkelwagen • € <span x-text="calculatedPrice"></span></span>
|
||||
<span>In Winkelmandje • € <span x-text="calculatedPrice"></span></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-center space-x-4 text-xs font-bold text-slate-600 pt-1">
|
||||
<span class="flex items-center space-x-1">
|
||||
<span>🚚</span>
|
||||
<span>Gratis verzending vanaf € 50,-</span>
|
||||
</span>
|
||||
<div class="flex items-center justify-center space-x-3 text-[11px] text-slate-500 font-bold pt-1">
|
||||
<span>🚚 Gratis verzending vanaf €50</span>
|
||||
<span>•</span>
|
||||
<span class="flex items-center space-x-1">
|
||||
<span>📦</span>
|
||||
<span>PostNL Track & Trace</span>
|
||||
</span>
|
||||
<span>📦 PostNL Track & Trace</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ Route::get('/catalogus', [ShopController::class, 'catalog'])->name('catalog');
|
||||
Route::get('/product/{slug}', [ShopController::class, 'show'])->name('product.show');
|
||||
Route::get('/custom-3d-print', [ShopController::class, 'customRequest'])->name('custom.request');
|
||||
Route::post('/custom-3d-print', [ShopController::class, 'storeCustomRequest'])->name('custom.store');
|
||||
Route::post('/custom-3d-print/bestellen', [CartController::class, 'addCustom'])->name('custom.cart.add');
|
||||
|
||||
// Winkelwagen
|
||||
Route::get('/winkelwagen', [CartController::class, 'index'])->name('cart.index');
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\Material;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Tests\TestCase;
|
||||
|
||||
class CustomModelOrderTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_customer_can_order_custom_model_via_file_upload(): void
|
||||
{
|
||||
Storage::fake('public');
|
||||
|
||||
Material::updateOrCreate(['code' => 'pla'], [
|
||||
'name' => 'PLA+ Premium',
|
||||
'code' => 'pla',
|
||||
'price_multiplier' => 1.0,
|
||||
'is_active' => true,
|
||||
]);
|
||||
|
||||
$file = UploadedFile::fake()->create('custom_pikachu.stl', 1500, 'application/sla');
|
||||
|
||||
$response = $this->post(route('custom.cart.add'), [
|
||||
'model_name' => 'Mijn Custom Pikachu',
|
||||
'model_file' => $file,
|
||||
'size' => 'medium',
|
||||
'material' => 'pla',
|
||||
'color' => 'Zon Geel (Pikachu)',
|
||||
'quantity' => 2,
|
||||
]);
|
||||
|
||||
$response->assertRedirect(route('cart.index'));
|
||||
$response->assertSessionHas('success');
|
||||
|
||||
$cart = session('cart');
|
||||
$this->assertNotEmpty($cart);
|
||||
|
||||
$item = array_values($cart)[0];
|
||||
$this->assertTrue($item['is_custom']);
|
||||
$this->assertEquals('Custom Print: Mijn Custom Pikachu', $item['name']);
|
||||
$this->assertEquals(16.95, $item['price']);
|
||||
$this->assertEquals(2, $item['quantity']);
|
||||
$this->assertEquals('custom_pikachu.stl', $item['custom_file_name']);
|
||||
$this->assertNotNull($item['custom_file_path']);
|
||||
|
||||
Storage::disk('public')->assertExists($item['custom_file_path']);
|
||||
}
|
||||
|
||||
public function test_customer_can_order_custom_model_via_makerworld_url(): void
|
||||
{
|
||||
Material::updateOrCreate(['code' => 'pla'], [
|
||||
'name' => 'PLA+ Premium',
|
||||
'code' => 'pla',
|
||||
'price_multiplier' => 1.0,
|
||||
'is_active' => true,
|
||||
]);
|
||||
|
||||
$response = $this->post(route('custom.cart.add'), [
|
||||
'model_url' => 'https://makerworld.com/nl/models/55866',
|
||||
'size' => 'klein',
|
||||
'material' => 'pla',
|
||||
'color' => 'Vurig Rood (Charizard)',
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
$response->assertRedirect(route('cart.index'));
|
||||
|
||||
$cart = session('cart');
|
||||
$item = array_values($cart)[0];
|
||||
$this->assertTrue($item['is_custom']);
|
||||
$this->assertEquals(9.95, $item['price']);
|
||||
$this->assertEquals('https://makerworld.com/nl/models/55866', $item['custom_model_url']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user