feat(services): add services section with outsourcing and bugfix cards

Add new services section to showcase outsourcing projects and bug fixing services
Update i18n translations for services section
Change hero section link from projects to about
Remove personalInfo import and use translation for name in footer
This commit is contained in:
joyzhao
2025-06-16 17:29:35 +08:00
parent a18a0cdff1
commit 1354ffab58
5 changed files with 194 additions and 3 deletions

View File

@@ -1,4 +1,3 @@
import { personalInfo } from "@/lib/data";
import { useTranslations, type Lang } from "@/i18n/utils";
import { motion } from "framer-motion";
@@ -22,7 +21,7 @@ export default function Footer({ lang }: FooterProps) {
className="text-sm text-muted-foreground text-center md:text-left"
whileHover={{ scale: 1.01 }}
>
© {new Date().getFullYear()} {personalInfo.name}. {t('footer.rights')}
© {new Date().getFullYear()} {t('personal.name')}. {t('footer.rights')}
</motion.p>
<motion.p
className="text-sm text-muted-foreground mt-2 md:mt-0 text-center md:text-left"

View File

@@ -84,7 +84,7 @@ export default function HeroSection({ lang }: { lang: "en" | "zh" }) {
variants={childVariants}
>
<motion.a
href="#projects"
href="#about"
className="bg-purple-500 hover:bg-purple-600 text-white px-8 py-3 rounded-lg font-semibold transition-colors flex items-center gap-2"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}

View File

@@ -55,6 +55,21 @@ export const ui = {
'projects.title': 'Latest Projects',
'projects.viewOnGithub': 'View on GitHub',
// Services Section
'services.title': 'Services I Offer',
'services.outsourcing.title': 'Outsourcing Projects',
'services.outsourcing.item1': 'Provide outsourcing project services for overseas clients',
'services.outsourcing.item2': 'Project packaging, can provide services in different packages',
'services.outsourcing.item3': 'Use popular technologies: React, nest.js, next.js, etc.',
'services.outsourcing.item4': 'Project delivery, provide three months of free maintenance',
'services.outsourcing.item5': 'Regardless of project size, can provide services',
'services.bugfix.title': 'Bug Fixes',
'services.bugfix.item1': 'Quickly locate and fix website issues, able to quickly locate and solve problems',
'services.bugfix.item2': 'Help you solve any problems encountered in the project, Bug, functional optimization issues',
'services.bugfix.item3': 'Application of Vue, React, Node and other technologies',
'services.bugfix.item4': 'Frontend automation, deployment, monitoring, automation, etc.',
'services.bugfix.item5': 'Only limited to Node.js projects',
// Awards Section
'awards.title': 'Awards',
@@ -224,6 +239,21 @@ export const ui = {
'projects.title': '最新项目',
'projects.viewOnGithub': '在 GitHub 上查看',
// Services Section
'services.title': '我提供的服务',
'services.outsourcing.title': '外包项目',
'services.outsourcing.item1': '面向海外客户,提供外包项目服务',
'services.outsourcing.item2': '项目整包,分包均可提供服务',
'services.outsourcing.item3': '使用热门流行的技术栈React、nest.js、next.js等',
'services.outsourcing.item4': '项目交付后,提供三个月免费的维护',
'services.outsourcing.item5': '不论项目大小,均可提供服务',
'services.bugfix.title': 'Bug修复',
'services.bugfix.item1': '拥有丰富的错误问题经验,能够快速定位并解决问题',
'services.bugfix.item2': '帮助你解决项目中遇到的任何问题、Bug、功能优化等问题',
'services.bugfix.item3': 'Vue、React、Node等技术栈的应用',
'services.bugfix.item4': '前端自动化、部署、监控、自动化等',
'services.bugfix.item5': '仅限前端、Node.js项目',
// Awards Section
'awards.title': '获奖经历',

View File

@@ -19,6 +19,87 @@ const pageTitle = t('page.home.title');
<main class="min-h-screen">
<HeroSection lang={lang} client:only="react" />
<SkillsMarquee lang={lang} client:only="react" />
<!-- Services Section -->
<section class="py-20 px-4 bg-gradient-to-br from-slate-50 to-blue-50 dark:from-slate-900 dark:to-slate-800">
<div class="max-w-6xl mx-auto">
<h2 class="text-4xl font-bold text-center mb-16 bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
{t('services.title')}
</h2>
<div class="grid md:grid-cols-2 gap-8">
<!-- Outsourcing Projects Card -->
<div class="bg-white/70 dark:bg-slate-800/70 backdrop-blur-sm rounded-2xl p-8 border border-white/20 shadow-xl hover:shadow-2xl transition-all duration-300 hover:scale-105">
<div class="flex items-center mb-6">
<div class="w-12 h-12 bg-gradient-to-r from-blue-500 to-cyan-500 rounded-lg flex items-center justify-center mr-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path>
</svg>
</div>
<h3 class="text-2xl font-bold text-slate-800 dark:text-white">{t('services.outsourcing.title')}</h3>
</div>
<ul class="space-y-3">
<li class="flex items-start">
<span class="text-blue-500 mr-3 mt-1">1.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.outsourcing.item1')}</span>
</li>
<li class="flex items-start">
<span class="text-blue-500 mr-3 mt-1">2.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.outsourcing.item2')}</span>
</li>
<li class="flex items-start">
<span class="text-blue-500 mr-3 mt-1">3.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.outsourcing.item3')}</span>
</li>
<li class="flex items-start">
<span class="text-blue-500 mr-3 mt-1">4.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.outsourcing.item4')}</span>
</li>
<li class="flex items-start">
<span class="text-blue-500 mr-3 mt-1">5.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.outsourcing.item5')}</span>
</li>
</ul>
</div>
<!-- Bug Fixes Card -->
<div class="bg-white/70 dark:bg-slate-800/70 backdrop-blur-sm rounded-2xl p-8 border border-white/20 shadow-xl hover:shadow-2xl transition-all duration-300 hover:scale-105">
<div class="flex items-center mb-6">
<div class="w-12 h-12 bg-gradient-to-r from-red-500 to-pink-500 rounded-lg flex items-center justify-center mr-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"></path>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
</svg>
</div>
<h3 class="text-2xl font-bold text-slate-800 dark:text-white">{t('services.bugfix.title')}</h3>
</div>
<ul class="space-y-3">
<li class="flex items-start">
<span class="text-red-500 mr-3 mt-1">1.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.bugfix.item1')}</span>
</li>
<li class="flex items-start">
<span class="text-red-500 mr-3 mt-1">2.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.bugfix.item2')}</span>
</li>
<li class="flex items-start">
<span class="text-red-500 mr-3 mt-1">3.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.bugfix.item3')}</span>
</li>
<li class="flex items-start">
<span class="text-red-500 mr-3 mt-1">4.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.bugfix.item4')}</span>
</li>
<li class="flex items-start">
<span class="text-red-500 mr-3 mt-1">5.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.bugfix.item5')}</span>
</li>
</ul>
</div>
</div>
</div>
</section>
<AboutSection lang={lang} client:only="react" />
<ProjectsSection lang={lang} client:only="react" />
</main>

View File

@@ -18,6 +18,87 @@ const pageTitle = t('page.home.title');
<main class="min-h-screen">
<HeroSection lang={lang} client:only="react" />
<SkillsMarquee lang={lang} client:only="react" />
<!-- Services Section -->
<section class="py-20 px-4 bg-gradient-to-br from-slate-50 to-blue-50 dark:from-slate-900 dark:to-slate-800">
<div class="max-w-6xl mx-auto">
<h2 class="text-4xl font-bold text-center mb-16 bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
{t('services.title')}
</h2>
<div class="grid md:grid-cols-2 gap-8">
<!-- Outsourcing Projects Card -->
<div class="bg-white/70 dark:bg-slate-800/70 backdrop-blur-sm rounded-2xl p-8 border border-white/20 shadow-xl hover:shadow-2xl transition-all duration-300 hover:scale-105">
<div class="flex items-center mb-6">
<div class="w-12 h-12 bg-gradient-to-r from-blue-500 to-cyan-500 rounded-lg flex items-center justify-center mr-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path>
</svg>
</div>
<h3 class="text-2xl font-bold text-slate-800 dark:text-white">{t('services.outsourcing.title')}</h3>
</div>
<ul class="space-y-3">
<li class="flex items-start">
<span class="text-blue-500 mr-3 mt-1">1.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.outsourcing.item1')}</span>
</li>
<li class="flex items-start">
<span class="text-blue-500 mr-3 mt-1">2.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.outsourcing.item2')}</span>
</li>
<li class="flex items-start">
<span class="text-blue-500 mr-3 mt-1">3.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.outsourcing.item3')}</span>
</li>
<li class="flex items-start">
<span class="text-blue-500 mr-3 mt-1">4.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.outsourcing.item4')}</span>
</li>
<li class="flex items-start">
<span class="text-blue-500 mr-3 mt-1">5.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.outsourcing.item5')}</span>
</li>
</ul>
</div>
<!-- Bug Fixes Card -->
<div class="bg-white/70 dark:bg-slate-800/70 backdrop-blur-sm rounded-2xl p-8 border border-white/20 shadow-xl hover:shadow-2xl transition-all duration-300 hover:scale-105">
<div class="flex items-center mb-6">
<div class="w-12 h-12 bg-gradient-to-r from-red-500 to-pink-500 rounded-lg flex items-center justify-center mr-4">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"></path>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
</svg>
</div>
<h3 class="text-2xl font-bold text-slate-800 dark:text-white">{t('services.bugfix.title')}</h3>
</div>
<ul class="space-y-3">
<li class="flex items-start">
<span class="text-red-500 mr-3 mt-1">1.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.bugfix.item1')}</span>
</li>
<li class="flex items-start">
<span class="text-red-500 mr-3 mt-1">2.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.bugfix.item2')}</span>
</li>
<li class="flex items-start">
<span class="text-red-500 mr-3 mt-1">3.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.bugfix.item3')}</span>
</li>
<li class="flex items-start">
<span class="text-red-500 mr-3 mt-1">4.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.bugfix.item4')}</span>
</li>
<li class="flex items-start">
<span class="text-red-500 mr-3 mt-1">5.</span>
<span class="text-slate-600 dark:text-slate-300">{t('services.bugfix.item5')}</span>
</li>
</ul>
</div>
</div>
</div>
</section>
<AboutSection lang={lang} client:only="react" />
<ProjectsSection lang={lang} client:only="react" />
</main>