@@ -2,61 +2,75 @@ import { useState, useEffect } from 'react';
22import ReactMarkdown from 'react-markdown' ;
33import Analytics from './Analytics' ;
44import NotFound from './NotFound' ;
5+ import Home from './Home' ;
56
6- const allPostFiles = import . meta. glob ( '/public/posts/**/*.md' , { query : '?url' , import : 'default' } ) ;
7-
8- function App ( ) {
7+ export default function App ( ) {
98 const [ content , setContent ] = useState ( '' ) ;
9+ const [ posts , setPosts ] = useState ( [ ] ) ;
1010 const [ status , setStatus ] = useState ( 'loading' ) ;
1111
1212 useEffect ( ( ) => {
1313 const params = new URLSearchParams ( window . location . search ) ;
1414 const redirectedPath = params . get ( 'p' ) ;
15- const currentPath = redirectedPath || window . location . pathname ;
15+ let currentPath = redirectedPath || window . location . pathname ;
1616
1717 if ( redirectedPath ) {
1818 window . history . replaceState ( null , '' , redirectedPath ) ;
1919 }
2020
21- if ( currentPath === '/' || currentPath === '/index.html' ) {
22- setContent ( '# Welcome My Blog' ) ;
23- setStatus ( 'success' ) ;
24- return ;
25- }
21+ fetch ( '/posts.json' )
22+ . then ( res => res . json ( ) )
23+ . then ( data => {
24+ setPosts ( data ) ;
25+
26+ const pathClean = currentPath . replace ( / \. h t m l $ / , '' ) ;
27+ const parts = pathClean . split ( '/' ) . filter ( Boolean ) ;
2628
27- const parts = currentPath . replace ( / \. h t m l $ / , '' ) . split ( '/' ) . filter ( Boolean ) ;
28- const [ year , slug ] = parts ;
29-
30- if ( year && slug ) {
31- const expectedPath = `/public/posts/${ year } /${ slug } .md` ;
32-
33- if ( allPostFiles [ expectedPath ] ) {
34- fetch ( `/posts/${ year } /${ slug } .md` )
35- . then ( res => res . text ( ) )
36- . then ( text => {
37- setContent ( text ) ;
38- setStatus ( 'success' ) ;
39- } )
40- . catch ( ( ) => setStatus ( '404' ) ) ;
41- } else {
42- setStatus ( '404' ) ;
43- }
44- } else {
45- setStatus ( '404' ) ;
46- }
29+ if ( parts . length === 0 || ( parts . length === 1 && parts [ 0 ] === 'index' ) ) {
30+ setStatus ( 'home' ) ;
31+ return ;
32+ }
33+
34+ if ( parts . length === 2 ) {
35+ const [ year , slug ] = parts ;
36+ const found = data . find ( p => p . year === year && p . slug === slug ) ;
37+
38+ if ( found ) {
39+ fetch ( `/posts/${ year } /${ found . originalName } .md` )
40+ . then ( res => res . text ( ) )
41+ . then ( text => {
42+ setContent ( text ) ;
43+ setStatus ( 'post' ) ;
44+ } )
45+ . catch ( ( ) => setStatus ( '404' ) ) ;
46+ } else {
47+ setStatus ( '404' ) ;
48+ }
49+ } else {
50+ setStatus ( '404' ) ;
51+ }
52+ } )
53+ . catch ( ( ) => setStatus ( '404' ) ) ;
4754 } , [ ] ) ;
4855
4956 if ( status === 'loading' ) return < div > Loading...</ div > ;
50- if ( status === '404' ) return < NotFound /> ;
5157
5258 return (
5359 < >
5460 < Analytics />
55- < article style = { { padding : '40px' , maxWidth : '800px' , margin : '0 auto' } } >
56- < ReactMarkdown > { content } </ ReactMarkdown >
57- </ article >
61+ < div className = "app-shell" style = { { padding : '40px' , maxWidth : '800px' , margin : '0 auto' } } >
62+ { status === '404' ? (
63+ < NotFound />
64+ ) : status === 'home' ? (
65+ < Home posts = { posts } />
66+ ) : (
67+ < article >
68+ < ReactMarkdown > { content } </ ReactMarkdown >
69+ < hr />
70+ < a href = "/" style = { { display : 'block' , marginTop : '20px' } } > ← Back to Home</ a >
71+ </ article >
72+ ) }
73+ </ div >
5874 </ >
5975 ) ;
60- }
61-
62- export default App ;
76+ }
0 commit comments