From ea01dc6dd896c99d9b3994a71ac697ebc544df77 Mon Sep 17 00:00:00 2001 From: joyzhao Date: Sat, 21 Jun 2025 09:18:39 +0800 Subject: [PATCH] refactor: reorganize project structure and improve type definitions - Split types into separate modules for better organization - Move data files to dedicated directories with proper documentation - Enhance i18n utilities with better type safety and performance - Maintain backward compatibility with legacy imports --- src/i18n/translations.ts | 143 +++++++++++++++++ src/i18n/ui.ts | 134 +++------------- src/i18n/utils.ts | 63 ++++++-- src/lib/data.ts | 293 +++++++--------------------------- src/lib/data/index.ts | 9 ++ src/lib/data/personal-info.ts | 55 +++++++ src/lib/data/projects.ts | 136 ++++++++++++++++ src/lib/data/services.ts | 76 +++++++++ src/lib/index.ts | 7 + src/types/blog.ts | 78 +++++++++ src/types/components.ts | 22 +++ src/types/data.ts | 88 ++++++++++ src/types/i18n.ts | 36 +++++ src/types/index.ts | 167 +------------------ 14 files changed, 784 insertions(+), 523 deletions(-) create mode 100644 src/i18n/translations.ts create mode 100644 src/lib/data/index.ts create mode 100644 src/lib/data/personal-info.ts create mode 100644 src/lib/data/projects.ts create mode 100644 src/lib/data/services.ts create mode 100644 src/lib/index.ts create mode 100644 src/types/blog.ts create mode 100644 src/types/components.ts create mode 100644 src/types/data.ts create mode 100644 src/types/i18n.ts diff --git a/src/i18n/translations.ts b/src/i18n/translations.ts new file mode 100644 index 0000000..3ed9851 --- /dev/null +++ b/src/i18n/translations.ts @@ -0,0 +1,143 @@ +/** + * Translations module + * Contains all translation data for the application + */ + +/** + * Available languages in the application + */ +export const languages = { + en: 'English', + zh: '简体中文', +} as const; + +/** + * Default language for the application + */ +export const defaultLang = 'en'; + +/** + * Structured translations data + * Organized by language and feature area + */ +export const translations = { + en: { + 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.', + slogan: 'Crafting elegant solutions to complex problems with clean code and innovative thinking.', + }, + blog: { + slogan: 'This is where innovative thinking meets complex problems.', + }, + }, + zh: { + 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: '这里展示了我最近的作品集,展现了创新解决方案和整洁的代码。请浏览下方了解每个项目的详细信息。', + slogan: '用优雅的代码和创新的思维,为复杂问题打造精致的解决方案。', + }, + blog: { + slogan: '这里是创新思维与复杂问题相遇的地方。', + }, + }, +} as const; + +/** + * Generate flattened translations for better performance + * This creates a flat object with dot notation keys + */ +export function generateFlatTranslations() { + const flattenedTranslations: Record> = {}; + + // Initialize for each language + Object.keys(translations).forEach(lang => { + flattenedTranslations[lang] = {}; + }); + + // Recursive function to flatten nested objects + function flatten(obj: any, lang: string, prefix = '') { + for (const key in obj) { + const value = obj[key]; + const newKey = prefix ? `${prefix}.${key}` : key; + + if (typeof value === 'object' && value !== null) { + flatten(value, lang, newKey); + } else { + flattenedTranslations[lang][newKey] = value; + } + } + } + + // Process each language + Object.keys(translations).forEach(lang => { + flatten(translations[lang as keyof typeof translations], lang); + }); + + return flattenedTranslations; +} + +/** + * Flattened translations for faster lookups + */ +export const flatTranslations = generateFlatTranslations(); \ No newline at end of file diff --git a/src/i18n/ui.ts b/src/i18n/ui.ts index 0fb2668..c59a614 100644 --- a/src/i18n/ui.ts +++ b/src/i18n/ui.ts @@ -1,123 +1,30 @@ -// src/i18n/ui.ts -export const languages = { - en: 'English', - zh: '简体中文', -} as const; +/** + * UI internationalization module + * This file is maintained for backward compatibility + * New code should import from translations.ts directly + */ -export const defaultLang = 'en'; +// Re-export from translations.ts +export { languages, defaultLang, translations as structuredUI } from './translations'; -// 定义嵌套结构的国际化数据 -const structuredUi = { - en: { - 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.', - slogan: 'Crafting elegant solutions to complex problems with clean code and innovative thinking.', - }, - blog: { - slogan: 'This is where innovative thinking meets complex problems.', - }, - // Projects and services content has been inlined into respective page files - // to reduce reliance on the translation system and improve maintainability - }, - zh: { - 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: '这里展示了我最近的作品集,展现了创新解决方案和整洁的代码。请浏览下方了解每个项目的详细信息。', - slogan: '用优雅的代码和创新的思维,为复杂问题打造精致的解决方案。', - }, - blog: { - slogan: '这里是创新思维与复杂问题相遇的地方。', - }, - // Projects and services content has been inlined into respective page files - // to reduce reliance on the translation system and improve maintainability - }, -} as const; +// Import flattened translations for compatibility layer +import { flatTranslations } from './translations'; -// 创建代理对象,保持与现有代码的兼容性 +/** + * Create a backward compatible UI object + * This maintains the old API for existing code + */ function createCompatibleUi() { - // 为每种语言创建代理 const compatibleUi: Record = {}; - Object.keys(structuredUi).forEach(lang => { + // Create a proxy for each language + Object.keys(flatTranslations).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 the translation from flattened translations + return flatTranslations[lang][prop]; } }); }); @@ -125,8 +32,5 @@ function createCompatibleUi() { return compatibleUi; } -// 导出兼容的UI对象 -export const ui = createCompatibleUi() as typeof structuredUi; - -// 导出结构化的UI对象,供将来使用 -export const structuredUI = structuredUi; \ No newline at end of file +// Export the compatible UI object +export const ui = createCompatibleUi(); \ No newline at end of file diff --git a/src/i18n/utils.ts b/src/i18n/utils.ts index ede16d8..2d03f0d 100644 --- a/src/i18n/utils.ts +++ b/src/i18n/utils.ts @@ -1,25 +1,68 @@ -// src/i18n/utils.ts -import { ui, defaultLang, languages } from './ui'; -import { type Lang, type UiKeys } from '@/types'; - -// 重新导出类型,以保持向后兼容性 -export type { Lang, UiKeys }; +/** + * Internationalization utilities module + * Contains helper functions for i18n functionality + */ +import { defaultLang, languages, flatTranslations } from './translations'; +import type { Lang } from '@/types/i18n'; +/** + * Translation key type + * Represents a dot-notation path to a translation string + */ +export type TranslationKey = string; +/** + * Get translation function + * Returns a function that can be used to get translations for a specific language + * + * @param lang - The language to get translations for + * @returns A translation function + */ export function useTranslations(lang: Lang | undefined) { const currentLang = lang || defaultLang; - return function t(key: UiKeys, ...args: any[]): string { - // 使用类型断言解决索引问题 - let translation: string = (ui[currentLang] as any)[key] || (ui[defaultLang] as any)[key]; + + /** + * Translation function + * Gets a translation string for the specified key and replaces placeholders + * + * @param key - The translation key (dot notation) + * @param args - Optional arguments to replace placeholders in the translation + * @returns The translated string + */ + return function t(key: TranslationKey, ...args: any[]): string { + // Get translation from flattened translations for better performance + let translation = flatTranslations[currentLang][key]; + + // Fallback to default language if translation not found + if (!translation && currentLang !== defaultLang) { + translation = flatTranslations[defaultLang][key]; + } + + // Fallback to key if translation not found in any language + if (!translation) { + console.warn(`Translation key not found: ${key}`); + return key; + } + + // Replace placeholders with arguments if (args.length > 0) { args.forEach((arg, index) => { - translation = translation.replace(`{${index}}`, arg); + translation = translation.replace(`{${index}}`, String(arg)); }); } + return translation; }; } +/** + * Get localized path + * Adds language prefix to path if needed + * + * @param path - The path to localize + * @param lang - The language to localize for + * @returns The localized path + */ export function getLocalizedPath(path: string, lang: Lang | undefined): string { const currentLang = lang || defaultLang; const basePath = import.meta.env.BASE_URL === '/' ? '' : import.meta.env.BASE_URL; diff --git a/src/lib/data.ts b/src/lib/data.ts index 80bcf09..f0b1274 100644 --- a/src/lib/data.ts +++ b/src/lib/data.ts @@ -1,241 +1,58 @@ -import type { PersonalInfo } from '@/types'; +/** + * Data module (Legacy) + * This file is kept for backward compatibility + * All data has been moved to src/lib/data/ directory + */ -export const personalInfo: PersonalInfo = { - name: "Joy Zhao", - location: "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", - website: "https://zhaoguiyang.com", - twitter: "https://twitter.com/zhaoguiyang", - position: { - en: "Full Stack Engineer", - zh: "全栈工程师" - }, - description: { - en: "Crafting elegant solutions to complex problems with clean code and innovative thinking. Welcome to my personal dev workspace where ideas come to life.", - zh: "用优雅的代码和创新的思维,为复杂问题打造精致的解决方案。欢迎来到我的个人开发工作空间,这里是想法变为现实的地方。" - }, - about: { - en: [ - "I started my programming journey in 2016 when I accidentally encountered programming. This opportunity became the catalyst for my coding adventure, and I fell in love with programming during my subsequent self-learning journey.", - "I enjoy creating websites and applications with code and sharing them with users. The sense of achievement I get from this process makes me increasingly fascinated. My dream is to become a lifelong coder.", - "I love reading, traveling (especially road trips), enjoying various cuisines (particularly hot pot), and playing mobile games like League of Legends, Honor of Kings, and PUBG Mobile." - ], - zh: [ - "在2016年一次偶然的机会中接触到了编程,以此为契机,开始了我的编程之旅,并在后续的自学之旅中爱上了编程。", - "我喜欢用代码编写出一个个的网页、应用,分享给用户使用,这其中获得的成就感让我愈发着迷。梦想是成为一名终身编码者。", - "热爱生活、阅读以及编程,寻找远程工作的机会,探索自由职业的可能性。喜欢自驾,去追寻那些美丽的风景,尝试新的事物。" - ] - }, - stats: { - repositories: 152, - commits: "42K", - contributions: 87 - }, - skills: { - frontend: ["HTML", "CSS", "JavaScript", "Vue.js", "React.js", "TypeScript"], - backend: ["Node.js"], - database: ["MySQL", "MongoDB"], - devops: ["Linux", "Git", "Docker", "Nginx", "Apache"], - mobile: ["React Native", "Flutter"] - }, - terminal: { - username: "joy@dev-workspace" - } -}; +// Re-export all data from the new modules +export { personalInfo } from './data/personal-info'; +export { projects } from './data/projects'; +export { services } from './data/services'; -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: "#", - }, - ], -}; +// For TypeScript type checking +import { personalInfo } from './data/personal-info'; +import { projects } from './data/projects'; +import { services } from './data/services'; -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 +// Type exports are now handled in src/types/index.ts +// This file is now just a re-export wrapper +// The actual data is in the respective files in src/lib/data/ directory + +// 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: "#", +// }, +// ... +// ], +// zh: [...] +// }; +// +// export const services = { +// en: [ +// { +// title: "Outsourcing Projects", +// icon: {...}, +// items: [...], +// color: "blue", +// }, +// ... +// ], +// zh: [...] +// }; \ No newline at end of file diff --git a/src/lib/data/index.ts b/src/lib/data/index.ts new file mode 100644 index 0000000..77d5659 --- /dev/null +++ b/src/lib/data/index.ts @@ -0,0 +1,9 @@ +/** + * Data index module + * Re-exports all data modules to maintain backward compatibility + */ + +// Re-export all data modules +export { personalInfo } from './personal-info'; +export { projects } from './projects'; +export { services } from './services'; \ No newline at end of file diff --git a/src/lib/data/personal-info.ts b/src/lib/data/personal-info.ts new file mode 100644 index 0000000..c1207e9 --- /dev/null +++ b/src/lib/data/personal-info.ts @@ -0,0 +1,55 @@ +/** + * Personal information data module + * Contains all personal information used throughout the site + */ +import type { PersonalInfo } from '@/types'; + +/** + * Personal information data + * This data is used in various components like Header, Footer, and About sections + */ +export const personalInfo: PersonalInfo = { + name: "Joy Zhao", + location: "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", + website: "https://zhaoguiyang.com", + twitter: "https://twitter.com/zhaoguiyang", + position: { + en: "Full Stack Engineer", + zh: "全栈工程师" + }, + description: { + en: "Crafting elegant solutions to complex problems with clean code and innovative thinking. Welcome to my personal dev workspace where ideas come to life.", + zh: "用优雅的代码和创新的思维,为复杂问题打造精致的解决方案。欢迎来到我的个人开发工作空间,这里是想法变为现实的地方。" + }, + about: { + en: [ + "I started my programming journey in 2016 when I accidentally encountered programming. This opportunity became the catalyst for my coding adventure, and I fell in love with programming during my subsequent self-learning journey.", + "I enjoy creating websites and applications with code and sharing them with users. The sense of achievement I get from this process makes me increasingly fascinated. My dream is to become a lifelong coder.", + "I love reading, traveling (especially road trips), enjoying various cuisines (particularly hot pot), and playing mobile games like League of Legends, Honor of Kings, and PUBG Mobile." + ], + zh: [ + "在2016年一次偶然的机会中接触到了编程,以此为契机,开始了我的编程之旅,并在后续的自学之旅中爱上了编程。", + "我喜欢用代码编写出一个个的网页、应用,分享给用户使用,这其中获得的成就感让我愈发着迷。梦想是成为一名终身编码者。", + "热爱生活、阅读以及编程,寻找远程工作的机会,探索自由职业的可能性。喜欢自驾,去追寻那些美丽的风景,尝试新的事物。" + ] + }, + stats: { + repositories: 152, + commits: "42K", + contributions: 87 + }, + skills: { + frontend: ["HTML", "CSS", "JavaScript", "Vue.js", "React.js", "TypeScript"], + backend: ["Node.js"], + database: ["MySQL", "MongoDB"], + devops: ["Linux", "Git", "Docker", "Nginx", "Apache"], + mobile: ["React Native", "Flutter"] + }, + terminal: { + username: "joy@dev-workspace" + } +}; \ No newline at end of file diff --git a/src/lib/data/projects.ts b/src/lib/data/projects.ts new file mode 100644 index 0000000..4012f11 --- /dev/null +++ b/src/lib/data/projects.ts @@ -0,0 +1,136 @@ +/** + * Projects data module + * Contains all project information displayed in the projects page + */ +import type { Project } from '@/types'; + +/** + * Projects data with localization support + * Each project contains information like id, tag, title, description, tech stack, etc. + */ +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: "#", + }, + ], +}; \ No newline at end of file diff --git a/src/lib/data/services.ts b/src/lib/data/services.ts new file mode 100644 index 0000000..e092681 --- /dev/null +++ b/src/lib/data/services.ts @@ -0,0 +1,76 @@ +/** + * Services data module + * Contains all service information displayed in the services section + */ +import type { Service } from '@/types'; + +/** + * Services data with localization support + * Each service contains information like title, icon, items, and color + */ +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/lib/index.ts b/src/lib/index.ts new file mode 100644 index 0000000..27a2f49 --- /dev/null +++ b/src/lib/index.ts @@ -0,0 +1,7 @@ +/** + * Library index module + * Re-exports all data modules to maintain backward compatibility + */ + +// Re-export all data modules from data directory +export * from './data'; \ No newline at end of file diff --git a/src/types/blog.ts b/src/types/blog.ts new file mode 100644 index 0000000..8032978 --- /dev/null +++ b/src/types/blog.ts @@ -0,0 +1,78 @@ +/** + * Blog types module + * Contains type definitions for blog functionality + */ +import type { Lang } from './i18n'; + +/** + * Author information interface + */ +export interface Author { + name: string; + bio?: string; + avatar?: string; + website?: string; + twitter?: string; + github?: string; + linkedin?: string; +} + +/** + * Blog post interface + */ +export interface BlogPost { + title: string; + description: string; + image: string; + slug: string; + tags: string[]; + tagId?: string[]; + category?: string[]; + categoryId?: string[]; + date: string; + readTime: string; + url?: string; +} + +/** + * Blog post frontmatter properties interface + */ +export interface FrontmatterProps { + title: string; + description?: string; + publishDate?: string; + date?: string; // Alternative field name for publish date + author?: string; + tags?: string[]; + tagId?: string[]; // Tag unique identifier for multilingual tag routing + category?: string | string[]; + categoryId?: string[] | string; // Category unique identifier for multilingual category routing + readingTime?: number; + readTime?: string; // Alternative field name for reading time +} + +/** + * Author card component props + */ +export interface AuthorCardProps { + lang: Lang; + author?: Author; +} + +/** + * Share buttons component props + */ +export interface ShareButtonsProps { + lang: Lang; + title: string; + url?: string; +} + +/** + * Blog list component props + */ +export interface BlogListProps { + posts: BlogPost[]; + lang: Lang; + baseUrl?: string; // Base URL for blog posts, defaults to '/blog/posts/' +} \ No newline at end of file diff --git a/src/types/components.ts b/src/types/components.ts new file mode 100644 index 0000000..cd559a3 --- /dev/null +++ b/src/types/components.ts @@ -0,0 +1,22 @@ +/** + * Component types module + * Contains type definitions for UI components + */ +import type { Lang } from './i18n'; + +/** + * Skill item interface + */ +export interface SkillItem { + name: string; + icon: string; + color: string; +} + +/** + * Skill section component props + */ +export interface SkillSectionProps { + title: string; + skills: SkillItem[]; +} \ No newline at end of file diff --git a/src/types/data.ts b/src/types/data.ts new file mode 100644 index 0000000..e3f930a --- /dev/null +++ b/src/types/data.ts @@ -0,0 +1,88 @@ +/** + * Data types module + * Contains type definitions for all data structures used in the application + */ +import type { Lang } from './i18n.ts'; + +/** + * Multi-language text type + */ +export type LocalizedText = { + [K in Lang]: string; +}; + +/** + * Personal information interface + */ +export interface PersonalInfo { + name: string; + location: string; + avatar: string; + email: string; + github: string; + linkedin: string; + website: string; + twitter: string; + position: LocalizedText; + description: LocalizedText; + about: { + [K in Lang]: string[]; + }; + stats: { + repositories: number; + commits: string; + contributions: number; + }; + skills: { + frontend: string[]; + backend: string[]; + database: string[]; + devops: string[]; + mobile: string[]; + }; + terminal: { + username: string; + }; +} + +/** + * Project image interface + */ +export interface ProjectImage { + bg: string; + hover: string; + text: string; +} + +/** + * Project interface + */ +export interface Project { + id: string; + tag: string; + title: string; + icon: string; + color: string; + image: ProjectImage; + description: string[]; + tech: string[]; + link: string; +} + +/** + * Service icon interface + */ +export interface ServiceIcon { + svg: string; + gradient: string; +} + +/** + * Service interface + */ +export interface Service { + title: string; + icon: ServiceIcon; + items: string[]; + color: string; +} \ No newline at end of file diff --git a/src/types/i18n.ts b/src/types/i18n.ts new file mode 100644 index 0000000..0ab22b5 --- /dev/null +++ b/src/types/i18n.ts @@ -0,0 +1,36 @@ +/** + * Internationalization types module + * Contains type definitions for i18n functionality + */ +import { languages } from '@/i18n/translations'; + +/** + * Language type definition + */ +export type Lang = keyof typeof languages; + +/** + * UI translation keys type + */ +export type UiKeys = string; + +/** + * Language switcher component props + */ +export interface LanguageSwitcherProps { + lang: Lang; +} + +/** + * Glass header component props + */ +export interface GlassHeaderProps { + lang: Lang; +} + +/** + * Footer component props + */ +export interface FooterProps { + lang?: Lang; +} \ No newline at end of file diff --git a/src/types/index.ts b/src/types/index.ts index cded4ce..0780071 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,163 +1,10 @@ /** - * 集中管理项目中的类型定义 - * 这个文件包含了项目中常用的接口和类型定义,减少代码冗余和提高可维护性 + * Types index module + * Re-exports all type modules to maintain backward compatibility */ -import { languages } from '@/i18n/ui'; - -/** - * 语言类型定义 - */ -export type Lang = keyof typeof languages; - -/** - * 国际化文本键类型 - */ -export type UiKeys = string; - -/** - * 多语言文本类型 - */ -export type LocalizedText = { - [K in Lang]: string; -}; - -/** - * 作者信息接口 - */ -export interface Author { - name: string; - bio?: string; - avatar?: string; - website?: string; - twitter?: string; - github?: string; - linkedin?: string; -} - -/** - * 博客文章接口 - */ -export interface BlogPost { - title: string; - description: string; - image: string; - slug: string; - tags: string[]; - tagId?: string[]; - category?: string[]; - categoryId?: string[]; - date: string; - readTime: string; - url?: string; -} - -/** - * 博客文章前置元数据接口 - */ -export interface FrontmatterProps { - title: string; - description?: string; - publishDate?: string; - date?: string; // Alternative field name for publish date - author?: string; - tags?: string[]; - tagId?: string[]; // 标签唯一标识符,用于多语言环境下的标签路由 - category?: string | string[]; - categoryId?: string[] | string; // 分类唯一标识符,用于多语言环境下的分类路由 - readingTime?: number; - readTime?: string; // Alternative field name for reading time -} - -/** - * 技能项接口 - */ -export interface SkillItem { - name: string; - icon: string; // skillicons icon name -} - -/** - * 个人信息接口 - */ -export interface PersonalInfo { - name: string; - location: string; - avatar: string; - email: string; - github: string; - linkedin: string; - website: string; - twitter: string; - position: LocalizedText; - description: LocalizedText; - about: { - [K in Lang]: string[]; - }; - stats: { - repositories: number; - commits: string; - contributions: number; - }; - skills: { - frontend: string[]; - backend: string[]; - database: string[]; - devops: string[]; - mobile: string[]; - }; - terminal: { - username: string; - }; -} - -/** - * 组件 Props 接口 - */ - -/** - * 作者卡片组件 Props - */ -export interface AuthorCardProps { - lang: Lang; - author?: Author; -} - -/** - * 分享按钮组件 Props - */ -export interface ShareButtonsProps { - lang: Lang; - title: string; - url?: string; -} - -/** - * 页脚组件 Props - */ -export interface FooterProps { - lang?: Lang; -} - -/** - * 玻璃标题组件 Props - */ -export interface GlassHeaderProps { - lang: Lang; -} - -/** - * 博客列表组件 Props - */ -export interface BlogListProps { - posts: BlogPost[]; - lang: Lang; - baseUrl?: string; // Base URL for blog posts, defaults to '/blog/posts/' -} - -/** - * 语言切换器组件 Props - */ -export interface LanguageSwitcherProps { - lang: Lang; -} \ No newline at end of file +// Re-export all type modules +export * from './data'; +export * from './i18n'; +export * from './blog'; +export * from './components'; \ No newline at end of file