improve code

This commit is contained in:
Henry Hiles 2023-06-23 14:13:48 -04:00
parent 2c103f70ae
commit 4bf53a4b14
7 changed files with 121 additions and 129 deletions

7
src/categories.js Normal file
View 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" }
})

View file

@ -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

View 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>

View file

@ -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>

View file

@ -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;
}

View file

@ -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%;
}

View file

@ -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 {