This commit is contained in:
Julian Freeman
2026-03-26 12:10:39 -04:00
parent 6793a2070e
commit 1e1307b8d4
10 changed files with 773 additions and 849 deletions

View File

@@ -0,0 +1,75 @@
import { ref, computed, watch } from "vue";
import { invoke } from "@tauri-apps/api/core";
import { DBEvent } from "../types";
import { currentDate, getTagColor, getTagName, formatMinutes } from "./index";
// Re-export for easier access in Dashboard component
export { getTagColor, getTagName, formatMinutes };
export const dashboardRange = ref<'today' | '7days' | '30days'>('today');
export const dashboardStartDate = ref(currentDate.value);
export const dashboardEndDate = ref(currentDate.value);
export const dashboardEvents = ref<DBEvent[]>([]);
export const dailyAverageMode = ref<'natural' | 'recorded'>('natural');
export const loadDashboardEvents = async () => {
dashboardEvents.value = await invoke("get_events_range", { startDate: dashboardStartDate.value, endDate: dashboardEndDate.value });
};
watch([dashboardRange, currentDate], () => {
const end = new Date(currentDate.value);
let start = new Date(currentDate.value);
if (dashboardRange.value === '7days') start.setDate(end.getDate() - 6);
else if (dashboardRange.value === '30days') start.setDate(end.getDate() - 29);
dashboardStartDate.value = start.toLocaleDateString('sv');
dashboardEndDate.value = end.toLocaleDateString('sv');
loadDashboardEvents();
}, { immediate: true });
export const dashboardStats = computed(() => {
let totalMinutes = 0;
const mainTagMap = new Map<number, { total: number, subTags: Map<number, number> }>();
const uniqueDays = new Set<string>();
dashboardEvents.value.forEach(ev => {
let diff = ev.end_minute - ev.start_minute;
if (diff < 0) diff += 1440;
totalMinutes += diff;
uniqueDays.add(ev.date);
if (!mainTagMap.has(ev.main_tag_id)) {
mainTagMap.set(ev.main_tag_id, { total: 0, subTags: new Map() });
}
const mainStat = mainTagMap.get(ev.main_tag_id)!;
mainStat.total += diff;
if (ev.sub_tag_id) {
const subTotal = mainStat.subTags.get(ev.sub_tag_id) || 0;
mainStat.subTags.set(ev.sub_tag_id, subTotal + diff);
}
});
const start = new Date(dashboardStartDate.value);
const end = new Date(dashboardEndDate.value);
const naturalDays = Math.max(1, Math.floor((end.getTime() - start.getTime()) / 86400000) + 1);
const recordedDays = Math.max(1, uniqueDays.size);
const daysCount = dailyAverageMode.value === 'natural' ? naturalDays : recordedDays;
const mainTagsList = Array.from(mainTagMap.entries()).map(([id, stat]) => {
const subTagsList = Array.from(stat.subTags.entries()).map(([subId, subTotal]) => ({
id: subId,
total: subTotal,
percentage: stat.total > 0 ? (subTotal / stat.total) * 100 : 0
})).sort((a, b) => b.total - a.total);
return {
id,
total: stat.total,
dailyAverage: stat.total / daysCount,
percentage: totalMinutes > 0 ? (stat.total / totalMinutes) * 100 : 0,
subTags: subTagsList
};
}).sort((a, b) => b.total - a.total);
return { totalMinutes, dailyAverage: totalMinutes / daysCount, mainTags: mainTagsList, naturalDays, recordedDays, daysCount };
});