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:
143
src/i18n/translations.ts
Normal file
143
src/i18n/translations.ts
Normal 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();
|
||||||
134
src/i18n/ui.ts
134
src/i18n/ui.ts
@@ -1,123 +1,30 @@
|
|||||||
// src/i18n/ui.ts
|
/**
|
||||||
export const languages = {
|
* UI internationalization module
|
||||||
en: 'English',
|
* This file is maintained for backward compatibility
|
||||||
zh: '简体中文',
|
* New code should import from translations.ts directly
|
||||||
} as const;
|
*/
|
||||||
|
|
||||||
export const defaultLang = 'en';
|
// Re-export from translations.ts
|
||||||
|
export { languages, defaultLang, translations as structuredUI } from './translations';
|
||||||
|
|
||||||
// 定义嵌套结构的国际化数据
|
// Import flattened translations for compatibility layer
|
||||||
const structuredUi = {
|
import { flatTranslations } from './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.',
|
|
||||||
},
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
// 创建代理对象,保持与现有代码的兼容性
|
/**
|
||||||
|
* Create a backward compatible UI object
|
||||||
|
* This maintains the old API for existing code
|
||||||
|
*/
|
||||||
function createCompatibleUi() {
|
function createCompatibleUi() {
|
||||||
// 为每种语言创建代理
|
|
||||||
const compatibleUi: Record<string, any> = {};
|
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({}, {
|
compatibleUi[lang] = new Proxy({}, {
|
||||||
get(target, prop) {
|
get(target, prop) {
|
||||||
if (typeof prop !== 'string') return undefined;
|
if (typeof prop !== 'string') return undefined;
|
||||||
|
|
||||||
// 处理点符号键 (如 'nav.home')
|
// Return the translation from flattened translations
|
||||||
const parts = prop.split('.');
|
return flatTranslations[lang][prop];
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -125,8 +32,5 @@ function createCompatibleUi() {
|
|||||||
return compatibleUi;
|
return compatibleUi;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导出兼容的UI对象
|
// Export the compatible UI object
|
||||||
export const ui = createCompatibleUi() as typeof structuredUi;
|
export const ui = createCompatibleUi();
|
||||||
|
|
||||||
// 导出结构化的UI对象,供将来使用
|
|
||||||
export const structuredUI = structuredUi;
|
|
||||||
@@ -1,25 +1,68 @@
|
|||||||
// src/i18n/utils.ts
|
/**
|
||||||
import { ui, defaultLang, languages } from './ui';
|
* Internationalization utilities module
|
||||||
import { type Lang, type UiKeys } from '@/types';
|
* Contains helper functions for i18n functionality
|
||||||
|
*/
|
||||||
// 重新导出类型,以保持向后兼容性
|
import { defaultLang, languages, flatTranslations } from './translations';
|
||||||
export type { Lang, UiKeys };
|
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) {
|
export function useTranslations(lang: Lang | undefined) {
|
||||||
const currentLang = lang || defaultLang;
|
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) {
|
if (args.length > 0) {
|
||||||
args.forEach((arg, index) => {
|
args.forEach((arg, index) => {
|
||||||
translation = translation.replace(`{${index}}`, arg);
|
translation = translation.replace(`{${index}}`, String(arg));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return translation;
|
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 {
|
export function getLocalizedPath(path: string, lang: Lang | undefined): string {
|
||||||
const currentLang = lang || defaultLang;
|
const currentLang = lang || defaultLang;
|
||||||
const basePath = import.meta.env.BASE_URL === '/' ? '' : import.meta.env.BASE_URL;
|
const basePath = import.meta.env.BASE_URL === '/' ? '' : import.meta.env.BASE_URL;
|
||||||
|
|||||||
293
src/lib/data.ts
293
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 = {
|
// Re-export all data from the new modules
|
||||||
name: "Joy Zhao",
|
export { personalInfo } from './data/personal-info';
|
||||||
location: "China",
|
export { projects } from './data/projects';
|
||||||
avatar: "https://avatars.githubusercontent.com/u/24975063?v=4",
|
export { services } from './data/services';
|
||||||
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"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const projects = {
|
// For TypeScript type checking
|
||||||
en: [
|
import { personalInfo } from './data/personal-info';
|
||||||
{
|
import { projects } from './data/projects';
|
||||||
id: "taskify",
|
import { services } from './data/services';
|
||||||
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 = {
|
// Type exports are now handled in src/types/index.ts
|
||||||
en: [
|
// This file is now just a re-export wrapper
|
||||||
{
|
// The actual data is in the respective files in src/lib/data/ directory
|
||||||
title: "Outsourcing Projects",
|
|
||||||
icon: {
|
// export const projects = {
|
||||||
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>`,
|
// en: [{
|
||||||
gradient: "from-blue-500 to-cyan-500",
|
// id: "taskify",
|
||||||
},
|
// tag: "business",
|
||||||
items: [
|
// title: "Taskify App",
|
||||||
"Provide outsourcing project services for overseas clients",
|
// icon: "📱",
|
||||||
"Project packaging, can provide services in different packages",
|
// color: "purple",
|
||||||
"Use popular technologies: React, nest.js, next.js, etc.",
|
// image: {
|
||||||
"Project delivery, provide three months of free maintenance",
|
// bg: "from-purple-500/20 to-purple-600/20",
|
||||||
"Regardless of project size, can provide services",
|
// hover: "from-purple-500/20 to-purple-600/20",
|
||||||
],
|
// text: "text-purple-400",
|
||||||
color: "blue",
|
// },
|
||||||
},
|
// description: [
|
||||||
{
|
// "A comprehensive task management application with drag-and-drop functionality.",
|
||||||
title: "Bug Fixes",
|
// "Built with React, TypeScript, and Tailwind CSS using modern development approaches.",
|
||||||
icon: {
|
// "Real-time collaboration through WebSocket integration for instant updates.",
|
||||||
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>`,
|
// "Advanced task filtering, sorting, and project management capabilities.",
|
||||||
gradient: "from-red-500 to-pink-500",
|
// ],
|
||||||
},
|
// tech: ["React", "Node.js", "MongoDB"],
|
||||||
items: [
|
// link: "#",
|
||||||
"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.",
|
// zh: [...]
|
||||||
"Only limited to Node.js projects",
|
// };
|
||||||
],
|
//
|
||||||
color: "red",
|
// export const services = {
|
||||||
},
|
// en: [
|
||||||
],
|
// {
|
||||||
zh: [
|
// title: "Outsourcing Projects",
|
||||||
{
|
// icon: {...},
|
||||||
title: "外包项目",
|
// items: [...],
|
||||||
icon: {
|
// color: "blue",
|
||||||
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: [
|
// zh: [...]
|
||||||
"为海外客户提供外包项目服务",
|
// };
|
||||||
"项目打包,可以提供不同套餐的服务",
|
|
||||||
"使用流行技术: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",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
9
src/lib/data/index.ts
Normal file
9
src/lib/data/index.ts
Normal 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';
|
||||||
55
src/lib/data/personal-info.ts
Normal file
55
src/lib/data/personal-info.ts
Normal 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
136
src/lib/data/projects.ts
Normal 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
76
src/lib/data/services.ts
Normal 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
7
src/lib/index.ts
Normal 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
78
src/types/blog.ts
Normal 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
22
src/types/components.ts
Normal 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
88
src/types/data.ts
Normal 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
36
src/types/i18n.ts
Normal 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;
|
||||||
|
}
|
||||||
@@ -1,163 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* 集中管理项目中的类型定义
|
* Types index module
|
||||||
* 这个文件包含了项目中常用的接口和类型定义,减少代码冗余和提高可维护性
|
* Re-exports all type modules to maintain backward compatibility
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { languages } from '@/i18n/ui';
|
// Re-export all type modules
|
||||||
|
export * from './data';
|
||||||
/**
|
export * from './i18n';
|
||||||
* 语言类型定义
|
export * from './blog';
|
||||||
*/
|
export * from './components';
|
||||||
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;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user