diff --git a/.gitignore b/.gitignore index a547bf3..e114360 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Posts +public/posts.json + # Logs logs *.log diff --git a/build.js b/build.js index 5af3c71..00de931 100644 --- a/build.js +++ b/build.js @@ -3,7 +3,7 @@ import path from 'path'; const postsDir = './public/posts'; const distDir = './dist'; - +const allPosts = []; const years = fs.readdirSync(postsDir); years.forEach(year => { @@ -12,23 +12,46 @@ years.forEach(year => { const files = fs.readdirSync(yearPath); files.forEach(file => { if (file.endsWith('.md')) { - const slug = file.replace('.md', ''); - const targetDir = path.join(distDir, year); - - if (!fs.existsSync(targetDir)) { - fs.mkdirSync(targetDir, { - recursive: true - }); - } - fs.copyFileSync(path.join(distDir, 'index.html'), path.join(targetDir, `${slug}.html`)); + const fileName = file.replace('.md', ''); + const parts = fileName.split('-'); + const date = parts.slice(0, 3).join('-'); + const slug = parts.slice(3).join('-'); + + allPosts.push({ + year, + date, + slug, + originalName: fileName, + title: slug.replace(/-/g, ' ') + }); } }); } }); -fs.copyFileSync( - path.join(distDir, 'index.html'), - path.join(distDir, '404.html') -); +allPosts.sort((a, b) => b.date.localeCompare(a.date)); + +const postsData = JSON.stringify(allPosts, null, 2); +fs.writeFileSync('./public/posts.json', postsData); + +if (fs.existsSync(path.join(distDir, 'index.html'))) { + fs.writeFileSync(path.join(distDir, 'posts.json'), postsData); + + allPosts.forEach(post => { + const targetDir = path.join(distDir, post.year); + if (!fs.existsSync(targetDir)) { + fs.mkdirSync(targetDir, { recursive: true }); + } + fs.copyFileSync( + path.join(distDir, 'index.html'), + path.join(targetDir, `${post.slug}.html`) + ); + }); + + fs.copyFileSync( + path.join(distDir, 'index.html'), + path.join(distDir, '404.html') + ); +} -console.log('✅ Build HTML from Markdown Post'); \ No newline at end of file +console.log(`✅ Build ${allPosts.length} Posts Successfully`); diff --git a/public/posts/2025/2025-12-13-Test7.md b/public/posts/2025/2025-12-13-Test7.md new file mode 100644 index 0000000..7b82441 --- /dev/null +++ b/public/posts/2025/2025-12-13-Test7.md @@ -0,0 +1 @@ +Test7 file \ No newline at end of file diff --git a/public/posts/2026/2026-01-29-Test3.md b/public/posts/2026/2026-01-29-Test3.md new file mode 100644 index 0000000..0c1d4e5 --- /dev/null +++ b/public/posts/2026/2026-01-29-Test3.md @@ -0,0 +1 @@ +test3 file \ No newline at end of file diff --git a/public/posts/2026/2026-01-31-Test123.md b/public/posts/2026/2026-01-31-Test123.md new file mode 100644 index 0000000..a208335 --- /dev/null +++ b/public/posts/2026/2026-01-31-Test123.md @@ -0,0 +1 @@ +test 123 file \ No newline at end of file diff --git a/public/posts/2026/2026-02-03-Test5.md b/public/posts/2026/2026-02-03-Test5.md new file mode 100644 index 0000000..4f1bd33 --- /dev/null +++ b/public/posts/2026/2026-02-03-Test5.md @@ -0,0 +1 @@ +test5 \ No newline at end of file diff --git a/public/posts/2026/Test.md b/public/posts/2026/2026-03-05-Test.md similarity index 100% rename from public/posts/2026/Test.md rename to public/posts/2026/2026-03-05-Test.md diff --git a/src/App.jsx b/src/App.jsx index 683cbd7..a55115d 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -2,61 +2,75 @@ import { useState, useEffect } from 'react'; import ReactMarkdown from 'react-markdown'; import Analytics from './Analytics'; import NotFound from './NotFound'; +import Home from './Home'; -const allPostFiles = import.meta.glob('/public/posts/**/*.md', { query: '?url', import: 'default' }); - -function App() { +export default function App() { const [content, setContent] = useState(''); + const [posts, setPosts] = useState([]); const [status, setStatus] = useState('loading'); useEffect(() => { const params = new URLSearchParams(window.location.search); const redirectedPath = params.get('p'); - const currentPath = redirectedPath || window.location.pathname; + let currentPath = redirectedPath || window.location.pathname; if (redirectedPath) { window.history.replaceState(null, '', redirectedPath); } - if (currentPath === '/' || currentPath === '/index.html') { - setContent('# Welcome My Blog'); - setStatus('success'); - return; - } + fetch('/posts.json') + .then(res => res.json()) + .then(data => { + setPosts(data); + + const pathClean = currentPath.replace(/\.html$/, ''); + const parts = pathClean.split('/').filter(Boolean); - const parts = currentPath.replace(/\.html$/, '').split('/').filter(Boolean); - const [year, slug] = parts; - - if (year && slug) { - const expectedPath = `/public/posts/${year}/${slug}.md`; - - if (allPostFiles[expectedPath]) { - fetch(`/posts/${year}/${slug}.md`) - .then(res => res.text()) - .then(text => { - setContent(text); - setStatus('success'); - }) - .catch(() => setStatus('404')); - } else { - setStatus('404'); - } - } else { - setStatus('404'); - } + if (parts.length === 0 || (parts.length === 1 && parts[0] === 'index')) { + setStatus('home'); + return; + } + + if (parts.length === 2) { + const [year, slug] = parts; + const found = data.find(p => p.year === year && p.slug === slug); + + if (found) { + fetch(`/posts/${year}/${found.originalName}.md`) + .then(res => res.text()) + .then(text => { + setContent(text); + setStatus('post'); + }) + .catch(() => setStatus('404')); + } else { + setStatus('404'); + } + } else { + setStatus('404'); + } + }) + .catch(() => setStatus('404')); }, []); if (status === 'loading') return