Files
zhaoguiyang.site/src/components/HeroSection.tsx
joyzhao 720686751a feat(i18n): add multilingual support for all sections
Implement internationalization across all components by adding lang prop and translation keys
Update data structure to use translation keys instead of hardcoded text
Add comprehensive English and Chinese translations in ui.ts
2025-06-15 09:34:17 +08:00

135 lines
4.8 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { personalInfo } from "@/lib/data";
import { Mail, Github, MapPin, Linkedin } from "lucide-react";
import { useTranslations } from "@/i18n/utils";
import { motion } from "framer-motion";
import MotionWrapper from "./MotionWrapper";
export default function HeroSection({ lang }: { lang: "en" | "zh" }) {
const t = useTranslations(lang);
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.2,
delayChildren: 0.3,
},
},
};
const childVariants = {
hidden: { opacity: 0, y: 20 },
visible: {
opacity: 1,
y: 0,
transition: {
duration: 0.5,
},
},
};
return (
<section className="py-16 md:py-24 relative overflow-hidden">
<div className="container max-w-4xl mx-auto px-6 md:px-4 relative z-10">
<motion.div
className="flex flex-col md:flex-row md:items-center justify-between mb-8"
variants={containerVariants}
initial="hidden"
animate="visible"
>
<div className="text-center md:text-left">
<motion.h1
className="text-4xl font-bold mb-2"
variants={childVariants}
>
{t('personal.name')}{" "}
<span className="inline-block animate-pulse"></span>
</motion.h1>
<motion.p
className="text-xl text-muted-foreground mb-6"
variants={childVariants}
>
{t('personal.title')}
</motion.p>
<motion.div
className="flex flex-col gap-2 items-center md:items-start"
variants={containerVariants}
>
<motion.div
className="flex items-center text-sm text-muted-foreground"
variants={childVariants}
whileHover={{ scale: 1.05, color: "#4b5563" }}
>
<MapPin className="h-4 w-4 mr-2" />
📍 {t('personal.location')}
</motion.div>
<motion.a
href={`mailto:${t('personal.email')}`}
className="flex items-center text-sm text-muted-foreground hover:text-foreground transition-colors"
variants={childVariants}
whileHover={{ scale: 1.05, color: "#4b5563" }}
>
<Mail className="h-4 w-4 mr-2" />
{t('personal.email')}
</motion.a>
<motion.a
href={personalInfo.github}
target="_blank"
rel="noopener noreferrer"
className="flex items-center text-sm text-muted-foreground hover:text-foreground transition-colors"
variants={childVariants}
whileHover={{ scale: 1.05, color: "#4b5563" }}
>
<Github className="h-4 w-4 mr-2" />
🌟 {t('hero.githubLink')}
</motion.a>
<motion.a
href={personalInfo.linkedin}
target="_blank"
rel="noopener noreferrer"
className="flex items-center text-sm text-muted-foreground hover:text-foreground transition-colors"
variants={childVariants}
whileHover={{ scale: 1.05, color: "#4b5563" }}
>
<Linkedin className="h-4 w-4 mr-2" />
🔗 {t('hero.linkedinLink')}
</motion.a>
</motion.div>
</div>
<motion.div
className="mt-6 md:mt-0 flex justify-center"
variants={childVariants}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
<div className="relative">
<div className="absolute -inset-1 bg-gradient-to-r from-pink-500 to-purple-500 rounded-full blur opacity-30 group-hover:opacity-100 transition duration-1000 group-hover:duration-200"></div>
<img
src="/profile.jpg"
alt="Profile"
className="w-48 md:w-60 rounded-full relative ring-2 ring-purple-500/50"
style={{ objectFit: "cover" }}
/>
</div>
</motion.div>
</motion.div>
<MotionWrapper>
<div className="bg-gradient-to-r from-purple-500/10 to-pink-500/10 backdrop-blur-sm backdrop-filter p-4 rounded-lg border border-purple-500/20 dark:border-purple-500/10 shadow-sm">
<p className="text-muted-foreground pl-4 py-2 mb-4 relative">
<span className="absolute left-0 top-0 h-full w-1 bg-gradient-to-b from-purple-500 to-pink-500 rounded-full"></span>
{t('hero.description')}
</p>
</div>
</MotionWrapper>
</div>
</section>
);
}