diff --git a/src/components/Search.astro b/src/components/Search.astro index 509dd52..255277f 100644 --- a/src/components/Search.astro +++ b/src/components/Search.astro @@ -19,16 +19,26 @@ let fuse; let posts = []; + let searchInitialized = false; async function initializeSearch() { - const response = await fetch('/search-index.json'); - posts = await response.json(); - - fuse = new Fuse(posts, { - keys: ['title', 'description', 'content'], - threshold: 0.3, - includeMatches: true - }); + // Prevent multiple initializations + if (searchInitialized) return; + try { + // Fetch the search index + const response = await fetch('/search-index.json'); + posts = await response.json(); + + fuse = new Fuse(posts, { + keys: ['title', 'description', 'content'], + threshold: 0.3, + includeMatches: true + }); + searchInitialized = true; + document.getElementById('search-results').innerHTML = ''; + } catch (error) { + console.error('Error fetching search index:', error); + } } function performSearch(query) { @@ -37,6 +47,8 @@ return; } + if (!searchInitialized) return; + const results = fuse.search(query); const resultsElement = document.getElementById('search-results'); @@ -58,14 +70,27 @@ resultsElement.innerHTML = html; } - - // Initialize search when the component mounts - initializeSearch(); - // Add event listener for search input const searchInput = document.getElementById('search-input'); + + // Initialize search only when the input is focused or clicked + searchInput.addEventListener('focus', initializeSearch); + searchInput.addEventListener('click', initializeSearch); + searchInput.addEventListener('input', (e) => { - performSearch(e.target.value); + if (!searchInitialized) { + initializeSearch().then(() => { + performSearch(e.target.value); + }); + } else { + performSearch(e.target.value); + } + }); + + searchInput.addEventListener('focus', () => { + if (!searchInitialized) { + document.getElementById('search-results').innerHTML = '
Loading search index...
'; + } }); diff --git a/src/content/config.ts b/src/content/config.ts index 2a3f37e..f0cc13e 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -1,11 +1,17 @@ import { defineCollection } from 'astro:content'; -import { blogs } from './blog/_schemas'; +import { posts } from './posts/_schemas'; +import { pages } from "./pages/_schemas"; const blogCollection = defineCollection({ type: 'content', - schema: blogs, + schema: posts, +}); +const pageCollection = defineCollection({ + type: 'content', + schema: pages, }); export const collections = { - 'blog': blogCollection, + 'posts': blogCollection, + 'pages': pageCollection, }; \ No newline at end of file diff --git a/src/content/pages/_schemas.ts b/src/content/pages/_schemas.ts new file mode 100644 index 0000000..ec1c912 --- /dev/null +++ b/src/content/pages/_schemas.ts @@ -0,0 +1,7 @@ +import { z } from 'astro:content'; + +export const pages = z.object({ + title: z.string(), + description: z.string(), + heroImage: z.string().optional() +}); \ No newline at end of file diff --git a/src/content/pages/test.md b/src/content/pages/test.md new file mode 100644 index 0000000..7818aee --- /dev/null +++ b/src/content/pages/test.md @@ -0,0 +1,5 @@ +--- +title: 'Test Page' +description: 'This is a test page' +--- +testestestest \ No newline at end of file diff --git a/src/content/blog/_schemas.ts b/src/content/posts/_schemas.ts similarity index 85% rename from src/content/blog/_schemas.ts rename to src/content/posts/_schemas.ts index 23945ba..a1e7613 100644 --- a/src/content/blog/_schemas.ts +++ b/src/content/posts/_schemas.ts @@ -1,6 +1,6 @@ import { z } from 'astro:content'; -export const blogs = z.object({ +export const posts = z.object({ title: z.string(), description: z.string(), pubDate: z.coerce.date(), diff --git a/src/content/blog/first-post.md b/src/content/posts/first-post.md similarity index 100% rename from src/content/blog/first-post.md rename to src/content/posts/first-post.md diff --git a/src/content/blog/minimalism.md b/src/content/posts/minimalism.md similarity index 100% rename from src/content/blog/minimalism.md rename to src/content/posts/minimalism.md diff --git a/src/content/blog/terminal-setup.md b/src/content/posts/terminal-setup.md similarity index 100% rename from src/content/blog/terminal-setup.md rename to src/content/posts/terminal-setup.md diff --git a/src/pages/[...slug].astro b/src/pages/[...slug].astro new file mode 100644 index 0000000..ced400d --- /dev/null +++ b/src/pages/[...slug].astro @@ -0,0 +1,21 @@ +--- +import Layout from '../layouts/Layout.astro'; +import { getCollection } from "astro:content"; + +export async function getStaticPaths() { + const pageEntries = await getCollection('pages'); + return pageEntries.map(entry => ({ + params: { slug: entry.slug }, props: { entry }, + })); +} +const { entry } = Astro.props; +const { Content } = await entry.render(); + +--- + +{new Date(post.data.pubDate).toISOString().split('T')[0]} - {post.data.title} + {post.data.title}
))} diff --git a/src/pages/blog/[...slug].astro b/src/pages/post/[...slug].astro similarity index 97% rename from src/pages/blog/[...slug].astro rename to src/pages/post/[...slug].astro index 56d86fd..2826d2d 100644 --- a/src/pages/blog/[...slug].astro +++ b/src/pages/post/[...slug].astro @@ -3,7 +3,7 @@ import Layout from '../../layouts/Layout.astro'; import { getCollection } from 'astro:content'; export async function getStaticPaths() { - const blogEntries = await getCollection('blog'); + const blogEntries = await getCollection('posts'); return blogEntries.map(entry => ({ params: { slug: entry.slug }, props: { entry }, })); diff --git a/src/pages/post/[...slug].txt.js b/src/pages/post/[...slug].txt.js new file mode 100644 index 0000000..8d5624f --- /dev/null +++ b/src/pages/post/[...slug].txt.js @@ -0,0 +1,25 @@ +import { getCollection } from 'astro:content'; + +export const prerender = true; +export async function getStaticPaths() { + const blogEntries = await getCollection('posts'); + return blogEntries.map(entry => ({ + params: { slug: entry.slug }, props: { entry }, + })); +} +export async function GET({ props }) { + const { entry } = props; + // Format the content as plain text + const title = entry.data.title; + const date = entry.data.pubDate.toISOString().split('T')[0]; + const content = entry.body; + + // Combine the post info and body into a single text file + const textContent = `Title: ${title}\nPublished at: ${date}\n\n${content}`; + + return new Response(textContent, { + headers: { + 'Content-Type': 'text/plain', + }, + }); +} \ No newline at end of file diff --git a/src/pages/rss.xml.js b/src/pages/rss.xml.js index 75401dc..77e0091 100644 --- a/src/pages/rss.xml.js +++ b/src/pages/rss.xml.js @@ -21,7 +21,7 @@ export async function GET(context) { const container = await AstroContainer.create({ renderers }); // Load the content collection entries to add to our RSS feed. - const posts = (await getCollection("blog")).sort((a, b) => + const posts = (await getCollection("posts")).sort((a, b) => // Sort by publication date descending. a.data.pubDate > b.data.pubDate ? -1 : 1 ); diff --git a/src/pages/search-index.json.js b/src/pages/search-index.json.js index 64fddd4..8b91cef 100644 --- a/src/pages/search-index.json.js +++ b/src/pages/search-index.json.js @@ -1,7 +1,7 @@ import { getCollection } from 'astro:content'; export async function GET() { - const posts = await getCollection('blog'); + const posts = await getCollection('posts'); const searchIndex = posts.map(post => ({ title: post.data.title, description: post.data.description, diff --git a/src/styles/global.css b/src/styles/global.css index 8128d4a..17d0a69 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -13,7 +13,7 @@ } /* Light theme */ @media (prefers-color-scheme: light) { - :root { + :root:not([data-theme="dark"]) { --bg-color: #f3f4f6; --text-color: #374151; --accent-color: #3b82f6; @@ -23,16 +23,6 @@ --terminal-yellow: #d97706; --terminal-red: #dc2626; } - :root:not([data-theme="light"]) { - --bg-color: #1f2937; - --text-color: #a5b4cf; - --accent-color: #64a0ff; - --border-color: #3b4351; - --header-color: #83a2ce; - --terminal-green: #4ade80; - --terminal-yellow: #fbbf24; - --terminal-red: #ef4444; - } } /* Light theme override (for switch) */ :root[data-theme="light"] { @@ -46,6 +36,7 @@ --terminal-red: #dc2626; } + *, *::before, *::after { box-sizing: border-box; margin: 0;