diff --git a/src/views/Dashboard.vue b/src/views/Dashboard.vue index 84aca8e..9e253ce 100644 --- a/src/views/Dashboard.vue +++ b/src/views/Dashboard.vue @@ -1,61 +1,80 @@ @@ -72,6 +91,7 @@ import { Tooltip, Legend } from 'chart.js' +import { Clock } from 'lucide-vue-next' import { useEntriesStore } from '../stores/entries' import { useProjectsStore } from '../stores/projects' import type { TimeEntry } from '../stores/entries' @@ -82,10 +102,34 @@ ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend) const entriesStore = useEntriesStore() const projectsStore = useProjectsStore() +const todayStats = ref<{ totalSeconds: number; byProject: unknown[] }>({ totalSeconds: 0, byProject: [] }) const weekStats = ref<{ totalSeconds: number; byProject: unknown[] }>({ totalSeconds: 0, byProject: [] }) const monthStats = ref<{ totalSeconds: number; byProject: unknown[] }>({ totalSeconds: 0, byProject: [] }) const recentEntries = ref([]) +// Greeting based on time of day +const greeting = computed(() => { + const hour = new Date().getHours() + if (hour < 12) return 'Good morning' + if (hour < 18) return 'Good afternoon' + return 'Good evening' +}) + +// Formatted date +const formattedDate = computed(() => { + return new Date().toLocaleDateString('en-US', { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric' + }) +}) + +// Empty state check +const isEmpty = computed(() => { + return recentEntries.value.length === 0 && weekStats.value.totalSeconds === 0 +}) + // Get start of current week (Monday) function getWeekStart(): string { const now = new Date() @@ -138,6 +182,8 @@ const chartData = computed(() => { const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] const weekStart = getWeekStart() const today = getToday() + const todayIndex = new Date().getDay() + const todayArrayIndex = todayIndex === 0 ? 6 : todayIndex - 1 // Initialize hours for each day const hoursPerDay = [0, 0, 0, 0, 0, 0, 0] @@ -147,20 +193,22 @@ const chartData = computed(() => { const entryDate = new Date(entry.start_time).toISOString().split('T')[0] if (entryDate >= weekStart && entryDate <= today) { const dayIndex = new Date(entry.start_time).getDay() - // Convert Monday=0, Sunday=6 to array index const index = dayIndex === 0 ? 6 : dayIndex - 1 hoursPerDay[index] += entry.duration / 3600 } }) + // Color today's bar lighter amber + const colors = hoursPerDay.map((_, i) => i === todayArrayIndex ? '#FBBF24' : '#D97706') + return { labels: days, datasets: [ { label: 'Hours', data: hoursPerDay, - backgroundColor: '#F59E0B', - borderRadius: 4 + backgroundColor: colors, + borderRadius: 2 } ] } @@ -187,10 +235,10 @@ const chartOptions = { y: { beginAtZero: true, grid: { - color: '#2E2E2E' + color: '#2E2E2A' }, ticks: { - color: '#A0A0A0' + color: '#5A5A54' } }, x: { @@ -198,7 +246,7 @@ const chartOptions = { display: false }, ticks: { - color: '#A0A0A0' + color: '#5A5A54' } } } @@ -206,13 +254,18 @@ const chartOptions = { // Load data on mount onMounted(async () => { - // Fetch projects first await projectsStore.fetchProjects() - - // Fetch all entries await entriesStore.fetchEntries() - // Get this week's stats + try { + todayStats.value = await invoke('get_reports', { + startDate: getToday(), + endDate: getToday() + }) + } catch (error) { + console.error('Failed to fetch today stats:', error) + } + try { weekStats.value = await invoke('get_reports', { startDate: getWeekStart(), @@ -222,7 +275,6 @@ onMounted(async () => { console.error('Failed to fetch week stats:', error) } - // Get this month's stats try { monthStats.value = await invoke('get_reports', { startDate: getMonthStart(), @@ -232,7 +284,6 @@ onMounted(async () => { console.error('Failed to fetch month stats:', error) } - // Get recent entries (last 5) recentEntries.value = entriesStore.entries.slice(0, 5) })