diff --git a/apps/web/app/(dashboard)/calendar/page.tsx b/apps/web/app/(dashboard)/calendar/page.tsx index 8f76c13..c7a521c 100644 --- a/apps/web/app/(dashboard)/calendar/page.tsx +++ b/apps/web/app/(dashboard)/calendar/page.tsx @@ -248,15 +248,15 @@ export default function CalendarPage() {

Domains

- {['personal', 'work', 'ots'].map((domain) => ( -
+ {(domainOptions.length > 0 ? domainOptions : []).map((domain) => ( +
toggleDomain(domain)} + id={domain.id} + checked={selectedDomains.includes(domain.id)} + onCheckedChange={() => toggleDomain(domain.id)} /> -
))} diff --git a/apps/web/app/(dashboard)/projects/page.tsx b/apps/web/app/(dashboard)/projects/page.tsx index ff2a1ab..91195b8 100644 --- a/apps/web/app/(dashboard)/projects/page.tsx +++ b/apps/web/app/(dashboard)/projects/page.tsx @@ -1,13 +1,15 @@ "use client"; import { useEffect, useState } from "react"; -import { Trash2 } from "lucide-react"; +import { Plus, Trash2 } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog"; import { toast } from "sonner"; import Link from "next/link"; +import { CreateItemDialog } from "@/components/create-item-dialog"; +import { useCreateDialogStore } from "@/lib/stores/use-create-dialog-store"; interface Project { id: string; @@ -22,6 +24,8 @@ export default function ProjectsPage() { const [loading, setLoading] = useState(true); const [deleteId, setDeleteId] = useState(null); const [deleting, setDeleting] = useState(false); + const [refreshKey, setRefreshKey] = useState(0); + const { open, openCreate, closeCreate } = useCreateDialogStore(); useEffect(() => { fetchProjects(); fetchDomains(); }, []); @@ -64,9 +68,12 @@ export default function ProjectsPage() {

Projects

Plan and track your work.

+
{projects.length === 0 ?

No projects yet.

: ( -
+
{projects.map((p) => ( @@ -97,6 +104,7 @@ export default function ProjectsPage() { + (o ? openCreate("project") : closeCreate())} onCreated={() => setRefreshKey((k) => k + 1)} />
); } diff --git a/apps/web/components/dashboard/widgets/project-progress-widget.tsx b/apps/web/components/dashboard/widgets/project-progress-widget.tsx index dc6e78b..63fdfb2 100644 --- a/apps/web/components/dashboard/widgets/project-progress-widget.tsx +++ b/apps/web/components/dashboard/widgets/project-progress-widget.tsx @@ -26,7 +26,21 @@ export function ProjectProgressWidget() { ); if (response.ok) { const data = await response.json(); - setProjects(data.items || []); + const items = data.items || []; + // Fetch progress for each project since the list API doesn't include it + const withProgress = await Promise.all( + items.map(async (p: { id: string; name: string }) => { + try { + const progRes = await fetch(`/api/projects/${p.id}/progress`); + if (progRes.ok) { + const progData = await progRes.json(); + return { ...p, progress: progData.progress ?? 0 }; + } + } catch {} + return { ...p, progress: 0 }; + }) + ); + setProjects(withProgress); } } catch (error) { console.error('Failed to fetch projects:', error); diff --git a/apps/web/components/dashboard/widgets/today-tasks-widget.tsx b/apps/web/components/dashboard/widgets/today-tasks-widget.tsx index 24f536e..1508a34 100644 --- a/apps/web/components/dashboard/widgets/today-tasks-widget.tsx +++ b/apps/web/components/dashboard/widgets/today-tasks-widget.tsx @@ -5,6 +5,7 @@ import { CheckCircle2, Circle, ListTodo } from 'lucide-react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; +import { useRouter } from 'next/navigation'; interface Task { id: string; @@ -20,11 +21,25 @@ export function TodayTasksWidget() { const [tasks, setTasks] = useState([]); const [loading, setLoading] = useState(true); const [domainMap, setDomainMap] = useState>(new Map()); + const router = useRouter(); useEffect(() => { fetchTasks(); + fetchDomains(); }, []); + async function fetchDomains() { + try { + const res = await fetch("/api/domains?sort=sort_order"); + if (res.ok) { + const data = await res.json(); + const map = new Map(); + for (const d of data.items || []) map.set(d.id, d.name); + setDomainMap(map); + } + } catch {} + } + async function fetchTasks() { try { const response = await fetch( @@ -63,7 +78,7 @@ export function TodayTasksWidget() {
diff --git a/apps/web/components/settings/settings-domains.tsx b/apps/web/components/settings/settings-domains.tsx index 3ac66f4..991a506 100644 --- a/apps/web/components/settings/settings-domains.tsx +++ b/apps/web/components/settings/settings-domains.tsx @@ -67,7 +67,7 @@ export function SettingsDomains() { headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: newDomainName, - color: '#3b82f6', + color: newDomainColor, icon: '📁', sort_order: domains.length, }), diff --git a/apps/web/components/tasks/tasks-list-view.tsx b/apps/web/components/tasks/tasks-list-view.tsx index 7e21e50..083a72e 100644 --- a/apps/web/components/tasks/tasks-list-view.tsx +++ b/apps/web/components/tasks/tasks-list-view.tsx @@ -13,7 +13,7 @@ import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Checkbox } from '@/components/ui/checkbox'; import { ScrollArea, ScrollBar } from '@/components/ui/scroll-area'; -import { Calendar, MoreHorizontal } from 'lucide-react'; +import { Calendar, MoreHorizontal, Pencil, Trash2 } from 'lucide-react'; import { toast } from 'sonner'; import { TaskDetailPanel } from './task-detail-panel'; import { @@ -157,14 +157,28 @@ export function TasksListView() { )} - + + + + + + setSelectedTask(task)}> + + Edit + + setDeleteId(task.id)}> + + Delete + + + ))}