/* Order page — builder direction, no summary, focused on building the order */
const OrderPage = ({ scale = 1 }) => {
const [items, setItems] = React.useState({ 1: 1, 2: 0, 3: 0, 4: 0, 5: 0 });
const [time, setTime] = React.useState('18:00');
const [emailReceipt, setEmailReceipt] = React.useState(false);
const pizzas = [
{ id: 1, name: 'Margherita', desc: 'Tomatensaus, mozzarella, basilicum, oregano', price: 10.00, color: '#dc2626', emoji: '🍅' },
{ id: 2, name: 'Salami', desc: 'Tomatensaus, kaas, salami', price: 11.50, color: '#b91c1c', emoji: '🌶️' },
{ id: 3, name: 'Quattro Stagioni', desc: 'Ham, artisjok, champignons, olijven, kappertjes', price: 12.50, color: '#a16207', emoji: '🍄' },
{ id: 4, name: 'Rucola', desc: 'Mozzarella, parmaham, Parmezaan, rucola', price: 12.00, color: '#15803d', emoji: '🌿' },
{ id: 5, name: 'Napolitana', desc: 'Olijven, ansjovis, kappertjes, Spaanse peper', price: 12.00, color: '#1d4ed8', emoji: '🫒' },
];
const total = pizzas.reduce((s, p) => s + p.price * (items[p.id] || 0), 0);
const totalQty = Object.values(items).reduce((a, b) => a + b, 0);
const inc = (id) => setItems({ ...items, [id]: Math.min(8, (items[id] || 0) + 1) });
const dec = (id) => setItems({ ...items, [id]: Math.max(0, (items[id] || 0) - 1) });
// Generate slots: every 5 min from 17:00 to 20:25 (42 slots). Mark some as full.
const allSlots = [];
for (let h = 17; h <= 20; h++) {
for (let m = 0; m < 60; m += 5) {
if (h === 20 && m > 25) break;
allSlots.push(`${String(h).padStart(2,'0')}:${String(m).padStart(2,'0')}`);
}
}
// Demo: a handful of slots are "full" (peak times)
const fullSlots = new Set(['17:30','18:00','18:05','18:10','18:30','19:00','19:15','19:20']);
// Group by hour for cleaner scanning
const slotsByHour = {};
allSlots.forEach(s => {
const h = s.slice(0,2);
(slotsByHour[h] = slotsByHour[h] || []).push(s);
});
return (
Kies je pizza's
{pizzas.map(p => {
const qty = items[p.id] || 0;
const selected = qty > 0;
return (
{selected && (
{qty}
)}
{p.emoji}
{p.name}
{p.desc}
€{p.price.toFixed(2)}
inc(p.id)} onDec={() => dec(p.id)} color={p.color} />
);
})}
Wanneer haal je op?
Elke 5 min · ma haaltijd 20:25
{Object.entries(slotsByHour).map(([h, slots]) => (
{h}:00 — {h}:55
{slots.map(s => {
const full = fullSlots.has(s);
const selected = time === s;
return (
);
})}
))}
{/* Legend */}
Gekozen
Beschikbaar
Vol
ⓘ Je ophaaltijd is pas definitief na het afrekenen. Als het gekozen tijdslot ondertussen vol raakt, kan je definitieve ophaaltijd iets later worden.
Jouw gegevens
{emailReceipt && (
)}
{/* Sticky bottom CTA — small total preview, no full summary */}
);
};
const BuilderHeader = ({ subtitle }) => (
Gouden Plakje · Pizza Friday
Pizza Zaterdag
{subtitle}
);
const Steps = ({ active }) => (
= 1} done={active > 1} />
= 2} done={active > 2} />
= 3} done={active > 3} />
= 4} done={false} />
);
const Step = ({ n, label, active, done }) => (
{done ? '✓' : n}
{label}
);
const Stepline = () => ;
const SectionTitle = ({ children }) => (
{children}
);
const ChunkyInput = ({ placeholder, type = 'text' }) => (
);
const ChunkyStepper = ({ qty, onInc, onDec, color }) => (
0 ? color : '#a8a29e' }}>
{qty}
);
window.OrderPage = OrderPage;
window.BuilderHeader = BuilderHeader;
window.Steps = Steps;
window.SectionTitle = SectionTitle;