feat: implement internationalization with next-intl and add core portfolio sections

This commit is contained in:
Yolando
2026-03-28 19:59:39 +07:00
parent 5b0254d71b
commit 39f8567519
17 changed files with 1304 additions and 253 deletions

View File

@@ -2,23 +2,23 @@
import { motion } from "framer-motion";
import { ArrowDown, FileText, Send } from "lucide-react";
import { useTranslations } from "next-intl";
export function HeroSection() {
const t = useTranslations("Hero");
return (
<section
id="hero"
className="relative min-h-screen flex items-center justify-center overflow-hidden"
>
{/* Background effects */}
<div className="absolute inset-0 grid-pattern opacity-30" />
{/* Gradient orbs */}
<div className="absolute top-1/4 -left-32 w-96 h-96 rounded-full bg-accent/20 blur-[120px] animate-pulse-glow" />
<div className="absolute bottom-1/4 -right-32 w-96 h-96 rounded-full bg-purple-500/15 blur-[120px] animate-pulse-glow" style={{ animationDelay: "2s" }} />
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px] rounded-full bg-indigo-500/5 blur-[100px]" />
<div className="relative z-10 max-w-5xl mx-auto px-6 text-center">
{/* Status badge */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
@@ -29,37 +29,32 @@ export function HeroSection() {
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-success opacity-75" />
<span className="relative inline-flex rounded-full h-2 w-2 bg-success" />
</span>
Available for opportunities
{t("badge")}
</span>
</motion.div>
{/* Main heading */}
<motion.h1
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.7, delay: 0.3 }}
className="text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-bold tracking-tight leading-[1.1] mb-6"
>
Building{" "}
<span className="gradient-text">Secure, Scalable</span>
{t("titlePart1")}{" "}
<span className="gradient-text">{t("titleHighlight")}</span>
<br />
Enterprise-Grade Systems
{t("titlePart2")}
</motion.h1>
{/* Subtitle */}
<motion.p
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.7, delay: 0.5 }}
className="text-lg md:text-xl text-muted-foreground max-w-2xl mx-auto mb-10 leading-relaxed"
>
<span className="font-mono text-accent font-semibold">3+ Years</span>{" "}
in Banking Technology.{" "}
<span className="text-foreground">Backend Developer</span> specializing in
Java Spring Boot, Microservices Architecture, and Enterprise Security.
<span className="font-mono text-accent font-semibold">{t("yearsExp")}</span>{" "}
{t("subtitle")}
</motion.p>
{/* CTA buttons */}
<motion.div
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
@@ -71,18 +66,17 @@ export function HeroSection() {
className="group inline-flex items-center gap-2 px-7 py-3.5 rounded-xl bg-gradient-to-r from-accent to-purple-500 text-white font-semibold text-sm shadow-lg shadow-accent/25 hover:shadow-accent/40 hover:scale-105 transition-all duration-300"
>
<Send size={16} />
Get in Touch
{t("ctaContact")}
</a>
<a
href="#projects"
className="inline-flex items-center gap-2 px-7 py-3.5 rounded-xl font-semibold text-sm border border-border hover:bg-muted/50 transition-all duration-300 hover:scale-105"
>
<FileText size={16} />
View Projects
{t("ctaProjects")}
</a>
</motion.div>
{/* Tech badges */}
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
@@ -100,7 +94,6 @@ export function HeroSection() {
</motion.div>
</div>
{/* Scroll indicator */}
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
@@ -108,7 +101,7 @@ export function HeroSection() {
className="absolute bottom-8 left-1/2 -translate-x-1/2"
>
<a href="#experience" className="flex flex-col items-center gap-2 text-muted-foreground hover:text-accent transition-colors">
<span className="text-xs font-mono">Scroll</span>
<span className="text-xs font-mono">{t("scroll")}</span>
<motion.div
animate={{ y: [0, 8, 0] }}
transition={{ duration: 1.5, repeat: Infinity }}