459 lines
31 KiB
HTML
459 lines
31 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="nl">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Telvero Sales Panel V1</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<script src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
|
|
<style>
|
|
[x-cloak] {
|
|
display: none !important;
|
|
}
|
|
|
|
.custom-scrollbar::-webkit-scrollbar {
|
|
width: 4px;
|
|
}
|
|
|
|
.custom-scrollbar::-webkit-scrollbar-thumb {
|
|
background: #334155;
|
|
border-radius: 10px;
|
|
}
|
|
</style>
|
|
<!-- Load JavaScript modules with cache busting -->
|
|
<script>
|
|
// Change this version number to bust cache for all JS files
|
|
const APP_VERSION = '1.1';
|
|
|
|
const scripts = [
|
|
'js/services/api.js',
|
|
'js/services/bogo.js',
|
|
'js/components/cart.js',
|
|
'js/components/products.js',
|
|
'js/components/forms.js',
|
|
'js/app.js'
|
|
];
|
|
|
|
scripts.forEach(src => {
|
|
document.write(`<script src="${src}?v=${APP_VERSION}"><\/script>`);
|
|
});
|
|
</script>
|
|
</head>
|
|
|
|
<body class="bg-slate-100 min-h-screen font-sans" x-data="salesApp()">
|
|
<template x-if="isLoading">
|
|
<div class="fixed inset-0 bg-slate-900 flex items-center justify-center z-[60]">
|
|
<div class="text-center">
|
|
<div class="relative mb-6 mx-auto w-20 h-20">
|
|
<!-- Outer spinning ring -->
|
|
<div class="w-20 h-20 border-4 border-blue-500/30 rounded-full"></div>
|
|
<!-- Inner spinning ring -->
|
|
<div class="absolute top-0 left-0 w-20 h-20 border-4 border-transparent border-t-blue-500 rounded-full animate-spin"></div>
|
|
<!-- Session icon in center -->
|
|
<div class="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-blue-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<h3 class="text-white font-black text-lg uppercase tracking-wider mb-2">Sessie Laden</h3>
|
|
<p class="text-blue-400 text-sm font-medium animate-pulse">Even geduld...</p>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template x-if="!isLoggedIn && !isLoading && !isLoadingProducts">
|
|
<div class="fixed inset-0 bg-slate-900 flex items-center justify-center p-4 z-50">
|
|
<div
|
|
class="bg-white p-10 rounded-[2.5rem] shadow-2xl w-full max-w-md text-center border-t-8 border-blue-600">
|
|
<h2 class="text-3xl font-black mb-8 italic tracking-tighter text-slate-800">TELVERO <span
|
|
class="text-blue-600">LOGIN</span></h2>
|
|
<div class="space-y-4">
|
|
<input type="text" x-model="loginForm.username" placeholder="Gebruikersnaam"
|
|
class="w-full border p-4 rounded-2xl outline-none focus:border-blue-500 bg-slate-50 font-bold">
|
|
<input type="password" x-model="loginForm.password" @keyup.enter="doLogin()"
|
|
placeholder="Wachtwoord"
|
|
class="w-full border p-4 rounded-2xl outline-none focus:border-blue-500 bg-slate-50">
|
|
<button @click="doLogin()"
|
|
class="w-full bg-blue-600 text-white p-5 rounded-2xl font-black shadow-lg hover:bg-blue-700 transition uppercase tracking-widest text-sm">Inloggen</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<!-- Loading Products Overlay -->
|
|
<template x-if="isLoadingProducts">
|
|
<div class="fixed inset-0 bg-slate-900 flex items-center justify-center z-[55]">
|
|
<div class="text-center">
|
|
<div class="relative mb-6 mx-auto w-20 h-20">
|
|
<!-- Outer spinning ring -->
|
|
<div class="w-20 h-20 border-4 border-blue-500/30 rounded-full"></div>
|
|
<!-- Inner spinning ring -->
|
|
<div class="absolute top-0 left-0 w-20 h-20 border-4 border-transparent border-t-blue-500 rounded-full animate-spin"></div>
|
|
<!-- Product icon in center -->
|
|
<div class="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-blue-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<h3 class="text-white font-black text-lg uppercase tracking-wider mb-2">Producten Laden</h3>
|
|
<p class="text-blue-400 text-sm font-medium animate-pulse" x-text="loadingMessage || 'Even geduld...'"></p>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<div x-show="isLoggedIn && !isLoading" x-cloak class="max-w-[1440px] mx-auto p-6">
|
|
<header
|
|
class="flex justify-between items-center mb-8 bg-white p-6 rounded-3xl shadow-sm border-b-4 border-blue-600">
|
|
<h1 class="text-2xl font-black italic tracking-tighter">TELVERO <span class="text-blue-600">PANEL</span>
|
|
</h1>
|
|
<div class="flex items-center gap-6 text-sm font-bold text-slate-400">
|
|
<span x-text="'Agent: ' + currentUser"></span>
|
|
<!-- Admin Links - Only visible for administrators -->
|
|
<template x-if="userRole === 'administrator'">
|
|
<div class="flex items-center gap-3">
|
|
<a href="logs.php" class="bg-emerald-100 text-emerald-600 px-4 py-2 rounded-xl text-[10px] font-black uppercase tracking-widest hover:bg-emerald-200 transition">
|
|
📊 Logs
|
|
</a>
|
|
<a href="users.php" class="bg-purple-100 text-purple-600 px-4 py-2 rounded-xl text-[10px] font-black uppercase tracking-widest hover:bg-purple-200 transition">
|
|
👥 Users
|
|
</a>
|
|
</div>
|
|
</template>
|
|
<button @click="doLogout()"
|
|
class="text-red-500 underline uppercase text-xs font-black">Uitloggen</button>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="grid grid-cols-12 gap-8">
|
|
<div class="col-span-12 lg:col-span-4 bg-white p-8 rounded-[2rem] shadow-sm border border-slate-200">
|
|
<div class="mb-8 p-6 bg-blue-50 rounded-2xl border-2 border-blue-100 shadow-inner">
|
|
<label
|
|
class="block text-[10px] font-black text-blue-600 uppercase tracking-widest mb-3 italic text-center">Mediacode</label>
|
|
<select x-model="meta.mediacode"
|
|
class="w-full border-2 border-white p-4 rounded-xl font-bold text-blue-800 shadow-sm outline-none focus:border-blue-300">
|
|
<option value="">-- KIES MEDIACODE --</option>
|
|
<option value="Telvero - Net5">Telvero - Net5</option>
|
|
<option value="Telvero - SBS9">Telvero - SBS9</option>
|
|
<option value="Klantenservice">Klantenservice</option>
|
|
<option value="Website">Website</option>
|
|
</select>
|
|
</div>
|
|
<div class="space-y-4">
|
|
<div class="grid grid-cols-2 gap-3">
|
|
<input type="text" x-model="form.initials" @blur="formatInitials()" placeholder="Voorletters"
|
|
class="border p-3 rounded-xl w-full">
|
|
<input type="text" x-model="form.lastname" @blur="formatLastname()" placeholder="Achternaam"
|
|
class="border p-3 rounded-xl w-full">
|
|
</div>
|
|
<div class="grid grid-cols-3 gap-2">
|
|
<input type="text" x-model="form.postcode" placeholder="Postcode"
|
|
class="border p-3 rounded-xl w-full font-mono">
|
|
<input type="text" x-model="form.houseno" @blur="lookupAddress()" placeholder="Nr."
|
|
class="border p-3 rounded-xl w-full">
|
|
<input type="text" x-model="form.suffix" placeholder="Toev."
|
|
class="border p-3 rounded-xl w-full">
|
|
</div>
|
|
<p x-show="addressError" x-text="addressError" class="text-red-500 text-xs font-bold mt-1"></p>
|
|
<input type="text" x-model="form.street" placeholder="Straat"
|
|
class="w-full border p-3 rounded-xl bg-slate-50">
|
|
<input type="text" x-model="form.city" placeholder="Stad"
|
|
class="w-full border p-3 rounded-xl bg-slate-50">
|
|
<input type="tel" x-model="form.phone" placeholder="Telefoonnummer"
|
|
class="border p-3 rounded-xl w-full outline-none focus:border-blue-500">
|
|
<input type="email" x-model="form.email" placeholder="E-mail (Verplicht)"
|
|
class="border-2 border-amber-300 p-3 rounded-xl w-full outline-none focus:border-amber-500 shadow-sm">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-span-12 lg:col-span-5 bg-white p-8 rounded-[2rem] shadow-sm border border-slate-200">
|
|
<h2
|
|
class="font-bold mb-4 text-slate-400 uppercase text-[10px] tracking-widest border-b pb-2 text-center italic">
|
|
Producten</h2>
|
|
|
|
<!-- Custom searchable dropdown for main product -->
|
|
<div class="relative mb-6" x-data="{ open: false }" @click.away="open = false">
|
|
<button type="button" @click="open = !open"
|
|
class="w-full border-2 border-slate-100 p-5 rounded-2xl font-black text-slate-700 bg-slate-50 outline-none focus:border-blue-500 shadow-sm text-left flex justify-between items-center">
|
|
<span x-text="selectedProductId ? products.find(p => p.id == selectedProductId)?.name : '-- Kies Hoofdproduct --'" class="truncate"></span>
|
|
<svg class="w-5 h-5 text-slate-400 transition-transform" :class="{ 'rotate-180': open }" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
|
|
</svg>
|
|
</button>
|
|
<div x-show="open" x-cloak
|
|
class="absolute z-50 w-full mt-2 bg-white border-2 border-slate-200 rounded-2xl shadow-xl overflow-hidden">
|
|
<div class="p-3 border-b border-slate-100">
|
|
<input type="text" x-model="productSearch" placeholder="Zoek product..."
|
|
class="w-full border border-slate-200 p-3 rounded-xl text-sm outline-none focus:border-blue-500"
|
|
@click.stop>
|
|
</div>
|
|
<div class="max-h-60 overflow-y-auto custom-scrollbar">
|
|
<div @click="selectedProductId = ''; selectProduct(); open = false; productSearch = ''"
|
|
class="p-4 hover:bg-slate-50 cursor-pointer text-slate-500 font-medium text-sm">
|
|
-- Kies Hoofdproduct --
|
|
</div>
|
|
<template x-for="p in filteredProducts" :key="p.id">
|
|
<div @click="selectedProductId = p.id; selectProduct(); open = false; productSearch = ''"
|
|
class="p-4 hover:bg-blue-50 cursor-pointer font-bold text-sm text-slate-700"
|
|
:class="{ 'bg-blue-100': selectedProductId == p.id }">
|
|
<div class="flex items-center justify-between">
|
|
<span x-text="p.name"></span>
|
|
<span x-show="p.bogo_rules && p.bogo_rules.length > 0"
|
|
x-text="p.bogo_rules[0]?.badge_text || p.bogo_rules[0]?.label"
|
|
class="ml-2 px-2 py-1 bg-red-500 text-white text-[9px] font-black rounded-full uppercase">
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<div x-show="filteredProducts.length === 0" class="p-4 text-slate-400 text-sm text-center">
|
|
Geen producten gevonden
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- BOGO Actie Banner - Only for buy_x_get_x rules -->
|
|
<div x-show="activeProduct && activeProduct.bogo_rules && activeProduct.bogo_rules.length > 0 && activeProduct.bogo_rules[0].type === 'buy_x_get_x'" x-cloak
|
|
class="mb-6 p-4 bg-gradient-to-r from-red-500 to-pink-500 rounded-2xl text-white shadow-lg">
|
|
<div class="flex items-center justify-between gap-3">
|
|
<div class="flex items-center gap-3">
|
|
<div class="bg-white/20 p-2 rounded-full">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v13m0-13V6a2 2 0 112 2h-2zm0 0V5.5A2.5 2.5 0 109.5 8H12zm-7 4h14M5 12a2 2 0 110-4h14a2 2 0 110 4M5 12v7a2 2 0 002 2h10a2 2 0 002-2v-7" />
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<p class="font-black text-sm uppercase tracking-wide" x-text="activeProduct?.bogo_rules?.[0]?.badge_text || activeProduct?.bogo_rules?.[0]?.label || ''"></p>
|
|
<p class="text-[10px] opacity-80" x-text="'Actie: ' + (activeProduct?.bogo_rules?.[0]?.rule_title || '')"></p>
|
|
</div>
|
|
</div>
|
|
<!-- Button for flat/percentage discount BOGO rules -->
|
|
<button
|
|
x-show="activeProduct?.bogo_rules?.[0]?.discount_type === 'flat' || activeProduct?.bogo_rules?.[0]?.discount_type === 'percentage'"
|
|
@click="addBogoDiscountedItem(activeProduct)"
|
|
:disabled="!canAddBogoDiscountedItem(activeProduct)"
|
|
class="bg-white text-red-500 px-4 py-2 rounded-xl font-black text-xs uppercase shadow-md hover:bg-red-50 transition disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap">
|
|
<span x-text="'+ €' + getBogoDiscountedPrice(activeProduct)"></span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div x-show="variations.length > 0" x-cloak
|
|
class="mb-8 p-6 bg-blue-50 rounded-3xl border border-blue-100 shadow-inner">
|
|
<select x-model="selectedVariationId" @change="selectVariation()"
|
|
class="w-full border-2 border-white p-4 rounded-2xl font-bold bg-white text-slate-700 shadow-sm outline-none">
|
|
<option value="">-- Kies Optie --</option>
|
|
<template x-for="v in variations" :key="v.id">
|
|
<option :value="v.id" x-text="getVarName(v) + ' (€' + v.price + ')'"></option>
|
|
</template>
|
|
</select>
|
|
</div>
|
|
<div x-show="recommendedOptions.length > 0" x-cloak class="mt-8 space-y-3">
|
|
<p class="text-[10px] font-black text-red-500 uppercase tracking-widest italic px-2 text-center">
|
|
Wellicht ook interessant</p>
|
|
|
|
<template x-for="u in recommendedOptions" :key="u.id">
|
|
<!-- Product with BOGO discount - styled like action block -->
|
|
<div x-show="getYProductBogoDiscount(u)"
|
|
class="p-4 bg-gradient-to-r from-red-500 to-pink-500 rounded-2xl text-white shadow-lg">
|
|
<div class="flex items-center justify-between gap-3">
|
|
<div class="flex items-center gap-3">
|
|
<div class="bg-white/20 p-2 rounded-full">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v13m0-13V6a2 2 0 112 2h-2zm0 0V5.5A2.5 2.5 0 109.5 8H12zm-7 4h14M5 12a2 2 0 110-4h14a2 2 0 110 4M5 12v7a2 2 0 002 2h10a2 2 0 002-2v-7" />
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<p class="font-black text-sm uppercase tracking-wide" x-text="u.name"></p>
|
|
<p class="text-[10px] opacity-80" x-text="getYProductDiscountLabel(u)"></p>
|
|
</div>
|
|
</div>
|
|
<button @click="toggleUpsell(u)"
|
|
:class="isInCart(u.id) ? 'bg-slate-700' : 'bg-white'"
|
|
:disabled="isInCart(u.id)"
|
|
class="text-red-500 px-4 py-2 rounded-xl font-black text-xs uppercase shadow-md hover:bg-red-50 transition disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap">
|
|
<span x-text="isInCart(u.id) ? 'Toegevoegd' : ('+ €' + getYProductDiscountedPrice(u))"></span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Regular product without BOGO discount -->
|
|
<div x-show="!getYProductBogoDiscount(u)"
|
|
class="flex items-center justify-between p-4 border rounded-2xl bg-slate-50 hover:bg-white transition-all shadow-sm">
|
|
<span class="text-xs font-bold text-slate-700"
|
|
x-text="u.name + ' (€' + u.price + ')'"></span>
|
|
<button @click="toggleUpsell(u)" :class="isInCart(u.id) ? 'bg-red-500' : 'bg-green-600'"
|
|
class="text-white px-6 py-2 rounded-xl text-[10px] font-black uppercase shadow-md"
|
|
x-text="isInCart(u.id) ? 'Verwijder' : 'Voeg toe'">
|
|
</button>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
<div class="mt-8 border-t pt-6">
|
|
<h2 class="font-bold mb-4 text-slate-400 uppercase text-[10px] tracking-widest italic text-center">
|
|
Voeg extra product toe</h2>
|
|
<div class="flex gap-2">
|
|
<!-- Custom searchable dropdown for extra products -->
|
|
<div class="relative flex-1" x-data="{ openExtra: false }" @click.away="openExtra = false">
|
|
<button type="button" @click="openExtra = !openExtra"
|
|
class="w-full border-2 border-slate-100 p-3 rounded-xl font-bold text-xs bg-slate-50 outline-none focus:border-green-500 text-left flex justify-between items-center text-slate-700">
|
|
<span x-text="extraProductId ? (products.find(p => p.id == extraProductId)?.name + ' (€' + products.find(p => p.id == extraProductId)?.price + ')') : '-- Voeg product toe --'" class="truncate"></span>
|
|
<svg class="w-4 h-4 text-slate-400 transition-transform flex-shrink-0 ml-2" :class="{ 'rotate-180': openExtra }" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
|
|
</svg>
|
|
</button>
|
|
<div x-show="openExtra" x-cloak
|
|
class="absolute z-50 w-full mt-2 bg-white border-2 border-slate-200 rounded-2xl shadow-xl overflow-hidden">
|
|
<div class="p-3 border-b border-slate-100">
|
|
<input type="text" x-model="extraProductSearch" placeholder="Zoek product..."
|
|
class="w-full border border-slate-200 p-2 rounded-xl text-sm outline-none focus:border-green-500"
|
|
@click.stop>
|
|
</div>
|
|
<div class="max-h-60 overflow-y-auto custom-scrollbar">
|
|
<div @click="extraProductId = ''; openExtra = false; extraProductSearch = ''"
|
|
class="p-3 hover:bg-slate-50 cursor-pointer text-slate-500 font-medium text-xs">
|
|
-- Voeg product toe --
|
|
</div>
|
|
<template x-for="p in filteredExtraProducts" :key="'extra-'+p.id">
|
|
<div @click="extraProductId = p.id; openExtra = false; extraProductSearch = ''"
|
|
class="p-3 hover:bg-green-50 cursor-pointer font-bold text-xs text-slate-700"
|
|
:class="{ 'bg-green-100': extraProductId == p.id }">
|
|
<span x-text="p.name + ' (€' + p.price + ')'"></span>
|
|
</div>
|
|
</template>
|
|
<div x-show="filteredExtraProducts.length === 0" class="p-3 text-slate-400 text-xs text-center">
|
|
Geen producten gevonden
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<button @click="addExtraItem()"
|
|
class="bg-green-600 text-white px-6 py-3 rounded-xl font-black text-[10px] uppercase shadow-md hover:bg-green-700 transition active:scale-95">Add</button>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
<div class="col-span-12 lg:col-span-3">
|
|
<div
|
|
class="bg-slate-900 text-white p-8 rounded-[2.5rem] shadow-2xl sticky top-6 border border-slate-800 transition-all duration-500">
|
|
|
|
<template x-if="orderComplete">
|
|
<div class="text-center py-4">
|
|
<div
|
|
class="bg-green-500/20 text-green-400 w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-6 border-2 border-green-500/30 animate-bounce">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24"
|
|
stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3"
|
|
d="M5 13l4 4L19 7" />
|
|
</svg>
|
|
</div>
|
|
<h2 class="text-xl font-black mb-2 uppercase tracking-tighter text-white">Order Gelukt!</h2>
|
|
<p class="text-slate-400 text-[10px] mb-8 italic uppercase tracking-widest">Klant is
|
|
opgeslagen</p>
|
|
|
|
<div
|
|
class="bg-slate-800/50 rounded-2xl p-6 mb-8 text-left border border-slate-700/50 space-y-4">
|
|
<div class="flex justify-between border-b border-slate-700/50 pb-2">
|
|
<span class="text-[9px] text-slate-500 font-black uppercase">Order ID</span>
|
|
<span class="text-sm font-black text-blue-400" x-text="'#' + lastOrder.id"></span>
|
|
</div>
|
|
<div class="flex justify-between border-b border-slate-700/50 pb-2">
|
|
<span class="text-[9px] text-slate-500 font-black uppercase">Klant</span>
|
|
<span class="text-sm font-bold text-slate-200" x-text="lastOrder.name"></span>
|
|
</div>
|
|
<div class="flex justify-between">
|
|
<span class="text-[9px] text-slate-500 font-black uppercase">Bedrag</span>
|
|
<span class="text-xl font-black text-green-400"
|
|
x-text="'€' + lastOrder.total"></span>
|
|
</div>
|
|
</div>
|
|
|
|
<button @click="resetForNewOrder()"
|
|
class="w-full bg-blue-600 text-white p-5 rounded-2xl font-black shadow-lg hover:bg-blue-500 transition uppercase tracking-widest text-xs active:scale-95">
|
|
Start Nieuwe Order
|
|
</button>
|
|
</div>
|
|
</template>
|
|
|
|
<template x-if="!orderComplete">
|
|
<div>
|
|
<h2
|
|
class="font-bold mb-6 border-b border-slate-800 pb-2 text-[10px] uppercase text-slate-500 tracking-widest italic text-center">
|
|
Samenvatting</h2>
|
|
|
|
<div
|
|
class="space-y-4 mb-6 min-h-[100px] max-h-[300px] overflow-y-auto pr-2 custom-scrollbar">
|
|
<template x-for="(item, index) in cart" :key="index">
|
|
<div class="flex justify-between items-center group"
|
|
:class="{
|
|
'bg-green-900/30 -mx-2 px-2 py-1 rounded-lg': item.isFree,
|
|
'bg-amber-900/30 -mx-2 px-2 py-1 rounded-lg': item.isDiscounted && !item.isFree
|
|
}">
|
|
<div class="flex flex-col flex-1">
|
|
<span x-text="item.name"
|
|
class="text-[11px] font-medium leading-tight"
|
|
:class="{
|
|
'text-green-400': item.isFree,
|
|
'text-amber-400': item.isDiscounted && !item.isFree,
|
|
'text-slate-300': !item.isFree && !item.isDiscounted
|
|
}"></span>
|
|
<div class="flex items-center gap-2">
|
|
<span x-show="(item.isFree || item.isDiscounted) && item.originalPrice"
|
|
x-text="'€' + item.originalPrice"
|
|
class="text-[10px] text-slate-500 line-through"></span>
|
|
<span x-text="'€' + item.price"
|
|
class="text-[11px] font-black"
|
|
:class="{
|
|
'text-green-400': item.isFree,
|
|
'text-amber-400': item.isDiscounted && !item.isFree,
|
|
'text-blue-400': !item.isFree && !item.isDiscounted
|
|
}"></span>
|
|
</div>
|
|
</div>
|
|
<button x-show="!item.isFree" @click="removeFromCart(index)"
|
|
class="text-slate-600 hover:text-red-500 transition">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none"
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
|
</svg>
|
|
</button>
|
|
<span x-show="item.isFree && !item.isDiscounted" class="text-green-400 text-[9px] font-black uppercase">
|
|
Gratis
|
|
</span>
|
|
<span x-show="item.isDiscounted && !item.isFree" class="text-amber-400 text-[9px] font-black uppercase">
|
|
Korting
|
|
</span>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
|
|
<div class="mb-6 pt-4 border-t border-slate-800 flex justify-between items-center">
|
|
<label
|
|
class="text-[10px] text-slate-500 uppercase font-black italic">Verzendkosten</label>
|
|
<input type="number" x-model="shipping" step="0.01"
|
|
class="w-20 bg-slate-800 border border-slate-700 rounded-lg p-1 text-right text-xs font-bold text-blue-400 outline-none">
|
|
</div>
|
|
|
|
<div class="flex justify-between items-center mb-8 pt-4 border-t border-slate-800">
|
|
<span class="text-[10px] text-slate-500 font-black uppercase">Totaal</span>
|
|
<span class="text-3xl font-black text-green-400" x-text="'€' + total"></span>
|
|
</div>
|
|
|
|
<button @click="submitOrder()"
|
|
:disabled="submitting || !form.email || !meta.mediacode || cart.length === 0"
|
|
class="w-full bg-blue-600 hover:bg-blue-500 p-6 rounded-2xl font-black text-lg shadow-xl disabled:opacity-20 uppercase tracking-tighter transition active:scale-95">
|
|
<span x-text="submitting ? 'BEZIG...' : 'BEVESTIGEN'"></span>
|
|
</button>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
|
|
</html>
|