1+ "use client" ;
2+
13import Link from 'next/link' ;
24import clsx from 'clsx' ;
35import { CheckCircleIcon , EllipsisHorizontalIcon , TrophyIcon } from '@heroicons/react/20/solid' ;
46
57import roadmap from './roadmap.json' ;
68import { BlankLayout } from '@/components/BlankLayout' ;
79import { formatDate } from '@/lib/formatDate'
10+ import { useState } from 'react' ;
11+ import { ArrowDown , ArrowRight , ChevronDown , ChevronRight } from 'lucide-react' ;
812
9- export const metadata = {
10- title : 'Roadmap' ,
11- description :
12- 'Iroh 1.0 roadmap. Here\'s where we\'re headed, and progress we made against our goal to date.' ,
13- } ;
14-
13+ // export const metadata = {
14+ // title: 'Roadmap',
15+ // description:
16+ // 'Iroh 1.0 roadmap. Here\'s where we\'re headed, and progress we made against our goal to date.',
17+ // };
1518
1619export default function Component ( ) {
1720 const { last_updated } = roadmap ;
@@ -26,20 +29,50 @@ export default function Component() {
2629 < h1 className = 'text-3xl font-bold font-space-mono text-iroh-gray-700 mb-4' > </ h1 >
2730 < p className = 'text-iroh-gray-500' > </ p >
2831 </ div >
29- { roadmap . milestones . map ( ( milestone , i ) => {
30- if ( milestone . version ) {
31- return < Release key = { i } data = { milestone } />
32- } else if ( milestone . all_done === false || milestone . all_done === true ) {
33- return < AllDone key = { i } data = { milestone } />
34- } else if ( milestone . ellipsis ) {
35- return < Ellipsis key = { i } data = { milestone } />
36- }
37- return < Milestone key = { i } data = { milestone } />
38- } ) }
32+ < Milestones data = { roadmap . milestones } />
3933 </ BlankLayout >
4034 )
4135}
4236
37+ function Milestones ( { data } ) {
38+ return data . map ( ( milestone , i ) => {
39+ if ( milestone . section ) {
40+ return < Section key = { i } data = { milestone } />
41+ } else if ( milestone . version ) {
42+ return < Release key = { i } data = { milestone } />
43+ } else if ( milestone . all_done === false || milestone . all_done === true ) {
44+ return < AllDone key = { i } data = { milestone } />
45+ } else if ( milestone . ellipsis ) {
46+ return < Ellipsis key = { i } data = { milestone } />
47+ }
48+ return < Milestone key = { i } data = { milestone } />
49+ } )
50+ }
51+
52+ function Section ( { data } ) {
53+ const { section, startCollapsed, milestones } = data ;
54+ const [ collapsed , setCollapsed ] = useState ( startCollapsed ) ;
55+ const first_release_string = formatDate ( milestones . find ( ( m ) => m . released ) . released , true )
56+ const last_release_string = formatDate ( milestones . findLast ( ( m ) => m . released ) . released , true )
57+
58+ return (
59+ < div >
60+ < div style = { { marginLeft : '6.5rem' } } className = 'pr-5 relative flex gap-4 w-full' >
61+ < button className = 'cursor-pointer border-1 border-iroh-purple-400 p-3 w-12 h-12 rounded-full' onClick = { ( ) => setCollapsed ( ! collapsed ) } >
62+ { collapsed ? < ChevronRight /> : < ChevronDown /> }
63+ </ button >
64+ < button className = 'text-left cursor-pointer' onClick = { ( ) => setCollapsed ( ! collapsed ) } >
65+ < h3 className = 'w-full text-xl leading-6 text-iroh-gray-600 font-space font-bold dark:text-iroh-gray-400' > { section } </ h3 >
66+ < p className = 'text-xs text-iroh-gray-400 dark:text-iroh-gray-600' >
67+ { milestones . filter ( ( m ) => m . version ) . length } releases: { first_release_string } - { last_release_string }
68+ </ p >
69+ </ button >
70+ </ div >
71+ { ! collapsed && < Milestones data = { milestones } /> }
72+ </ div >
73+ )
74+ }
75+
4376function Release ( { data } ) {
4477 const { version, done, doc, released, expected } = data ;
4578 return (
@@ -63,6 +96,7 @@ function Release({ data }) {
6396 )
6497}
6598
99+
66100function Milestone ( { data } ) {
67101 const { done, title, description, subtasks, tracking_issue, doc } = data ;
68102 const issueNunber = tracking_issue ?. split ( "/" ) . slice ( - 1 ) [ 0 ]
0 commit comments