From 32b9d22de5024671adc8fe32f1b87cde0989ccdd Mon Sep 17 00:00:00 2001 From: Arca Ege Cengiz Date: Wed, 22 Jul 2026 00:50:58 +0100 Subject: [PATCH] Fix funnel --- .../admin/admin/stats/+page.server.ts | 6 +-- .../dashboard/admin/admin/stats/+page.svelte | 41 +++++++++++++------ 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/routes/dashboard/admin/admin/stats/+page.server.ts b/src/routes/dashboard/admin/admin/stats/+page.server.ts index c4b5f8f..3ac4741 100644 --- a/src/routes/dashboard/admin/admin/stats/+page.server.ts +++ b/src/routes/dashboard/admin/admin/stats/+page.server.ts @@ -120,10 +120,10 @@ export async function load({ locals }) { .select({ count: countDistinct(printerOrder.userId) }) .from(printerOrder); - const [printerQueued] = await db + const [requestedPrinter] = await db .select({ count: count() }) .from(user) - .where(inArray(user.printerFulfilment, ['queued', 'approved'])); + .where(inArray(user.printerFulfilment, ['queued', 'approved', 'fulfilled'])); const [printerFulfilled] = await db .select({ count: count() }) @@ -137,7 +137,7 @@ export async function load({ locals }) { hours25, hours40, boughtPrinter: printerBought.count, - printerQueued: printerQueued.count, + requestedPrinter: requestedPrinter.count, printerFulfilled: printerFulfilled.count, }; diff --git a/src/routes/dashboard/admin/admin/stats/+page.svelte b/src/routes/dashboard/admin/admin/stats/+page.svelte index f7a6bdb..7313fbd 100644 --- a/src/routes/dashboard/admin/admin/stats/+page.svelte +++ b/src/routes/dashboard/admin/admin/stats/+page.svelte @@ -45,7 +45,7 @@ { label: '25 Hours Finalised', key: 'hours25' }, { label: '40 Hours Finalised', key: 'hours40' }, { label: 'Bought a printer', key: 'boughtPrinter' }, - { label: 'Printer in queue', key: 'printerQueued' }, + { label: 'Requested printer', key: 'requestedPrinter' }, { label: 'Printer fulfilled', key: 'printerFulfilled' }, ] as const; const chartColors = { @@ -164,6 +164,7 @@ const labels = funnelStages.map(s => s.label); const values = funnelStages.map(s => data.funnel[s.key] as number); const total = data.funnel.totalUsers; + const maxVal = Math.max(...values); const stageColors = funnelStages.map((_, i) => { if (i < 6) return '#f89708'; @@ -171,18 +172,26 @@ return '#338eda'; }); + const offsetData = values.map(v => (maxVal - v) / 2); + const chart = new Chart(ctx, { type: 'bar', data: { labels, - datasets: [{ - data: values, - backgroundColor: stageColors, - borderRadius: 4, - }] + datasets: [ + { + data: offsetData, + backgroundColor: 'transparent', + hoverBackgroundColor: 'transparent', + }, + { + data: values, + backgroundColor: stageColors, + borderRadius: 2, + } + ] }, options: { - indexAxis: 'y', responsive: true, maintainAspectRatio: false, plugins: { @@ -195,7 +204,8 @@ padding: 10, callbacks: { label: (ctx) => { - const val = ctx.parsed.x ?? 0; + if (ctx.datasetIndex === 0) return; + const val = ctx.parsed.y ?? 0; const pct = total > 0 ? ((val / total) * 100).toFixed(1) : '0.0'; return `${val} (${pct}%)`; } @@ -204,13 +214,18 @@ }, scales: { x: { - beginAtZero: true, - ticks: { color: '#94857d', font: { size: 10 } }, - grid: { color: '#342f2c' }, + stacked: true, + ticks: { + color: '#94857d', + font: { size: 10 }, + maxRotation: 45, + }, + grid: { display: false }, }, y: { - ticks: { color: '#94857d', font: { size: 11 } }, - grid: { display: false }, + stacked: true, + beginAtZero: true, + display: false, } }, interaction: {