Skip to content

Commit

Permalink
feat: Add [...page].astro (blog) pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
nicosalm committed Oct 14, 2024
1 parent c4572e8 commit 817a54f
Show file tree
Hide file tree
Showing 9 changed files with 341 additions and 163 deletions.
12 changes: 9 additions & 3 deletions public/search-index.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
"Hackathon",
"Student Experience"
],
"url": "/blog/mit-iquhack-2024/"
"url": "/blog/mit-iquhack-2024/",
"pubDate": "2024/01/21",
"minutesRead": "7"
},
{
"title": "Preserving my Future Self",
Expand All @@ -19,7 +21,9 @@
"split keyboards",
"colemak-dh"
],
"url": "/blog/ergonomics/"
"url": "/blog/ergonomics/",
"pubDate": "2024/08/18",
"minutesRead": "7"
},
{
"title": "Spotlight: CLI Productivity",
Expand All @@ -30,6 +34,8 @@
"tmux",
"terminal efficiency"
],
"url": "/blog/cli-productivity/"
"url": "/blog/cli-productivity/",
"pubDate": "2024/10/10",
"minutesRead": "7"
}
]
6 changes: 3 additions & 3 deletions src/components/Header.astro
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const currentPath = Astro.url.pathname;
}
.nav-links {
display: flex;
gap: 1.5rem; /* Increased gap */
gap: 1.5rem;
align-items: center;
}
.nav-links a {
Expand All @@ -54,13 +54,13 @@ const currentPath = Astro.url.pathname;
font-weight: 500;
transition: color 0.3s ease, background-color 0.3s ease;
padding: 0.5rem 1rem;
border-radius: 9999px; /* Pill shape */
border-radius: 9999px; /* pill */
}
.nav-links a:hover, .nav-links a.active {
color: var(--color-bg);
background-color: var(--color-accent);
}
/* Styles for the theme toggle */
/* styles for the theme toggle */
:global(.nav-links .theme-toggle) {
width: 2.5rem;
height: 2.5rem;
Expand Down
157 changes: 81 additions & 76 deletions src/components/SearchBar.astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,41 @@
---
<div class="search-container">
<input type="text" id="search-input" placeholder="Search blog posts..." />
<div id="search-results"></div>
</div>

<script>
const searchInput = document.getElementById('search-input');
const searchResults = document.getElementById('search-results');
interface BlogPost {
title: string;
description: string;
tags: string[];
url: string;
pubDate: string;
minutesRead: string;
}

const searchInput = document.getElementById('search-input') as HTMLInputElement;
const articleList = document.querySelector('.article-list') as HTMLUListElement;
const pagination = document.querySelector('.pagination') as HTMLElement;

// This will be populated with all blog posts
let allPosts = [];
let allPosts: BlogPost[] = [];
let originalContent: string = '';

// Fetch all blog posts
// fetch all blog posts
fetch('/search-index.json')
.then(response => response.json())
.then(posts => {
allPosts = posts;
// store the original content
originalContent = articleList.innerHTML;
});

searchInput.addEventListener('input', () => {
const searchTerm = searchInput.value.toLowerCase();

if (searchTerm.length < 3) {
searchResults.innerHTML = '';
// restore original content
articleList.innerHTML = originalContent;
if (pagination) pagination.style.display = 'flex';
return;
}

Expand All @@ -32,23 +46,40 @@
post.tags.some(tag => tag.toLowerCase().includes(searchTerm))
);

searchResults.innerHTML = filteredPosts.map(post => `
<div class="search-result">
<a href="${post.url}">
<h3>${post.title}</h3>
<p>${post.description}</p>
// update the article list with filtered results
articleList.innerHTML = filteredPosts.map(post => `
<li class="article-item">
<a href="${post.url}" class="article-link">
<h2 class="article-title">${post.title}</h2>
<p class="article-description">${post.description}</p>
<div class="article-meta">
<span class="article-date">
${new Date(post.pubDate).toLocaleDateString("en-us", { year: "numeric", month: "short", day: "numeric" })} · ${post.minutesRead} min read
</span>
</div>
</a>
</div>
</li>
`).join('');

// hide pagination when showing search results
if (pagination) {
pagination.style.display = 'none';
}
});

// Restore original content when search is cleared
searchInput.addEventListener('blur', () => {
if (searchInput.value.length === 0) {
articleList.innerHTML = originalContent;
if (pagination) pagination.style.display = 'flex';
}
});
</script>

<style>
.search-container {
margin-bottom: 2rem;
position: relative;
}

#search-input {
width: 100%;
padding: 0.75rem 1rem;
Expand All @@ -60,86 +91,60 @@
font-family: var(--font-serif);
transition: border-color 0.3s ease, background-color 0.3s ease, color 0.3s ease;
}

#search-input:focus {
outline: none;
border-color: var(--color-accent);
}

#search-input::placeholder {
color: var(--color-secondary);
opacity: 0.7;
}

#search-results {
position: absolute;
top: 100%;
left: 0;
right: 0;
background-color: var(--color-bg);
border: 1px solid var(--color-border);
border-top: none;
border-radius: 0 0 0.35rem 0.35rem;
max-height: 300px;
overflow-y: auto;
z-index: 1000;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: background-color 0.3s ease, border-color 0.3s ease;
/* Dark mode specific styles */
:root.dark #search-input {
background-color: var(--color-bg-dark);
color: var(--color-text-dark);
border-color: var(--color-border-dark);
}

.search-result {
padding: 0.75rem 1rem;
border-bottom: 1px solid var(--color-border);
transition: background-color 0.2s ease;

/* Styles for search results (matching index.astro and [...page].astro) */
.article-list {
list-style-type: none;
padding: 0;
margin: 0;
}

.search-result:hover {
background-color: var(--color-bg-hover);
.article-item {
margin-bottom: 2rem;
padding-bottom: 2rem;
border-bottom: 1px solid var(--color-border);
}

.search-result:last-child {
.article-item:last-child {
border-bottom: none;
}

.search-result a {
.article-link {
text-decoration: none;
color: var(--color-text);
color: inherit;
display: block;
transition: transform 0.2s ease, background-color 0.2s ease;
padding: 0.5rem;
border-radius: 4px;
}

.search-result h3 {
margin: 0 0 0.25rem 0;
font-size: 1.1rem;
.article-link:hover {
transform: translateX(5px);
background-color: rgba(255, 255, 255, 0.05);
}
.article-title {
font-size: 1.5rem;
margin: 0 0 0.5rem 0;
color: var(--color-accent);
transition: color 0.2s ease;
}

.search-result p {
margin: 0;
.article-description {
font-size: 1rem;
margin: 0 0 0.5rem 0;
color: var(--color-text);
}
.article-meta {
font-size: 0.9rem;
color: var(--color-secondary);
}

/* Dark mode specific styles */
:root.dark #search-input {
background-color: var(--color-bg-dark);
color: var(--color-text-dark);
border-color: var(--color-border-dark);
}

:root.dark #search-results {
background-color: var(--color-bg-dark);
border-color: var(--color-border-dark);
}

:root.dark .search-result:hover {
background-color: var(--color-bg-hover-dark);
}

:root.dark .search-result h3 {
color: var(--color-accent-dark);
}

:root.dark .search-result p {
color: var(--color-secondary-dark);
}
</style>
36 changes: 0 additions & 36 deletions src/pages/blog.astro

This file was deleted.

Loading

0 comments on commit 817a54f

Please sign in to comment.