From 734a0619d2a209f88638f3fb4508623796c0ec78 Mon Sep 17 00:00:00 2001 From: Falanger-debug Date: Thu, 8 Jan 2026 19:49:47 +0100 Subject: [PATCH 1/3] =?UTF-8?q?co=C5=9B=20tam=20=C5=9Bmiga?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/api/history.ts | 33 +++ .../components/HistoryStatusChangeDialog.vue | 4 +- .../src/components/RecoveredHoursCard.vue | 6 +- frontend/src/stores/history.ts | 25 +++ frontend/src/views/HistoryView.vue | 204 +++++++++++------- 5 files changed, 186 insertions(+), 86 deletions(-) create mode 100644 frontend/src/api/history.ts create mode 100644 frontend/src/stores/history.ts diff --git a/frontend/src/api/history.ts b/frontend/src/api/history.ts new file mode 100644 index 0000000..29182cd --- /dev/null +++ b/frontend/src/api/history.ts @@ -0,0 +1,33 @@ +import { API_BASE_URL } from '@/api/config.ts' +import type {DayStatus} from "@/api/dashboard.ts"; + +export type SingleDayEntry = { + date: string; + dayOfWeek: string; + status: DayStatus; +} + +export type HistoryData = { + addictionName: string + singleDayCost: number + totalSavings: number + totalHistory: SingleDayEntry[] +}; + +export async function fetchHistoryData(token?: string) { + const res = await fetch(`${API_BASE_URL}/api/progress`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + ...(token ? { 'Authorization': `Bearer ${token}` } : {}) + } + }); + + if (!res.ok) { + const msg = await res.text(); + throw new Error(msg || 'Failed to fetch history data'); + } + + return await res.json() as HistoryData; + +} diff --git a/frontend/src/components/HistoryStatusChangeDialog.vue b/frontend/src/components/HistoryStatusChangeDialog.vue index 730a6c1..345ec26 100644 --- a/frontend/src/components/HistoryStatusChangeDialog.vue +++ b/frontend/src/components/HistoryStatusChangeDialog.vue @@ -42,7 +42,7 @@ import { ref, watch } from 'vue'; import Dialog from 'primevue/dialog'; import SelectButton from 'primevue/selectbutton'; -type DayStatus = 'success' | 'relapse' | 'none'; +type DayStatus = 'success' | 'failure' | 'none'; interface HistoryEntry { date: Date; @@ -61,7 +61,7 @@ const internalEntry = ref({ ...props.entry }); const extendedStatusOptions = ref([ { label: 'Sukces', value: 'success', icon: 'pi pi-check-circle' }, { label: 'Brak', value: 'none', icon: 'pi pi-minus-circle' }, - { label: 'Wpadka', value: 'relapse', icon: 'pi pi-exclamation-circle' } + { label: 'Wpadka', value: 'failure', icon: 'pi pi-exclamation-circle' } ]); watch(() => props.entry, (newVal) => { diff --git a/frontend/src/components/RecoveredHoursCard.vue b/frontend/src/components/RecoveredHoursCard.vue index 7b6f122..ede7378 100644 --- a/frontend/src/components/RecoveredHoursCard.vue +++ b/frontend/src/components/RecoveredHoursCard.vue @@ -8,12 +8,8 @@
- Zyskany czas życia + Odzyskaj Życie -
- 5 - godzin -
diff --git a/frontend/src/stores/history.ts b/frontend/src/stores/history.ts new file mode 100644 index 0000000..0bf1a74 --- /dev/null +++ b/frontend/src/stores/history.ts @@ -0,0 +1,25 @@ +import {defineStore } from 'pinia'; +import { + fetchHistoryData, type HistoryData +} from "@/api/history.ts"; + +export const useHistoryStore = defineStore('history', { + state: () => ({ + token: localStorage.getItem('token') as string | null, + }), + + getters: { + isAuthenticated: (state) => !!state.token, + }, + + actions: { + async fetchHistory(): Promise { + try { + return await fetchHistoryData(this.token ?? undefined); + } catch(e) { + console.error('Failed to fetch history data', e); + throw e; + } + } + } +}) diff --git a/frontend/src/views/HistoryView.vue b/frontend/src/views/HistoryView.vue index 1bec77f..fac01ef 100644 --- a/frontend/src/views/HistoryView.vue +++ b/frontend/src/views/HistoryView.vue @@ -9,7 +9,8 @@

- Świetnie Ci idzie, Janek! + Świetnie Ci idzie walka z + {{addictionName}}!

@@ -19,13 +20,16 @@
+
Ładowanie danych...
+ +