// ASA Timmerwerken v2 — All Pages
// ── Shared Data ──────────────────────────────────────────────
const SERVICES = [
{ slug: 'aanbouw', num: '01', title: 'Aanbouw en uitbouw', short: 'Meer ruimte, meer licht.', body: 'Een uitbreiding die naadloos aansluit op de bestaande woning — van fundering tot dakrand doordacht.', long: 'Meer woonoppervlak zonder te verhuizen. Een aanbouw vergroot niet alleen de ruimte, maar verandert ook hoe je huis aanvoelt. We denken mee over lichtinval, gebruik en architectuur.', img: () => MEDIA.aanbouw },
{ slug: 'renovatie', num: '02', title: 'Complete renovaties', short: 'Van verouderd naar strak.', body: 'Van sloopwerk tot afwerking — wij coördineren het gehele traject, zodat jij geen bouwstress hebt.', long: 'Van verouderde indeling naar een frisse, logische leefomgeving. We begeleiden het volledige traject van sloopwerk tot sleutelklaar opleveren.', img: () => MEDIA.renovatie },
{ slug: 'badkamers', num: '03', title: 'Badkamers en zolders', short: 'Elke centimeter benut.', body: 'Slimme maatoplossingen voor ruimtes die intensief gebruik aankunnen, met aandacht voor ventilatie en comfort.', long: 'Badkamers en zolders vragen om maatoplossingen. We denken na over elke centimeter: afvoer, ventilatie, tegels en inbouwkasten.', img: () => MEDIA.badkamer },
{ slug: 'maatwerk', num: '04', title: 'Maatwerk en houtdetail', short: 'Karakter door vakwerk.', body: 'Kozijnen, gevelbekleding en maatwerkkasten die sfeer en kwaliteit toevoegen voor decennialange duurzaamheid.', long: 'Van kozijnen en gevelbekleding tot maatwerkkasten en houtdetailwerk. Duurzame oplossingen die karakter geven en decennialang meegaan.', img: () => MEDIA.maatwerk },
];
const STEPS = [
{ title: 'Verzoek indienen', body: 'Stuur ons je plannen. We beantwoorden elk verzoek binnen één werkdag en stellen gerichte vragen.' },
{ title: 'Opname op locatie', body: 'We meten en beoordelen de bestaande situatie ter plekke. Geen verrassing achteraf.' },
{ title: 'Offerte en planning', body: 'Een heldere begroting, realistische planning en duidelijke afspraken. Zonder verborgen kosten.' },
{ title: 'Uitvoering en oplevering', body: 'Vakkundig uitgevoerd, netjes opgeleverd — met aandacht tot de allerlaatste hand.' },
];
const FAQS = [
{ q: 'In welk gebied zijn jullie actief?', a: 'Primair Utrecht en de directe omgeving: Zeist, Houten, Nieuwegein, Maarssen en IJsselstein.' },
{ q: 'Hoe vraag ik een offerte aan?', a: 'Via het contactformulier of telefonisch. We plannen daarna een locatiebezoek en sturen een uitgewerkte offerte.' },
{ q: 'Hoe lang duurt een gemiddeld project?', a: 'Een badkamerrenovatie duurt doorgaans 1–2 weken. Een aanbouw 6–10 weken. We geven altijd een realistische planning.' },
{ q: 'Regelen jullie ook vergunningen?', a: 'We adviseren over welke vergunningen nodig zijn en helpen bij de aanvraag. Kleine aanbouwen zijn vaak vergunningsvrij.' },
{ q: 'Werken jullie ook voor bedrijven?', a: 'Ja. Naast particulieren werken we voor bedrijfspanden: kantoorverbouwingen, gevelbekleding en maatwerk.' },
{ q: 'Kan ik ook terecht voor klein onderhoud?', a: 'Neem contact op. Afhankelijk van onze agenda kijken we wat mogelijk is. Renovaties en aanbouwen hebben prioriteit.' },
];
// ── Responsieve stijlen hook ─────────────────────────────────
function useG() {
const mob = useMobile();
const G = {
cont: { maxWidth: 1280, margin: '0 auto', padding: mob ? '0 20px' : '0 48px' },
h1l: { fontFamily:"'Syne',sans-serif", fontSize: mob ? 34 : 62, fontWeight: 700, color: '#FAF6EF', lineHeight: 1.07, letterSpacing: '-0.025em' },
h1d: { fontFamily:"'Syne',sans-serif", fontSize: mob ? 30 : 56, fontWeight: 700, color: '#1C1916', lineHeight: 1.07, letterSpacing: '-0.025em' },
h2: { fontFamily:"'Syne',sans-serif", fontSize: mob ? 26 : 42, fontWeight: 700, color: '#1C1916', lineHeight: 1.12, letterSpacing: '-0.02em' },
h2l: { fontFamily:"'Syne',sans-serif", fontSize: mob ? 26 : 42, fontWeight: 700, color: '#FAF6EF', lineHeight: 1.12, letterSpacing: '-0.02em' },
h3: { fontFamily:"'Syne',sans-serif", fontSize: 20, fontWeight: 600, color: '#1C1916', lineHeight: 1.2 },
p: { fontSize: 16, color: '#6A6058', lineHeight: 1.8 },
pl: { fontSize: 16, color: '#9A8F84', lineHeight: 1.8 },
sec: mob ? '64px 0' : '112px 0',
secSm: mob ? '48px 0' : '80px 0',
gap2: mob ? 32 : 80,
};
return { mob, G };
}
// ── HOME PAGE ────────────────────────────────────────────────
function HomePage({ navigate }) {
const { mob, G } = useG();
const [videoOpen, setVideoOpen] = React.useState(false);
return (
{videoOpen &&
setVideoOpen(false)} />}
{/* Hero — full-screen video */}
Vakmanschap in Utrecht
Renovatie, aanbouw en onderhoud met oog voor detail.
ASA Timmerwerken verzorgt renovaties, aanbouwen en maatwerk voor woningen en bedrijfspanden in Utrecht en omgeving — vakkundig en helder geregeld.
{ navigate('contact'); window.scrollTo(0,0); }}>Offerte aanvragen
{ navigate('diensten'); window.scrollTo(0,0); }}>Onze diensten
{/* Stats row */}
{[['30+','Jaar ervaring'],['100+','Projecten afgerond'],['Utrecht','Werkgebied']].map(([n,l],i) => (
{n.includes('+') ? <>{n.replace('+','')}+ > : n}
{l}
))}
{/* Scrolling marquee strip */}
{[1,2].map(k => (
{['Renovatie','Aanbouw','Badkamers','Maatwerk','Kozijnen','Gevelbekleding','Zolders','Utrecht'].map((t,j) => (
{t}
◆
))}
))}
{/* About intro */}
Over ons
Een bouwpartner die meedenkt van idee tot oplevering.
ASA Timmerwerken verzorgt renovaties, aanbouwen en maatwerk voor woningen en bedrijfspanden. Meer dan 30 jaar ervaring, heldere afspraken en een afwerking die het verschil maakt.
We geloven in korte lijnen en transparante communicatie. Van eerste gesprek tot sleutelklare oplevering.
{ navigate('over'); window.scrollTo(0,0); }}>Lees meer over ons
{!mob && (
30+
Jaar vakmanschap in Utrecht
)}
{/* Diensten grid */}
Onze diensten
Wat kunnen we voor je bouwen?
{!mob &&
{ navigate('diensten'); window.scrollTo(0,0); }}>Alle diensten bekijken }
{SERVICES.map((s, i) => (
{ navigate('dienst-detail'); window.scrollTo(0,0); }}>
e.currentTarget.style.transform = 'scale(1.06)'}
onMouseLeave={e => e.currentTarget.style.transform = 'scale(1)'} />
{s.num}
{s.title}
{s.short}
))}
{mob && (
{ navigate('diensten'); window.scrollTo(0,0); }}>Alle diensten bekijken
)}
{/* Video showcase */}
Bekijk ons werk
Prachtige resultaten, vakkundig afgewerkt.
Elk project is uniek. Van interieur tot exterieur, van badkamer tot volledige verbouwing — de kwaliteit van de afwerking is altijd ons visitekaartje.
setVideoOpen(true)}>
e.currentTarget.style.transform = 'scale(1.03)'}
onMouseLeave={e => e.currentTarget.style.transform = 'scale(1)'} />
{/* Werkwijze */}
Onze aanpak
Heldere stappen, geen verrassingen.
ASA Timmerwerken werkt met een doordachte volgorde zodat je altijd weet wat je mag verwachten.
{!mob &&
{ navigate('contact'); window.scrollTo(0,0); }}>Start jouw project }
{STEPS.map((s, i) => (
))}
{mob && (
{ navigate('contact'); window.scrollTo(0,0); }}>Start jouw project
)}
{/* Photo CTA banner */}
Klaar om te starten?
Vraag vrijblijvend een offerte aan.
We denken graag met je mee over jouw project in Utrecht en omgeving. Geen verplichtingen, gewoon een goed gesprek.
{ navigate('contact'); window.scrollTo(0,0); }}>Offerte aanvragen
{ navigate('over'); window.scrollTo(0,0); }}>Over ons
);
}
// ── OVER ONS ─────────────────────────────────────────────────
function OverOnsPage({ navigate }) {
const { mob, G } = useG();
const [openFaq, setOpenFaq] = React.useState(null);
return (
{/* Hero */}
Over ons
Vakmanschap als fundament.
{/* Intro */}
Een bouwpartner die meedenkt van idee tot nette oplevering.
ASA Timmerwerken is opgericht vanuit de overtuiging dat bouwen en verbouwen helder en rustig kan verlopen. Meer dan 30 jaar ervaring, honderden projecten en een vaste basis in Utrecht.
We geloven in korte communicatielijnen en transparante afspraken. Niet alleen bouwen, maar zorgen dat het eindresultaat rustig, netjes en duurzaam aanvoelt.
{ navigate('contact'); window.scrollTo(0,0); }}>Offerte aanvragen
{ navigate('diensten'); window.scrollTo(0,0); }}>Onze diensten
{[['Heldere communicatie','Korte lijnen, duidelijke afspraken en een planning die overzicht geeft.'],['Strakke afwerking','Het eindresultaat voelt rustig, netjes en duurzaam aan.'],['Meedenken','Oplossingen die passen bij woning, lichtinval, gebruik en budget.'],['Betrouwbaar','Van opname tot oplevering met aandacht voor elk detail.']].map(([t,b],i) => (
))}
{/* Stats */}
{[['30+','Jaar ervaring','Opgericht midden jaren negentig met een focus op kwaliteit boven kwantiteit.'],['100+','Afgeronde projecten','Van kleine renovatie tot complete verbouwing, steeds met dezelfde toewijding.'],['Utrecht','Werkgebied','Actief in Utrecht en alle omliggende gemeenten. Thuis in de regio.']].map(([n,l,d]) => (
{n.includes('+') ? <>{n.replace('+','')}+ > : n}
{l}
{d}
))}
{/* FAQ */}
Veelgestelde vragen
Alles wat je wilt weten.
{FAQS.map((f, i) => (
setOpenFaq(openFaq === i ? null : i)}
style={{ width: '100%', textAlign: 'left', background: 'none', border: 'none', cursor: 'pointer', padding: '24px 0', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 16 }}>
{f.q}
+
{openFaq === i &&
{f.a}
}
))}
);
}
// ── DIENSTEN ─────────────────────────────────────────────────
function DienstenPage({ navigate }) {
const { mob, G } = useG();
return (
Diensten
Wat kunnen we voor je bouwen?
Van kleine renovatie tot complete verbouwing — elk project met dezelfde aandacht en kwaliteit.
{SERVICES.map((s, i) => (
{s.num} — Dienst
{s.title}
{s.long}
{ navigate('dienst-detail'); window.scrollTo(0,0); }}>Bekijk deze dienst
e.currentTarget.style.transform = 'scale(1.04)'}
onMouseLeave={e => e.currentTarget.style.transform = 'scale(1)'} />
))}
Twijfel je welke dienst past?
We denken graag met je mee. Neem contact op voor een vrijblijvend gesprek.
{ navigate('contact'); window.scrollTo(0,0); }}>Neem contact op
);
}
// ── DIENST DETAIL ────────────────────────────────────────────
function DienstDetailPage({ navigate }) {
const { mob, G } = useG();
const s = SERVICES[0];
const gallery = [MEDIA.gallery1, MEDIA.gallery2, MEDIA.gallery3, MEDIA.gallery4, MEDIA.gallery5, MEDIA.gallery6];
const galleryLabels = ['Woonhuis Rotterdam-wijk, Utrecht','Uitbouw woonkeuken, Zeist','Extra verdieping, Utrecht','Serre-uitbouw, Houten','Kozijnen & uitbouw, Maarssen','Kantoor aan huis, Utrecht'];
return (
{/* Hero with video */}
{ navigate('diensten'); window.scrollTo(0,0); }} style={{ background: 'none', border: 'none', color: 'rgba(250,246,239,0.5)', fontSize: 11, cursor: 'pointer', marginBottom: 28, padding: 0, letterSpacing: '0.09em', textTransform: 'uppercase', display: 'flex', alignItems: 'center', gap: 8 }}>← Alle diensten
{s.num} — Dienst
{s.title}
{s.short}
{ navigate('contact'); window.scrollTo(0,0); }}>Offerte aanvragen
{/* Content */}
Wat je krijgt
Meer ruimte, meer licht — aangebouwd op maat.
{s.long}
We ontwerpen mee, denken na over lichtinval en gebruik, en leveren op met een nette afwerking die naadloos aansluit op het bestaande pand.
Inbegrepen in het traject
{['Intakegesprek en inmeting op locatie','Uitgewerkt budgetvoorstel zonder verborgen kosten','Coördinatie van vergunningen indien nodig','Uitvoering inclusief fundering en dakwerk','Afwerking passend bij de bestaande architectuur','Nette oplevering met eindcontrole'].map((item, i) => (
0{i+1}
{item}
))}
{/* Gallery */}
Realisaties
Uitgevoerde aanbouwprojecten.
{gallery.map((src, i) => (
{ e.currentTarget.style.transform = 'scale(1.06)'; e.currentTarget.nextSibling.style.opacity = '1'; }}
onMouseLeave={e => { e.currentTarget.style.transform = 'scale(1)'; e.currentTarget.nextSibling.style.opacity = '0'; }} />
))}
{/* Related */}
Meer diensten
Misschien ook interessant.
{SERVICES.slice(1).map((sv, i) => (
window.scrollTo(0,0)}>
e.currentTarget.style.transform = 'scale(1.06)'}
onMouseLeave={e => e.currentTarget.style.transform = 'scale(1)'} />
))}
);
}
// ── CONTACT ──────────────────────────────────────────────────
function ContactPage() {
const { mob, G } = useG();
const [form, setForm] = React.useState({ naam:'', tel:'', email:'', type:'', bericht:'' });
const [errors, setErrors] = React.useState({});
const [sent, setSent] = React.useState(false);
const validate = () => {
const e = {};
if (!form.naam.trim()) e.naam = 'Vul je naam in';
if (!/\S+@\S+\.\S+/.test(form.email)) e.email = 'Geldig e-mailadres vereist';
if (!form.type) e.type = 'Selecteer een type project';
if (!form.bericht.trim()) e.bericht = 'Omschrijf je project';
return e;
};
const submit = e => { e.preventDefault(); const er = validate(); setErrors(er); if (!Object.keys(er).length) setSent(true); };
const inp = (err) => ({ width:'100%', fontFamily:"'DM Sans',sans-serif", fontSize:15, background:'#fff', color:P.ink, border:`1px solid ${err ? '#B05A3A' : P.warmBdr}`, padding:'13px 16px', outline:'none', boxSizing:'border-box', transition:'border 0.15s', fontWeight: 300 });
return (
Contact
Laten we het over jouw project hebben.
Vraag vrijblijvend een offerte aan. Actief in Utrecht en omgeving.
{/* Contact info */}
{[['Telefoon','+31 6 30133754','tel:+31630133754'],['E-mail','asatimmerwerken@gmail.com','mailto:asatimmerwerken@gmail.com'],['Adres','Pahud de Mortangesdreef 50\n3562 AB Utrecht',null],['Werkgebied','Utrecht en omgeving',null]].map(([l,v,h]) => (
))}
Snel antwoord nodig?
Bel direct. We zijn bereikbaar op werkdagen van 08:00–17:00.
Bel direct
{/* Form */}
{sent ? (
Aanvraag ontvangen
Bedankt, {form.naam.split(' ')[0]}. We nemen binnen 1–2 werkdagen contact met je op.
{ setSent(false); setForm({naam:'',tel:'',email:'',type:'',bericht:''}); setErrors({}); }} style={{ background: 'none', border: `1px solid ${P.warmBdr}`, color: P.warmMid, padding: '11px 24px', cursor: 'pointer', fontSize: 12, letterSpacing: '0.09em', textTransform: 'uppercase', fontFamily:"'DM Sans',sans-serif" }}>Nieuwe aanvraag
) : (
)}
);
}
// ── CALCULATOR ───────────────────────────────────────────────
// Realistische richtprijzen voor de regio Utrecht (incl. materiaal + arbeid,
// excl. btw). Indicatief — de definitieve prijs volgt na opname op locatie.
const CALC_TYPES = [
{ id: 'aanbouw', label: 'Aanbouw / uitbouw', base: 2250, blurb: 'Extra woonruimte op de begane grond.' },
{ id: 'renovatie', label: 'Complete renovatie', base: 1450, blurb: 'Bestaande ruimte volledig vernieuwen.' },
{ id: 'badkamer', label: 'Badkamer', base: 1950, blurb: 'Inclusief tegelwerk, sanitair en afvoer.' },
{ id: 'zolder', label: 'Zolder / verdieping', base: 1150, blurb: 'Onbenutte ruimte bewoonbaar maken.' },
];
const CALC_FINISH = [
{ id: 'casco', label: 'Casco', factor: 1.0, blurb: 'Wind- en waterdicht, zelf afwerken.' },
{ id: 'standaard', label: 'Netjes afgewerkt', factor: 1.18, blurb: 'Instapklaar, nette standaardmaterialen.' },
{ id: 'luxe', label: 'Luxe maatwerk', factor: 1.38, blurb: 'Hoogwaardige materialen en maatwerk.' },
];
const CALC_EXTRAS = [
{ id: 'opening', label: 'Constructieve doorbraak / stalen ligger', add: 6500, weeks: 1 },
{ id: 'pui', label: 'Grote schuifpui of veel glas', add: 7500, weeks: 1 },
{ id: 'daklicht', label: 'Daklicht of lichtstraat', add: 4200, weeks: 1 },
{ id: 'vloer', label: 'Vloerverwarming', perM2: 55, weeks: 0 },
{ id: 'gevel', label: 'Luxe gevelbekleding', add: 4800, weeks: 0 },
];
const eur = new Intl.NumberFormat('nl-NL', { style: 'currency', currency: 'EUR', maximumFractionDigits: 0 });
const num1 = new Intl.NumberFormat('nl-NL', { minimumFractionDigits: 0, maximumFractionDigits: 1 });
const round500 = (v) => Math.round(v / 500) * 500;
function CalculatorPage({ navigate }) {
const { mob, G } = useG();
const [type, setType] = React.useState('aanbouw');
const [finish, setFinish] = React.useState('standaard');
const [width, setWidth] = React.useState(5);
const [depth, setDepth] = React.useState(4);
const [extras, setExtras] = React.useState([]);
const [form, setForm] = React.useState({ naam: '', email: '', tel: '', locatie: '', bericht: '' });
const [errors, setErrors] = React.useState({});
const [status, setStatus] = React.useState(null); // null | 'sending' | 'sent' | 'error'
const toggleExtra = (id) =>
setExtras((p) => (p.includes(id) ? p.filter((x) => x !== id) : [...p, id]));
// ── Berekening ──────────────────────────────────────────────
const calc = React.useMemo(() => {
const t = CALC_TYPES.find((x) => x.id === type);
const f = CALC_FINISH.find((x) => x.id === finish);
const area = Math.max(width * depth, 0);
const chosen = CALC_EXTRAS.filter((e) => extras.includes(e.id));
const baseConstruction = area * t.base * f.factor;
const extrasTotal = chosen.reduce((s, e) => s + (e.add || 0) + (e.perM2 ? e.perM2 * area : 0), 0);
const extraWeeks = chosen.reduce((s, e) => s + (e.weeks || 0), 0);
const low = round500(baseConstruction + extrasTotal);
const high = round500(low * 1.16 + area * 90);
const perM2 = area > 0 ? Math.round(low / area) : 0;
const weeks = area > 0 ? Math.max(3, Math.round(2.5 + area * 0.22 + extraWeeks)) : 0;
return { t, f, area, chosen, low, high, perM2, weeks };
}, [type, finish, width, depth, extras]);
// ── Verzenden naar CRM ──────────────────────────────────────
const submit = async (e) => {
e.preventDefault();
const err = {};
if (!form.naam.trim()) err.naam = 'Vul je naam in';
if (!/\S+@\S+\.\S+/.test(form.email) && !form.tel.trim()) err.email = 'Vul e-mail of telefoon in';
setErrors(err);
if (Object.keys(err).length) return;
setStatus('sending');
const payload = {
locatie: form.locatie || '—',
type: calc.t.label,
afmetingen: `${num1.format(width)} × ${num1.format(depth)} m (${num1.format(calc.area)} m²)`,
afwerking: calc.f.label,
extras: calc.chosen.map((x) => x.label),
indicatie: `${eur.format(calc.low)} – ${eur.format(calc.high)} (excl. btw)`,
prijs_per_m2: `${eur.format(calc.perM2)} / m²`,
bouwtijd_weken: calc.weeks,
toelichting: form.bericht || '—',
};
try {
const res = await fetch('api/api.php?action=lead.create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: form.naam,
email: form.email,
phone: form.tel,
source: 'website-calculator',
amount: calc.low,
payload,
}),
});
const data = await res.json().catch(() => ({}));
setStatus(res.ok && data.ok ? 'sent' : 'error');
} catch (_) {
setStatus('error');
}
};
// ── Gedeelde stijlen ────────────────────────────────────────
const card = { background: '#fff', border: `1px solid ${P.warmBdr}`, padding: mob ? 20 : 28 };
const lbl = { fontFamily: "'DM Mono',monospace", fontSize: 10, color: P.warmMid, letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 14, display: 'block' };
const inp = (err) => ({ width: '100%', fontFamily: "'DM Sans',sans-serif", fontSize: 15, background: '#fff', color: P.ink, border: `1px solid ${err ? '#B05A3A' : P.warmBdr}`, padding: '12px 14px', outline: 'none', boxSizing: 'border-box', fontWeight: 300 });
const ChoiceBtn = ({ active, onClick, title, sub }) => {
const [hov, setHov] = React.useState(false);
return (
setHov(true)} onMouseLeave={() => setHov(false)}
style={{
textAlign: 'left', cursor: 'pointer', padding: '14px 16px', width: '100%',
background: active ? P.ink : (hov ? P.linen : '#fff'),
border: `1px solid ${active ? P.ink : P.warmBdr}`,
transition: 'all 0.18s', display: 'block',
}}>
{title}
{sub && {sub}
}
);
};
const Slider = ({ label, value, set, min, max, step }) => (
);
return (
{/* Hero */}
Prijsindicatie
Wat kost jouw project ongeveer?
Stel je project samen en zie direct een richtprijs en bouwtijd. Vrijblijvend en zonder verplichtingen.
{/* Calculator */}
{/* ── Linker kolom: keuzes ── */}
{/* Type */}
1 — Type project
{CALC_TYPES.map((t) => (
setType(t.id)} title={t.label} sub={t.blurb} />
))}
{/* Afmetingen */}
2 — Afmetingen
Oppervlakte
{num1.format(calc.area)} m²
{/* Afwerking */}
3 — Afwerkingsniveau
{CALC_FINISH.map((f) => (
setFinish(f.id)} title={f.label} sub={f.blurb} />
))}
{/* Extra's */}
4 — Extra opties
{CALC_EXTRAS.map((e) => {
const on = extras.includes(e.id);
const price = e.perM2 ? `${eur.format(e.perM2)}/m²` : `+ ${eur.format(e.add)}`;
return (
toggleExtra(e.id)}
style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, width: '100%', textAlign: 'left', cursor: 'pointer', padding: '13px 16px', background: on ? P.linen : '#fff', border: `1px solid ${on ? P.gold : P.warmBdr}`, transition: 'all 0.18s' }}>
{on && }
{e.label}
{price}
);
})}
{/* ── Rechter kolom: resultaat (sticky) ── */}
Jouw richtprijs
{eur.format(calc.low)}
–
{eur.format(calc.high)}
Indicatie excl. btw · regio Utrecht
{[['Oppervlakte', `${num1.format(calc.area)} m²`], ['Prijs per m²', eur.format(calc.perM2)], ['Bouwtijd', `± ${calc.weeks} wkn`], ['Afwerking', calc.f.label]].map(([k, v]) => (
))}
{calc.chosen.length > 0 && (
Inbegrepen extra's
{calc.chosen.map((x) => (
◆ {x.label}
))}
)}
{/* Contact / verzenden */}
{status === 'sent' ? (
Aanvraag verstuurd
Bedankt {form.naam.split(' ')[0]}. We nemen binnen 1–2 werkdagen contact met je op voor een opname op locatie.
) : (
Ontvang deze berekening en een vrijblijvende offerte op maat:
setForm({ ...form, naam: e.target.value })} />
{errors.naam && {errors.naam}
}
setForm({ ...form, email: e.target.value })} />
setForm({ ...form, tel: e.target.value })} />
{errors.email && {errors.email}
}
setForm({ ...form, locatie: e.target.value })} />
setForm({ ...form, bericht: e.target.value })} />
{status === 'error' && (
)}
{status === 'sending' ? 'Bezig met versturen…' : 'Verstuur mijn aanvraag'}
Richtprijs is indicatief. De exacte prijs volgt na opname op locatie.
)}
{/* Uitleg / vertrouwen */}
{[
['Hoe komt deze prijs tot stand?', 'De richtprijs is gebaseerd op gangbare tarieven in de regio Utrecht: materiaal én arbeid, op basis van oppervlakte, afwerkingsniveau en gekozen opties.'],
['Waarom een prijsrange?', 'Elke situatie is anders. De bandbreedte houdt rekening met variatie in ondergrond, bereikbaarheid en detaillering. Na opname krijg je een vaste offerte.'],
['Wat is de volgende stap?', 'Stuur je berekening op. We plannen een vrijblijvende opname op locatie en werken daarna een heldere, vaste offerte uit — zonder verborgen kosten.'],
].map(([t, b], i) => (
0{i + 1}
{t}
{b}
))}
);
}
Object.assign(window, { SERVICES, STEPS, FAQS, HomePage, OverOnsPage, DienstenPage, DienstDetailPage, ContactPage, CalculatorPage });