Rework home page to use $state, $props, and $derived

This commit is contained in:
qowevisa 2024-12-01 19:53:22 +02:00
parent 5716d1ebc4
commit 7aa2fcd504
2 changed files with 61 additions and 50 deletions

View File

@ -0,0 +1,13 @@
import type { StatsTypeCurrencyChart } from "$lib/entities";
import type { PageServerLoad } from "./$types";
export const load: PageServerLoad = async ({ fetch }) => {
try {
const expensesData: StatsTypeCurrencyChart[] = await fetch("/api/statistics/type").then((res) => res.json());
return { expensesData: expensesData };
} catch (error) {
console.log("error in +page.server.ts", error)
return { expensesData: [] };
}
};

View File

@ -13,48 +13,41 @@
Chart.register(DoughnutController, ArcElement, Tooltip, Legend); Chart.register(DoughnutController, ArcElement, Tooltip, Legend);
let error: string | null = null; let { data } = $props();
let data: StatsTypeCurrencyChart[] = []; $inspect(data);
let configs: ChartConfiguration[] = []; let error: string | null = $state(null);
let charts: Chart[] = []; let { expensesData }: { expensesData: StatsTypeCurrencyChart[] } =
$state(data);
$inspect("expensesData =", expensesData);
// let expensesData: StatsTypeCurrencyChart[] = $state(data.expensesData);
let canvases: HTMLCanvasElement[] = []; let canvases: HTMLCanvasElement[] = [];
let charts: Chart[] = [];
async function fetchChartStats() { let configs: ChartConfiguration[] = $derived(
try { expensesData.map((chart) => ({
const result = await fetch("/api/statistics/type"); type: "doughnut",
if (!result.ok) { data: {
const obj = await result.json(); labels: chart.elements.map((type) => type.name),
error = obj.message; datasets: [
} else { {
data = await result.json(); label: chart.label,
data: chart.elements.map((type) => type.value / 100),
configs = data.map((chart) => ({ backgroundColor: chart.elements.map((type) => type.color),
type: "doughnut",
data: {
labels: chart.elements.map((type) => type.name),
datasets: [
{
label: chart.label,
data: chart.elements.map((type) => type.value / 100),
backgroundColor: chart.elements.map((type) => type.color),
},
],
}, },
})); ],
} },
} catch (e) { })),
console.error("Error fetching data:", e); );
error = "Failed to fetch chart data.";
}
}
function createTypeCharts() { function createTypeCharts() {
charts.forEach((chart) => chart.destroy()); charts.forEach((chart) => chart.destroy());
charts = configs.map((config, index) => new Chart(canvases[index], config)); charts = configs.map((config, index) => new Chart(canvases[index], config));
} }
onMount(async () => {
await fetchChartStats(); onMount(() => {
createTypeCharts(); if (expensesData && canvases.length > 0) {
createTypeCharts();
}
}); });
onDestroy(() => { onDestroy(() => {
@ -67,22 +60,27 @@
{/if} {/if}
<!-- Render canvas elements for charts --> <!-- Render canvas elements for charts -->
<div class="flex items-center justify-center"> <div class="container mx-auto my-8 bg-gray-100 p-6">
<div <h2 class="text-2xl mb-4 font-bold text-center block">
class="{configs.length > 4 Expenses doughnut charts
? 'grid-cols-4' </h2>
: 'grid-cols-2'} w-fit grid gap-4" <div class="flex items-center justify-center">
> <div
{#each configs as _, index} class="{configs.length > 4
<div class="flex flex-col"> ? 'grid-cols-4'
<div class="type-chart"> : 'grid-cols-2'} w-fit grid gap-4"
<canvas bind:this={canvases[index]}></canvas> >
<span class="flex justify-center" {#each configs as _, index}
>{`Total: ${NumberToFPA(data[index].total)} ${data[index].label}`}</span <div class="flex flex-col">
> <div class="type-chart">
<canvas bind:this={canvases[index]}></canvas>
<span class="flex justify-center"
>{`Total: ${NumberToFPA(expensesData[index].total)} ${expensesData[index].label}`}</span
>
</div>
</div> </div>
</div> {/each}
{/each} </div>
</div> </div>
</div> </div>