Upload index.html
Browse files- index.html +30 -1
index.html
CHANGED
|
@@ -430,6 +430,16 @@
|
|
| 430 |
.insight-question p{font-size:11px;line-height:1.48;color:#b4cce6;margin:0}
|
| 431 |
.insight-note{font-size:10px;line-height:1.55;color:#a0b6d4;margin-top:15px;border-top:1px solid #2c4462;padding-top:12px}
|
| 432 |
@media(max-width:900px){.topbar .actions{flex-wrap:wrap;justify-content:flex-end}}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 433 |
</style></head>
|
| 434 |
<body>
|
| 435 |
<div class="app">
|
|
@@ -473,7 +483,7 @@
|
|
| 473 |
</div>
|
| 474 |
<div class="definition-guide-note">Een verloren of vervangen scanpas telt niet als een nieuwe cliënt: meerdere passen van dezelfde cliënt worden samengevoegd.</div>
|
| 475 |
</section>
|
| 476 |
-
<div class="charts-grid"><section class="panel chart-panel"><div class="panel-heading"><div><span class="section-kicker">TRENDANALYSE</span><h3>Bezoeken per locatie</h3></div><span class="subtle">Jul – Sep 2026</span></div><canvas id="chart" width="640" height="250" aria-label="Grafiek fictieve bezoeken per locatie"></canvas><div class="legend"><span><i style="background:#3ee1b6"></i> Soeda</span><span><i style="background:#ffc66a"></i> Rietdijk</span><span><i style="background:#5b9cff"></i> Vredehof</span><span><i style="background:#ad88ff"></i> Gouda</span></div></section>
|
| 477 |
<section class="panel verification"><div class="panel-heading"><div><span class="section-kicker">KWALITEITSBORGING</span><h3>Verificatie Businesscontroller</h3></div><span class="warn-label">DEMO</span></div><div id="checks" class="checks"></div><div class="warning">⚠ 1 fictieve afwijking. Rapport niet gevalideerd.</div></section></div>
|
| 478 |
|
| 479 |
<section class="panel controller-panel" id="controllerPanel" aria-label="Vergelijking met businesscontroller">
|
|
@@ -1066,6 +1076,7 @@ function renderImported(result){
|
|
| 1066 |
document.querySelector('.verification .warning').textContent=quality.mismatches?`⚠ ${quality.mismatches} interne telverschillen gevonden. Cijfers nader onderzoeken. NIET GEVALIDEERD.`:
|
| 1067 |
quality.sourceIssues.length?`⚠ Tweede telling sluit aan; ${quality.sourceIssues.length} soorten bronafwijkingen beoordeeld. Zie aantallen en KPI-impact hierboven. NIET EXTERN GEVALIDEERD.`:
|
| 1068 |
`✓ ${quality.checks.length} interne telcontroles sluiten aan. ${result.historyLoaded?'Historie 2025 meegenomen.':'2025 ontbreekt: instroom voorlopig.'} Businesscontrollercontrole optioneel; niet extern gevalideerd.`;
|
|
|
|
| 1069 |
}
|
| 1070 |
async function startImported(){
|
| 1071 |
if(running)return;
|
|
@@ -1186,6 +1197,22 @@ function reportChartLine(names,values){
|
|
| 1186 |
dots.forEach(([x,y],i)=>{out+=`<circle cx="${x}" cy="${y}" r="4" fill="#6630dc"/><text x="${x}" y="${Math.max(11,y-10)}" font-size="11" font-weight="700" text-anchor="middle" fill="#5a22cb">${values[i]}</text><text x="${x}" y="${H-9}" text-anchor="middle" font-size="10" fill="#1d255e">${escapeHTML(names[i])}</text>`});
|
| 1187 |
return out+'</svg>';
|
| 1188 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1189 |
function getReportData(){
|
| 1190 |
if(!importedData?.last) return null;
|
| 1191 |
const result=importedData.last,site=result.site,period=result.period;
|
|
@@ -1606,6 +1633,8 @@ function syncDashboardButton(){const b=$('exportBtn');if(b)b.disabled=running||!
|
|
| 1606 |
$('startBtn').addEventListener('click',start);
|
| 1607 |
window.addEventListener('resize',()=>requestAnimationFrame(nextBuildGraph));
|
| 1608 |
if(typeof ResizeObserver!=='undefined')new ResizeObserver(()=>requestAnimationFrame(nextBuildGraph)).observe(document.querySelector('.orchestra'));
|
|
|
|
|
|
|
| 1609 |
nextInitCards();requestAnimationFrame(nextBuildGraph);
|
| 1610 |
|
| 1611 |
</script></body></html>
|
|
|
|
| 430 |
.insight-question p{font-size:11px;line-height:1.48;color:#b4cce6;margin:0}
|
| 431 |
.insight-note{font-size:10px;line-height:1.55;color:#a0b6d4;margin-top:15px;border-top:1px solid #2c4462;padding-top:12px}
|
| 432 |
@media(max-width:900px){.topbar .actions{flex-wrap:wrap;justify-content:flex-end}}
|
| 433 |
+
|
| 434 |
+
/* v8 — hergebruik van bestaande Reakt-monitor grafieken in de linkerkolom. */
|
| 435 |
+
.inline-report-charts{display:grid;grid-template-columns:minmax(0,1fr);gap:15px;margin-top:22px;padding-top:18px;border-top:1px solid #2a4667}
|
| 436 |
+
.inline-chart-card{border:1px solid #355374;border-radius:10px;background:linear-gradient(145deg,#132944,#102036);padding:12px;min-width:0}
|
| 437 |
+
.inline-chart-card h4{font-size:12px;line-height:1.35;color:#e7f4ff;margin:0 0 10px;font-weight:750}
|
| 438 |
+
.inline-chart-card h4 small{font-size:10px;font-weight:400;color:#a8bcd3}
|
| 439 |
+
.inline-chart-svg{height:188px;background:#f8faff;border-radius:7px;padding:7px;overflow:hidden}
|
| 440 |
+
.inline-chart-svg svg{display:block;width:100%;height:100%}
|
| 441 |
+
.inline-chart-empty{border:1px dashed #385473;border-radius:9px;color:#9fb8d4;font-size:11px;line-height:1.5;padding:15px}
|
| 442 |
+
.inline-chart-foot{color:#8eaaca;font-size:10px;line-height:1.4;margin-top:10px}
|
| 443 |
</style></head>
|
| 444 |
<body>
|
| 445 |
<div class="app">
|
|
|
|
| 483 |
</div>
|
| 484 |
<div class="definition-guide-note">Een verloren of vervangen scanpas telt niet als een nieuwe cliënt: meerdere passen van dezelfde cliënt worden samengevoegd.</div>
|
| 485 |
</section>
|
| 486 |
+
<div class="charts-grid"><section class="panel chart-panel"><div class="panel-heading"><div><span class="section-kicker">TRENDANALYSE</span><h3>Bezoeken per locatie</h3></div><span class="subtle">Jul – Sep 2026</span></div><canvas id="chart" width="640" height="250" aria-label="Grafiek fictieve bezoeken per locatie"></canvas><div class="legend"><span><i style="background:#3ee1b6"></i> Soeda</span><span><i style="background:#ffc66a"></i> Rietdijk</span><span><i style="background:#5b9cff"></i> Vredehof</span><span><i style="background:#ad88ff"></i> Gouda</span></div><div id="inlineReportCharts" class="inline-report-charts" aria-live="polite"><div class="inline-chart-empty">Na de Excelanalyse verschijnen hier drie bestaande grafieken uit de witte Reakt-monitor.</div></div></section>
|
| 487 |
<section class="panel verification"><div class="panel-heading"><div><span class="section-kicker">KWALITEITSBORGING</span><h3>Verificatie Businesscontroller</h3></div><span class="warn-label">DEMO</span></div><div id="checks" class="checks"></div><div class="warning">⚠ 1 fictieve afwijking. Rapport niet gevalideerd.</div></section></div>
|
| 488 |
|
| 489 |
<section class="panel controller-panel" id="controllerPanel" aria-label="Vergelijking met businesscontroller">
|
|
|
|
| 1076 |
document.querySelector('.verification .warning').textContent=quality.mismatches?`⚠ ${quality.mismatches} interne telverschillen gevonden. Cijfers nader onderzoeken. NIET GEVALIDEERD.`:
|
| 1077 |
quality.sourceIssues.length?`⚠ Tweede telling sluit aan; ${quality.sourceIssues.length} soorten bronafwijkingen beoordeeld. Zie aantallen en KPI-impact hierboven. NIET EXTERN GEVALIDEERD.`:
|
| 1078 |
`✓ ${quality.checks.length} interne telcontroles sluiten aan. ${result.historyLoaded?'Historie 2025 meegenomen.':'2025 ontbreekt: instroom voorlopig.'} Businesscontrollercontrole optioneel; niet extern gevalideerd.`;
|
| 1079 |
+
renderInlineReportCharts();
|
| 1080 |
}
|
| 1081 |
async function startImported(){
|
| 1082 |
if(running)return;
|
|
|
|
| 1197 |
dots.forEach(([x,y],i)=>{out+=`<circle cx="${x}" cy="${y}" r="4" fill="#6630dc"/><text x="${x}" y="${Math.max(11,y-10)}" font-size="11" font-weight="700" text-anchor="middle" fill="#5a22cb">${values[i]}</text><text x="${x}" y="${H-9}" text-anchor="middle" font-size="10" fill="#1d255e">${escapeHTML(names[i])}</text>`});
|
| 1198 |
return out+'</svg>';
|
| 1199 |
}
|
| 1200 |
+
// Hergebruik exact de grafieken en de brongegevens van de witte Reakt-monitor.
|
| 1201 |
+
// Geen aparte KPI-rekenregels, geen AI-API en geen verzonnen grafiekwaarden.
|
| 1202 |
+
function renderInlineReportCharts(){
|
| 1203 |
+
const host=$('inlineReportCharts');if(!host)return;
|
| 1204 |
+
const data=getReportData();
|
| 1205 |
+
if(!data){host.innerHTML='<div class="inline-chart-empty">Analyseer eerst een Excelbestand om de bestaande rapportagegrafieken te zien.</div>';return;}
|
| 1206 |
+
const labels=data.months.map(m=>m.label);
|
| 1207 |
+
const specs=[
|
| 1208 |
+
['Nieuwe instroom per maand','Eerste geregistreerde scan op locatie',reportChartBars(labels,data.months.map(m=>m.newIntake),'#288e28')],
|
| 1209 |
+
['Bezoekdagen per weekdag','Unieke cliënt-/locatie-/bezoekdagen',reportChartBars(['Ma','Di','Wo','Do','Vr','Za','Zo'],data.byWeek,'#ff6410',true)],
|
| 1210 |
+
['Aantal cliënten per maand','Iedere cliënt maximaal één keer per maand',reportChartClientMonth(labels,data.months.map(m=>m.clients))]
|
| 1211 |
+
];
|
| 1212 |
+
host.innerHTML=specs.map(([title,description,svg])=>`<section class="inline-chart-card"><h4>${title} <small>· ${description}</small></h4><div class="inline-chart-svg">${svg}</div></section>`).join('')+
|
| 1213 |
+
'<div class="inline-chart-foot">Dezelfde gegevens en grafieken als in de witte Reakt-monitor. Alleen lokale Excelanalyse · niet extern gevalideerd.</div>';
|
| 1214 |
+
}
|
| 1215 |
+
function invalidateInlineReportCharts(){const host=$('inlineReportCharts');if(host)host.innerHTML='<div class="inline-chart-empty">Selectie gewijzigd: start de analyse voor bijgewerkte grafieken.</div>';}
|
| 1216 |
function getReportData(){
|
| 1217 |
if(!importedData?.last) return null;
|
| 1218 |
const result=importedData.last,site=result.site,period=result.period;
|
|
|
|
| 1633 |
$('startBtn').addEventListener('click',start);
|
| 1634 |
window.addEventListener('resize',()=>requestAnimationFrame(nextBuildGraph));
|
| 1635 |
if(typeof ResizeObserver!=='undefined')new ResizeObserver(()=>requestAnimationFrame(nextBuildGraph)).observe(document.querySelector('.orchestra'));
|
| 1636 |
+
// Bij veranderde bronbestanden of selectie blijven oude grafieken niet ten onrechte zichtbaar.
|
| 1637 |
+
['scanFile','historyFile','siteSelect','periodSelect','periodType'].forEach(id=>$(id)?.addEventListener('change',invalidateInlineReportCharts));
|
| 1638 |
nextInitCards();requestAnimationFrame(nextBuildGraph);
|
| 1639 |
|
| 1640 |
</script></body></html>
|