const { useState, useEffect, useRef } = React; const TYPE_OPTIONS = [ { label: 'Web App', multiplier: 1.0, desc: 'Eén organisatie, in de browser. Denk aan een intern dashboard, planningstool of administratie-app. Inclusief gebruikersbeheer en beveiligde login.', }, { label: 'PWA', multiplier: 1.3, desc: 'Alles van een Web App, plus: installeerbaar op telefoon en tablet, werkt offline en ondersteunt push-notificaties. Native app-gevoel zonder App Store.', }, { label: 'SaaS Platform', multiplier: 1.5, desc: 'Meerdere klanten of vestigingen op één platform, elk met eigen data en gebruikers (multi-tenant). Inclusief rollenbeheer en facturatie-koppeling.', }, { label: 'Enterprise Suite', multiplier: 1.8, desc: 'Meerdere gekoppelde modules met integraties naar uw bestaande systemen (ERP, CRM, boekhouding), single sign-on en audit-trails voor compliance.', }, ]; const MAX_SCREENS = 30; const MAX_USERS = 200; function Pricing() { const [screens, setScreens] = useState(8); const [users, setUsers] = useState(25); const [typeIdx, setTypeIdx] = useState(0); const isMax = screens >= MAX_SCREENS; const isMaxUsers = users >= MAX_USERS; const base = 4000; const screenCost = screens * 600; const userCost = Math.round(Math.log(users + 1) * 800 / 100) * 100; const type = TYPE_OPTIONS[typeIdx]; const total = Math.round((base + screenCost + userCost) * type.multiplier / 100) * 100; // Prijs telt soepel naar nieuwe waarde const [displayTotal, setDisplayTotal] = useState(total); const animRef = useRef(null); const currentRef = useRef(total); useEffect(() => { if (animRef.current) animRef.current.pause(); const obj = { v: currentRef.current }; animRef.current = anime({ targets: obj, v: total, duration: 400, easing: 'easeOutQuad', update: () => { currentRef.current = obj.v; setDisplayTotal(Math.round(obj.v / 100) * 100); } }); }, [total]); const fmt = (n) => '€\u00a0' + n.toLocaleString('nl-NL'); return (
Investering

Wat kost uw project?

Bereken een indicatie — en zie precies hoe die is opgebouwd. Geen verplichtingen, geen spam.

Project Estimator
Pas de sliders aan om een globale inschatting te krijgen
setScreens(+e.target.value)} />
Een scherm = één pagina of functie, b.v. "klantoverzicht" of "facturen"
setUsers(+e.target.value)} />
Meer gebruikers vraagt om zwaardere infrastructuur en rollenbeheer
{TYPE_OPTIONS.map((opt, i) => ( ))}
{type.desc}
Basisproject — architectuur, setup, beveiliging {fmt(base)}
{isMax ? '30+' : screens} schermen × €600 {isMax ? 'op maat' : fmt(screenCost)}
Schaal voor {isMaxUsers ? '200+' : users} gebruikers {fmt(userCost)}
{type.label} — factor ×{type.multiplier.toFixed(1)} {type.multiplier === 1 ? '—' : '+' + Math.round((type.multiplier - 1) * 100) + '%'}
{(isMax || isMaxUsers) ? 'Indicatie vanaf' : 'Indicatieve investering'}
Inclusief design, development & 3 maanden support
{(isMax || isMaxUsers) ?
Bij deze omvang maken we een offerte op maat — plan een gratis scoping-gesprek
:
Ter vergelijking: traditionele bureaus rekenen voor vergelijkbaar werk doorgaans €60.000+
}
{(isMax || isMaxUsers) ? 'vanaf ' + fmt(displayTotal) : fmt(displayTotal)}
); } Object.assign(window, { Pricing });