improve code
This commit is contained in:
parent
2c103f70ae
commit
4bf53a4b14
7 changed files with 121 additions and 129 deletions
7
src/categories.js
Normal file
7
src/categories.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
export default Object.entries({
|
||||
all: { title: "All", default: true },
|
||||
linux: { title: "Linux" },
|
||||
web: { title: "Web Development" },
|
||||
bot: { title: "Discord Bot Development" },
|
||||
other: { title: "Other" }
|
||||
})
|
|
@ -12,6 +12,7 @@ import styles from "../styles/Nav.module.css"
|
|||
<a href="/#portfolio">Projects</a>
|
||||
<a href="/#about">About</a>
|
||||
<a href="/#hire">Hire</a>
|
||||
<a href="/blog">Blog</a>
|
||||
</section>
|
||||
<section>
|
||||
<a
|
||||
|
|
104
src/pages/blog/[...category]/index.astro
Normal file
104
src/pages/blog/[...category]/index.astro
Normal file
|
@ -0,0 +1,104 @@
|
|||
---
|
||||
import Layout from "../../../layouts/Layout.astro"
|
||||
import BlogPost from "../../../components/BlogPost.astro"
|
||||
import styles from "../../../styles/Blog.module.css"
|
||||
import { getCollection } from "astro:content"
|
||||
import categories from "../../../categories"
|
||||
import Divider from "../../../components/Divider.astro"
|
||||
|
||||
export const getStaticPaths = async () => {
|
||||
const posts = await getCollection("blog")
|
||||
|
||||
return categories.map(([category, properties]) => ({
|
||||
params: { category: properties.default ? undefined : category },
|
||||
props: {
|
||||
filteredPosts: properties.default
|
||||
? posts
|
||||
: posts.filter((post) => post.data.category == category)
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
const { category } = Astro.params
|
||||
const { filteredPosts } = Astro.props
|
||||
---
|
||||
|
||||
<Layout page="Blog" description="The blog of Henry Hiles">
|
||||
<div class={styles.container}>
|
||||
<aside class={styles.sidebar}>
|
||||
<input type="text" placeholder="Search..." id="search" />
|
||||
|
||||
<section class={styles.categories}>
|
||||
{
|
||||
categories.map(([id, properties]) => (
|
||||
<a
|
||||
class={`${styles.category} ${
|
||||
(properties.default && category == undefined) ||
|
||||
id == category
|
||||
? styles.selected
|
||||
: ""
|
||||
}`}
|
||||
href={`/blog/${properties.default ? "" : id}`}
|
||||
>
|
||||
{properties.title}
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</section>
|
||||
</aside>
|
||||
<div class={styles.right}>
|
||||
<article class={styles.description}>
|
||||
<h1>Welcome to the blog!</h1>
|
||||
<Divider />
|
||||
<p>
|
||||
Hello, and welcome to my blog. I post about Discord Bot
|
||||
Development, Web Development, Linux, and other Tech-related
|
||||
subjects. You can filter and search in the sidebar.
|
||||
</p>
|
||||
</article>
|
||||
{
|
||||
filteredPosts.map((post) => (
|
||||
<a
|
||||
class={styles.link}
|
||||
href={`/blog/${post.slug}`}
|
||||
data-title={post.data.title}
|
||||
data-category={post.data.category}
|
||||
>
|
||||
<BlogPost post={post} standalone={false} />
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
|
||||
<script>
|
||||
const searchBar = document.querySelector("#search") as HTMLInputElement
|
||||
const posts = document.querySelectorAll(
|
||||
"[data-title]"
|
||||
) as NodeListOf<HTMLElement>
|
||||
const urlParams = new URLSearchParams(location.search)
|
||||
|
||||
const search = () =>
|
||||
posts.forEach((post) =>
|
||||
post.setAttribute(
|
||||
"aria-hidden",
|
||||
(
|
||||
post.dataset.title
|
||||
?.toLowerCase()
|
||||
?.includes(searchBar.value.toLowerCase()) ?? false
|
||||
).toString()
|
||||
)
|
||||
)
|
||||
|
||||
searchBar?.addEventListener("input", () => {
|
||||
urlParams.set("search", searchBar.value)
|
||||
history.replaceState({}, "", `?${urlParams}`)
|
||||
search()
|
||||
})
|
||||
|
||||
addEventListener("load", () => {
|
||||
searchBar.value = urlParams.get("search") ?? ""
|
||||
search()
|
||||
})
|
||||
</script>
|
|
@ -1,119 +0,0 @@
|
|||
---
|
||||
import Layout from "../../layouts/Layout.astro"
|
||||
import BlogPost from "../../components/BlogPost.astro"
|
||||
import styles from "../../styles/Blog.module.css"
|
||||
import { getCollection } from "astro:content"
|
||||
import Divider from "../../components/Divider.astro"
|
||||
|
||||
const posts = await getCollection("blog")
|
||||
---
|
||||
|
||||
<Layout page="Blog" description="The blog of Henry Hiles">
|
||||
<div class={styles.container}>
|
||||
<aside class={styles.sidebar}>
|
||||
<input type="text" placeholder="Search..." id="search" />
|
||||
|
||||
<section class={styles.radios}>
|
||||
<input type="radio" name="category" id="all" checked />
|
||||
<label for="all">All</label>
|
||||
|
||||
<input type="radio" name="category" id="linux" />
|
||||
<label for="linux">Linux</label>
|
||||
|
||||
<input type="radio" name="category" id="web" />
|
||||
<label for="web">Web Development</label>
|
||||
|
||||
<input type="radio" name="category" id="bot" />
|
||||
<label for="bot">Discord Bot Development</label>
|
||||
|
||||
<input type="radio" name="category" id="other" />
|
||||
<label for="other">Other</label>
|
||||
</section>
|
||||
</aside>
|
||||
<div class={styles.right}>
|
||||
<article class={styles.description}>
|
||||
<h1>Welcome to the blog!</h1>
|
||||
<Divider />
|
||||
<p>
|
||||
Hello, and welcome to my blog. I post about Discord Bot
|
||||
Development, Web Development, Linux, and other Tech-related
|
||||
subjects. You can filter and search in the sidebar.
|
||||
</p>
|
||||
</article>
|
||||
{
|
||||
posts.map((post) => (
|
||||
<a
|
||||
class={styles.link}
|
||||
href={`/blog/${post.slug}`}
|
||||
data-title={post.data.title}
|
||||
data-category={post.data.category}
|
||||
>
|
||||
<BlogPost post={post} standalone={false} />
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
|
||||
<script>
|
||||
let category = "all"
|
||||
const searchBar = document.querySelector("#search") as HTMLInputElement
|
||||
const posts = document.querySelectorAll(
|
||||
"[data-title]"
|
||||
) as NodeListOf<HTMLElement>
|
||||
const radios = document.querySelectorAll('input[type="radio"]')
|
||||
const urlParams = new URLSearchParams(location.search)
|
||||
const set = (name: string, value: string) => {
|
||||
urlParams.set(name, value)
|
||||
history.replaceState({}, "", `?${urlParams}`)
|
||||
}
|
||||
|
||||
radios.forEach((radio) =>
|
||||
radio.addEventListener("click", ({ target }) => {
|
||||
if (target instanceof HTMLInputElement) {
|
||||
set("category", target.id)
|
||||
category = target.id
|
||||
filterByCategory()
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
const search = () =>
|
||||
filter(
|
||||
(post) =>
|
||||
!!post.dataset.title
|
||||
?.toLowerCase()
|
||||
?.includes(searchBar.value.toLowerCase())
|
||||
)
|
||||
|
||||
const filterByCategory = () =>
|
||||
filter((post) =>
|
||||
category == "all" ? true : post.dataset.category == category
|
||||
)
|
||||
|
||||
const filter = (condition: (element: HTMLElement) => boolean) =>
|
||||
posts.forEach((post) =>
|
||||
post.setAttribute("aria-hidden", (!condition(post)).toString())
|
||||
)
|
||||
|
||||
searchBar?.addEventListener("input", () => {
|
||||
set("search", searchBar.value)
|
||||
search()
|
||||
})
|
||||
|
||||
addEventListener("load", () => {
|
||||
searchBar.value = urlParams.get("search") ?? ""
|
||||
Array.from(radios).find((radio) => {
|
||||
if (
|
||||
radio instanceof HTMLInputElement &&
|
||||
radio.id == urlParams.get("category")
|
||||
) {
|
||||
radio.checked = true
|
||||
category = radio.id
|
||||
}
|
||||
})
|
||||
search()
|
||||
filterByCategory()
|
||||
})
|
||||
</script>
|
|
@ -46,21 +46,19 @@
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
[aria-hidden="true"],
|
||||
.radios [type="radio"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.radios :checked + label {
|
||||
.category.selected {
|
||||
color: var(--primary);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
label {
|
||||
.category {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
.radios {
|
||||
.categories {
|
||||
display: flex;
|
||||
gap: 0.1rem;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ main {
|
|||
transition: scale 0.2s;
|
||||
}
|
||||
|
||||
:is(article, section, aside):not(section *, nav *, header *):hover {
|
||||
:is(article, section, aside):not(section *, nav *, header *, aside *):hover {
|
||||
scale: 101.5%;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
.nav {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
@ -18,7 +19,7 @@
|
|||
}
|
||||
|
||||
.nav :is(svg, img) {
|
||||
height: 2rem;
|
||||
width: 2rem;
|
||||
}
|
||||
|
||||
.nav button {
|
||||
|
|
Loading…
Add table
Reference in a new issue