Initial commit

This commit is contained in:
2026-02-02 22:47:52 +03:00
committed by GitHub
commit f53016aeda
239 changed files with 84360 additions and 0 deletions

112
src/pages/[...menu].astro Normal file
View File

@@ -0,0 +1,112 @@
---
import { Icon } from "astro-icon/components";
import { type NavbarLink } from "@/types/config";
import { navbarConfig } from "@/config";
import { LinkPresets } from "@constants/link-presets";
import { url } from "@utils/url";
import GridLayout from "@layouts/grid.astro";
import BackwardButton from "@components/backwardButton.astro";
export async function getStaticPaths() {
return navbarConfig.links
.filter(link => typeof link !== "number" && link.children && link.children.length > 0)
.map(link => {
const navLink = link as NavbarLink;
// 提取 slug去掉前后的斜杠
const slug = navLink.url.replace(/^\/|\/$/g, '');
return {
params: { menu: slug },
props: { link: navLink }
};
});
}
interface Props {
link: NavbarLink;
}
const { link } = Astro.props;
// 获取子链接,并将 LinkPreset 转换为完整的 NavbarLink 对象
const childrenLinks = link.children || [];
const processedLinks = childrenLinks.map(child => {
if (typeof child === "number") {
return LinkPresets[child];
}
return child;
});
const pageTitle = link.name;
const pageDescription = link.description || "";
---
<GridLayout title={pageTitle} description={pageDescription}>
<div class="flex w-full rounded-(--radius-large) overflow-hidden relative min-h-32">
<div class="card-base z-10 px-9 py-6 relative w-full">
<BackwardButton currentPath={Astro.url.pathname} />
<!-- 标题 -->
<header class="mb-8">
<h1 class="text-3xl font-bold text-neutral-900 dark:text-neutral-100 mb-3">
{pageTitle}
</h1>
{pageDescription && (
<p class="text-neutral-600 dark:text-neutral-400">
{pageDescription}
</p>
)}
</header>
<!-- 链接网格 -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{processedLinks.map(child => (
<a
href={child.external ? child.url : url(child.url)}
target={child.external ? "_blank" : null}
class="menu-card group flex flex-col items-center justify-center p-8 rounded-xl border transition-all duration-300"
>
<div class="icon-wrapper w-16 h-16 flex items-center justify-center rounded-full mb-4 transition-all duration-300">
{child.icon && <Icon name={child.icon} class="text-3xl" />}
</div>
<h2 class="text-xl font-bold text-neutral-900 dark:text-neutral-100 group-hover:text-(--primary) transition-colors duration-300 text-center">
{child.name}
</h2>
{child.description && (
<p class="text-sm text-neutral-600 dark:text-neutral-400 text-center mt-2 line-clamp-2">
{child.description}
</p>
)}
</a>
))}
</div>
</div>
</div>
</GridLayout>
<style>
.menu-card {
cursor: pointer;
background-color: none;
border-color: var(--line-divider);
}
.icon-wrapper {
background-color: color-mix(in oklch, var(--primary), transparent 85%);
color: var(--primary);
}
.menu-card:hover {
background-color: color-mix(in oklch, var(--primary), transparent 95%);
border-color: var(--primary);
box-shadow: 0 0 20px color-mix(in oklch, var(--primary), transparent 80%);
translate: 0 -4px;
}
.menu-card:hover .icon-wrapper {
background-color: var(--primary);
color: white;
box-shadow: 0 0 15px color-mix(in oklch, var(--primary), transparent 50%);
}
</style>