portal/src/components/Footer.tsx

106 lines
4.5 KiB
TypeScript

"use client";
import { Github, Linkedin, Moon, Sun, Twitter } from "lucide-react";
import Link from "next/link";
import { useLanguage } from "../i18n/LanguageProvider";
import { useThemeStore } from "@components/theme";
import { useViewStore } from "./theme/viewStore";
export default function Footer() {
const isDark = useThemeStore((state) => state.isDark);
const toggleTheme = useThemeStore((state) => state.toggleTheme);
const { view, setView } = useViewStore();
const { language } = useLanguage();
const isChinese = language === "zh";
const socials = [
{
label: "GitHub",
icon: Github,
href: "https://github.com/Cloud-Neutral-Toolkit",
},
{ label: "X", icon: Twitter, href: "https://x.com/Cloud_Neutral" },
{
label: "Linkedin",
icon: Linkedin,
href: "https://www.linkedin.com/in/haitaopan/",
},
];
const toggleLabel = isDark ? "切换为浅色主题" : "切换为深色主题";
const viewToggleLabel =
view === "classic" ? "Switch to Material View" : "Switch to Classic View";
const handleViewToggle = () => {
setView(view === "classic" ? "material" : "classic");
};
return (
<footer className="mt-12 flex flex-col items-center justify-center gap-4 rounded-[2rem] border border-white/75 bg-[linear-gradient(135deg,rgba(15,23,42,0.95),rgba(30,41,59,0.92))] px-6 py-5 text-sm text-slate-300 shadow-[0_24px_60px_rgba(15,23,42,0.16)]">
<div className="flex w-full flex-col items-center gap-4 sm:flex-row sm:justify-between">
<div className="flex gap-4 order-2 sm:order-1">
<Link href="/terms" className="transition-colors hover:text-white">
{isChinese ? "服务条款" : "Terms of Service"}
</Link>
<Link href="/privacy" className="transition-colors hover:text-white">
{isChinese ? "隐私政策" : "Privacy Policy"}
</Link>
<Link href="/support" className="transition-colors hover:text-white">
{isChinese ? "联系我们" : "Contact Us"}
</Link>
</div>
<div className="flex items-center justify-center gap-3 order-1 sm:order-2">
{socials.map(({ label, icon: Icon, href }) => (
<a
key={label}
href={href}
className="flex h-9 w-9 items-center justify-center rounded-full border border-white/10 bg-white/5 text-white transition hover:border-indigo-400/50 hover:text-indigo-100"
>
<Icon className="h-4 w-4" aria-hidden />
<span className="sr-only">{label}</span>
</a>
))}
</div>
<div className="flex items-center gap-4 order-3">
<button
data-testid="view-switcher"
type="button"
onClick={handleViewToggle}
aria-label={viewToggleLabel}
title={viewToggleLabel}
className="group flex h-10 w-10 items-center justify-center rounded-full border border-white/10 bg-white/5 text-white transition hover:border-indigo-400/50 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500"
>
<span className="material-symbols-outlined text-xl">
{view === "classic" ? "view_quilt" : "view_cozy"}
</span>
</button>
<button
type="button"
onClick={toggleTheme}
aria-pressed={isDark}
aria-label={toggleLabel}
title={toggleLabel}
className="group relative flex h-10 w-20 items-center rounded-full border border-white/10 bg-white/5 px-2 text-white transition hover:border-indigo-400/50 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500"
>
<span className="relative z-10 flex w-full items-center justify-between text-slate-300">
<Moon
className={`h-4 w-4 transition-colors ${isDark ? "text-white" : "text-slate-500"}`}
aria-hidden
/>
<Sun
className={`h-4 w-4 transition-colors ${isDark ? "text-slate-500" : "text-amber-300"}`}
aria-hidden
/>
</span>
<span
aria-hidden
className={`absolute inset-y-1 left-1 h-8 w-8 rounded-full bg-white shadow-sm transition-transform duration-300 ease-out ${isDark ? "translate-x-0" : "translate-x-10"}`}
/>
</button>
</div>
</div>
</footer>
);
}