From 075173760ec2d2c5df3c13eb0e90685fe1a0c125 Mon Sep 17 00:00:00 2001 From: Tomas Gruner <47506558+MegaRedHand@users.noreply.github.com> Date: Sun, 26 May 2024 20:39:00 -0300 Subject: [PATCH] feat: add spendings per category graphs --- my-app/package-lock.json | 19 +++++++ my-app/package.json | 3 +- my-app/src/lib/server/api.ts | 1 - .../details/[[id=integer]]/+page.server.ts | 2 +- .../graphs/[[id=integer]]/+page.server.ts | 26 +++++++++ .../groups/graphs/[[id=integer]]/+page.svelte | 53 +++++++++++++++++++ .../movements/[id=integer]/+page.svelte | 3 +- my-app/src/types.d.ts | 4 +- 8 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 my-app/src/routes/groups/graphs/[[id=integer]]/+page.server.ts create mode 100644 my-app/src/routes/groups/graphs/[[id=integer]]/+page.svelte diff --git a/my-app/package-lock.json b/my-app/package-lock.json index 52c0c34..0cc7d6d 100644 --- a/my-app/package-lock.json +++ b/my-app/package-lock.json @@ -19,6 +19,7 @@ "@types/eslint": "^8.56.0", "@typescript-eslint/eslint-plugin": "^7.0.0", "@typescript-eslint/parser": "^7.0.0", + "chart.js": "^4.0.0", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-svelte": "^2.35.1", @@ -606,6 +607,12 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==", + "dev": true + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1693,6 +1700,18 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chart.js": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.3.tgz", + "integrity": "sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==", + "dev": true, + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, "node_modules/check-error": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", diff --git a/my-app/package.json b/my-app/package.json index 715d858..0f91ebd 100644 --- a/my-app/package.json +++ b/my-app/package.json @@ -33,7 +33,8 @@ "tslib": "^2.4.1", "typescript": "^5.0.0", "vite": "^5.0.3", - "vitest": "^1.2.0" + "vitest": "^1.2.0", + "chart.js": "^4.0.0" }, "type": "module", "dependencies": { diff --git a/my-app/src/lib/server/api.ts b/my-app/src/lib/server/api.ts index 58d6a0b..f08fa10 100644 --- a/my-app/src/lib/server/api.ts +++ b/my-app/src/lib/server/api.ts @@ -89,6 +89,5 @@ export const categoryService = { data.id > 0 ? put(`category/${data.id}`, data, getAuthHeader(cookies)) : post('category', data, getAuthHeader(cookies)), - get: (id: Id, cookies: Cookies) => get(`category/${id}`, getAuthHeader(cookies)), list: (groupId: Id, cookies: Cookies) => get(`category/${groupId}`, getAuthHeader(cookies)) }; diff --git a/my-app/src/routes/categories/details/[[id=integer]]/+page.server.ts b/my-app/src/routes/categories/details/[[id=integer]]/+page.server.ts index 0a5071a..c1c81ff 100644 --- a/my-app/src/routes/categories/details/[[id=integer]]/+page.server.ts +++ b/my-app/src/routes/categories/details/[[id=integer]]/+page.server.ts @@ -7,7 +7,7 @@ export const load: PageServerLoad = async ({ params, url, cookies }) => { const group_id = url.searchParams.get('groupId') || ''; const id = Number(params.id) || 0; const category: Category = id - ? await categoryService.get(id, cookies) + ? await categoryService.list(id, cookies) : { id: 0, group_id, name: '', description: '', strategy: '' }; const groups: Group[] = await groupService.list(cookies); return { category, groups }; diff --git a/my-app/src/routes/groups/graphs/[[id=integer]]/+page.server.ts b/my-app/src/routes/groups/graphs/[[id=integer]]/+page.server.ts new file mode 100644 index 0000000..f52883a --- /dev/null +++ b/my-app/src/routes/groups/graphs/[[id=integer]]/+page.server.ts @@ -0,0 +1,26 @@ +import { categoryService, groupService, spendingService } from '$lib/server/api'; +import type { PageServerLoad } from './$types'; + +export const load: PageServerLoad = async ({ params, cookies }) => { + const id = Number(params.id) || 0; + const group: Group = id + ? await groupService.get(id, cookies) + : { name: '', description: '', id: 0, owner_id: 0, is_archived: false }; + const categories = await categoryService.list(id, cookies); + const spendings = await spendingService.list(id, cookies); + const graphData = computePerCategorySpending(categories, spendings); + return { group, graphData }; +}; + +function computePerCategorySpending(categories: Category[], spendings: Spending[]) { + const categoryMap = new Map(categories.map((category) => [category.name, 0])); + spendings.forEach(({ amount }) => { + const randomChoice = Math.floor(Math.random() * categories.length); + const categoryName = categories[randomChoice].name; + const acc = categoryMap.get(categoryName)!; + categoryMap.set(categoryName, acc + amount); + }); + const labels = Array.from(categoryMap.keys()); + const values = Array.from(categoryMap.values()); + return { labels, values }; +} diff --git a/my-app/src/routes/groups/graphs/[[id=integer]]/+page.svelte b/my-app/src/routes/groups/graphs/[[id=integer]]/+page.svelte new file mode 100644 index 0000000..6dd63f6 --- /dev/null +++ b/my-app/src/routes/groups/graphs/[[id=integer]]/+page.svelte @@ -0,0 +1,53 @@ + + + + {title} - Gráficos de finanzas + + + + +
+
+

Gráficos de finanzas

+

{data.group.description}

+
+
+ +
diff --git a/my-app/src/routes/groups/movements/[id=integer]/+page.svelte b/my-app/src/routes/groups/movements/[id=integer]/+page.svelte index cf80477..9dfe18d 100644 --- a/my-app/src/routes/groups/movements/[id=integer]/+page.svelte +++ b/my-app/src/routes/groups/movements/[id=integer]/+page.svelte @@ -22,7 +22,7 @@
-

Moovimietos

+

Moovimientos

{data.group.description}

@@ -31,6 +31,7 @@ Resumenes