diff --git a/frontend/src/api/dashboard.ts b/frontend/src/api/dashboard.ts index f60118c..628bc92 100644 --- a/frontend/src/api/dashboard.ts +++ b/frontend/src/api/dashboard.ts @@ -20,6 +20,12 @@ export type Last7DaysResponse = { last7Days: Last7DaysAPIEntry[]; }; +export type DashboardError = { + code?: string; + error?: boolean; + message?: string; +}; + export async function fetchDashboardData(token?: string) { const res = await fetch(`${API_BASE_URL}/api/dashboard`, { method: 'GET', @@ -30,8 +36,16 @@ export async function fetchDashboardData(token?: string) { }); if (!res.ok) { - const msg = await res.text(); - throw new Error(msg || 'Failed to fetch dashboard data'); + let errorData: DashboardError = {}; + try { + errorData = await res.json(); + } catch { + errorData = { message: 'Failed to fetch dashboard data' }; + } + + const error = new Error(errorData.message || 'Failed to fetch dashboard data') as Error & { code?: string }; + error.code = errorData.code; + throw error; } return await res.json() as DashboardData; @@ -47,8 +61,16 @@ export async function fetchLast7DaysHistory(token?: string) { }); if (!res.ok) { - const msg = await res.text(); - throw new Error(msg || 'Failed to fetch last 7 days history'); + let errorData: DashboardError = {}; + try { + errorData = await res.json(); + } catch { + errorData = { message: 'Failed to fetch last 7 days history' }; + } + + const error = new Error(errorData.message || 'Failed to fetch last 7 days history') as Error & { code?: string }; + error.code = errorData.code; + throw error; } return await res.json() as Last7DaysResponse; diff --git a/frontend/src/api/history.ts b/frontend/src/api/history.ts index 09658f3..510a3d9 100644 --- a/frontend/src/api/history.ts +++ b/frontend/src/api/history.ts @@ -14,6 +14,12 @@ export type HistoryData = { entries: SingleDayEntry[] }; +export type HistoryError = { + code?: string; + error?: boolean; + message?: string; +}; + export async function fetchHistoryData(token?: string) { const res = await fetch(`${API_BASE_URL}/api/progress`, { method: 'GET', @@ -24,8 +30,16 @@ export async function fetchHistoryData(token?: string) { }); if (!res.ok) { - const msg = await res.text(); - throw new Error(msg || 'Failed to fetch history data'); + let errorData: HistoryError = {}; + try { + errorData = await res.json(); + } catch { + errorData = { message: 'Failed to fetch history data' }; + } + + const error = new Error(errorData.message || 'Failed to fetch history data') as Error & { code?: string }; + error.code = errorData.code; + throw error; } return await res.json() as HistoryData; diff --git a/frontend/src/components/LandingLast7Days.vue b/frontend/src/components/LandingLast7Days.vue index c4bfb41..7bd66e5 100644 --- a/frontend/src/components/LandingLast7Days.vue +++ b/frontend/src/components/LandingLast7Days.vue @@ -50,6 +50,7 @@ import {onMounted, ref} from 'vue'; import Card from 'primevue/card'; import {useDashboardStore} from "@/stores/dashboard.ts"; import type {Last7DaysAPIEntry, Last7DaysResponse} from "@/api/dashboard.ts"; +import {useRouter} from 'vue-router'; interface DayUI { day: string; @@ -60,6 +61,7 @@ interface DayUI { const lastSevenDays = ref([]); const dashboard = useDashboardStore(); +const router = useRouter(); async function loadData() { @@ -85,6 +87,14 @@ async function loadData() { }); } catch (error) { + const err = error as Error & { code?: string }; + + // Jeśli brak uzależnienia, przekieruj na konfigurację + if (err.code === 'DASHBOARD_FETCH_ERROR') { + await router.push('/configure-habit'); + return; + } + console.error('Błąd pobierania historii (submit):', error); } } diff --git a/frontend/src/components/LandingSummary.vue b/frontend/src/components/LandingSummary.vue index 51033fc..79a5a6e 100644 --- a/frontend/src/components/LandingSummary.vue +++ b/frontend/src/components/LandingSummary.vue @@ -88,6 +88,7 @@ import {useDashboardStore} from "@/stores/dashboard.ts"; import HistoryStatusChangeDialog from "@/components/HistoryStatusChangeDialog.vue"; import {useHistoryStore} from "@/stores/history.ts"; import type {DayStatus} from "@/api/dashboard.ts"; +import {useRouter} from 'vue-router'; const savedMoney = ref(0); const streakDays = ref(0); @@ -102,6 +103,7 @@ const todayEntry = ref<{ date: Date, status: DayStatus }>({ const dashboard = useDashboardStore() const history = useHistoryStore() +const router = useRouter() async function submit() { @@ -112,7 +114,15 @@ async function submit() { currentDays.value = data.dailyStreak; addictionName.value = data.addictionName; } catch (err) { - alert((err as Error).message) + const error = err as Error & { code?: string }; + + // Jeśli brak uzależnienia, przekieruj na konfigurację + if (error.code === 'DASHBOARD_FETCH_ERROR') { + await router.push('/configure-habit'); + return; + } + + alert(error.message) } } diff --git a/frontend/src/views/HistoryView.vue b/frontend/src/views/HistoryView.vue index 0a6e506..e676194 100644 --- a/frontend/src/views/HistoryView.vue +++ b/frontend/src/views/HistoryView.vue @@ -74,6 +74,7 @@ import RecoveredHoursCard from "@/components/RecoveredHoursCard.vue"; import type {HistoryData, SingleDayEntry} from "@/api/history.ts"; import type { DayStatus } from "@/api/dashboard.ts"; import { useHistoryStore } from "@/stores/history.ts"; +import { useRouter } from 'vue-router'; interface HistoryEntry { date: Date; @@ -125,6 +126,7 @@ const statusOptions = ref<{ label: string; value: DayStatus }[]>([ { label: 'Wpadka', value: 'failure' } ]); const historyStore = useHistoryStore(); +const router = useRouter(); async function submit() { try { @@ -157,6 +159,14 @@ async function submit() { chartRawData.value = tempChartData.reverse(); } catch (error) { + const err = error as Error & { code?: string }; + + // Jeśli brak uzależnienia, przekieruj na konfigurację + if (err.code === 'PROGRESS_FETCH_ERROR') { + await router.push('/configure-habit'); + return; + } + console.error('Błąd pobierania historii:', error); } } diff --git a/frontend/src/views/SettingsView.vue b/frontend/src/views/SettingsView.vue index 0755485..84dbbd0 100644 --- a/frontend/src/views/SettingsView.vue +++ b/frontend/src/views/SettingsView.vue @@ -69,13 +69,20 @@ import { fetchSettingsFromAPI, updateSettingsAPI, habitOptions, resetSettingsAPI } from '@/stores/settings' import Select from "primevue/select"; +import { useRouter } from 'vue-router'; const showUsernameInput = ref(false) const showHabitNameInput = ref(false) const showHabitCostInput = ref(false) +const router = useRouter(); -onMounted(() => { - fetchSettingsFromAPI() +onMounted(async () => { + await fetchSettingsFromAPI() + + // Jeśli habitName lub habitCost jest null, przekieruj na konfigurację + if (habitName.value === null || habitName.value === '' || habitCost.value === null) { + await router.push('/configure-habit'); + } }) async function saveSettings() {