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
This commit is contained in:
joyzhao
2025-06-21 09:18:39 +08:00
parent e38ec6b12f
commit ea01dc6dd8
14 changed files with 784 additions and 523 deletions

143
src/i18n/translations.ts Normal file
View File

@@ -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<string, Record<string, string>> = {};
// 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();

View File

@@ -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<string, any> = {};
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;
// Export the compatible UI object
export const ui = createCompatibleUi();

View File

@@ -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;

View File

@@ -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: `<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>`,
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: `<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>`,
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: `<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>`,
gradient: "from-blue-500 to-cyan-500",
},
items: [
"为海外客户提供外包项目服务",
"项目打包,可以提供不同套餐的服务",
"使用流行技术React、nest.js、next.js 等",
"项目交付,提供三个月免费维护",
"不论项目大小,都可以提供服务",
],
color: "blue",
},
{
title: "Bug 修复",
icon: {
svg: `<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>`,
gradient: "from-red-500 to-pink-500",
},
items: [
"快速定位和修复网站问题,能够快速定位和解决问题",
"帮助您解决项目中遇到的任何问题Bug、功能优化问题",
"Vue、React、Node 等技术的应用",
"前端自动化、部署、监控、自动化等",
"仅限于 Node.js 项目",
],
color: "red",
},
],
};
// 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: [...]
// };

9
src/lib/data/index.ts Normal file
View File

@@ -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';

View File

@@ -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"
}
};

136
src/lib/data/projects.ts Normal file
View File

@@ -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: "#",
},
],
};

76
src/lib/data/services.ts Normal file
View File

@@ -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: `<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>`,
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: `<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>`,
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: `<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>`,
gradient: "from-blue-500 to-cyan-500",
},
items: [
"为海外客户提供外包项目服务",
"项目打包,可以提供不同套餐的服务",
"使用流行技术React、nest.js、next.js 等",
"项目交付,提供三个月免费维护",
"不论项目大小,都可以提供服务",
],
color: "blue",
},
{
title: "Bug 修复",
icon: {
svg: `<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>`,
gradient: "from-red-500 to-pink-500",
},
items: [
"快速定位和修复网站问题,能够快速定位和解决问题",
"帮助您解决项目中遇到的任何问题Bug、功能优化问题",
"Vue、React、Node 等技术的应用",
"前端自动化、部署、监控、自动化等",
"仅限于 Node.js 项目",
],
color: "red",
},
],
};

7
src/lib/index.ts Normal file
View File

@@ -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';

78
src/types/blog.ts Normal file
View File

@@ -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/'
}

22
src/types/components.ts Normal file
View File

@@ -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[];
}

88
src/types/data.ts Normal file
View File

@@ -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;
}

36
src/types/i18n.ts Normal file
View File

@@ -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;
}

View File

@@ -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;
}
// Re-export all type modules
export * from './data';
export * from './i18n';
export * from './blog';
export * from './components';