Initial commit

This commit is contained in:
Slide Deck
2025-12-05 22:37:53 +08:00
commit fa24a82568
34 changed files with 8641 additions and 0 deletions

41
src/apps/footer.tsx Normal file
View File

@@ -0,0 +1,41 @@
import { wrapBasename } from "@/modules/basename"
export const Footer = () => {
const links = [
{
href: wrapBasename('/'),
label: '主页',
},
{
href: wrapBasename('/docs'),
label: '文档',
},
]
return (
<footer className="fixed bottom-0 w-full bg-white border-t border-gray-200 shadow-lg">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
{/* 链接区域 */}
<nav className="flex flex-wrap justify-center items-center gap-2 sm:gap-4 mb-3">
{links.map((link) => (
<a
key={link.href}
href={link.href}
className="relative px-4 py-2 text-sm sm:text-base font-medium text-gray-600 hover:text-blue-600 transition-all duration-300 ease-in-out
before:absolute before:bottom-0 before:left-0 before:w-0 before:h-0.5 before:bg-blue-600 before:transition-all before:duration-300
hover:before:w-full active:scale-95"
>
{link.label}
</a>
))}
</nav>
{/* 版权信息 */}
<div className="text-center text-xs sm:text-sm text-gray-500">
&copy; 2025 Daily Question
</div>
</div>
</footer>
)
}

56
src/apps/menu.tsx Normal file
View File

@@ -0,0 +1,56 @@
import { useMemo } from "react";
export type MenuProps = {
items: MenuItem[];
basename?: string;
};
export type MenuItem = {
id: string;
data: {
title: string;
tags: string[];
hideInMenu?: boolean;
}
}
export const Menu = (props: MenuProps) => {
const { items, basename = '' } = props;
const list = useMemo(() => {
return items.filter(item => !item.data?.hideInMenu);
}, [items]);
if (list.length === 0) {
return null;
}
return (
<nav className='flex-1 overflow-y-auto scrollbar bg-sidebar border border-sidebar-border rounded-lg p-4 shadow-sm'>
<h2 className="text-sm font-semibold text-sidebar-foreground"></h2>
<div className="space-y-1">
{list.map(item => (
<a
key={item.id}
href={`${basename}/docs/${item.id}/`}
className="group block rounded-md hover:bg-sidebar-accent transition-all duration-200 ease-in-out"
>
<div className="px-3 py-2.5">
<h3 className="text-sm font-semibold text-sidebar-foreground group-hover:text-sidebar-accent-foreground transition-colors">
{item.data?.title}
</h3>
{item.data?.tags && item.data.tags.length > 0 && (
<div className="flex flex-wrap gap-1.5 mt-2">
{item.data.tags.map(tag => (
<span
key={tag}
className="text-xs px-2 py-0.5 rounded-full bg-muted/60 text-muted-foreground font-medium hover:bg-muted transition-colors"
>
{tag}
</span>
))}
</div>
)}
</div>
</a>
))}
</div>
</nav>
);
}