diff --git a/apps/manacore/apps/web/src/lib/api/services/todo.ts b/apps/manacore/apps/web/src/lib/api/services/todo.ts index 6e5a88d44..814a77b2c 100644 --- a/apps/manacore/apps/web/src/lib/api/services/todo.ts +++ b/apps/manacore/apps/web/src/lib/api/services/todo.ts @@ -97,6 +97,30 @@ export const todoService = { return { data: result.data.tasks || [], error: null }; }, + /** + * Get all open tasks sorted by due date (today first, then future, then no date) + */ + async getAllOpenTasks(): Promise> { + const result = await getClient().get<{ tasks: Task[] }>('/tasks'); + + if (result.error || !result.data) { + return { data: null, error: result.error }; + } + + const openTasks = (result.data.tasks || []).filter((t) => !t.isCompleted); + + // Sort: today/overdue first, then by date ascending, tasks without date last + const now = new Date(); + now.setHours(0, 0, 0, 0); + openTasks.sort((a, b) => { + const dateA = a.dueDate ? new Date(a.dueDate).getTime() : Infinity; + const dateB = b.dueDate ? new Date(b.dueDate).getTime() : Infinity; + return dateA - dateB; + }); + + return { data: openTasks, error: null }; + }, + /** * Get upcoming tasks for the next N days */ diff --git a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/TasksTodayWidget.svelte b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/TasksTodayWidget.svelte index 8d7fd7757..9c737690a 100644 --- a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/TasksTodayWidget.svelte +++ b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/TasksTodayWidget.svelte @@ -7,9 +7,25 @@ import { _ } from 'svelte-i18n'; import { todoService, type Task } from '$lib/api/services'; import { APP_URLS } from '@manacore/shared-branding'; + import { format, isToday, isTomorrow, isPast } from 'date-fns'; + import { de } from 'date-fns/locale'; import WidgetSkeleton from '../WidgetSkeleton.svelte'; import WidgetError from '../WidgetError.svelte'; + function formatDueDate(dueDate?: string): string | null { + if (!dueDate) return null; + const date = new Date(dueDate); + if (isToday(date)) return 'Heute'; + if (isTomorrow(date)) return 'Morgen'; + return format(date, 'dd. MMM', { locale: de }); + } + + function isOverdue(dueDate?: string): boolean { + if (!dueDate) return false; + const date = new Date(dueDate); + return isPast(date) && !isToday(date); + } + let state = $state<'loading' | 'success' | 'error'>('loading'); let data = $state([]); let error = $state(null); @@ -32,7 +48,7 @@ state = 'loading'; retrying = true; - const result = await todoService.getTodayTasks(); + const result = await todoService.getAllOpenTasks(); if (result.data) { data = result.data; @@ -124,13 +140,24 @@
-

- {task.title} -

+
+

+ {task.title} +

+ {#if formatDueDate(task.dueDate)} + + {formatDueDate(task.dueDate)} + + {/if} +
{#if task.dueTime || getSubtaskProgress(task) || (task.labels && task.labels.length > 0)}
diff --git a/apps/manacore/apps/web/src/lib/i18n/locales/de.json b/apps/manacore/apps/web/src/lib/i18n/locales/de.json index 26c0ee109..f8addf7de 100644 --- a/apps/manacore/apps/web/src/lib/i18n/locales/de.json +++ b/apps/manacore/apps/web/src/lib/i18n/locales/de.json @@ -33,9 +33,9 @@ "empty": "Keine Transaktionen" }, "tasks_today": { - "title": "Aufgaben heute", - "description": "Deine heutigen Aufgaben", - "empty": "Keine Aufgaben für heute" + "title": "Aufgaben", + "description": "Deine offenen Aufgaben", + "empty": "Keine offenen Aufgaben" }, "tasks_upcoming": { "title": "Kommende Aufgaben", diff --git a/apps/manacore/apps/web/src/lib/i18n/locales/en.json b/apps/manacore/apps/web/src/lib/i18n/locales/en.json index 83528e862..5ae243670 100644 --- a/apps/manacore/apps/web/src/lib/i18n/locales/en.json +++ b/apps/manacore/apps/web/src/lib/i18n/locales/en.json @@ -33,9 +33,9 @@ "empty": "No transactions" }, "tasks_today": { - "title": "Tasks Today", - "description": "Your tasks for today", - "empty": "No tasks for today" + "title": "Tasks", + "description": "Your open tasks", + "empty": "No open tasks" }, "tasks_upcoming": { "title": "Upcoming Tasks",