@@ -280,6 +280,19 @@ const FileViewer = ({ file, type, onClose, playClick, onVocabClick }) => {
280280
281281 useEffect ( ( ) => {
282282 if ( type === 'post' ) {
283+ if ( file . isSeries ) {
284+ const seriesContent = `
285+ # ${ file . title }
286+ ${ file . description || '' }
287+
288+ ## Series Index
289+ ${ file . posts . map ( ( p , i ) => `${ i + 1 } . [${ p . title } ](/blog/${ p . slug } )` ) . join ( '\n' ) }
290+ ` ;
291+ setContent ( seriesContent ) ;
292+ setLoading ( false ) ;
293+ return ;
294+ }
295+
283296 setLoading ( true ) ;
284297 const fetchPath = file . content
285298 ? null
@@ -610,14 +623,47 @@ const Workstation = ({
610623 } ) )
611624 . sort ( ( a , b ) => a . title . localeCompare ( b . title ) ) ;
612625
613- useEffect ( ( ) => {
614- // Fetch posts
615- fetch ( '/posts/posts.json' )
616- . then ( ( res ) => res . json ( ) )
617- . then ( ( data ) => setPosts ( data ) )
618- . catch ( ( err ) => console . error ( err ) ) ;
626+ useEffect ( ( ) => {
627+ // Fetch posts
628+ fetch ( '/posts/posts.json' )
629+ . then ( ( res ) => res . json ( ) )
630+ . then ( ( data ) => {
631+ const processedItems = data . map ( ( item ) => {
632+ if ( item . series ) {
633+ // This is a series container
634+ return {
635+ ...item ,
636+ isSeries : true ,
637+ // Flatten the nested posts array to the top level for FileViewer compatibility
638+ posts : item . series . posts . map ( p => ( {
639+ ...p ,
640+ // Ensure filename is clean
641+ filename : p . filename ?. startsWith ( '/' ) ? p . filename . substring ( 1 ) : p . filename
642+ } ) ) ,
643+ category : 'series' , // Ensure category is set for styling
644+ // Inherit tags from first post or use own
645+ tags : item . tags || ( item . series . posts && item . series . posts [ 0 ] && item . series . posts [ 0 ] . tags ) || [ ] ,
646+ description : item . description || ( item . series && item . series . description )
647+ } ;
648+ } else {
649+ // Individual post
650+ return {
651+ ...item ,
652+ filename : item . filename ?. startsWith ( '/' ) ? item . filename . substring ( 1 ) : item . filename
653+ } ;
654+ }
655+ } ) ;
619656
620- // Fetch About
657+ // Sort by updated/date
658+ processedItems . sort (
659+ ( a , b ) =>
660+ new Date ( b . updated || b . date ) - new Date ( a . updated || a . date ) ,
661+ ) ;
662+ setPosts ( processedItems ) ;
663+ } )
664+ . catch ( ( err ) => console . error ( err ) ) ;
665+
666+ // Fetch About
621667 fetch ( '/about-me/about.txt' )
622668 . then ( ( res ) => res . text ( ) )
623669 . then ( ( text ) => setAboutContent ( text ) )
@@ -959,7 +1005,10 @@ const Workstation = ({
9591005 } )
9601006 : 'Unknown' }
9611007 </ div >
962- < div className = "col-span-5 font-medium text-[#e8f7f7] group-hover:text-white truncate" >
1008+ < div className = "col-span-5 font-medium text-[#e8f7f7] group-hover:text-white truncate flex items-center gap-2" >
1009+ { post . isSeries && (
1010+ < Folder size = { 16 } weight = "fill" className = "text-amber-400 shrink-0" />
1011+ ) }
9631012 { post . title }
9641013 </ div >
9651014 < div className = "col-span-2" >
0 commit comments