From 621a1d419a2cd24785f13e19d9220e78bb36202a Mon Sep 17 00:00:00 2001 From: Dave Date: Mon, 21 Sep 2026 16:16:40 +0200 Subject: [PATCH] feat(plan): GanttPlanView top-level component Composes one ProjectSection per section with a single shared timeline range. Renders the 'Nothing scheduled yet' empty state when no section has any dated cards or subtasks. --- src/components/roadmap/gantt-plan-view.tsx | 56 ++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/components/roadmap/gantt-plan-view.tsx diff --git a/src/components/roadmap/gantt-plan-view.tsx b/src/components/roadmap/gantt-plan-view.tsx new file mode 100644 index 0000000..5724546 --- /dev/null +++ b/src/components/roadmap/gantt-plan-view.tsx @@ -0,0 +1,56 @@ +"use client"; + +import { useMemo } from "react"; + +import { ProjectSection } from "@/components/roadmap/project-section"; +import { timelineRange } from "@/lib/roadmap/timeline"; +import type { PlanSection } from "@/lib/roadmap/load"; + +/** + * Top-level Gantt view. Computes one shared timeline range across every + * project section so a card in one project and a card in another share + * the same month/week axis. When every card and every subtask has no + * dates, shows the "Nothing scheduled yet" empty state. + */ +export function GanttPlanView({ sections }: { sections: PlanSection[] }) { + const range = useMemo(() => { + let n = 0; + const items: { id: string; startDate: string; targetDate: string }[] = []; + for (const s of sections) { + for (const c of s.cards) { + if (c.startDate || c.targetDate) { + items.push({ id: `c-${++n}`, startDate: c.startDate, targetDate: c.targetDate }); + } + for (const st of c.datedSubtasks) { + items.push({ id: `s-${++n}`, startDate: st.startDate, targetDate: st.targetDate }); + } + } + } + return timelineRange(items); + }, [sections]); + + if (sections.length === 0) { + return ( +
+

+ Nothing scheduled yet +

+

+ Set a start date and target date on a card to see it appear here. +

+
+ ); + } + + return ( +
+ {sections.map((section) => ( + + ))} +
+ ); +}