Tags & Categories

This commit is contained in:
2024-01-21 17:07:34 +08:00
parent fcfbb6118f
commit 2bd6b8758b
13 changed files with 179 additions and 60 deletions

View File

@@ -81,12 +81,7 @@ const items: MenuItem[] = [
</div>
<div class="navbar-end">
<label class="swap swap-rotate px-[16px]">
<input
type="checkbox"
class="theme-controller"
value="dark"
data-toggle-theme="dark"
/>
<input type="checkbox" class="theme-controller" value="light" checked />
<svg
class="swap-on fill-current w-8 h-8"
@@ -108,9 +103,3 @@ const items: MenuItem[] = [
</label>
</div>
</div>
<script>
import { themeChange } from "theme-change";
themeChange();
</script>

View File

@@ -0,0 +1,45 @@
---
interface Props {
posts: any[];
}
import { POST_TYPES } from "../scripts/consts";
const { posts } = Astro.props;
---
<div class="grid justify-items-strench gap-6">
{
posts?.map((item) => (
<a href={`/posts/${item.slug}`}>
<div class="card sm:card-side hover:bg-base-200 transition-colors sm:max-w-none shadow-xl">
{item.heroImg && (
<figure class="mx-auto w-full object-cover p-6 max-sm:pb-0 sm:max-w-[12rem] sm:pe-0">
<img
loading="lazy"
src={item.heroImg}
class="border-base-content bg-base-300 rounded-btn border border-opacity-5"
alt={item.title}
/>
</figure>
)}
<div class="card-body">
<h2 class="text-xl">{item.title}</h2>
<div>
<span class="badge badge-accent">{POST_TYPES[item.type]}</span>
{item.categories?.map((category: string) => (
<span class="badge badge-primary">{category}</span>
))}
{item.tags?.map((tag: string) => (
<span class="badge badge-secondary">{tag}</span>
))}
</div>
<div class="text-xs opacity-60 line-clamp-3">
{item.description}
</div>
</div>
</div>
</a>
))
}
</div>

View File

@@ -15,17 +15,6 @@ const { title } = Astro.props;
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
<script is:inline>
if (localStorage.getItem("theme") === null) {
document.documentElement.setAttribute("data-theme", "light");
} else {
document.documentElement.setAttribute(
"data-theme",
localStorage.getItem("theme")
);
}
</script>
<ViewTransitions />
</head>
<body>

View File

@@ -0,0 +1,35 @@
---
import PageLayout from "../../layouts/PageLayout.astro";
import { client } from "../../../tina/__generated__/client";
import PostList from "../../components/PostList.astro";
export const prerender = false;
const { slug } = Astro.params;
const postsResponse = await client.queries.postConnection({
filter: { categories: { in: [slug ?? "index"] } },
});
const posts = postsResponse.data.postConnection.edges
?.sort((a, b) =>
new Date(a?.node?.date ?? 0).getTime() <=
new Date(b?.node?.date ?? 0).getTime()
? -1
: 0
)
.map((event) => {
return { ...event?.node, slug: event?.node?._sys.filename };
});
---
<PageLayout>
<div class="max-w-[720px] mx-auto">
<div class="pt-16 pb-6 px-6">
<h1 class="text-4xl font-bold">分类检索</h1>
<p class="pt-3">以下是包含「{slug}」分类的记录……</p>
</div>
<PostList posts={posts as any[]} />
</div>
</PageLayout>

View File

@@ -4,6 +4,8 @@ import PageLayout from "../../layouts/PageLayout.astro";
import { client } from "../../../tina/__generated__/client";
import { TinaMarkdown } from "tinacms/dist/rich-text";
export const prerender = false;
const eventsResponse = await client.queries.eventConnection();
const events = eventsResponse.data.eventConnection.edges
?.sort((a, b) =>

View File

@@ -1,7 +1,8 @@
---
import PageLayout from "../../layouts/PageLayout.astro";
import client from "../../../tina/__generated__/client";
import { POST_TYPES } from "../../scripts/consts";
import { client } from "../../../tina/__generated__/client";
import { TinaMarkdown } from "tinacms/dist/rich-text";
export const prerender = false;
@@ -42,6 +43,34 @@ const { data } = await client.queries.post({
<div>作者</div>
<div>{data.post.author?.name ?? "佚名"}</div>
</div>
<div>
<div>类型</div>
<div class="text-accent">{POST_TYPES[data.post.type as unknown as string]}</div>
</div>
<div>
<div>分类</div>
<div class="flex gap-1">
{
data.post.categories?.map((category) => (
<a href={`/categories/${category}`} class="link link-primary">
{category}
</a>
))
}
</div>
</div>
<div>
<div>标签</div>
<div class="flex gap-1">
{
data.post.tags?.map((tag) => (
<a href={`/tags/${tag}`} class="link link-secondary">
{tag}
</a>
))
}
</div>
</div>
<div>
<div>发布于</div>
<div>{new Date(data.post.date ?? 0).toLocaleString()}</div>

View File

@@ -2,6 +2,9 @@
import PageLayout from "../../layouts/PageLayout.astro";
import { client } from "../../../tina/__generated__/client";
import PostList from "../../components/PostList.astro";
export const prerender = false;
const postsResponse = await client.queries.postConnection();
const posts = postsResponse.data.postConnection.edges
@@ -23,33 +26,5 @@ const posts = postsResponse.data.postConnection.edges
<p class="pt-3">记录生活,记录理想,记录记录……</p>
</div>
<div class="card card-compact w-full shadow-xl">
<div class="card-body">
<div class="grid justify-items-strench gap-6">
{
posts?.map((item) => (
<a href={`/posts/${item.slug}`}>
<div class="card sm:card-side hover:bg-base-200 transition-colors sm:max-w-none">
{item.heroImg && (
<figure class="mx-auto w-full object-cover p-6 max-sm:pb-0 sm:max-w-[12rem] sm:pe-0">
<img
loading="lazy"
src={item.heroImg}
class="border-base-content bg-base-300 rounded-btn border border-opacity-5"
alt={item.title}
/>
</figure>
)}
<div class="card-body">
<h2 class="card-title">{item.title}</h2>
<p class="text-xs opacity-60">{item.description}</p>
</div>
</div>
</a>
))
}
</div>
</div>
</div>
</div>
<PostList posts={posts as any[]} />
</PageLayout>

View File

@@ -0,0 +1,35 @@
---
import PageLayout from "../../layouts/PageLayout.astro";
import { client } from "../../../tina/__generated__/client";
import PostList from "../../components/PostList.astro";
export const prerender = false;
const { slug } = Astro.params;
const postsResponse = await client.queries.postConnection({
filter: { tags: { in: [slug ?? "index"] } },
});
const posts = postsResponse.data.postConnection.edges
?.sort((a, b) =>
new Date(a?.node?.date ?? 0).getTime() <=
new Date(b?.node?.date ?? 0).getTime()
? -1
: 0
)
.map((event) => {
return { ...event?.node, slug: event?.node?._sys.filename };
});
---
<PageLayout>
<div class="max-w-[720px] mx-auto">
<div class="pt-16 pb-6 px-6">
<h1 class="text-4xl font-bold">标签检索</h1>
<p class="pt-3">以下是包含「{slug}」标签的记录……</p>
</div>
<PostList posts={posts as any[]} />
</div>
</PageLayout>

5
src/scripts/consts.ts Normal file
View File

@@ -0,0 +1,5 @@
export const POST_TYPES: { [id: string]: string } = {
article: "文章",
podcast: "播客",
announcements: "通告",
};