Upload index.html
Browse files- index.html +26 -21
index.html
CHANGED
|
@@ -181,6 +181,11 @@
|
|
| 181 |
.source-issue-detail{font-size:10px;color:#adbfdb;line-height:1.5;margin:4px 0 0}
|
| 182 |
.source-audit-ok{font-size:10px;color:#71e8be;line-height:1.5}
|
| 183 |
@media(max-width:1080px){header{grid-template-columns:1fr;justify-items:start}.header-center-logo{justify-content:flex-start;padding:4px 0 0}.header-center-logo img{height:60px}.header-actions{justify-self:start}}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
</style></head>
|
| 185 |
<body>
|
| 186 |
<div class="app">
|
|
@@ -246,7 +251,7 @@
|
|
| 246 |
</main>
|
| 247 |
</div>
|
| 248 |
<div id="reportOverlay" role="dialog" aria-modal="true" aria-label="Reakt Monitor rapport" aria-hidden="true">
|
| 249 |
-
<div class="report-actions"><span><strong>REAKT · Rapportvoorvertoning v1.6.
|
| 250 |
<section id="reportSheet" aria-label="Witte Inloop Monitor"></section>
|
| 251 |
</div>
|
| 252 |
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
|
|
@@ -911,43 +916,43 @@ function getReportData(){
|
|
| 911 |
const result=importedData.last,site=result.site,period=result.period;
|
| 912 |
const history=importedData.all.filter(r=>(site==='*'||r.site===site)&&r.date<=period.peildatum);
|
| 913 |
const quarter=history.filter(r=>r.date>=period.begin);
|
| 914 |
-
const counts=new Map(),uniqueDates=new Set(),byMonth=new Map(period.months.map(m=>[m,0])),byWeek=[0,0,0,0,0,0,0];
|
| 915 |
for(const r of quarter){
|
| 916 |
const key=JSON.stringify([r.site,r.id,r.date]);if(uniqueDates.has(key))continue;
|
| 917 |
uniqueDates.add(key);
|
| 918 |
const mk=r.date.slice(0,7);byMonth.set(mk,(byMonth.get(mk)||0)+1);
|
| 919 |
const wk=new Date(r.date+'T12:00:00Z').getUTCDay();byWeek[(wk+6)%7]++;
|
| 920 |
const ck=JSON.stringify([r.site,r.id]);counts.set(ck,(counts.get(ck)||0)+1);
|
|
|
|
|
|
|
| 921 |
}
|
| 922 |
const intensities=[0,0,0,0,0],daysPerClient=[...counts.values()];
|
| 923 |
daysPerClient.forEach(c=>{intensities[c<=5?0:c<=20?1:c<=50?2:c<=100?3:4]++});
|
| 924 |
const sorted=daysPerClient.sort((a,b)=>a-b),median=sorted.length?(sorted.length%2?sorted[(sorted.length-1)/2]:(sorted[sorted.length/2-1]+sorted[sorted.length/2])/2):0;
|
| 925 |
const monthLabels=['jan','feb','mrt','apr','mei','jun','jul','aug','sep','okt','nov','dec'];
|
| 926 |
-
const months=period.months.map(key=>({key,label:monthLabels[Number(key.slice(5))-1],visits:byMonth.get(key),newIntake:result.instroomByMonth.get(key)||0}));
|
| 927 |
return {site:site==='*'?'Alle locaties':site,period,months,byWeek,intensities,
|
| 928 |
visits:uniqueDates.size,unique:result.unique,quarterClients:result.quarterClients,newIntake:result.newIntake,active:result.active,
|
| 929 |
-
average:counts.size?uniqueDates.size/counts.size:0,median,maxDays:Math.max(0,...daysPerClient),
|
| 930 |
earliest:period.begin,latest:period.peildatum,issues:result.passConflicts+result.identityConflicts+result.unmatchedPasses,hasShadow:false,
|
| 931 |
historyLoaded:result.historyLoaded,correctedExisting:result.correctedExisting,correctedJanuary:result.correctedJanuary};
|
| 932 |
}
|
| 933 |
function buildWhiteReport(){
|
| 934 |
const d=getReportData();if(!d)return;
|
| 935 |
const range=d.earliest===d.latest?d.earliest:`${d.earliest} t/m ${d.latest}`;
|
| 936 |
-
const
|
| 937 |
const activeWindow=readableDate(d.period.activeFrom)+' t/m '+readableDate(d.period.peildatum);
|
| 938 |
-
const mon=d.months.map(m=>m.label),values=d.months.map(m=>m.visits),newPerMonth=d.months.map(m=>m.newIntake),week=['Ma','Di','Wo','Do','Vr','Za','Zo'];
|
| 939 |
const weekdayMax=Math.max(...d.byWeek),weekdayMin=Math.min(...d.byWeek),busiest=week[d.byWeek.indexOf(weekdayMax)],quietest=week[d.byWeek.indexOf(weekdayMin)];
|
| 940 |
-
const summary=[`In ${d.period.label} zijn bij ${escapeHTML(d.site)} ${reportNL(d.unique)} unieke cliënten met minimaal één geldige scan geregistreerd. Deze cliënten waren samen goed voor ${reportNL(d.visits)}
|
| 941 |
-
`De instroom in ${d.period.label} bedraagt ${reportNL(d.newIntake)} cliënten. Er zijn ${reportNL(d.active)} actieve cliënten met minimaal één scan van ${activeWindow}.`,
|
| 942 |
-
`
|
| 943 |
-
`
|
| 944 |
-
const kpis=[{klass:'purple',icon:'♟',label:'Unieke cliënten',value:reportNL(d.unique),sub:'
|
| 945 |
{klass:'green',icon:'+',label:'Nieuwe instroom',value:reportNL(d.newIntake),sub:'Eerste geldige scan op locatie in '+d.period.label},
|
| 946 |
-
{klass:'purple',icon:'♙',label:'Actieve cliënten',value:reportNL(d.active),sub:'
|
| 947 |
-
{klass:'orange',icon:'▦',label:'
|
| 948 |
const kpiHTML=kpis.map(k=>`<div class="report-kpi ${k.klass}"><div class="k-icon">${k.icon}</div><div><div class="k-label">${k.label}</div><div class="k-num">${k.value}</div><div class="k-sub">${k.sub}</div></div><div class="k-underline"></div></div>`).join('');
|
| 949 |
-
const maxI=Math.max(1,...d.intensities),ilabels=['1 – 5 dagen','6 – 20 dagen','21 – 50 dagen','51 – 100 dagen','101 dagen of meer'];
|
| 950 |
-
const itHTML=d.intensities.map((c,i)=>`<div class="report-intensity-row"><span class="int-label">${ilabels[i]}</span><div class="int-bar-track"><div class="int-bar" style="width:${c/maxI*100}%"></div></div><strong>${c}</strong></div>`).join('');
|
| 951 |
$('reportSheet').innerHTML=`
|
| 952 |
<div class="report-brand"><img class="report-logo" src="data:image/png;base64,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" alt="Reakt PG logo"></div>
|
| 953 |
<div class="report-heading"><div><h1>Reakt Inloop Monitor ${escapeHTML(d.site)}</h1><p>Inzicht in bereik, betrokkenheid en bezoekpatronen</p></div>
|
|
@@ -960,19 +965,19 @@ function buildWhiteReport(){
|
|
| 960 |
<div><b>Nieuwe instroom</b>De eerste geldige scan van een cliënt op deze locatie (binnen de beschikbare historie) valt in de rapportageperiode.</div>
|
| 961 |
<div><b>Actieve cliënten</b>Minimaal één scan op deze locatie tussen ${escapeHTML(activeWindow)}.</div>
|
| 962 |
</div>
|
| 963 |
-
<div class="report-definitions-note">Een vervangende scanpas telt niet als nieuwe cliënt
|
| 964 |
</section>
|
| 965 |
<div class="report-chart-grid">
|
| 966 |
-
<section class="report-panel"><h2>Instroom per maand <small>(nieuwe
|
| 967 |
-
<section class="report-panel"><h2>
|
| 968 |
<section class="report-panel"><h2>Bezoekdagen per weekdag</h2><div class="chart-box">${reportChartBars(week,d.byWeek,'#ff6410',true)}</div></section>
|
| 969 |
</div>
|
| 970 |
<div class="report-bottom-grid">
|
| 971 |
-
<section class="report-panel"><h2>Kerncijfers locatie</h2><table class="report-mini-table"><thead><tr><th>Locatie</th><th>Unieke cliënten</th><th>
|
| 972 |
-
<section class="report-panel"><h2>
|
| 973 |
<section class="report-panel"><h2>Managementanalyse</h2><div class="report-analysis">${summary.map(t=>`<p>${t}</p>`).join('')}</div></section>
|
| 974 |
</div>
|
| 975 |
-
<div class="report-foot"><span>Bron:
|
| 976 |
}
|
| 977 |
function openWhiteReport(){
|
| 978 |
if(!importedData?.last){alert('Upload eerst een Excelbestand en rond de analyse af. Deze witte rapportage gebruikt geen verzonnen demo-KPI’s.');return;}
|
|
|
|
| 181 |
.source-issue-detail{font-size:10px;color:#adbfdb;line-height:1.5;margin:4px 0 0}
|
| 182 |
.source-audit-ok{font-size:10px;color:#71e8be;line-height:1.5}
|
| 183 |
@media(max-width:1080px){header{grid-template-columns:1fr;justify-items:start}.header-center-logo{justify-content:flex-start;padding:4px 0 0}.header-center-logo img{height:60px}.header-actions{justify-self:start}}
|
| 184 |
+
/* v1.6.3: alleen de witte managementrapportage, bestaande dashboard-huisstijl onveranderd */
|
| 185 |
+
#reportSheet .report-average-note{margin-top:8px;font-size:9px;color:#68739a;line-height:1.25}
|
| 186 |
+
#reportSheet .report-client-month-chart{height:157px;max-width:100%;min-width:0}
|
| 187 |
+
#reportSheet .report-client-month-chart svg{display:block;max-width:100%;height:100%}
|
| 188 |
+
@media print{#reportSheet .report-average-note{font-size:8px!important;margin-top:5px!important}#reportSheet .report-client-month-chart{height:133px!important}}
|
| 189 |
</style></head>
|
| 190 |
<body>
|
| 191 |
<div class="app">
|
|
|
|
| 251 |
</main>
|
| 252 |
</div>
|
| 253 |
<div id="reportOverlay" role="dialog" aria-modal="true" aria-label="Reakt Monitor rapport" aria-hidden="true">
|
| 254 |
+
<div class="report-actions"><span><strong>REAKT · Rapportvoorvertoning v1.6.3</strong> — voorlopige managementrapportage, controle vereist</span><div><button id="reportClose" type="button">✕ Sluiten</button> <button id="reportPng" class="report-png" type="button">⬇ Download PNG</button> <button id="reportJpg" class="report-jpg" type="button">⬇ Download JPG</button> <button id="reportPrint" class="report-print" type="button">↓ Opslaan als PDF / Afdrukken</button></div></div>
|
| 255 |
<section id="reportSheet" aria-label="Witte Inloop Monitor"></section>
|
| 256 |
</div>
|
| 257 |
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
|
|
|
|
| 916 |
const result=importedData.last,site=result.site,period=result.period;
|
| 917 |
const history=importedData.all.filter(r=>(site==='*'||r.site===site)&&r.date<=period.peildatum);
|
| 918 |
const quarter=history.filter(r=>r.date>=period.begin);
|
| 919 |
+
const counts=new Map(),uniqueDates=new Set(),byMonth=new Map(period.months.map(m=>[m,0])),clientsByMonth=new Map(period.months.map(m=>[m,new Set()])),daysWithScans=new Set(),byWeek=[0,0,0,0,0,0,0];
|
| 920 |
for(const r of quarter){
|
| 921 |
const key=JSON.stringify([r.site,r.id,r.date]);if(uniqueDates.has(key))continue;
|
| 922 |
uniqueDates.add(key);
|
| 923 |
const mk=r.date.slice(0,7);byMonth.set(mk,(byMonth.get(mk)||0)+1);
|
| 924 |
const wk=new Date(r.date+'T12:00:00Z').getUTCDay();byWeek[(wk+6)%7]++;
|
| 925 |
const ck=JSON.stringify([r.site,r.id]);counts.set(ck,(counts.get(ck)||0)+1);
|
| 926 |
+
clientsByMonth.get(mk)?.add(ck);
|
| 927 |
+
daysWithScans.add(r.date);
|
| 928 |
}
|
| 929 |
const intensities=[0,0,0,0,0],daysPerClient=[...counts.values()];
|
| 930 |
daysPerClient.forEach(c=>{intensities[c<=5?0:c<=20?1:c<=50?2:c<=100?3:4]++});
|
| 931 |
const sorted=daysPerClient.sort((a,b)=>a-b),median=sorted.length?(sorted.length%2?sorted[(sorted.length-1)/2]:(sorted[sorted.length/2-1]+sorted[sorted.length/2])/2):0;
|
| 932 |
const monthLabels=['jan','feb','mrt','apr','mei','jun','jul','aug','sep','okt','nov','dec'];
|
| 933 |
+
const months=period.months.map(key=>({key,label:monthLabels[Number(key.slice(5))-1],visits:byMonth.get(key),clients:clientsByMonth.get(key)?.size||0,newIntake:result.instroomByMonth.get(key)||0}));
|
| 934 |
return {site:site==='*'?'Alle locaties':site,period,months,byWeek,intensities,
|
| 935 |
visits:uniqueDates.size,unique:result.unique,quarterClients:result.quarterClients,newIntake:result.newIntake,active:result.active,
|
| 936 |
+
average:counts.size?uniqueDates.size/counts.size:0,averageClientsPerDay:daysWithScans.size?uniqueDates.size/daysWithScans.size:0,daysWithScans:daysWithScans.size,median,maxDays:Math.max(0,...daysPerClient),
|
| 937 |
earliest:period.begin,latest:period.peildatum,issues:result.passConflicts+result.identityConflicts+result.unmatchedPasses,hasShadow:false,
|
| 938 |
historyLoaded:result.historyLoaded,correctedExisting:result.correctedExisting,correctedJanuary:result.correctedJanuary};
|
| 939 |
}
|
| 940 |
function buildWhiteReport(){
|
| 941 |
const d=getReportData();if(!d)return;
|
| 942 |
const range=d.earliest===d.latest?d.earliest:`${d.earliest} t/m ${d.latest}`;
|
| 943 |
+
const avgDay=d.averageClientsPerDay.toLocaleString('nl-NL',{minimumFractionDigits:1,maximumFractionDigits:1});
|
| 944 |
const activeWindow=readableDate(d.period.activeFrom)+' t/m '+readableDate(d.period.peildatum);
|
| 945 |
+
const mon=d.months.map(m=>m.label),values=d.months.map(m=>m.visits),clientsPerMonth=d.months.map(m=>m.clients),newPerMonth=d.months.map(m=>m.newIntake),week=['Ma','Di','Wo','Do','Vr','Za','Zo'];
|
| 946 |
const weekdayMax=Math.max(...d.byWeek),weekdayMin=Math.min(...d.byWeek),busiest=week[d.byWeek.indexOf(weekdayMax)],quietest=week[d.byWeek.indexOf(weekdayMin)];
|
| 947 |
+
const summary=[`In ${d.period.label} zijn bij ${escapeHTML(d.site)} ${reportNL(d.unique)} unieke cliënten met minimaal één geldige scan geregistreerd. Deze cliënten waren samen goed voor ${reportNL(d.visits)} bezoekdagen.`,
|
| 948 |
+
`De instroom in ${d.period.label} bedraagt ${reportNL(d.newIntake)} cliënten. Er zijn ${reportNL(d.active)} actieve cliënten met minimaal één scan in de afgelopen drie maanden (van ${activeWindow}).`,
|
| 949 |
+
`Op dagen met geregistreerde scans kwamen gemiddeld ${avgDay} cliënten per dag (${reportNL(d.daysWithScans)} geregistreerde dagen). De meeste bezoekdagen vallen op ${busiest} (${reportNL(weekdayMax)}).`,
|
| 950 |
+
`De instroom is gebaseerd op de eerste geldige scan in ${d.historyLoaded?'2025 en 2026':'alleen 2026'}, niet op pasuitgifte. ${d.historyLoaded?reportNL(d.correctedExisting)+' aanvankelijk nieuwe cliënten bleken al in 2025 geregistreerd.':'Historie 2025 ontbreekt; de instroom is voorlopig.'} Eerdere scans van vóór 2025 kunnen ontbreken.`];
|
| 951 |
+
const kpis=[{klass:'purple',icon:'♟',label:'Unieke cliënten',value:reportNL(d.unique),sub:''},
|
| 952 |
{klass:'green',icon:'+',label:'Nieuwe instroom',value:reportNL(d.newIntake),sub:'Eerste geldige scan op locatie in '+d.period.label},
|
| 953 |
+
{klass:'purple',icon:'♙',label:'Actieve cliënten',value:reportNL(d.active),sub:'Minimaal 1 scan in de afgelopen drie maanden.'},
|
| 954 |
+
{klass:'orange',icon:'▦',label:'Bezoekdagen',value:reportNL(d.visits),sub:'Eén cliënt per locatie per kalenderdag'}];
|
| 955 |
const kpiHTML=kpis.map(k=>`<div class="report-kpi ${k.klass}"><div class="k-icon">${k.icon}</div><div><div class="k-label">${k.label}</div><div class="k-num">${k.value}</div><div class="k-sub">${k.sub}</div></div><div class="k-underline"></div></div>`).join('');
|
|
|
|
|
|
|
| 956 |
$('reportSheet').innerHTML=`
|
| 957 |
<div class="report-brand"><img class="report-logo" src="data:image/png;base64,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" alt="Reakt PG logo"></div>
|
| 958 |
<div class="report-heading"><div><h1>Reakt Inloop Monitor ${escapeHTML(d.site)}</h1><p>Inzicht in bereik, betrokkenheid en bezoekpatronen</p></div>
|
|
|
|
| 965 |
<div><b>Nieuwe instroom</b>De eerste geldige scan van een cliënt op deze locatie (binnen de beschikbare historie) valt in de rapportageperiode.</div>
|
| 966 |
<div><b>Actieve cliënten</b>Minimaal één scan op deze locatie tussen ${escapeHTML(activeWindow)}.</div>
|
| 967 |
</div>
|
| 968 |
+
<div class="report-definitions-note">Een vervangende scanpas telt niet als nieuwe cliënt.</div>
|
| 969 |
</section>
|
| 970 |
<div class="report-chart-grid">
|
| 971 |
+
<section class="report-panel"><h2>Instroom per maand <small>(nieuwe cliënten)</small></h2><div class="chart-box">${reportChartBars(mon,newPerMonth,'#288e28')}</div></section>
|
| 972 |
+
<section class="report-panel"><h2>Bezoekdagen per maand</h2><div class="chart-box">${reportChartLine(mon,values)}</div></section>
|
| 973 |
<section class="report-panel"><h2>Bezoekdagen per weekdag</h2><div class="chart-box">${reportChartBars(week,d.byWeek,'#ff6410',true)}</div></section>
|
| 974 |
</div>
|
| 975 |
<div class="report-bottom-grid">
|
| 976 |
+
<section class="report-panel"><h2>Kerncijfers locatie</h2><table class="report-mini-table"><thead><tr><th>Locatie</th><th>Unieke cliënten</th><th>Bezoekdagen</th><th>Gem. cliënten per dag*</th></tr></thead><tbody><tr><td>⌖ ${escapeHTML(d.site)}</td><td>${reportNL(d.unique)}</td><td>${reportNL(d.visits)}</td><td>${avgDay}</td></tr><tr class="total"><td>Totaal / gemiddelde</td><td>${reportNL(d.unique)}</td><td>${reportNL(d.visits)}</td><td>${avgDay}</td></tr></tbody></table><div class="report-average-note">* Gemiddeld over ${reportNL(d.daysWithScans)} dagen met geregistreerde scans.</div></section>
|
| 977 |
+
<section class="report-panel"><h2>Aantal cliënten per maand <small>(iedere cliënt maximaal één keer per maand)</small></h2><div class="chart-box report-client-month-chart">${reportChartBars(mon,clientsPerMonth,'#763fc7')}</div></section>
|
| 978 |
<section class="report-panel"><h2>Managementanalyse</h2><div class="report-analysis">${summary.map(t=>`<p>${t}</p>`).join('')}</div></section>
|
| 979 |
</div>
|
| 980 |
+
<div class="report-foot"><span>Bron: scanregistratie 2026${d.historyLoaded?' en historisch referentiebestand 2025':''}. Rapportageperiode en peildatum staan bovenaan vermeld.</span></div>`;
|
| 981 |
}
|
| 982 |
function openWhiteReport(){
|
| 983 |
if(!importedData?.last){alert('Upload eerst een Excelbestand en rond de analyse af. Deze witte rapportage gebruikt geen verzonnen demo-KPI’s.');return;}
|