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 = {
|
||||
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();
|
||||
@@ -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;
|
||||
|
||||
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 = {
|
||||
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
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';
|
||||
|
||||
/**
|
||||
* 语言类型定义
|
||||
*/
|
||||
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';
|
||||
Reference in New Issue
Block a user