ChenyuRabbitLove's picture
feat: optimize for-students and for-teachers page
5081fcb
"use client";
import * as React from "react";
import { Moon, Sun } from "lucide-react";
import { useTheme } from "next-themes";
import Link from "next/link";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
/**
* TopNav - A responsive navigation header component with theme switching functionality
* Features:
* - Colorful brand logo/text
* - Navigation links for teachers and students
* - Theme switcher (light/dark/system) with animated icons
* - Client-side hydration handling
*/
export function TopNav() {
const { setTheme } = useTheme();
// Track component mounting to prevent hydration mismatch
const [mounted, setMounted] = React.useState(false);
// Enable theme switching only after client-side hydration
React.useEffect(() => {
setMounted(true);
}, []);
// Pre-hydration render - shows a simplified version without theme toggle
if (!mounted) {
return (
<header className="fixed w-full bg-background-secondary/80 backdrop-blur-sm border-b border-border z-50">
<div className="container mx-auto px-4 py-4 flex items-center">
<Link href="/" className="text-3xl font-bold">
<span className="text-[#FF6B6B]">P</span>
<span className="text-[#4ECDC4]">l</span>
<span className="text-[#45B7D1]">a</span>
<span className="text-[#FDCB6E]">y</span>
<span className="text-[#FF6B6B]">G</span>
<span className="text-[#4ECDC4]">o</span>
<span className="ml-2 text-[#45B7D1]">A</span>
<span className="text-[#FDCB6E]">I</span>
</Link>
<nav className="flex items-center justify-center flex-1 space-x-8">
<Link
href="/for-teachers"
className="text-text-secondary hover:text-primary"
>
我是老師
</Link>
<Link
href="/for-students"
className="text-text-secondary hover:text-primary"
>
我是學生
</Link>
</nav>
<div className="w-9 h-9" />{" "}
{/* Placeholder maintaining layout consistency during hydration */}
</div>
</header>
);
}
// Post-hydration render - includes full functionality with theme toggle
return (
<header className="fixed w-full bg-background-secondary/80 backdrop-blur-sm border-b border-border z-50">
<div className="container mx-auto px-4 py-4 flex items-center">
{/* Brand logo with multi-colored letters */}
<Link href="/" className="text-3xl font-bold">
<span className="text-[#FF6B6B]">P</span>
<span className="text-[#4ECDC4]">l</span>
<span className="text-[#45B7D1]">a</span>
<span className="text-[#FDCB6E]">y</span>
<span className="text-[#FF6B6B]">G</span>
<span className="text-[#4ECDC4]">o</span>
<span className="ml-2 text-[#45B7D1]">A</span>
<span className="text-[#FDCB6E]">I</span>
</Link>
{/* Navigation links with language-specific text (Traditional Chinese) */}
<nav className="flex items-center justify-center flex-1 space-x-8">
<Link
href="/for-teachers"
className="text-text-secondary hover:text-primary"
>
我是老師
</Link>
<Link
href="/for-students"
className="text-text-secondary hover:text-primary"
>
我是學生
</Link>
</nav>
{/* Theme switcher dropdown with animated sun/moon icons */}
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button>
{/* Animated sun/moon icons that rotate based on theme */}
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
</DropdownMenuTrigger>
{/* Theme selection menu */}
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme("light")}>
Light
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("dark")}>
Dark
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("system")}>
System
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</header>
);
}