From 5b6b9f5d586820bb29ed1b8552abbac2f79b14d4 Mon Sep 17 00:00:00 2001 From: joyzhao Date: Thu, 19 Jun 2025 10:52:05 +0800 Subject: [PATCH] refactor(i18n): restructure translation system with nested objects and proxy feat(data): add projects and services data structure for dynamic rendering refactor(pages): replace hardcoded content with dynamic data-driven components --- src/i18n/ui.ts | 152 +++++++++++++++++------- src/i18n/utils.ts | 7 +- src/lib/data.ts | 204 ++++++++++++++++++++++++++++++++- src/pages/index.astro | 86 +++----------- src/pages/projects.astro | 223 ++++++++---------------------------- src/pages/zh/index.astro | 92 ++++----------- src/pages/zh/projects.astro | 223 ++++++++---------------------------- 7 files changed, 446 insertions(+), 541 deletions(-) diff --git a/src/i18n/ui.ts b/src/i18n/ui.ts index d3c831e..196e506 100644 --- a/src/i18n/ui.ts +++ b/src/i18n/ui.ts @@ -6,53 +6,119 @@ export const languages = { export const defaultLang = 'en'; -export const ui = { +// 定义嵌套结构的国际化数据 +const structuredUi = { en: { - 'nav.home': 'Home', - 'nav.about': 'About', - 'nav.services': 'Services', - 'nav.projects': 'Projects', - 'nav.blog': 'Blog', - 'nav.contact': 'Contact', - 'site.title': 'Joy Zhao - Full Stack Developer', - 'site.description': 'Full Stack Developer specializing in React, Node.js, and modern web technologies', - 'hero.githubLink': 'GitHub Profile', - 'hero.linkedinLink': 'LinkedIn Profile', - 'footer.rights': 'All rights reserved', - 'project.tag.business': 'Business Project', - 'project.tag.opensource': 'Open Source', - 'project.tag.personal': 'Personal Product', - 'project.tag.portfolio': 'Portfolio', - 'project.tag.ecommerce': 'E-Commerce', - 'project.visit': 'Visit', - 'project.demo': 'Live Demo', - 'projects.title': 'My Projects', - 'projects.description': 'A collection of my recent work, showcasing innovative solutions and clean code. Explore the details of each project below.' + nav: { + home: 'Home', + about: 'About', + services: 'Services', + projects: 'Projects', + blog: 'Blog', + contact: 'Contact', + }, + site: { + title: 'Joy Zhao - Full Stack Developer', + description: 'Full Stack Developer specializing in React, Node.js, and modern web technologies', + }, + hero: { + githubLink: 'GitHub Profile', + linkedinLink: 'LinkedIn Profile', + }, + footer: { + rights: 'All rights reserved', + }, + project: { + tag: { + business: 'Business Project', + opensource: 'Open Source', + personal: 'Personal Product', + portfolio: 'Portfolio', + ecommerce: 'E-Commerce', + }, + visit: 'Visit', + demo: 'Live Demo', + }, + projects: { + title: 'My Projects', + description: 'A collection of my recent work, showcasing innovative solutions and clean code. Explore the details of each project below.', + }, // Projects and services content has been inlined into respective page files // to reduce reliance on the translation system and improve maintainability }, zh: { - 'nav.home': '首页', - 'nav.about': '关于', - 'nav.services': '服务', - 'nav.projects': '项目', - 'nav.blog': '博客', - 'nav.contact': '联系', - 'site.title': 'Joy Zhao - 全栈开发者', - 'site.description': '专注于 React、Node.js 和现代 Web 技术的全栈开发者', - 'hero.githubLink': 'GitHub 主页', - 'hero.linkedinLink': 'LinkedIn 主页', - 'footer.rights': '版权所有', - 'project.tag.business': '商业项目', - 'project.tag.opensource': '开源项目', - 'project.tag.personal': '个人产品', - 'project.tag.portfolio': '作品集', - 'project.tag.ecommerce': '电子商务', - 'project.visit': '访问', - 'project.demo': '在线演示', - 'projects.title': '我的项目', - 'projects.description': '这里展示了我最近的作品集,展现了创新解决方案和整洁的代码。请浏览下方了解每个项目的详细信息。' + nav: { + home: '首页', + about: '关于', + services: '服务', + projects: '项目', + blog: '博客', + contact: '联系', + }, + site: { + title: 'Joy Zhao - 全栈开发者', + description: '专注于 React、Node.js 和现代 Web 技术的全栈开发者', + }, + hero: { + githubLink: 'GitHub 主页', + linkedinLink: 'LinkedIn 主页', + }, + footer: { + rights: '版权所有', + }, + project: { + tag: { + business: '商业项目', + opensource: '开源项目', + personal: '个人产品', + portfolio: '作品集', + ecommerce: '电子商务', + }, + visit: '访问', + demo: '在线演示', + }, + projects: { + title: '我的项目', + description: '这里展示了我最近的作品集,展现了创新解决方案和整洁的代码。请浏览下方了解每个项目的详细信息。', + }, // Projects and services content has been inlined into respective page files // to reduce reliance on the translation system and improve maintainability - } -} as const; \ No newline at end of file + }, +} as const; + +// 创建代理对象,保持与现有代码的兼容性 +function createCompatibleUi() { + // 为每种语言创建代理 + const compatibleUi: Record = {}; + + Object.keys(structuredUi).forEach(lang => { + compatibleUi[lang] = new Proxy({}, { + get(target, prop) { + if (typeof prop !== 'string') return undefined; + + // 处理点符号键 (如 'nav.home') + const parts = prop.split('.'); + let value: any = structuredUi[lang as keyof typeof structuredUi]; + + // 遍历嵌套结构 + for (const part of parts) { + if (value && typeof value === 'object' && part in value) { + value = value[part as keyof typeof value]; + } else { + return undefined; // 键不存在 + } + } + + return value; + } + }); + }); + + return compatibleUi; +} + +// 导出兼容的UI对象 +export const ui = createCompatibleUi() as typeof structuredUi; + +// 导出结构化的UI对象,供将来使用 +export const structuredUI = structuredUi; \ No newline at end of file diff --git a/src/i18n/utils.ts b/src/i18n/utils.ts index 4a77480..126c58f 100644 --- a/src/i18n/utils.ts +++ b/src/i18n/utils.ts @@ -2,14 +2,17 @@ import { ui, defaultLang, languages } from './ui'; export type Lang = keyof typeof languages; -export type UiKeys = keyof typeof ui[typeof defaultLang]; +// 简化类型定义,直接使用字符串类型 +// 这样可以兼容点符号键,同时避免复杂的类型推导问题 +export type UiKeys = string; export function useTranslations(lang: Lang | undefined) { const currentLang = lang || defaultLang; return function t(key: UiKeys, ...args: any[]): string { - let translation: string = ui[currentLang][key] || ui[defaultLang][key]; + // 使用类型断言解决索引问题 + let translation: string = (ui[currentLang] as any)[key] || (ui[defaultLang] as any)[key]; if (args.length > 0) { args.forEach((arg, index) => { translation = translation.replace(`{${index}}`, arg); diff --git a/src/lib/data.ts b/src/lib/data.ts index ee75d69..4f1149d 100644 --- a/src/lib/data.ts +++ b/src/lib/data.ts @@ -1,8 +1,202 @@ export const personalInfo = { - name: "Joy Zhao", + name: "Guiyang Zhao", location: "Shanghai, China", - avatar:"https://avatars.githubusercontent.com/u/24975063?v=4", - email: "zhaoguiyang18@gmail.com", - github: "https://github.com/zguiyang", - linkedin: "https://linkedin.com/in/zhaoguiyang" + avatar: "/images/avatar.jpg", + email: "zhaoguiyang@gmail.com", + github: "https://github.com/zhaoguiyang", + linkedin: "https://linkedin.com/in/zhaoguiyang", +}; + +export const projects = { + en: [ + { + id: "taskify", + tag: "business", + title: "Taskify App", + icon: "📱", + color: "purple", + image: { + bg: "from-purple-500/20 to-purple-600/20", + hover: "from-purple-500/20 to-purple-600/20", + text: "text-purple-400", + }, + description: [ + "A comprehensive task management application with drag-and-drop functionality.", + "Built with React, TypeScript, and Tailwind CSS using modern development approaches.", + "Real-time collaboration through WebSocket integration for instant updates.", + "Advanced task filtering, sorting, and project management capabilities.", + ], + tech: ["React", "Node.js", "MongoDB"], + link: "#", + }, + { + id: "eshop", + tag: "ecommerce", + title: "E-Shop Platform", + icon: "🛒", + color: "green", + image: { + bg: "from-green-500/20 to-green-600/20", + hover: "from-green-500/20 to-green-600/20", + text: "text-green-400", + }, + description: [ + "Scalable e-commerce platform built with Next.js, Stripe payments, and TailwindCSS.", + "Mobile-first responsive design for optimal user experience across devices.", + "Integrated payment processing with Stripe for secure transactions.", + "Admin dashboard for inventory management and order processing.", + ], + tech: ["Next.js", "Stripe", "TailwindCSS"], + link: "#", + }, + { + id: "portfolio", + tag: "portfolio", + title: "Portfolio Site", + icon: "🌐", + color: "purple", + image: { + bg: "from-purple-500/20 to-purple-600/20", + hover: "from-purple-500/20 to-purple-600/20", + text: "text-purple-400", + }, + description: [ + "Personal portfolio showcasing my work, built with HTML, TailwindCSS, and Alpine.js.", + "Responsive design with dark mode support and smooth animations.", + "Optimized for performance with minimal JavaScript and efficient CSS.", + "Integrated blog section with markdown support for content management.", + ], + tech: ["HTML", "TailwindCSS", "Alpine.js"], + link: "#", + }, + ], + zh: [ + { + id: "taskify", + tag: "business", + title: "Taskify 应用", + icon: "📱", + color: "purple", + image: { + bg: "from-purple-500/20 to-purple-600/20", + hover: "from-purple-500/20 to-purple-600/20", + text: "text-purple-400", + }, + description: [ + "一个全面的任务管理应用,具有拖放功能。", + "使用React、TypeScript和Tailwind CSS构建,采用现代开发方法。", + "通过WebSocket集成实现实时协作功能,实现即时更新。", + "高级任务筛选、排序和项目管理功能。", + ], + tech: ["React", "Node.js", "MongoDB"], + link: "#", + }, + { + id: "eshop", + tag: "ecommerce", + title: "电商平台", + icon: "🛒", + color: "green", + image: { + bg: "from-green-500/20 to-green-600/20", + hover: "from-green-500/20 to-green-600/20", + text: "text-green-400", + }, + description: [ + "使用Next.js、Stripe支付和TailwindCSS构建的可扩展电子商务平台。", + "采用移动优先的响应式设计,提供最佳用户体验。", + "集成Stripe支付处理,确保交易安全。", + "管理员仪表板,用于库存管理和订单处理。", + ], + tech: ["Next.js", "Stripe", "TailwindCSS"], + link: "#", + }, + { + id: "portfolio", + tag: "portfolio", + title: "个人作品集网站", + icon: "🌐", + color: "purple", + image: { + bg: "from-purple-500/20 to-purple-600/20", + hover: "from-purple-500/20 to-purple-600/20", + text: "text-purple-400", + }, + description: [ + "展示我的作品的个人作品集,使用HTML、TailwindCSS和Alpine.js构建。", + "响应式设计,支持暗黑模式和平滑动画。", + "通过最小化JavaScript和高效CSS优化性能。", + "集成博客部分,支持markdown内容管理。", + ], + tech: ["HTML", "TailwindCSS", "Alpine.js"], + link: "#", + }, + ], +}; + +export const services = { + en: [ + { + title: "Outsourcing Projects", + icon: { + svg: ``, + gradient: "from-blue-500 to-cyan-500", + }, + items: [ + "Provide outsourcing project services for overseas clients", + "Project packaging, can provide services in different packages", + "Use popular technologies: React, nest.js, next.js, etc.", + "Project delivery, provide three months of free maintenance", + "Regardless of project size, can provide services", + ], + color: "blue", + }, + { + title: "Bug Fixes", + icon: { + svg: ``, + gradient: "from-red-500 to-pink-500", + }, + items: [ + "Quickly locate and fix website issues, able to quickly locate and solve problems", + "Help you solve any problems encountered in the project, Bug, functional optimization issues", + "Application of Vue, React, Node and other technologies", + "Frontend automation, deployment, monitoring, automation, etc.", + "Only limited to Node.js projects", + ], + color: "red", + }, + ], + zh: [ + { + title: "外包项目", + icon: { + svg: ``, + gradient: "from-blue-500 to-cyan-500", + }, + items: [ + "为海外客户提供外包项目服务", + "项目打包,可以提供不同套餐的服务", + "使用流行技术:React、nest.js、next.js 等", + "项目交付,提供三个月免费维护", + "不论项目大小,都可以提供服务", + ], + color: "blue", + }, + { + title: "Bug 修复", + icon: { + svg: ``, + gradient: "from-red-500 to-pink-500", + }, + items: [ + "快速定位和修复网站问题,能够快速定位和解决问题", + "帮助您解决项目中遇到的任何问题,Bug、功能优化问题", + "Vue、React、Node 等技术的应用", + "前端自动化、部署、监控、自动化等", + "仅限于 Node.js 项目", + ], + color: "red", + }, + ], }; \ No newline at end of file diff --git a/src/pages/index.astro b/src/pages/index.astro index a3e1bde..7afe9e7 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -5,7 +5,7 @@ import SkillsMarquee from "@/components/SkillsMarquee"; import Footer from "@/components/Footer"; import { useTranslations, type Lang } from "@/i18n/utils"; import { defaultLang } from "@/i18n/ui"; -import { personalInfo } from "@/lib/data"; +import { personalInfo, services } from "@/lib/data"; // 使用Astro.currentLocale获取当前语言环境 const lang = Astro.currentLocale as Lang || defaultLang; @@ -175,74 +175,26 @@ const pageTitle = t('site.title');
- -
-
-
- - - + {services.en.map((service) => ( +
+
+
+ + + +
+

{service.title}

-

Outsourcing Projects

+
    + {service.items.map((item, index) => ( +
  • + {index + 1}. + {item} +
  • + ))} +
-
    -
  • - 1. - Provide outsourcing project services for overseas clients -
  • -
  • - 2. - Project packaging, can provide services in different packages -
  • -
  • - 3. - Use popular technologies: React, nest.js, next.js, etc. -
  • -
  • - 4. - Project delivery, provide three months of free maintenance -
  • -
  • - 5. - Regardless of project size, can provide services -
  • -
-
- - -
-
-
- - - - -
-

Bug Fixes

-
-
    -
  • - 1. - Quickly locate and fix website issues, able to quickly locate and solve problems -
  • -
  • - 2. - Help you solve any problems encountered in the project, Bug, functional optimization issues -
  • -
  • - 3. - Application of Vue, React, Node and other technologies -
  • -
  • - 4. - Frontend automation, deployment, monitoring, automation, etc. -
  • -
  • - 5. - Only limited to Node.js projects -
  • -
-
+ ))}
diff --git a/src/pages/projects.astro b/src/pages/projects.astro index ee7a0c6..acdf9c2 100644 --- a/src/pages/projects.astro +++ b/src/pages/projects.astro @@ -4,11 +4,15 @@ import GlassHeader from "@/components/GlassHeader"; import Footer from "@/components/Footer"; import { useTranslations, type Lang } from "@/i18n/utils"; import { defaultLang } from "@/i18n/ui"; +import { projects } from "@/lib/data"; // 使用Astro.currentLocale获取当前语言环境 const lang = Astro.currentLocale as Lang || defaultLang; const t = useTranslations(lang); const pageTitle = t('projects.title'); + +// 根据当前语言获取项目数据 +const currentProjects = projects[lang as keyof typeof projects] || projects.en; --- @@ -41,194 +45,59 @@ const pageTitle = t('projects.title');
- -
- -
- {t('project.tag.business')} -
- - -
-
-
-
- Taskify App -
+ {currentProjects.map((project) => ( +
+ +
+ {t(`project.tag.${project.tag}`)}
-
- -
-

- 📱 - Taskify App -

-
- -
-
-
- - A comprehensive task management application with drag-and-drop functionality. -
-
- - Built with React, TypeScript, and Tailwind CSS for modern development. -
-
- - Real-time collaboration features with WebSocket integration for instant updates. -
-
- - Advanced task filtering, sorting, and project management capabilities. + + +
+
+
+
+ {project.title} +
- -
- React - Node.js - MongoDB +
+

+ {project.icon} + {project.title} +

-
- - - -
- - -
- -
- {t('project.tag.ecommerce')} -
- - -
-
-
-
- E-Shop Platform + +
+
+ {project.description.map((desc) => ( +
+ + {desc} +
+ ))}
-
-
- -
-

- 🛒 - E-Shop Platform -

-
- -
-
-
- - A scalable e-commerce platform with Next.js, Stripe payments, and TailwindCSS. -
-
- - Responsive design with mobile-first approach for optimal user experience. -
-
- - Integrated payment processing with Stripe for secure transactions. -
-
- - Admin dashboard for inventory management and order processing. + + +
+ {project.tech.map((tech) => ( + {tech} + ))}
- -
- Next.js - Stripe - TailwindCSS + +
- - - -
- - -
- -
- {t('project.tag.portfolio')} -
- - -
-
-
-
- Portfolio Site -
-
-
- -
-

- 🌐 - Portfolio Site -

-
- -
-
-
- - My personal portfolio showcasing my work, built with HTML, TailwindCSS, and Alpine.js. -
-
- - Responsive design with dark mode support and smooth animations. -
-
- - Optimized for performance with minimal JavaScript and efficient CSS. -
-
- - Integrated blog section with markdown support for content management. -
-
- - -
- HTML - TailwindCSS - Alpine.js -
-
- - - -
+ ))}
diff --git a/src/pages/zh/index.astro b/src/pages/zh/index.astro index fd62081..85f1f24 100644 --- a/src/pages/zh/index.astro +++ b/src/pages/zh/index.astro @@ -1,11 +1,11 @@ --- import Layout from "@/layouts/Layout.astro"; -import GlassHeader from "@/components/GlassHeader.tsx"; -import SkillsMarquee from "@/components/SkillsMarquee.tsx"; -import Footer from "@/components/Footer.tsx"; +import GlassHeader from "@/components/GlassHeader"; +import SkillsMarquee from "@/components/SkillsMarquee"; +import Footer from "@/components/Footer"; import { useTranslations, type Lang } from "@/i18n/utils"; import { defaultLang } from "@/i18n/ui"; -import { personalInfo } from "@/lib/data"; +import { personalInfo, services } from "@/lib/data"; // 使用Astro.currentLocale获取当前语言环境 const lang = Astro.currentLocale as Lang || defaultLang; @@ -175,74 +175,26 @@ const pageTitle = t('site.title');
- -
-
-
- - - + {services.zh.map((service) => ( +
+
+
+ + + +
+

{service.title}

-

外包项目

+
    + {service.items.map((item, index) => ( +
  • + {index + 1}. + {item} +
  • + ))} +
-
    -
  • - 1. - 为海外客户提供外包项目服务 -
  • -
  • - 2. - 项目打包,可以提供不同套餐的服务 -
  • -
  • - 3. - 使用流行技术:React、nest.js、next.js 等 -
  • -
  • - 4. - 项目交付,提供三个月免费维护 -
  • -
  • - 5. - 不论项目大小,都可以提供服务 -
  • -
-
- - -
-
-
- - - - -
-

Bug 修复

-
-
    -
  • - 1. - 快速定位和修复网站问题,能够快速定位和解决问题 -
  • -
  • - 2. - 帮助您解决项目中遇到的任何问题,Bug、功能优化问题 -
  • -
  • - 3. - Vue、React、Node 等技术的应用 -
  • -
  • - 4. - 前端自动化、部署、监控、自动化等 -
  • -
  • - 5. - 仅限于 Node.js 项目 -
  • -
-
+ ))}
diff --git a/src/pages/zh/projects.astro b/src/pages/zh/projects.astro index 76f9391..acdf9c2 100644 --- a/src/pages/zh/projects.astro +++ b/src/pages/zh/projects.astro @@ -4,11 +4,15 @@ import GlassHeader from "@/components/GlassHeader"; import Footer from "@/components/Footer"; import { useTranslations, type Lang } from "@/i18n/utils"; import { defaultLang } from "@/i18n/ui"; +import { projects } from "@/lib/data"; // 使用Astro.currentLocale获取当前语言环境 const lang = Astro.currentLocale as Lang || defaultLang; const t = useTranslations(lang); const pageTitle = t('projects.title'); + +// 根据当前语言获取项目数据 +const currentProjects = projects[lang as keyof typeof projects] || projects.en; --- @@ -41,194 +45,59 @@ const pageTitle = t('projects.title');
- -
- -
- {t('project.tag.business')} -
- - -
-
-
-
- Taskify 应用 -
+ {currentProjects.map((project) => ( +
+ +
+ {t(`project.tag.${project.tag}`)}
-
- -
-

- 📱 - Taskify 应用 -

-
- -
-
-
- - 一个全面的任务管理应用,具有拖放功能。 -
-
- - 使用React、TypeScript和Tailwind CSS构建,采用现代开发方法。 -
-
- - 通过WebSocket集成实现实时协作功能,实现即时更新。 -
-
- - 高级任务筛选、排序和项目管理功能。 + + +
+
+
+
+ {project.title} +
- -
- React - Node.js - MongoDB +
+

+ {project.icon} + {project.title} +

-
- - - -
- - -
- -
- {t('project.tag.ecommerce')} -
- - -
-
-
-
- 电商平台 + +
+
+ {project.description.map((desc) => ( +
+ + {desc} +
+ ))}
-
-
- -
-

- 🛒 - 电商平台 -

-
- -
-
-
- - 使用Next.js、Stripe支付和TailwindCSS构建的可扩展电子商务平台。 -
-
- - 采用移动优先的响应式设计,提供最佳用户体验。 -
-
- - 集成Stripe支付处理,确保交易安全。 -
-
- - 管理员仪表板,用于库存管理和订单处理。 + + +
+ {project.tech.map((tech) => ( + {tech} + ))}
- -
- Next.js - Stripe - TailwindCSS + +
- - - -
- - -
- -
- {t('project.tag.portfolio')} -
- - -
-
-
-
- 个人作品集网站 -
-
-
- -
-

- 🌐 - 个人作品集网站 -

-
- -
-
-
- - 展示我的作品的个人作品集,使用HTML、TailwindCSS和Alpine.js构建。 -
-
- - 响应式设计,支持暗黑模式和平滑动画。 -
-
- - 通过最小化JavaScript和高效CSS优化性能。 -
-
- - 集成博客部分,支持markdown内容管理。 -
-
- - -
- HTML - TailwindCSS - Alpine.js -
-
- - - -
+ ))}