From b2c7551d5be14e80e1c094673d0c246f9355a60e Mon Sep 17 00:00:00 2001 From: mindesbunister Date: Tue, 25 Nov 2025 07:52:10 +0100 Subject: [PATCH] feat: Add collapsible roadmap items with completed collapsed by default - Added expandedItems state to track which items are expanded - Auto-expands only non-complete items on load (in-progress, planned) - Complete items collapsed by default for better overview - Click anywhere on item header or chevron to toggle - Smooth transitions and hover effects - Improves readability when many items are complete --- app/roadmap/page.tsx | 129 ++++++++++++++++++++++++++++++------------- 1 file changed, 90 insertions(+), 39 deletions(-) diff --git a/app/roadmap/page.tsx b/app/roadmap/page.tsx index 6383993..78219a9 100644 --- a/app/roadmap/page.tsx +++ b/app/roadmap/page.tsx @@ -15,6 +15,7 @@ interface RoadmapItem { export default function RoadmapPage() { const [roadmap, setRoadmap] = useState([]) const [loading, setLoading] = useState(true) + const [expandedItems, setExpandedItems] = useState>(new Set()) useEffect(() => { fetchRoadmap() @@ -25,6 +26,15 @@ export default function RoadmapPage() { const response = await fetch('/api/roadmap') const data = await response.json() setRoadmap(data.roadmap || []) + + // Auto-expand only non-complete items by default + const autoExpand = new Set() + data.roadmap?.forEach((item: RoadmapItem, index: number) => { + if (item.status !== 'complete') { + autoExpand.add(index) + } + }) + setExpandedItems(autoExpand) } catch (error) { console.error('Failed to fetch roadmap:', error) } finally { @@ -32,6 +42,16 @@ export default function RoadmapPage() { } } + const toggleItem = (index: number) => { + const newExpanded = new Set(expandedItems) + if (newExpanded.has(index)) { + newExpanded.delete(index) + } else { + newExpanded.add(index) + } + setExpandedItems(newExpanded) + } + const getStatusColor = (status: string) => { switch (status) { case 'complete': @@ -136,48 +156,79 @@ export default function RoadmapPage() { {/* Roadmap Items */}
- {roadmap.map((item, index) => ( -
-
-
-
- {getStatusIcon(item.status)} -

{item.title}

- - {item.phase} - -
-

{item.description}

-
-
Expected Impact
-
{item.impact}
-
- {item.completed && ( -
- ✓ Completed: {item.completed} + {roadmap.map((item, index) => { + const isExpanded = expandedItems.has(index) + return ( +
+
toggleItem(index)} + > +
+
+
+ {getStatusIcon(item.status)} +

{item.title}

+ + {item.phase} + +
+

{item.description}

+ {item.completed && ( +
+ ✓ Completed: {item.completed} +
+ )}
- )} + +
-
- {item.items && item.items.length > 0 && ( -
-
Implementation Details:
-
    - {item.items.map((subItem, subIndex) => ( -
  • - - {subItem} -
  • - ))} -
-
- )} -
- ))} + {isExpanded && ( +
+
+
+
Expected Impact
+
{item.impact}
+
+ + {item.items && item.items.length > 0 && ( +
+
Implementation Details:
+
    + {item.items.map((subItem, subIndex) => ( +
  • + + {subItem} +
  • + ))} +
+
+ )} +
+
+ )} +
+ ) + })}
{/* Footer */}