feat: build resume website with MagicUI components

- 6 sections: Hero, About, Experience, Skills, Projects, Contact
- MagicUI: Globe, Particles, Meteors, AnimatedList, IconCloud, BentoGrid
- Dark mode support, scroll-triggered animations
- Static export ready for deployment
This commit is contained in:
2026-04-14 15:09:48 +08:00
parent a0207c673f
commit 6fec90ea71
28 changed files with 8547 additions and 18 deletions

View File

@@ -0,0 +1,101 @@
"use client"
import {
Building03Icon,
CodeIcon,
Award02Icon,
ProjectorIcon,
} from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import { AnimatedList, AnimatedListItem } from "@/components/ui/animated-list"
import { SectionWrapper } from "@/components/section-wrapper"
interface ExperienceItem {
role: string
company: string
period: string
description: string
}
const experiences: ExperienceItem[] = [
{
role: "全栈开发工程师",
company: "MakeBlock",
period: "2024.10 - 2025.4",
description:
"负责内部质检与业务系统的全栈开发,覆盖前端页面、后端接口、数据流转与部署协作。",
},
{
role: "项目经理 / 技术负责人",
company: "HIT 重庆",
period: "2024.1 - 2024.9",
description:
"担任项目管理与技术负责人,统筹技术选型与团队协作,推动项目按期高质量交付。",
},
{
role: "测试开发工程师",
company: "ByteDance字节跳动",
period: "2021.12 - 2023.3",
description:
"负责内部测试工具与自动化流程的开发,保障产品质量与交付效率。",
},
{
role: "BIM 工程师",
company: "亚厦集团",
period: "2020.8 - 2021.11",
description:
"负责建筑信息模型BIM相关工作进行 3D 建模与工程协调。",
},
]
const icons = [
<HugeiconsIcon key="makeblock" icon={Building03Icon} className="size-5" />,
<HugeiconsIcon key="hit" icon={ProjectorIcon} className="size-5" />,
<HugeiconsIcon key="bytedance" icon={Award02Icon} className="size-5" />,
<HugeiconsIcon key="yasha" icon={CodeIcon} className="size-5" />,
]
export function Experience() {
return (
<SectionWrapper id="experience" className="py-24">
<div className="mx-auto max-w-3xl px-6">
<h2 className="mb-12 text-center text-3xl font-bold tracking-tight sm:text-4xl">
</h2>
<div className="space-y-6">
{experiences.map((exp, i) => (
<AnimatedListItem key={exp.company}>
<div className="group relative flex gap-4 rounded-xl border border-border bg-card p-6 transition-colors hover:bg-accent/50">
{/* 时间线 */}
<div className="relative flex flex-col items-center">
<div className="flex size-10 shrink-0 items-center justify-center rounded-full border border-border bg-background text-muted-foreground transition-colors group-hover:border-primary/50 group-hover:text-foreground">
{icons[i]}
</div>
{i < experiences.length - 1 && (
<div className="absolute top-12 h-full w-px bg-border" />
)}
</div>
{/* 内容 */}
<div className="flex-1">
<div className="flex flex-wrap items-center justify-between gap-2">
<h3 className="font-semibold">{exp.role}</h3>
<span className="text-sm text-muted-foreground">
{exp.period}
</span>
</div>
<p className="text-sm text-muted-foreground">{exp.company}</p>
<p className="mt-2 text-sm text-muted-foreground">
{exp.description}
</p>
</div>
</div>
</AnimatedListItem>
))}
</div>
</div>
</SectionWrapper>
)
}