1import{Q as _e,U as Ee,V as $e,W as Ie,j as e,X as Pe,B as I,A as De,w as V,o as J,Y as ge,Z as Be,v as Le,h as L,_ as Oe,$ as Ge,x as He,z as We,L as pe,a0 as Ue,a1 as ee,s as ae,H as X,D as Ze,a2 as Ke,a3 as Je,a4 as Ye,N as qe,P as Qe,b as Xe}from"./index-tp3ZBVoO.js";import{b as h}from"./recharts-D0niEN4L.js";import{g as ea}from"./kantoor-data-CnuNrH8Z.js";import{R as te,a as ne}from"./radio-group-BnOzTIOB.js";import{T as aa,a as ta,b as na,c as ia}from"./tooltip-Ba9jkgZI.js";import{A as oe}from"./arrow-right-F5BcStkK.js";import{R as ra}from"./rotate-ccw-DStGrL0z.js";import{S as sa,N as oa,D as la,C as da}from"./siren-DLO93Jqd.js";import{I as he}from"./info-NHuVvVc9.js";import{L as ca}from"./lock-CHsbw-4a.js";import"./circle-PatyTUqG.js";const O=[{key:"organisatie",titel:"Organisatie & beleid",intro:"Heldere afspraken en een vaste verantwoordelijke vormen de basis. Zonder beleid blijft veiligheid vrijblijvend.",gewicht:1,icoon:"ShieldCheck"},{key:"bewustzijn",titel:"Medewerkers & bewustzijn",intro:"Veel incidenten beginnen bij een verkeerde klik. Training en duidelijke regels maken het verschil.",gewicht:1.5,icoon:"Users"},{key:"techniek",titel:"Technische beveiliging",intro:"MFA, updates en endpointbescherming houden de meeste aanvallen tegen. Een ontbrekende update is vaak genoeg.",gewicht:2,icoon:"Cpu"},{key:"data",titel:"Data & back-ups",intro:"Een goede, geteste back-up redt u bij ransomware. Hoeveel klantdata u heeft, bepaalt mede uw risico.",gewicht:2,icoon:"Database"},{key:"leveranciers",titel:"Leveranciers & IT",intro:"U bent ook afhankelijk van uw IT-partij en cloud-leveranciers. Goede afspraken voorkomen verrassingen.",gewicht:1.5,icoon:"Network"},{key:"incident",titel:"Incidenten & continuïteit",intro:"Niet de vraag óf, maar wannéér. Een geoefend noodplan beperkt de schade aanzienlijk.",gewicht:1.5,icoon:"Siren"}],$=(t,r)=>[{waarde:"ja",label:"Ja",risico:0,tone:"ok",feedback:t},{waarde:"nee",label:"Nee",risico:10,tone:"risk",feedback:r}],C=(t,r,i)=>[{waarde:"ja",label:"Ja",risico:0,tone:"ok",feedback:t},{waarde:"nee",label:"Nee",risico:10,tone:"risk",feedback:r},{waarde:"weet_niet",label:"Weet ik niet",risico:7,tone:"unknown",feedback:i}],F=[{id:"V4",module:"organisatie",vraag:"Heeft uw bedrijf afspraken over digitale veiligheid op papier staan?",type:"ja_nee",maxRisico:10,opties:$("Sterk. Op papier staan = aanspreekbaar en overdraagbaar.","Zonder beleid is veiligheid een mening. Vastleggen is de eerste, goedkoopste stap.")},{id:"V5",module:"organisatie",vraag:"Worden die afspraken minstens één keer per jaar bekeken en bijgewerkt?",type:"ja_nee",maxRisico:10,opties:$("Top. Verouderd beleid is bijna net zo riskant als geen beleid.","Beleid van 3 jaar oud past niet meer bij de dreigingen van vandaag. Zet een jaarlijkse review in de agenda.")},{id:"V6",module:"organisatie",vraag:"Is er één vaste persoon verantwoordelijk voor digitale veiligheid?",type:"ja_nee",maxRisico:10,opties:$("Goed geregeld. Verantwoordelijkheid bij iedereen = verantwoordelijkheid bij niemand.","Zonder duidelijke eigenaar blijven taken liggen tot er iets misgaat. Wijs vandaag iemand aan.")},{id:"V7",module:"bewustzijn",vraag:"Krijgen medewerkers minstens één keer per jaar uitleg over digitale veiligheid?",type:"ja_nee",maxRisico:10,opties:$("Sterk. Bewuste medewerkers stoppen meer aanvallen dan welke firewall ook.","9 van de 10 incidenten starten bij een klik. Eén keer per jaar uitleg is het minimum.")},{id:"V8",module:"bewustzijn",vraag:"Test u medewerkers wel eens met een nep-phishingmail?",type:"ja_nee",maxRisico:10,opties:$("Precies zoals het hoort. Oefenen maakt het verschil tussen herkennen en erin trappen.","Zonder oefening weet u niet wie kwetsbaar is. Een phishingtest is voor weinig geld te regelen.")},{id:"V9",module:"bewustzijn",vraag:"Weten medewerkers wat ze moeten doen bij een verdachte e-mail?",type:"ja_nee",maxRisico:10,opties:$("Mooi. Snel melden beperkt de schade dramatisch.","Twijfel = stilte = besmetting. Een simpele 1-regel-instructie ('stuur door naar IT, klik niets aan') helpt enorm.")},{id:"V10",module:"bewustzijn",vraag:"Gebruikt uw bedrijf een wachtwoordmanager?",toelichting:"Een programma dat sterke wachtwoorden maakt en onthoudt, zoals 1Password of Bitwarden.",type:"ja_nee_weetniet",maxRisico:10,opties:C("Top. Hergebruikte wachtwoorden zijn de #1 oorzaak van account-overnames.","Zonder manager hergebruiken medewerkers wachtwoorden. Eén lek bij een externe site = toegang tot uw systemen.","Onbekend = blinde vlek. Vraag uw IT-partij of dit centraal geregeld is.")},{id:"V11",module:"bewustzijn",vraag:"Mogen medewerkers eigen laptop of telefoon voor het werk gebruiken?",type:"meerkeuze",maxRisico:10,opties:[{waarde:"nee",label:"Nee",risico:0,tone:"ok",feedback:"Helder. Alleen beheerde apparaten = veel minder onbekende risico's."},{waarde:"ja_regels",label:"Ja, met regels",risico:4,tone:"warn",feedback:"Werkbaar, mits regels echt worden gehandhaafd. Controleer of MFA en versleuteling ook op die apparaten staan."},{waarde:"ja_geen_regels",label:"Ja, zonder regels",risico:10,tone:"r
1isk",feedback:"Onbeheerde apparaten met bedrijfsdata = openstaande achterdeur. Leg minimaal vast: MFA, schermlock, versleuteling, geen privé-cloud."}]},{id:"V12",module:"techniek",vraag:"Gebruikt u een extra inlogcode op de telefoon (twee-staps-verificatie)?",toelichting:"Bijvoorbeeld een code via een app of sms naast uw wachtwoord.",type:"meerkeuze",maxRisico:10,opties:[{waarde:"overal",label:"Ja, overal",risico:0,tone:"ok",feedback:"Uitstekend. MFA stopt 99% van de account-aanvallen."},{waarde:"deels",label:"Ja, gedeeltelijk",risico:5,tone:"warn",feedback:"Gedeeltelijke MFA is een halve deur op slot. Aanvallers zoeken juist de accounts zonder tweede factor."},{waarde:"nee",label:"Nee",risico:10,tone:"risk",feedback:"Zonder MFA bent u één gelekt wachtwoord verwijderd van een inbraak. Hoogste prioriteit."}]},{id:"V13",module:"techniek",vraag:"Worden updates van programma's en apparaten automatisch en op tijd geïnstalleerd?",toelichting:"Geldt voor laptops, telefoons en software samen.",type:"ja_nee_weetniet",maxRisico:10,opties:C("Goed. De meeste hacks misbruiken bekende lekken waar al een update voor bestaat.","Een achterstallige update is letterlijk een aankondiging voor aanvallers. Zet automatische updates aan.","Niet weten = waarschijnlijk niet op orde. Vraag uw IT-partij om een patch-rapport.")},{id:"V14",module:"techniek",vraag:"Heeft uw bedrijf een actieve firewall en moderne antivirus?",type:"ja_nee_weetniet",maxRisico:10,opties:C("Goede basis. Combineer dit met MFA en updates voor een solide muur.","Geen firewall of antivirus = vrij toegankelijk voor automatische scans en malware.","Onbekend is een rood vlaggetje. Vraag concreet welke producten draaien en of meldingen worden opgevolgd.")},{id:"V15",module:"techniek",vraag:"Worden zakelijke laptops en telefoons centraal beheerd?",toelichting:"De beheerder kan op afstand het apparaat vergrendelen of wissen.",type:"ja_nee_weetniet",maxRisico:10,opties:C("Sterk. Een verloren laptop is dan een kostenpost, geen datalek.","Zonder centraal beheer kunt u een gestolen apparaat niet wissen. Dat is direct meldplichtig bij de AP.","Vraag uw IT-partij of er MDM (Mobile Device Management) draait. Zo niet, is dit een belangrijke vervolgstap.")},{id:"V16",module:"techniek",vraag:"Worden nep-mails die op uw bedrijfsmail lijken automatisch tegengehouden?",toelichting:"Via instellingen voor uw e-maildomein (SPF, DKIM en DMARC). Vraag uw IT-partij als u het niet zeker weet.",type:"ja_nee_weetniet",maxRisico:10,opties:C("Top. SPF/DKIM/DMARC voorkomt dat oplichters in uw naam factuur-fraude plegen.","Zonder deze instellingen kan iedereen mailen 'namens' uw bedrijf. Hoog reputatie- en fraude-risico.","Vrijwel altijd verbetering mogelijk. Vraag een DMARC-rapport op.")},{id:"V17",module:"techniek",vraag:"Is toegang op afstand (thuiswerken) extra beveiligd met een inlogcode?",type:"meerkeuze",maxRisico:10,opties:[{waarde:"ja",label:"Ja",risico:0,tone:"ok",feedback:"Goed. Thuiswerk-VPN of remote desktop zonder MFA is de favoriete ingang van ransomware-groepen."},{waarde:"nee",label:"Nee",risico:10,tone:"risk",feedback:"Remote-toegang zonder MFA is een open uitnodiging. Per direct aanzetten."},{waarde:"nvt",label:"Niet van toepassing",risico:0,tone:"ok",feedback:"Helder, dit risico geldt dan niet voor u."}]},{id:"V18",module:"data",vraag:"Weet u precies waar al uw bedrijfsgegevens staan opgeslagen?",type:"meerkeuze",maxRisico:10,opties:[{waarde:"ja",label:"Ja",risico:0,tone:"ok",feedback:"Sterk. Wat u kent kunt u beveiligen en back-uppen."},{waarde:"deels",label:"Gedeeltelijk",risico:5,tone:"warn",feedback:"Schaduw-IT (Dropbox, WhatsApp, lokale schijven) is waar datalekken meestal gebeuren. Inventariseer."},{waarde:"nee",label:"Nee",risico:10,tone:"risk",feedback:"Bij een datalek moet u binnen 72 uur kunnen melden wat er gelekt is. Zonder overzicht onmogelijk."}]},{id:"V19",module:"data",vraag:"Maakt u elke dag automatisch een back-up van belangrijke gegevens?",type:"ja_nee_weetniet",maxRisico:10,opties:C("Goed. Bij ransomware bepaalt de leeftijd van uw back-up direct uw schade.","Zonder dagelijkse back-up bent u bij ransomware aangewezen op losgeld betalen of dataverlies.","Vraag uw IT-partij om een schriftelijk back-up-overzicht. Dit hoort u te weten.")},{id:"V20",module:"data",vraag:"Staat er een back-up op een plek die niet kan worden aangepast of gewist?",toelichting:"Bijvoorbeeld apart bewaard of in een digitale 'kluis' die niet zomaar te wijzigen is.",type:"ja_nee_weetniet",maxRisico:10,opties:C("Cruciaal goed geregeld. Moderne ransomware zoekt en versleutelt juist de back-ups.","Een back-up die ook versleuteld kan worden is geen back-up. Zonder 'immutable' kopie staat u alsnog stil.","Vraag specifiek naar 'immutable' of 'offline' back-ups. Onmisbaar voor herstel.")}
1,{id:"V21",module:"data",vraag:"Heeft u in het afgelopen jaar getest of een back-up echt terug te zetten is?",type:"ja_nee",maxRisico:10,opties:$("Sterk. Een ongeteste back-up is een aanname, geen zekerheid.","Veel bedrijven ontdekken bij een incident dat back-ups stuk of incompleet zijn. Test minimaal jaarlijks een restore.")},{id:"V22",module:"data",vraag:"Slaat u persoonsgegevens of gevoelige gegevens van klanten op?",toelichting:"Zoals adressen, medische of financiële gegevens.",type:"meerkeuze",maxRisico:10,opties:[{waarde:"veel",label:"Ja, veel",risico:10,tone:"risk",feedback:"Hoog belang: bij een lek meldplicht AVG én potentieel forse boete. Maak dit dossier hard."},{waarde:"weinig",label:"Ja, weinig",risico:5,tone:"warn",feedback:"Ook 'weinig' gegevens vallen onder de AVG. Zorg dat verwerking, bewaartermijn en toegang vastliggen."},{waarde:"nee",label:"Nee",risico:0,tone:"ok",feedback:"Helder, dat beperkt uw AVG-risico aanzienlijk."}]},{id:"V23",module:"leveranciers",vraag:"Heeft u een externe IT-partij die uw systemen beheert?",type:"ja_nee",maxRisico:10,opties:[{waarde:"ja",label:"Ja",risico:0,tone:"ok",feedback:"Prima. Zorg wel dat hun verantwoordelijkheden zwart op wit staan (zie volgende vraag)."},{waarde:"nee",label:"Nee",risico:5,tone:"warn",feedback:"Zelf doen kan, mits iemand binnen het bedrijf echt tijd én kennis heeft. Vaak een onderschat risico."}]},{id:"V24",module:"leveranciers",vraag:"Staan er afspraken over veiligheid in het contract met die partij?",toelichting:"Bijvoorbeeld in een SLA: een schriftelijke afspraak over service en veiligheid.",type:"meerkeuze",maxRisico:10,conditional:{dependsOn:"V23",when:t=>t==="ja"},opties:[{waarde:"ja",label:"Ja",risico:0,tone:"ok",feedback:"Sterk. Bij een incident weet u wie wat doet en binnen welke tijd."},{waarde:"nee",label:"Nee",risico:10,tone:"risk",feedback:"Zonder SLA bent u afhankelijk van goodwill als het misgaat. Leg minimaal reactietijden, back-up en incidentafhandeling vast."},{waarde:"weet_niet",label:"Weet ik niet",risico:7,tone:"unknown",feedback:"Vraag uw contract op. Als 'veiligheid' er niet in staat, is dat een risico op zichzelf."},{waarde:"nvt",label:"Niet van toepassing",risico:0,tone:"ok",feedback:"Helder."}]},{id:"V25",module:"leveranciers",vraag:"Weet u welke beveiliging uw cloud-leveranciers gebruiken?",toelichting:"Denk aan Microsoft 365, Google Workspace of uw online boekhoudprogramma.",type:"meerkeuze",maxRisico:10,opties:[{waarde:"ja",label:"Ja",risico:0,tone:"ok",feedback:"Goed bezig. Cloudleveranciers leveren beveiliging, maar úw configuratie bepaalt het resultaat."},{waarde:"deels",label:"Gedeeltelijk",risico:5,tone:"warn",feedback:"Cloud is geen 'set and forget'. Vraag een security-overzicht of een M365-secure-score op."},{waarde:"nee",label:"Nee",risico:10,tone:"risk",feedback:"Veel cloud-incidenten zijn misconfiguraties van de klant, niet hacks van de leverancier. Laat dit checken."}]},{id:"V26",module:"incident",vraag:"Heeft uw bedrijf een plan voor digitale noodsituaties dat het afgelopen jaar is doorgenomen?",type:"meerkeuze",maxRisico:10,opties:[{waarde:"ja_getest",label:"Ja, getest",risico:0,tone:"ok",feedback:"Voorbeeldig. In crisis vallen mensen terug op wat ze geoefend hebben."},{waarde:"ja_niet_getest",label:"Ja, nog niet getest",risico:5,tone:"warn",feedback:"Een ongetest plan is een hoop papier. Plan een tabletop-oefening van 2 uur."},{waarde:"nee",label:"Nee",risico:10,tone:"risk",feedback:"Bij een incident gaat de eerste dag verloren aan 'wat nu?'. Een simpel A4 met telefoonnummers en stappen helpt al enorm."}]},{id:"V27",module:"incident",vraag:"Weet u wat u moet doen bij een datalek, inclusief melden bij de Autoriteit Persoonsgegevens?",type:"ja_nee_weetniet",maxRisico:10,opties:C("Goed. De 72-uurs meldplicht is hard, dus weten = winst.","Te laat melden bij de AP is zelfstandig een boete-grond. Leg de procedure nu vast, niet straks.","Onbekend = risico. Bij twijfel: bel een DPO of jurist binnen 24 uur na ontdekking.")},{id:"V28",module:"incident",vraag:"Heeft uw bedrijf in de afgelopen 3 jaar te maken gehad met:",toelichting:"Meerdere antwoorden mogelijk.",type:"multi_choice",maxRisico:10,opties:[{waarde:"phishing",label:"Phishing",risico:3,tone:"warn",feedback:""},{waarde:"malware",label:"Virus of malware",risico:4,tone:"warn",feedback:""},{waarde:"ransomware",label:"Ransomware (gijzelsoftware)",risico:6,tone:"r
1isk",feedback:""},{waarde:"datalek",label:"Datalek",risico:6,tone:"risk",feedback:""},{waarde:"fraude",label:"Fraude (bijv. CEO- of WhatsApp-fraude)",risico:5,tone:"risk",feedback:""},{waarde:"geen",label:"Geen van bovenstaande",risico:0,tone:"ok",feedback:""}]},{id:"V28b",module:"incident",vraag:"Heeft dit geleid tot schade, uitval of kosten?",type:"ja_nee",maxRisico:5,conditional:{dependsOn:"V28",when:t=>Array.isArray(t)&&t.length>0&&!(t.length===1&&t[0]==="geen")},opties:[{waarde:"ja",label:"Ja",risico:5,tone:"risk",feedback:"Eerdere schade voorspelt nieuwe schade als de oorzaak niet is weggenomen. Verzekeraars wegen dit zwaar mee."},{waarde:"nee",label:"Nee",risico:0,tone:"ok",feedback:"Geluk gehad. Gebruik dat momentum om de zwakke plek alsnog te dichten."}]}],le={V4:"Leg uw afspraken over digitale veiligheid vast in één kort document (1-2 A4).",V5:"Zet jaarlijks een terugkerende afspraak om uw veiligheidsregels te herzien.",V6:"Wijs één vaste persoon aan als verantwoordelijke voor digitale veiligheid.",V7:"Plan jaarlijks een korte training of e-learning over digitale veiligheid.",V8:"Doe 1-2 keer per jaar een nep-phishingtest om bewustzijn te meten.",V9:"Maak een korte instructie: wat doen medewerkers bij een verdachte e-mail?",V10:"Voer een wachtwoordmanager in (bijv. 1Password of Bitwarden).",V11:"Stel duidelijke regels op voor het gebruik van privé-apparaten voor werk.",V12:"Activeer twee-staps-verificatie (MFA) op alle accounts, ook bestaande.",V13:"Schakel automatische updates in op alle laptops, telefoons en software.",V14:"Controleer of er een actieve firewall én moderne antivirus draait.",V15:"Laat zakelijke apparaten centraal beheren (MDM), bespreek dit met uw IT-partij.",V16:"Stel SPF, DKIM en DMARC in voor uw e-maildomein (uw IT-partij kan helpen).",V17:"Beveilig toegang op afstand altijd met een extra inlogcode (MFA).",V18:"Maak een lijst van waar uw bedrijfsgegevens staan opgeslagen.",V19:"Stel dagelijkse, automatische back-ups in voor alle belangrijke gegevens.",V20:"Bewaar minstens één back-up op een plek die niet aanpasbaar of wisbaar is.",V21:"Test minstens één keer per jaar of een back-up daadwerkelijk terug te zetten is.",V24:"Leg veiligheidsafspraken vast in een contract of SLA met uw IT-partij.",V25:"Vraag uw cloud-leveranciers naar de beveiliging en bewaar de informatie.",V26:"Maak een kort noodplan voor digitale incidenten en oefen het jaarlijks.",V27:"Maak een korte instructie voor het melden van een datalek (binnen 72 uur bij de AP)."};function ma(t,r){if(r===void 0)return!0;const i=F.find(a=>a.id===t);if(!i||Array.isArray(r))return!1;const n=i.opties.find(a=>a.waarde===r);if(!n)return!0;const s=Math.min(...i.opties.map(a=>a.risico));return n.risico>s}function ua(t){const{niveau:r,moduleScores:i,antwoorden:n,bedrijf:s}=t,a=i.filter(u=>u.score<30).map(u=>u.titel),m=["techniek","data","bewustzijn","leveranciers","incident","organisatie"],c=[];F.forEach(u=>{if(!G(u.id,n)||!le[u.id]||!ma(u.id,n[u.id]))return;const w={techniek:2,data:2,bewustzijn:1.5,leveranciers:1.5,incident:1.5,organisatie:1}[u.module]??1,R=u.opties.find(T=>T.waarde===n[u.id])?.risico??u.maxRisico;c.push({vraagId:u.id,risico:R*w,modulegewicht:w})}),c.sort((u,w)=>w.risico-u.risico||m.indexOf(u.vraagId)-m.indexOf(w.vraagId));const d=c.slice(0,5).map(u=>le[u.vraagId]),p=s.heeft_verzekering,l=n.V22==="veel",b=n.V28,x=Array.isArray(b)&&(b.includes("ransomware")||b.includes("datalek"));let f;return p==="ja"?f=r==="hoog"?"U heeft al een cyberverzekering, laat door uw adviseur controleren of de dekking past bij uw huidige risico. Bij hoog risico worden vaak aanvullende voorwaarden gesteld (MFA, back-ups, endpoint-bescherming).":"U heeft al een cyberverzekering. Laat jaarlijks controleren of de dekking nog past bij uw bedrijfssituatie en gegevensvolume.":p==="weet_niet"?f="U weet niet zeker of er een cyberverzekering loopt. Laat dit door uw adviseur uitzoeken, een passende dekking is bij uw risicoprofiel sterk aan te raden.":r==="hoog"||x||l?f="Een cyberverzekering is in uw situatie sterk aan te raden. Verzekeraars stellen vaak MFA, back-ups en endpoint-bescherming als voorwaarde, werk eerst aan de prioriteiten hieronder en laat u adviseren over een passende dekking.":r==="midden"?f="Een cyberverzekering is in uw situatie aan te raden, vooral als aanvulling op de verbeterpunten hieronder. Bespreek de mogelijkheden met uw adviseur.":f="Uw risico is beperkt. Bespreek met uw adviseur of een (basis)cyberverzekering past bij uw bedrijfsomvang en de gevoeligheid van uw gegevens.",{prioriteiten:d,sterkePunten:a,verzekeringAdvies:f,uitlegBlok:{laag:"Uw digitale beveiliging is redelijk goed op orde. Blijf uw maatregelen actueel houden en test jaarlijks of back-ups en noodplannen nog werken.",midden:"Er zijn concrete aandac
1htspunten die de kans op schade vergroten. Met gerichte maatregelen kunt u uw risico aanzienlijk verlagen. Wij adviseren een gesprek over zowel preventie als verzekeringsdekking.",hoog:"Uw bedrijf loopt een verhoogd risico op een cyberincident met mogelijk grote financiële en operationele gevolgen. Wij adviseren om direct te starten met de prioritaire verbeterpunten hieronder en te beoordelen of uw huidige dekking toereikend is."}[r]}}function ke(t,r){if(r===void 0)return null;if(t.type==="multi_choice"&&Array.isArray(r)){if(r.length===0)return null;const m=r.map(l=>t.opties.find(b=>b.waarde===l)?.label).filter(Boolean);if(r.length===1&&r[0]==="geen")return{tone:"ok",feedback:"Mooi, geen incidenten in 3 jaar. Hou de huidige maatregelen op niveau."};const c=["ransomware","datalek","fraude"],d=r.some(l=>c.includes(l)),p=m.join(", ").toLowerCase();return d?{tone:"risk",feedback:`U meldt ${p} in de afgelopen 3 jaar. Dit type incident weegt zwaar bij verzekeraars en duidt op een blootliggende zwakte. Adresseer de oorzaak.`}:{tone:"warn",feedback:`U meldt ${p}. Dat zijn de klassieke voorlopers van een groter incident. Versterk training en e-mailfilters.`}}if(typeof r!="string")return null;const i=t.opties.find(m=>m.waarde===r);if(!i)return null;if(i.feedback&&i.tone)return{tone:i.tone,feedback:i.feedback};const n=t.maxRisico===0?0:i.risico/t.maxRisico;let s="ok";r==="weet_niet"?s="unknown":n>=.7?s="risk":n>0&&(s="warn");const a=s==="ok"?"Goed antwoord, dit beperkt uw risico.":s==="unknown"?"Niet weten is op zich al een signaal. Vraag dit na bij uw IT-partij.":s==="warn"?"Hier valt nog winst te behalen.":"Dit is een belangrijk aandachtspunt voor uw veiligheid.";return{tone:s,feedback:i.feedback??a}}const ga={zorg:1.3,financieel:1.3,juridisch:1.3,retail:1.1,bouw:1,horeca:1,anders:1};function G(t,r){const i=F.find(n=>n.id===t);return i?.conditional?i.conditional.when(r[i.conditional.dependsOn]):!0}function pa(t,r){const i=F.find(n=>n.id===t);if(!i)return 0;if(r===void 0)return i.maxRisico;if(i.type==="multi_choice"&&Array.isArray(r)){const n=r.reduce((s,a)=>{const m=i.opties.find(c=>c.waarde===a);return s+(m?.risico??0)},0);return Math.min(n,i.maxRisico)}return typeof r=="string"?i.opties.find(s=>s.waarde===r)?.risico??i.maxRisico:i.maxRisico}function de(t){return t<=30?"laag":t<=60?"midden":"hoog"}function ce(t,r){const i=O.map(x=>{const f=F.filter(v=>v.module===x.key&&G(v.id,t));let k=0,u=0;f.forEach(v=>{k+=pa(v.id,t[v.id]),u+=v.maxRisico});const w=u===0?0:Math.round(k/u*100);return{module:x.key,titel:x.titel,score:w,niveau:de(w)}});let n=0,s=0;i.forEach(x=>{const f=O.find(k=>k.key===x.module).gewicht;n+=x.score*f,s+=f});let a=s===0?0:n/s;const m=r.sector||"anders",c=ga[m]??1;a=a*c;const d=t.V28;let p=0;Array.isArray(d)&&(d.includes("ransomware")||d.includes("datalek"))&&(p=15),a=Math.min(100,Math.round(a+p));const l=de(a),b=ua({niveau:l,moduleScores:i,antwoorden:t,bedrijf:r});return{totaalscore:a,niveau:l,modules:i,brancheMultiplier:c,incidentBonus:p,prioriteiten:b.prioriteiten,sterkePunten:b.sterkePunten,verzekeringAdvies:b.verzekeringAdvies,uitlegBlok:b.uitlegBlok}}function M(t){return t==="laag"?"Laag risico":t==="midden"?"Gemiddeld risico":"Hoog risico"}function ie(t){return t==="laag"?"#10b981":t==="midden"?"#f59e0b":"#dc2626"}const be={zorg:58,financieel:52,juridisch:55,retail:50,bouw:48,horeca:47,anders:50},re={zorg:"Zorg & welzijn",financieel:"Financiële dienstverlening",juridisch:"Juridisch",bouw:"Bouw & techniek",retail:"Retail & webshop",horeca:"Horeca & events",anders:"Overig"},ha=[{waarde:"zorg",label:"Zorg & welzijn"},{waarde:"financieel",label:"Financiële dienstverlening"},{waarde:"juridisch",label:"Juridisch"},{waarde:"bouw",label:"Bouw & techniek"},{waarde:"retail",label:"Retail & webshop"},{waarde:"horeca",label:"Horeca & events"},{waarde:"anders",label:"Anders"}],ka=["1 (zzp)","2-10","11-25","26-50","50+"];function me(t){const r=t.replace("#",""),i=parseInt(r.length===3?r.split("").map(n=>n+n).join(""):r,16);return[i>>16&255,i>>8&255,i&255]}async function ue(t){const{bedrijf:r,resultaat:i,kantoor:n,klant:s}=t,a=new _e({unit:"pt",format:"a4"}),m=a.internal.pageSize.getWidth(),c=a.internal.pageSize.getHeight(),d=40,p=me(n?.primaire_kleur||"#1D50E3");a.setFillColor(...p),a.rect(0,0,m,140,"F"),a.setTextColor(255),a.setFont("helvetica","bold"),a.setFontSize(24),a.text("Cyber Risico-rapport",d,70),a.setFont("helvetica","normal"),a.setFontSize(12),a.text(`Voor ${r.bedrijfsnaam||"uw bedrijf"}`,d,96),a.setFontSize(10),a.text(`Uitgevoerd op ${new Date().toLocaleDateString("nl-NL",{day:"numeric",month:"long",year:"numeric"})}`+(n?.naam?` ⢠${n.naam}`:""),d,116);let l=180;const[b,x,f]=me(ie(i.niveau));a.setFillColor(b,x,f),a.circle(d+55,l+55,55,"F"),a.setTextColor(255),a.setFont("helvetica","bold"),a.setFontSize(32),a.text(String(i.totaalscore),d+55,l+60,{align:"center"}),a.setFontSize(10),a.text("/ 100",d+55,l+82,{align:"center"}),a.setTextColor(15,23,42),a.setFont("helvetica","bold"),a.setFontSize(18),a.text(M(i.niveau),d+140,l+36),a.setFont("helvetica","normal"),a.setFontSize(10),a.setTextColor(71,85,105);const k=a.splitTextToSize(i.uitlegBlok,m-d*2-140);a.text(k,d+140,l+58),l+=150;const u=r.sector||"anders",w=be[u],v=re[u];a.setFont("helvetica","bold"),a.setFontSize(11),a.setTextColor(15,23,42),a.text("Benchmark",d,l),l+=14,a.setFont("helvetica","normal"),a.setFontSize(10),a.setTextColor(71,85,105);const R=i.totaalscore-w,T=`Bedrijven in de sector ${v} scoren gemiddeld ${w}/100. U scoort ${Math.abs(R)}
1 punten ${R<=0?"lager (beter)":"hoger (meer risico)"} dan dit gemiddelde.`,_=a.splitTextToSize(T,m-d*2);a.text(_,d,l),l+=_.length*13+16,a.setFont("helvetica","bold"),a.setFontSize(13),a.setTextColor(15,23,42),a.text("Scores per module",d,l),l+=4,Ee(a,{startY:l+8,head:[["Module","Risicoscore","Niveau"]],headStyles:{fillColor:p,textColor:255},styles:{fontSize:10,cellPadding:6},columnStyles:{0:{cellWidth:"auto",fontStyle:"bold"},1:{cellWidth:100,halign:"center"},2:{cellWidth:120,halign:"center"}},body:i.modules.map(z=>[z.titel,`${z.score}/100`,M(z.niveau)])}),l=a.lastAutoTable.finalY+24,a.addPage(),l=d,i.sterkePunten.length&&(a.setFont("helvetica","bold"),a.setFontSize(14),a.setTextColor(15,23,42),a.text("Sterke punten",d,l),l+=18,a.setFont("helvetica","normal"),a.setFontSize(10),a.setTextColor(50,60,80),i.sterkePunten.forEach(z=>{a.text(`⢠${z}`,d+4,l),l+=14}),l+=12),a.setFont("helvetica","bold"),a.setFontSize(14),a.setTextColor(15,23,42),a.text("Prioriteiten voor de komende 3 maanden",d,l),l+=18,i.prioriteiten.length===0?(a.setFont("helvetica","italic"),a.setFontSize(10),a.setTextColor(100),a.text("Geen directe actiepunten, blijf alert en evalueer jaarlijks.",d,l),l+=18):(a.setFont("helvetica","normal"),a.setFontSize(10),a.setTextColor(50,60,80),i.prioriteiten.forEach((z,D)=>{const E=a.splitTextToSize(`${D+1}. ${z}`,m-d*2);l+E.length*14>c-d&&(a.addPage(),l=d),a.text(E,d,l),l+=E.length*14+4})),a.addPage(),l=d,a.setFillColor(...p),a.rect(0,0,m,60,"F"),a.setTextColor(255),a.setFont("helvetica","bold"),a.setFontSize(16),a.text("Advies cyberverzekering",d,38),l=100,a.setTextColor(15,23,42),a.setFont("helvetica","normal"),a.setFontSize(11);const P=a.splitTextToSize(i.verzekeringAdvies,m-d*2);a.text(P,d,l),l+=P.length*14+24,n&&(a.setFont("helvetica","bold"),a.setFontSize(12),a.text("Contact",d,l),l+=18,a.setFont("helvetica","normal"),a.setFontSize(10),a.setTextColor(60,70,85),a.text(n.naam,d,l),l+=14,n.email&&(a.text(`E-mail: ${n.email}`,d,l),l+=14),n.telefoon&&(a.text(`Telefoon: ${n.telefoon}`,d,l),l+=14)),l=c-80,a.setFontSize(8),a.setTextColor(120);const Y=a.splitTextToSize("Dit rapport is gebaseerd op uw eigen antwoorden en geeft een eerste indicatie van uw cyberrisico. Het vervangt geen volledige technische audit. Aan dit rapport kunnen geen rechten worden ontleend.",m-d*2);a.text(Y,d,l);const H=(r.bedrijfsnaam||"rapport").replace(/[^a-z0-9]+/gi,"-").toLowerCase();$e(a),s&&await Ie(a,n,"Cyber Risico Scan",`cyberrisico-${H}.pdf`,{score:i.totaalscore,categorie:M(i.niveau),klantNaam:s?.naam,klantEmail:s?.email,klantTelefoon:s?.telefoon,actie:s?.actie,voorkeurDag:s?.voorkeurDag,voorkeurTijdvak:s?.voorkeurTijdvak,opmerking:s?.opmerking}),a.save(`cyberrisico-${H}.pdf`)}const ba=t=>t===void 0?!1:Array.isArray(t)?t.length>0:!0;function K(t){return O.map(r=>{const i=F.filter(a=>a.module===r.key&&G(a.id,t)),n=i.filter(a=>ba(t[a.id])),s=n.filter(a=>ke(a,t[a.id])?.tone==="risk").length;return{key:r.key,titel:r.titel,totaal:i.length,beantwoord:n.length,klaar:i.length>0&&n.length===i.length,risicoRatio:n.length===0?0:s/n.length}})}function fa(t){const i=K(t).filter(a=>a.beantwoord>=1);if(i.length===0)return null;const n=[...i].sort((a,m)=>m.risicoRatio-a.risicoRatio)[0];return n.risicoRatio>=.34?`Eerste indruk: aandachtspunten in '${n.titel}'. Vul de scan af voor uw volledige rapport.`:`Eerste indruk: '${[...i].sort((a,m)=>a.risicoRatio-m.risicoRatio)[0].titel}' staat er goed voor. Vul de scan af voor uw volledige rapport.`}function va(t,r){for(let i=0;i<r.length;i++){const n=r[i],s=t[i];if(n.klaar&&(!s||!s.klaar)){const a=r.filter(p=>p.klaar).length,m=r.length,c=Math.round(a/m*100);let d=`Module '${n.titel}' afgerond.`;return c>=75&&c<100?d=`Bijna klaar - nog ${m-a} module${m-a===1?"":"s"} te gaan.`:c>=50&&c<75?d="Halverwege - uw scan is al voor de helft klaar.":c<50&&(d=`Goed bezig - module '${n.titel}' afgerond.`),{titel:"Mooi, weer een stap dichterbij",tekst:d}}}return null}function xa(t){return!isFinite(t)||t<=0?"bijna klaar":t<60?`nog ± ${Math.max(10,Math.round(t/10)*10)} sec`:`nog ± ${Math.max(1,Math.round(t/60))} min`}const wa={ShieldCheck:He,Users:Ge,Cpu:da,Database:la,Network:oa,Siren:sa};function ja({kantoor:t}){const i=`cyber-scan-${t.id}`,[n,s]=h.useState(0),[a,m]=h.useState({}),[c,d]=h.useState({bedrijfsnaam:"",sector:"",medewerkers:"",heeft_verzekering:"",naam:"",email:"",telefoon:""}),[p,l]=h.useState({}),[b,x]=h.useState("idle"),[f,k]=h.useState(null),[u,w]=h.useState(!1),[v,R]=h.useState(null),[T,_]=h.useState(null),[P,Y]=h.useState(!1),H=h.useRef(Date.now()),z=h.useRef(0),D=h.useRef([]),E=h.useMemo(()=>F.filter(o=>G(o.id,a)),[a]),y=E.length,A=y+1,S=n>=1&&n<=y?E[n-1]??null:null,W=S?O.find(o=>o.key===S.module)??null:null,B=E.filter(o=>{const g=a[o.id];return g===void 0?!1:Array.isArray(g)?g.length>0:!0}).length,fe=h.useMemo(()=>
1K(a),[a]),ve=W?O.findIndex(o=>o.key===W.key):-1,xe=h.useMemo(()=>{const o=(Date.now()-H.current)/1e3,g=z.current,N=g>0?Math.min(15,Math.max(4,o/g)):6;return Math.round((y-B)*N)},[B,y]),se=h.useMemo(()=>!P&&y>0&&B>=Math.ceil(y/2)&&B<y?fa(a):null,[P,B,y,a]);h.useEffect(()=>{try{const o=localStorage.getItem(i);if(!o)return;const g=JSON.parse(o);if(!g||g.stap<=0)return;if(Date.now()-(g.ts??0)>1e3*60*60*24*7){localStorage.removeItem(i);return}R({stap:g.stap,antwoorden:g.antwoorden??{},bedrijf:g.bedrijf??c})}catch{}},[]),h.useEffect(()=>{if(b!=="ok"&&!(n===0&&Object.keys(a).length===0))try{localStorage.setItem(i,JSON.stringify({stap:n,antwoorden:a,bedrijf:c,ts:Date.now()}))}catch{}},[n,a,c,b,i]),h.useEffect(()=>{if(!T)return;const o=setTimeout(()=>_(null),4500);return()=>clearTimeout(o)},[T]);const we=()=>{const o={};return c.bedrijfsnaam.trim()||(o.bedrijfsnaam="Vul uw bedrijfsnaam in."),c.medewerkers||(o.medewerkers="Kies een aantal medewerkers."),c.sector||(o.sector="Kies een sector."),c.heeft_verzekering||(o.heeft_verzekering="Maak een keuze."),o},je=o=>{const g={},N=a[o.id];return(N===void 0||Array.isArray(N)&&N.length===0)&&(g[o.id]="Beantwoord deze vraag om door te gaan."),g},ye=()=>{let o={};if(n===0?o=we():S&&(o=je(S)),Object.keys(o).length){l(o),X();return}if(S){z.current+=1;const g=K(a),N=va(D.current,g);N&&_(N),D.current=g}l({}),s(g=>Math.min(g+1,A)),X()},Ne=()=>{l({}),_(null),s(o=>Math.max(0,o-1)),X()},ze=()=>{v&&(m(v.antwoorden),d(v.bedrijf),s(v.stap),D.current=K(v.antwoorden),z.current=Object.values(v.antwoorden).filter(o=>o!==void 0).length,R(null))},Se=()=>{try{localStorage.removeItem(i)}catch{}R(null)},U=h.useMemo(()=>n>=A?ce(a,c):null,[n,a,c,A]),Ve={terugbellen:"Bel me terug",afspraak:"Afspraak maken",download:"Download rapport"},Te=async o=>{d(j=>({...j,naam:o.naam,email:o.email,telefoon:o.telefoon})),x("submitting"),k(null);const g=ce(a,c),N=[`Cyber Risico Scan ingevuld voor ${c.bedrijfsnaam}.`,`Gevraagde actie: ${Ve[o.actie]}`,...o.voorkeurDag?[`Voorkeursdag: ${o.voorkeurDag}`]:[],...o.voorkeurTijdvak?[`Voorkeurstijdvak: ${o.voorkeurTijdvak}`]:[],...o.opmerking?[`Opmerking: ${o.opmerking}`]:[],`Sector: ${re[c.sector]??c.sector} | Medewerkers: ${c.medewerkers}`,`Cyberverzekering aanwezig: ${c.heeft_verzekering}`,`Totaalscore: ${g.totaalscore}/100, ${M(g.niveau)}`,"","Scores per module:",...g.modules.map(j=>`⢠${j.titel}: ${j.score}/100 (${M(j.niveau)})`),"","Top verbeterpunten:",...g.prioriteiten.slice(0,3).map((j,Z)=>`${Z+1}. ${j}`),"",`Advies verzekering: ${g.verzekeringAdvies}`].join(` 2`),Me=N.length>1990?N.slice(0,1987)+"...":N,q=`Cyberscan ${M(g.niveau)} (${g.totaalscore}/100), ${c.bedrijfsnaam}`,Fe=q.length>145?q.slice(0,142)+"...":q;try{const j=typeof crypto<"u"&&"randomUUID"in crypto?crypto.randomUUID():`${Date.now()}-${Math.random().toString(16).slice(2)}`,{error:Z}=await ae.from("leads").insert({id:j,naam:o.naam.trim().slice(0,100),email:o.email.trim().toLowerCase().slice(0,255),telefoon:o.telefoon?.trim().slice(0,30)||null,onderwerp:Fe,notitie:Me,kantoor_id:t.id,status:"nieuw"});if(Z)throw Z;try{await ae.functions.invoke("send-lead-email",{body:{lead_id:j,bron_label:`Cyber Risico Scan (${t.naam})`}})}catch(Q){console.error("send-lead-email faalde:",Q)}try{localStorage.removeItem(i)}catch{}x("ok"),w(!0);try{await ue({bedrijf:{...c,naam:o.naam,email:o.email,telefoon:o.telefoon},resultaat:g,kantoor:t,klant:{naam:o.naam,email:o.email,telefoon:o.telefoon,actie:
2o.actie,voorkeurDag:o.voorkeurDag,voorkeurTijdvak:o.voorkeurTijdvak,opmerking:o.opmerking}})}catch(Q){console.error("Cyber-PDF genereren mislukte:",Q)}finally{w(!1)}}catch(j){throw console.error("Cyber-lead insert faalde:",j),x("error"),k(j instanceof Error?j.message:"Versturen lukte niet. Probeer het opnieuw of neem contact op."),j}},Ae=async()=>{if(U&&b==="ok"){w(!0);try{await ue({bedrijf:c,resultaat:U,kantoor:t})}finally{w(!1)}}},Re=y+2,Ce=n===0?`Stap 1 van ${Re}`:n===A?"Uw resultaat":`Vraag ${n} van ${y}`;return e.jsx(aa,{delayDuration:150,children:e.jsxs("div",{className:"min-h-screen bg-gradient-to-b from-background to-muted/40",children:[e.jsxs("header",{className:"border-b bg-background/80 backdrop-blur",children:[e.jsxs("div",{className:"mx-auto max-w-5xl px-4 sm:px-6 py-3 flex items-center justify-between gap-4",children:[e.jsxs("div",{className:"font-semibold tracking-tight text-sm sm:text-base",children:["Cyber Risico Scan ",e.jsxs("span",{className:"text-muted-foreground font-normal",children:["⢠",t.naam]})]}),e.jsxs("div",{className:"flex items-center gap-3 text-xs text-muted-foreground",children:[n>0&&n<A&&e.jsxs("span",{className:"hidden sm:inline-flex items-center gap-1.5",children:[e.jsx(Pe,{className:"h-3.5 w-3.5"})," ",xa(xe)]}),e.jsx("span",{className:"hidden sm:inline",children:Ce})]})]}),e.jsx(Ra,{modules:fe,actiefIdx:ve})]}),e.jsxs("main",{className:"mx-auto max-w-5xl px-4 sm:px-6 py-8 sm:py-12",children:[v&&e.jsx(Ca,{percentage:Math.round(Object.values(v.antwoorden).filter(o=>o!==void 0&&(!Array.isArray(o)||o.length>0)).length/Math.max(1,F.filter(o=>G(o.id,v.antwoorden)).length)*100),onVerder:ze,onOpnieuw:Se}),T&&n>0&&n<A&&e.jsx(Ma,{titel:T.titel,tekst:T.tekst,onClose:()=>_(null)}),se&&n>0&&n<A&&e.jsx(Fa,{tekst:se,onClose:()=>Y(!0)}),n===0&&e.jsx("div",{className:"max-w-3xl mx-auto",children:e.jsx(ya,{bedrijf:c,setBedrijf:d,errors:p})}),S&&W&&e.jsx(Na,{vraag:S,module:W,vraagIndex:n,totaalVragen:y,antwoord:a[S.id],setAntwoord:o=>{m(g=>({...g,[S.id]:o})),l(g=>({...g,[S.id]:""}))},error:p[S.id],kantoorNaam:t.naam}),n===A&&U&&e.jsx("div",{className:"max-w-3xl mx-auto",children:e.jsx(Aa,{resultaat:U,bedrijf:c,kantoor:t,onDownload:Ae,pdfBezig:u,errors:p,status:b,serverError:f,onVersturen:Te})}),n<A&&e.jsxs("div",{className:"mt-8 flex flex-wrap items-center justify-between gap-3 max-w-5xl mx-auto",children:[e.jsxs(I,{type:"button",variant:"ghost",onClick:Ne,disabled:n===0,className:"transition-all hover:shadow-sm active:scale-[0.98]",children:[e.jsx(De,{className:"h-4 w-4 mr-2"})," Vorige"]}),e.jsx(I,{type:"button",onClick:ye,className:"transition-all hover:shadow-md active:scale-[0.98]",children:n===y?e.jsxs(e.Fragment,{children:["Bekijk uw rapport ",e.jsx(oe,{className:"h-4 w-4 ml-2"})]}):e.jsxs(e.Fragment,{children:["Volgende ",e.jsx(oe,{className:"h-4 w-4 ml-2"})]})})]})]})]})})}function ya({bedrijf:t,setBedrijf:r,errors:i}){return e.jsxs("div",{children:[e.jsxs("div",{className:"mb-6",children:[e.jsx("div",{className:"text-xs uppercase tracking-wider text-muted-foreground mb-2",children:"Profiel"}),e.jsxs("div",{className:"flex items-start gap-4",children:[e.jsx("div",{className:"rounded-xl bg-primary/10 text-primary p-3 shrink-0",children:e.jsx(Le,{className:"h-6 w-6"})}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold tracking-tight",children:"Over uw bedrijf"}),e.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:"Met deze gegevens stemmen we het rapport en de risico-inschatting beter af op uw situatie."})]})]})]}),e.jsxs("div",{className:"rounded-lg border bg-card p-5 space-y-5",children:[e.jsxs("div",{children:[e.jsxs(L,{htmlFor:"cy-bedrijf",children:["Bedrijfsnaam ",e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsx("div",{className:V("mt-1.5",i.bedrijfsnaam&&"ring-1 ring-destructive rounded-md"),children:e.jsx(Oe,{value:t.bedrijfsnaam,onChange:n=>r(s=>({...s,bedrijfsnaam:n})),onPick:n=>r(s=>({...s,bedrijfsnaam:n.bedrijfsnaam})),placeholder:"Begin met typen om uw bedrijf te zoeken bij de KvKâ¦"})}),i.bedrijfsnaam&&e.jsx("p",{className:"text-xs text-destructive mt-1",children:i.bedrijfsnaam})]}),e.jsxs("div",{children:[e.jsxs(L,{children:["Hoeveel medewerkers heeft uw bedrijf? ",e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsx("div",{className:"mt-2 flex flex-wrap gap-2",children:ka.map(n=>e.jsx("button",{type:"button",onClick:()=>r(s=>({...s,medewerkers:n})),className:V("rounded-md border px-3 py-1.5 text-sm transition-all hover:shadow-sm active:scale-95",t.medewerkers===n?"border-primary bg-primary/10 text-foreground":"bg-background"),children:n},n))}),i.medewerkers&&e.jsx("p",{className:"text-xs text-destructive mt-1",children:i.medewerkers})]}),e.jsxs("div",{children:[e.jsxs(L,{children:["In welke sector werkt u? ",e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsx(te,{className:"mt-2 grid gap-2 sm:grid-cols-2",value:t.sector||"",onValueChange:n=>r(s=>({...s,sector:n})),children:ha.map(n=>e.jsxs("label",{htmlFor:`sec-${n.waarde}`,className:V("flex items-center gap-3 rounded-md border bg-background px-3 py-2.5 cursor-pointer text-sm transition-all","hover:border-primary/40 hover:shadow-sm active:scale-[0.99]",t.sector===n.waarde&&"border-primary bg-primary/5"),children:[e.jsx(ne,{value:n.waarde,id:`sec-${n.waarde}`}),e.jsx("span",{children:n.label})]},n.waarde))}),i.sector&&e.jsx("p",{className:"text-xs text-destructive mt-1",children:i.sector})]}),e.jsxs("div",{children:[e.jsxs(L,{children:["Heeft uw bedrijf al een cyberverzekering? ",e.jsx("span",{className:"text-destructive",children:"*"})]}),e.jsx(te,{className:"mt-2 grid gap-2 sm:grid-cols-3",value:t.heeft_verzekering||"",onValueChange:n=>r(s=>({...s,heeft_verzekering:n})),children:[{waarde:"ja",label:"Ja"},{waarde:"nee",label:"Nee"},{waarde:"weet_niet",label:"Weet ik niet"}].map(n=>e.jsxs("label",{htmlFor:`vz-${n.waarde}`,className:V("flex items-center gap-3 rounded-md border bg-background px-3 py-2.5 cursor-pointer text-sm transition-all","hover:border-primary/40 hover:shadow-sm active:scale-[0.99]",t.heeft_verzekering===n.waarde&&"border-primary bg-primary/5"),children:[e.jsx(ne,{value:n.waarde,id:`vz-${n.waarde}`}),e.jsx("span",{children:n.label})]},n.waarde))}),i.heeft_verzekering&&e.jsx("p",{className:"text-xs text-destructive mt-1",children:i.heeft_verzekering})]})]})]})}function Na({vraag:t,module:r,vraagIndex:i,totaalVragen:n,antwoord:s,setAntwoord:a,error:m,kantoorNaam:c}){const d=wa[r.icoon];return e.jsxs("div",{className:"grid gap-6 lg:grid-cols-[minmax(0,1fr)_320px]",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"mb-5 flex items-center gap-3",children:[e.jsx("div",{className:"rounded-lg bg-primary/10 text-primary p-2 shrink-0",children:e.jsx(d,{className:"h-5 w-5"})}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-wider text-muted-foreground font-medium truncate",children:r.titel}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:["Vraag ",i," van ",n]})]})]}),e.jsxs("div",{className:V("rounded-lg border bg-card p-5 sm:p-6 transition-shadow",m&&"border-destructive shadow-[0_0_0_3px_hsl(var(--destructive)/0.1)]"),children:[e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsxs(L,{className:"text-base sm:text-lg font-medium leading-snug flex-1",children:[t.vraag," ",e.jsx("span",{className:"text-destructive ml-0.5",children:"*"})]}),t.toelichting&&e.jsxs(ta,{children:[e.jsx(na,{asChild:!0,children:e.jsx("button",{type:"button",className:"text-muted-foreground hover:text-foreground mt-1","aria-label":"Toelichting",children:e.jsx(he,{className:"h-4 w-4"})})}),e.jsx(ia,{side:"left",className:"max-w-xs text-xs",children:t.toelichting})]})]}),t.toelichting&&e.jsx("p",{className:"mt-1 text-xs text-muted-foreground sm:hidden",children:t.toelichting}),t.type==="multi_choice"?e.jsx(Va,{opties:t.opties,value:s??[],onChange:p=>a(p)}):e.jsx(te,{className:"mt-3 grid gap-2",value:s??"",onValueChange:p=>a(p),children:t.opties.map(p=>e.jsxs("label",{htmlFor:`${t.id}-${p.waarde}`,className:V("flex items-center gap-3 rounded-md border bg-background px-3 py-2.5 cursor-pointer text-sm transition-all","hover:border-primary/40 hover:shadow-sm active:scale-[0.99]",s===p.waarde&&"border-primary bg-primary/5"),children:[e.jsx(ne,{value:p.waarde,id:`${t.id}-${p.waarde}`}),e.jsx("span",{children:p.label})]},p.waarde))}),m&&e.jsx("p",{className:"mt-3 text-xs text-destructive",children:m})]})]}),e.jsxs("aside",{className:"space-y-4",children:[e.jsx(Sa,{vraag:t,waarde:s}),e.jsx(We,{onderwerp:`Cyber Risico Scan - ${r.titel}: ${t.vraag}`,kantoorNaam:c,systeemExtra:`Je bent een uitleg-assistent bij de Cyber Risico Scan. Geef UITSLUITEND uitleg en achtergrond bij de huidige vraag en cyberveiligheidsbegrippen (MFA, wachtwoordmanager, back-up, phishing, ransomware, SPF/DKIM/DMARC, encryptie, AVG/datalek, leveranciersrisico). Geef NOOIT advies of de schijn van advies. Verwijs voor advies altijd door naar een menselijke Wft-adviseur van ${c}. Houd antwoorden kort (max ~120 woorden), in helder Nederlands. Gebruik nooit lange streepjes; gebruik '-' of een nieuwe zin. 3 4Huidige vraag: "${t.vraag}"${t.toelichting?` 5Toelichting: ${t.toelichting}`:""} 6Module: ${r.titel}`,context:{module:r.titel,vraag:t.vraag},suggesties:["Wat betekent deze vraag voor mijn bedrijf?","Waarom telt dit voor cyberweerbaarheid?","Welke begrippen moet ik kennen?"],intro:"Vragen over deze vraag? Ik geef u graag uitleg. Voor persoonlijk advies verwijs ik u door naar uw adviseur."})]})]})}const za={ok:{wrap:"border-emerald-500 bg-emerald-50 text-emerald-950",icon:"text-emerald-600",Icon:J},warn:{wrap:"border-amber-500 bg-amber-50 text-amber-950",icon:"text-amber-600",Icon:ee},risk:{wrap:"border-red-500 bg-red-50 text-red-950",icon:"text-red-600",Icon:ee},unknown:{wrap:"border-slate-400 bg-slate-50 text-slate-900",icon:"text-slate-500",Icon:Ke}};function Sa({vraag:t,waarde:r}){const i=ke(t,r);return e.jsxs("div",{className:"rounded-xl border border-border/70 bg-card p-5 shadow-sm min-h-[140px]",children:[e.jsxs("div",{className:"flex items-center gap-2 text-muted-foreground",children:[e.jsx(he,{className:"h-4 w-4"}),e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider",children:"Toelichting"})]}),!i||!i.feedback?e.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:"Kies een antwoord, hier verschijnt dan een korte uitleg."}):(()=>{const n=za[i.tone];return e.jsxs("div",{className:V("mt-3 flex gap-3 rounded-md border-l-4 p-3 text-sm animate-in fade-in slide-in-from-top-1",n.wrap),children:[e.jsx(n.Icon,{className:V("h-5 w-5 shrink-0 mt-0.5",n.icon)}),e.jsx("p",{className:"leading-relaxed",children:i.feedback})]})})()]})}function Va({opties:t,value:r,onChange:i}){const n=s=>{if(s==="geen"){i(r.includes("geen")?[]:["geen"]);return}const a=r.filter(m=>m!=="geen");i(a.includes(s)?a.filter(m=>m!==s):[...a,s])};return e.jsx("div",{className:"mt-3 grid gap-2",children:t.map(s=>{const a=r.includes(s.waarde);return e.jsxs("label",{className:V("flex items-center gap-3 rounded-md border bg-background px-3 py-2.5 cursor-pointer text-sm transition-all","hover:border-primary/40 hover:shadow-sm active:scale-[0.99]",a&&"border-primary bg-primary/5"),children:[e.jsx(Ze,{checked:a,onCheckedChange:()=>n(s.waarde)}),e.jsx("span",{children:s.label})]},s.waarde)})})}function Ta({errors:t,kantoor:r,status:i,serverError:n,onVersturen:s}){return e.jsxs("div",{id:"cyber-contact-blok",className:"rounded-2xl border bg-card p-6 mb-6",children:[n&&e.jsx("div",{className:"rounded-md border border-destructive/30 bg-destructive/10 p-3 text-sm text-destructive mb-4",children:n}),e.jsx(Je,{kantoor:r,onVerstuur:s,documentWoord:"rapport"})]})}function Aa({resultaat:t,bedrijf:r,kantoor:i,onDownload:n,pdfBezig:s,errors:a,status:m,serverError:c,onVersturen:d}){const p=ie(t.niveau),l=r.sector||"anders",b=be[l],x=t.totaalscore-b,f=m==="ok";return e.jsxs("div",{children:[e.jsxs("div",{className:"rounded-2xl border bg-card p-6 sm:p-8 mb-6 relative overflow-hidden",children:[e.jsx(J,{className:"absolute top-4 right-4 h-5 w-5 text-emerald-500"}),e.jsx("div",{className:"text-xs uppercase tracking-wider text-muted-foreground mb-2",children:"Uw resultaat"}),e.jsx("h1",{className:"text-2xl sm:text-3xl font-bold tracking-tight",children:r.bedrijfsnaam||"Uw bedrijf"}),e.jsxs("div",{className:"mt-6 flex items-center gap-5",children:[e.jsx("div",{className:"h-24 w-24 rounded-full flex items-center justify-center text-white font-bold text-3xl shrink-0 shadow-lg",style:{backgroundColor:p},children:t.totaalscore}),e.jsxs("div",{children:[e.jsxs("div",{className:"text-lg font-semibold",style:{color:p},children:[M(t.niveau),", ",t.totaalscore,"/100"]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1 max-w-md",children:t.uitlegBlok})]})]}),e.jsxs("div",{className:"mt-4 text-xs text-muted-foreground",children:["Sector ",re[l]," scoort gemiddeld ",b,"/100, u scoort ",Math.abs(x)," punten ",x<=0?"lager
6(beter)":"hoger (meer risico)",".",t.incidentBonus>0&&e.jsxs(e.Fragment,{children:[" Eerder incident telt mee als +",t.incidentBonus," risicopunten."]})]}),e.jsx("div",{className:"mt-6 flex flex-wrap gap-2",children:e.jsxs(I,{onClick:n,disabled:!f||s,className:"transition-all hover:shadow-md active:scale-[0.98]",children:[s?e.jsx(pe,{className:"h-4 w-4 mr-2 animate-spin"}):f?e.jsx(Ue,{className:"h-4 w-4 mr-2"}):e.jsx(ca,{className:"h-4 w-4 mr-2"}),f?"Download rapport (PDF)":"Download na invullen gegevens"]})})]}),e.jsx(Ta,{errors:a,kantoor:i,status:m,serverError:c,onVersturen:d}),e.jsx("h2",{className:"text-lg font-semibold mb-3",children:"Scores per module"}),e.jsx("div",{className:"grid sm:grid-cols-2 gap-3 mb-8",children:t.modules.map(k=>{const u=ie(k.niveau);return e.jsxs("div",{className:"rounded-lg border bg-card p-4",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("div",{className:"font-medium text-sm",children:k.titel}),e.jsxs("div",{className:"text-sm font-semibold",style:{color:u},children:[k.score,"/100"]})]}),e.jsx("div",{className:"h-2 rounded-full bg-muted overflow-hidden",children:e.jsx("div",{className:"h-full transition-all",style:{width:`${k.score}%`,backgroundColor:u}})}),e.jsx("div",{className:"mt-2 text-xs",style:{color:u},children:M(k.niveau)})]},k.module)})}),t.sterkePunten.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs("h2",{className:"text-lg font-semibold mb-3 flex items-center gap-2",children:[e.jsx(J,{className:"h-5 w-5 text-emerald-500"})," Sterke punten"]}),e.jsx("ul",{className:"rounded-lg border bg-card p-5 mb-8 space-y-2 text-sm",children:t.sterkePunten.map((k,u)=>e.jsxs("li",{className:"flex gap-2",children:[e.jsx("span",{className:"text-emerald-500 mt-0.5",children:"â"}),e.jsx("span",{children:k})]},u))})]}),e.jsxs("h2",{className:"text-lg font-semibold mb-3 flex items-center gap-2",children:[e.jsx(ee,{className:"h-5 w-5 text-amber-500"})," Prioriteiten voor de komende 3 maanden"]}),e.jsx("div",{className:"rounded-lg border bg-card p-5 mb-8",children:t.prioriteiten.length===0?e.jsx("p",{className:"text-sm text-muted-foreground italic",children:"Geen directe actiepunten, blijf alert en evalueer jaarlijks."}):e.jsx("ol",{className:"space-y-3 text-sm",children:t.prioriteiten.map((k,u)=>e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"flex-shrink-0 w-6 h-6 rounded-full bg-primary/10 text-primary flex items-center justify-center text-xs font-semibold",children:u+1}),e.jsx("span",{children:k})]},u))})}),e.jsx("h2",{className:"text-lg font-semibold mb-3",children:"Advies cyberverzekering"}),e.jsx("div",{className:"rounded-lg border bg-primary/5 p-5 text-sm mb-6",children:e.jsx("p",{children:t.verzekeringAdvies})}),f&&e.jsx("div",{className:"rounded-lg border bg-card p-5 text-sm",children:e.jsxs("p",{children:["Een kopie van deze enquête is verstuurd naar ",e.jsx("b",{children:i.naam}),". Zij nemen binnenkort contact met u op om de resultaten en eventuele cyberverzekering te bespreken."]})})]})}function Ra({modules:t,actiefIdx:r}){return e.jsx("div",{className:"flex gap-0.5 px-1 pb-0.5",children:t.map((i,n)=>{const s=i.totaal===0?0:Math.round(i.beantwoord/i.totaal*100),a=n===r;return e.jsx("div",{className:"flex-1 h-1.5 bg-muted overflow-hidden rounded-sm",title:`${i.titel}: ${i.beantwoord}/${i.totaal}`,children:e.jsx("div",{className:V("h-full transition-all",i.klaar?"bg-emerald-500":a?"bg-primary":"bg-primary/60"),style:{width:`${s}%`}})},i.key)})})}function Ca({percentage:t,onVerder:r,onOpnieuw:i}){return e.jsxs("div",{className:"mb-6 rounded-xl border border-primary/30 bg-primary/5 p-4 sm:p-5 flex flex-wrap items-center gap-3 animate-in fade-in slide-in-from-top-2",children:[e.jsx(ra,{className:"h-5 w-5 text-primary shrink-0"}),e.jsxs("div",{className:"flex-1 min-w-[200px] text-sm",children:[e.jsxs("div",{className:"font-medium",children:["U had de scan al voor ",t,"% afgerond."]}),e.jsx("div",{className:"text-muted-foreground text-xs mt-0.5",children:"Ga verder waar u was gebleven, of begin opnieuw."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(I,{size:"sm",variant:"ghost",onClick:i,className:"transition-all hover:shadow-sm active:scale-[0.98]",children:"Opnieuw"}),e.jsx(I,{size:"sm",onClick:r,className:"transition-all hover:shadow-md active:scale-[0.98]",children:"Verder gaan"})]})]})}function Ma({titel:t,tekst:r,onClose:i}){return e.jsxs("div",{className:"mb-6 rounded-xl border border-emerald-200 bg-emerald-50 p-4 flex items-start gap-3 animate-in fade-in slide-in-from-top-2",children:[e.jsx(J,{className:"h-5 w-5 text-emerald-600 shrink-0 mt-0.5"}),e.jsxs("div",{className:"flex-1 text-sm",children:[e.jsx("div",{className:"font-medium text-emerald-900",children:t}),e.jsx("div",{className:"text-emerald-900/80 text-xs mt-0.5",children:r})]}),e.jsx("button",{type:"button",onClick:i,className:"text-emerald-700/70 hover:text-emerald-900","aria-label":"Sluiten",children:e.jsx(ge,{className:"h-4 w-4"})})]})}function Fa({tekst:t,onClose:r}){return e.jsxs("div",{className:"mb-6 rounded-xl border border-primary/30 bg-gradient-to-r from-primary/5 to-transparent p-4 flex items-start gap-3 animate-in fade-in slide-in-from-top-2",children:[e.jsx(Be,{className:"h-5 w-5 text-primary shrink-0 mt-0.5"}),e.jsxs("div",{className:"flex-1 text-sm",children:[e.jsx("div",{className:"font-medium",children:"Een voorproefje"}),e.jsx("div",{className:"text-muted-foreground text-xs mt-0.5",children:t})]}),e.jsx("button",{type:"button",onClick:r,className:"text-muted-foreground hover:text-foreground","aria-label":"Sluiten",children:e.jsx(ge,{className:"h-4 w-4"})})]})}function Ua(){const{kantoorSlug:t}=Ye.useParams(),[r,i]=h.useState({status:"loading"});if(h.useEffect(()=>{let s=!1;return(async()=>{i({status:"loading"});const a=await ea(t);if(s)return;if(!a){qe(),i({status:"niet-gevonden"});return}const{data:m}=await ae.from("kantoren_publiek").select("email, telefoon").eq("id",a.id).maybeSingle();s||(Qe(a),i({status:"ok",kantoor:{...a,email:m?.email??null,telefoon:m?.telefoon??null}}))})(),()=>{s=!0}},[t]),r.status==="loading")return e.jsx("div",{className:"min-h-screen flex items-center justify-center",children:e.jsx(pe,{className:"h-6 w-6 animate-spin text-muted-foreground"})});if(r.status==="niet-gevonden")return e.jsxs(_a,{titel:"Kantoor niet gevonden",children:[e.jsxs("p",{className:"text-muted-foreground",children:["Het adres ",e.jsxs("code",{className:"bg-muted px-1.5 py-0.5 rounded",children:["/cyber/",t]})," hoort niet bij een bekend kantoor."]}),e.jsx("div",{className:"mt-6",children:e.jsx(Xe,{to:"/cyber",children:e.jsx(I,{variant:"outline",children:"Naar Cyber Risico Scan"})})})]});const n=r.kantoor.primaire_kleur||void 0;return e.jsx("div",{style:n?{"--primary":n}:void 0,children:e.jsx(ja,{kantoor:r.kantoor})})}function _a({titel:t,children:r}){return e.jsx("div",{className:"min-h-screen bg-gradient-to-b from-background to-muted/40",children:e.jsxs("section",{className:"mx-auto max-w-2xl px-6 py-24",children:[e.jsx("h1",{className:"text-3xl font-bold tracking-tight mb-4",children:t}),r]})})}export{Ua as component};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.