This commit is contained in:
z.ai committed 2026-10-08 11:09:37 +08:00
1 parent c1541b80df
commit b4c7908029
97 files changed
+12403 -154

No files matched your search

+86
View File
@@ -0,0 +1,86 @@
import { Link } from "@/i18n/navigation";
import { getTranslations } from "next-intl/server";
import { ArrowLeft, Compass } from "lucide-react";
import { Container, Section } from "@/components/ui/layout";
import { buttonClassName } from "@/components/ui/button-variants";
import { getAllPosts } from "@/lib/posts";
/**
* 404 页面(语言段内)。
*
* 位于 `app/[locale]/not-found.tsx`,因此能访问 next-intl 上下文并使用
* 站点的页头 / 页脚布局。同时列出最新文章作为"继续浏览"的出口,
* 避免用户走进死胡同。
*/
export default async function NotFound() {
const t = await getTranslations("NotFound");
const posts = (await getAllPosts()).slice(0, 3);
return (
<Section spacing="lg">
<Container size="narrow" className="flex flex-col items-center text-center">
<span
aria-hidden="true"
className="grid size-14 place-items-center rounded-full bg-surface"
>
<Compass className="size-6 text-steel" />
</span>
<p className="mt-lg font-mono text-micro-uppercase font-semibold uppercase tracking-[0.5px] text-brand-error">
{t("eyebrow")}
</p>
<h1 className="mt-sm text-heading-1 font-semibold text-ink text-balance-pretty">
{t("title")}
</h1>
<p className="mt-md max-w-[480px] text-subtitle text-steel text-balance-pretty">
{t("description")}
</p>
<div className="mt-xxl flex flex-col gap-sm sm:flex-row">
<Link
href="/"
className={buttonClassName({ variant: "primary", size: "md" })}
>
<ArrowLeft className="size-4" aria-hidden="true" />
{t("backHome")}
</Link>
<Link
href="/#posts"
className={buttonClassName({ variant: "secondary", size: "md" })}
>
{t("browsePosts")}
</Link>
</div>
{posts.length > 0 ? (
<div className="mt-section w-full border-t border-hairline-soft pt-xl text-left">
<h2 className="text-micro-uppercase font-semibold uppercase tracking-[0.5px] text-steel">
也许你想看看这些
</h2>
<ul className="mt-md flex flex-col divide-y divide-hairline-soft">
{posts.map((post) => (
<li key={post.slug}>
<Link
href={`/posts/${post.slug}`}
className="group flex flex-col gap-xxs py-md transition-colors duration-150"
>
<span className="text-body-md font-medium text-ink group-hover:text-brand-green-deep">
{post.title}
</span>
<span className="text-body-sm text-steel">
{post.summary}
</span>
</Link>
</li>
))}
</ul>
</div>
) : null}
</Container>
</Section>
);
}