feat(portfolio): redesign hero and projects sections with modern UI

- Implement new glassmorphism design for hero section with terminal mockup
- Redesign projects section with improved card layout and tech stack indicators
- Update project data with new entries and translations
- Add scroll-aware header with dynamic styling
- Remove unused ExperienceSection component
This commit is contained in:
joyzhao
2025-06-16 11:29:53 +08:00
parent 20ae3de62c
commit ed02039a9e
7 changed files with 335 additions and 155 deletions

View File

@@ -1,7 +1,7 @@
import ThemeToggle from "./ui/theme-toggle";
import LanguageSwitcher from "./LanguageSwitcher";
import { useTranslations, getLocalizedPath, type Lang } from "@/i18n/utils";
import { useState } from "react";
import { useState, useEffect } from "react";
import { Menu, X } from "lucide-react";
import { motion, AnimatePresence } from "framer-motion";
@@ -12,11 +12,25 @@ interface GlassHeaderProps {
export default function GlassHeader({ lang }: GlassHeaderProps) {
const t = useTranslations(lang);
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [isScrolled, setIsScrolled] = useState(false);
useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 0);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const toggleMenu = () => setIsMenuOpen(!isMenuOpen);
return (
<header className="sticky z-50 w-full backdrop-blur-md backdrop-filter bg-background/70 dark:bg-background/40 border-b border-border/40 supports-[backdrop-filter]:bg-background/60">
<header className={`fixed top-0 z-50 w-full transition-all duration-300 ${
isScrolled
? 'backdrop-blur-md backdrop-filter bg-white/80 dark:bg-black/80 border-b border-border/30 shadow-lg shadow-black/5 dark:shadow-black/20'
: 'bg-transparent'
}`}>
<div className="container max-w-4xl mx-auto p-4 flex justify-between items-center">
<motion.a
className="flex items-center text-lg font-medium"
@@ -30,7 +44,6 @@ export default function GlassHeader({ lang }: GlassHeaderProps) {
{/* Desktop Navigation */}
<nav className="hidden md:flex items-center space-x-6 text-sm font-medium">
{[
// { key: 'nav.experience', icon: '💼 ', sectionId: 'experience' },
{ key: 'nav.skills', icon: '🛠️ ', sectionId: 'skills' },
{ key: 'nav.projects', icon: '🚀 ', sectionId: 'projects' },
].map(
@@ -72,7 +85,11 @@ export default function GlassHeader({ lang }: GlassHeaderProps) {
<AnimatePresence>
{isMenuOpen && (
<motion.div
className="md:hidden py-4 px-4 border-t border-border/10 backdrop-blur-md backdrop-filter bg-background/80 dark:bg-background/40"
className={`md:hidden py-4 px-4 border-t border-border/10 transition-all duration-300 ${
isScrolled
? 'backdrop-blur-md backdrop-filter bg-white/80 dark:bg-black/80 shadow-lg shadow-black/5 dark:shadow-black/20'
: 'bg-transparent'
}`}
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: "auto" }}
exit={{ opacity: 0, height: 0 }}
@@ -80,11 +97,8 @@ export default function GlassHeader({ lang }: GlassHeaderProps) {
>
<nav className="flex flex-col space-y-4 text-sm font-medium">
{[
{ key: 'nav.experience', icon: '💼 ', sectionId: 'experience' },
{ key: 'nav.skills', icon: '🛠️ ', sectionId: 'skills' },
{ key: 'nav.projects', icon: '🚀 ', sectionId: 'projects' },
{ key: 'nav.awards', icon: '🏆 ', sectionId: 'awards' },
{ key: 'nav.education', icon: '🎓 ', sectionId: 'education' },
].map(
(item, index) => (
<motion.a