@@ -59,75 +59,87 @@ export default async function ChangelogPage() {
5959 } ;
6060
6161 return (
62- < main className = "px-6 py-12" >
63- < div className = "mx-auto flex max-w-3xl flex-col gap-6" >
64- < div className = "sticky top-0 z-10 flex flex-wrap items-center gap-3 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 py-4 -mx-6 px-6" >
65- < Button asChild variant = "ghost" size = "sm" >
66- < Link href = "/" >
67- < ArrowLeft className = "h-4 w-4" />
68- </ Link >
69- </ Button >
70- < h1 className = "text-2xl font-semibold tracking-tight" > Changelog</ h1 >
71- </ div >
72- < div className = "grid gap-6" >
73- { sections
74- . map ( ( section , index ) => ( {
75- ...section ,
76- index,
77- date : section . title . match ( / - \s * ( \d { 4 } - \d { 2 } - \d { 2 } ) \s * $ / ) ?. [ 1 ] ,
78- } ) )
79- . filter ( ( section ) => section . title . toLowerCase ( ) !== "[unreleased]" )
80- . sort ( ( a , b ) => {
81- if ( a . date && b . date ) {
82- return b . date . localeCompare ( a . date ) ;
83- }
84- if ( a . date ) {
85- return - 1 ;
86- }
87- if ( b . date ) {
88- return 1 ;
89- }
90- return b . index - a . index ;
91- } )
92- . map ( ( section ) => {
93- const content = markdownContent ( section . body ) ;
94- // Only render sections that have content
95- if ( ! content . trim ( ) ) {
96- return null ;
97- }
98- return (
99- < Card key = { section . title } >
100- < CardHeader >
101- < CardTitle > { section . title } </ CardTitle >
102- </ CardHeader >
103- < CardContent >
104- < div className = "prose prose-sm dark:prose-invert max-w-none [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:rounded [&_code]:bg-muted [&_code]:text-foreground [&_code]:text-xs [&_code]:font-mono [&_pre]:hidden" >
105- < ReactMarkdown
106- remarkPlugins = { [ remarkGfm ] }
107- components = { {
108- h3 : ( { children } ) => (
109- < h3 className = "text-base font-semibold mt-4 mb-2 first:mt-0" > { children } </ h3 >
110- ) ,
111- ul : ( { children } ) => (
112- < ul className = "list-disc pl-5 space-y-1 my-2" > { children } </ ul >
113- ) ,
114- li : ( { children } ) => (
115- < li className = "text-sm text-foreground" > { children } </ li >
116- ) ,
117- p : ( { children } ) => (
118- < p className = "text-sm text-foreground my-2" > { children } </ p >
119- ) ,
120- pre : ( ) => null ,
121- } }
122- >
123- { content }
124- </ ReactMarkdown >
125- </ div >
126- </ CardContent >
127- </ Card >
128- ) ;
129- } )
130- . filter ( Boolean ) }
62+ < main className = "min-h-screen" >
63+ < div className = "px-6 py-12" >
64+ < div className = "mx-auto flex max-w-3xl flex-col gap-6" >
65+ < div className = "flex flex-wrap items-center gap-3" >
66+ < Button
67+ asChild
68+ variant = "ghost"
69+ size = "sm"
70+ >
71+ < Link href = "/" >
72+ < ArrowLeft className = "h-4 w-4" />
73+ </ Link >
74+ </ Button >
75+ < h1 className = "text-3xl font-semibold tracking-tight" >
76+ Changelog
77+ </ h1 >
78+ </ div >
79+ < div className = "grid gap-6" >
80+ { sections
81+ . map ( ( section , index ) => ( {
82+ ...section ,
83+ index,
84+ date : section . title . match ( / - \s * ( \d { 4 } - \d { 2 } - \d { 2 } ) \s * $ / ) ?. [ 1 ] ,
85+ } ) )
86+ . filter ( ( section ) => section . title . toLowerCase ( ) !== "[unreleased]" )
87+ . toSorted ( ( a , b ) => {
88+ if ( a . date && b . date ) {
89+ return b . date . localeCompare ( a . date ) ;
90+ }
91+ if ( a . date ) {
92+ return - 1 ;
93+ }
94+ if ( b . date ) {
95+ return 1 ;
96+ }
97+ return b . index - a . index ;
98+ } )
99+ . map ( ( section ) => {
100+ const content = markdownContent ( section . body ) ;
101+ // Only render sections that have content
102+ if ( ! content . trim ( ) ) {
103+ return null ;
104+ }
105+ return (
106+ < Card
107+ key = { section . title }
108+ >
109+ < CardHeader >
110+ < CardTitle className = "text-xl" >
111+ { section . title }
112+ </ CardTitle >
113+ </ CardHeader >
114+ < CardContent >
115+ < div className = "prose prose-sm dark:prose-invert max-w-none [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:rounded [&_code]:bg-muted [&_code]:text-foreground [&_code]:text-xs [&_code]:font-mono [&_pre]:hidden" >
116+ < ReactMarkdown
117+ remarkPlugins = { [ remarkGfm ] }
118+ components = { {
119+ h3 : ( { children } ) => (
120+ < h3 className = "text-base font-semibold mt-4 mb-2 first:mt-0 text-primary" > { children } </ h3 >
121+ ) ,
122+ ul : ( { children } ) => (
123+ < ul className = "list-disc pl-5 space-y-1 my-2" > { children } </ ul >
124+ ) ,
125+ li : ( { children } ) => (
126+ < li className = "text-sm text-foreground" > { children } </ li >
127+ ) ,
128+ p : ( { children } ) => (
129+ < p className = "text-sm text-foreground my-2 leading-relaxed" > { children } </ p >
130+ ) ,
131+ pre : ( ) => null ,
132+ } }
133+ >
134+ { content }
135+ </ ReactMarkdown >
136+ </ div >
137+ </ CardContent >
138+ </ Card >
139+ ) ;
140+ } )
141+ . filter ( Boolean ) }
142+ </ div >
131143 </ div >
132144 </ div >
133145 </ main >
0 commit comments