✨ Posts
This commit is contained in:
@@ -7,12 +7,12 @@ interface MenuItem {
|
||||
|
||||
const items: MenuItem[] = [
|
||||
{ href: "/posts", label: "记录" },
|
||||
{ href: "/annoucements", label: "情报" },
|
||||
{ href: "/events", label: "情报" },
|
||||
{ href: "/projects", label: "企划" },
|
||||
];
|
||||
---
|
||||
|
||||
<div class="fixed top-0 navbar shadow-md bg-base-100 lg:px-5">
|
||||
<div class="fixed top-0 navbar shadow-md bg-base-100 lg:px-5 z-10">
|
||||
<div class="navbar-start">
|
||||
<div class="dropdown">
|
||||
<div tabindex="0" role="button" class="btn btn-ghost lg:hidden">
|
||||
@@ -84,9 +84,8 @@ const items: MenuItem[] = [
|
||||
<input
|
||||
type="checkbox"
|
||||
class="theme-controller"
|
||||
value="light"
|
||||
data-toggle-theme="dark,light"
|
||||
data-act-class="active"
|
||||
value="dark"
|
||||
data-toggle-theme="dark"
|
||||
/>
|
||||
|
||||
<svg
|
||||
|
@@ -33,7 +33,11 @@ const { title } = Astro.props;
|
||||
<Navbar />
|
||||
|
||||
<!-- Content -->
|
||||
<slot />
|
||||
<main transition:animate="slide">
|
||||
<slot />
|
||||
</main>
|
||||
|
||||
<!-- Styles -->
|
||||
<style>
|
||||
html {
|
||||
overflow-x: hidden !important;
|
||||
@@ -53,6 +57,10 @@ const { title } = Astro.props;
|
||||
.mt-header {
|
||||
margin-top: 64px;
|
||||
}
|
||||
|
||||
.top-header {
|
||||
top: 64px;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -21,7 +21,7 @@ const events = eventsResponse.data.eventConnection.edges
|
||||
<div class="max-w-[720px] mx-auto">
|
||||
<div class="card w-full shadow-xl">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">活动</h2>
|
||||
<h2 class="card-title">情报</h2>
|
||||
<p>读岁月史书,涨人生阅历</p>
|
||||
<div class="divider"></div>
|
||||
|
||||
|
79
src/pages/posts/[...slug].astro
Normal file
79
src/pages/posts/[...slug].astro
Normal file
@@ -0,0 +1,79 @@
|
||||
---
|
||||
import PageLayout from "../../layouts/PageLayout.astro";
|
||||
|
||||
import client from "../../../tina/__generated__/client";
|
||||
import { TinaMarkdown } from "tinacms/dist/rich-text";
|
||||
|
||||
export const prerender = false;
|
||||
|
||||
const { slug } = Astro.params;
|
||||
|
||||
const { data } = await client.queries.post({
|
||||
relativePath: (slug ?? "index") + ".mdx",
|
||||
});
|
||||
---
|
||||
|
||||
<PageLayout>
|
||||
<div class="wrapper">
|
||||
<div class="card w-full shadow-xl">
|
||||
{
|
||||
data.post.heroImg && (
|
||||
<figure>
|
||||
<img src={data.post.heroImg} alt={data.post.title} />
|
||||
</figure>
|
||||
)
|
||||
}
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">{data.post.title}</h2>
|
||||
<p class="description">{data.post.description ?? "No description"}</p>
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="prose max-w-none">
|
||||
<TinaMarkdown content={data.post._body} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h-fit sticky top-header">
|
||||
<div class="card shadow-xl">
|
||||
<div class="card-body">
|
||||
<div class="gap-2 text-sm metadata description">
|
||||
<div>
|
||||
<div>作者</div>
|
||||
<div>{data.post.author?.name ?? "佚名"}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>发布于</div>
|
||||
<div>{new Date(data.post.date ?? 0).toLocaleString()}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageLayout>
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.description {
|
||||
color: oklch(var(--bc) / 0.8);
|
||||
}
|
||||
|
||||
.metadata {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
transition: color 0.3s;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.wrapper {
|
||||
grid-template-columns: 2fr 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
55
src/pages/posts/index.astro
Normal file
55
src/pages/posts/index.astro
Normal file
@@ -0,0 +1,55 @@
|
||||
---
|
||||
import PageLayout from "../../layouts/PageLayout.astro";
|
||||
|
||||
import { client } from "../../../tina/__generated__/client";
|
||||
|
||||
const postsResponse = await client.queries.postConnection();
|
||||
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">记录生活,记录理想,记录记录……</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>
|
||||
</PageLayout>
|
Reference in New Issue
Block a user