This commit is contained in:
1 parent
c1541b80df
commit
b4c7908029
97 files changed
+12403
-154
No files matched your search
@@ -0,0 +1,107 @@
|
||||
import { Link } from "@/i18n/navigation";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { Mail, Rss, SquareArrowOutUpRight } from "lucide-react";
|
||||
import { siteConfig } from "@/lib/site-config";
|
||||
|
||||
/**
|
||||
* 社交链接图标。
|
||||
*
|
||||
* 注意:lucide-react v1.x 已移除品牌图标(Github / Twitter 等),
|
||||
* 因此这里使用通用图标,由 `label` 文本承载具体含义——
|
||||
* 图标仅作装饰(aria-hidden),可访问性不依赖它。
|
||||
*/
|
||||
const SOCIAL_ICONS = {
|
||||
github: SquareArrowOutUpRight,
|
||||
twitter: Rss,
|
||||
mail: Mail,
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* 站点页脚。
|
||||
*
|
||||
* DESIGN.md 的 footer-region:白底上一道 hairline 顶边,多列分组,
|
||||
* 分栏标题用 body-sm-medium 深色,链接用 body-sm 灰色。
|
||||
*/
|
||||
export async function SiteFooter() {
|
||||
const t = await getTranslations("Footer");
|
||||
const tNav = await getTranslations("Nav");
|
||||
const year = new Date().getFullYear();
|
||||
|
||||
return (
|
||||
<footer className="border-t border-hairline bg-canvas">
|
||||
<div className="mx-auto w-full max-w-[1280px] px-lg py-section sm:px-xxl">
|
||||
<div className="grid grid-cols-1 gap-xxl sm:grid-cols-2 lg:grid-cols-4">
|
||||
{/* 品牌列 */}
|
||||
<div className="flex flex-col gap-sm lg:col-span-2">
|
||||
<div className="flex items-center gap-xs text-body-md font-semibold text-ink">
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className="grid size-7 place-items-center rounded-md bg-primary font-mono text-caption font-semibold text-brand-green"
|
||||
>
|
||||
>_
|
||||
</span>
|
||||
{siteConfig.name}
|
||||
</div>
|
||||
|
||||
<p className="max-w-[360px] text-body-sm text-steel">
|
||||
{siteConfig.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* 导航列 */}
|
||||
<nav aria-label={t("navigation")} className="flex flex-col gap-xs">
|
||||
<h2 className="mb-xs text-body-sm font-medium text-ink">
|
||||
{t("navigation")}
|
||||
</h2>
|
||||
<Link
|
||||
href="/"
|
||||
className="py-xxs text-body-sm text-steel transition-colors duration-150 hover:text-ink"
|
||||
>
|
||||
{tNav("home")}
|
||||
</Link>
|
||||
<Link
|
||||
href="/about"
|
||||
className="py-xxs text-body-sm text-steel transition-colors duration-150 hover:text-ink"
|
||||
>
|
||||
{tNav("about")}
|
||||
</Link>
|
||||
</nav>
|
||||
|
||||
{/* 社交列 */}
|
||||
<div className="flex flex-col gap-xs">
|
||||
<h2 className="mb-xs text-body-sm font-medium text-ink">
|
||||
{t("elsewhere")}
|
||||
</h2>
|
||||
|
||||
<ul className="flex flex-col gap-xxs">
|
||||
{siteConfig.social.map((item) => {
|
||||
const Icon = SOCIAL_ICONS[item.icon];
|
||||
|
||||
return (
|
||||
<li key={item.label}>
|
||||
<a
|
||||
href={item.href}
|
||||
target={item.href.startsWith("mailto:") ? undefined : "_blank"}
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center gap-xs py-xxs text-body-sm text-steel transition-colors duration-150 hover:text-ink"
|
||||
>
|
||||
<Icon className="size-4" aria-hidden="true" />
|
||||
{item.label}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-xxl flex flex-col gap-xs border-t border-hairline-soft pt-lg text-caption text-steel sm:flex-row sm:items-center sm:justify-between">
|
||||
<p>
|
||||
© {year} {siteConfig.name}. {t("rights")}
|
||||
</p>
|
||||
<p className="font-mono">{t("builtWith")}</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user