diff --git a/src/config/initialResumeData.ts b/src/config/initialResumeData.ts
index 2dc5670..75c2a5f 100644
--- a/src/config/initialResumeData.ts
+++ b/src/config/initialResumeData.ts
@@ -167,3 +167,162 @@ export const initialResumeState = {
activeSection: "basic",
globalSettings: initialGlobalSettings,
};
+
+export const initialResumeStateEn = {
+ title: "New Resume",
+ basic: {
+ name: "John Smith",
+ title: "Senior Frontend Engineer",
+ employementStatus: "Available",
+ email: "john.smith@123.com",
+ phone: "555-123-4567",
+ location: "San Francisco, CA",
+ birthDate: "",
+ fieldOrder: DEFAULT_FIELD_ORDER,
+ icons: {
+ email: "Mail",
+ phone: "Phone",
+ birthDate: "CalendarRange",
+ employementStatus: "Briefcase",
+ location: "MapPin",
+ },
+ photoConfig: DEFAULT_CONFIG,
+ customFields: [],
+ photo: "/avatar.png",
+ githubKey: "",
+ githubUseName: "",
+ githubContributionsVisible: false,
+ },
+ education: [
+ {
+ id: "1",
+ school: "Stanford University",
+ major: "Computer Science",
+ degree: "",
+ startDate: "2013-09",
+ endDate: "2017-06",
+ visible: true,
+ gpa: "",
+ description: `
+ - Core courses: Data Structures, Algorithms, Operating Systems, Computer Networks, Web Development
+ - Top 5% of class, received Dean's List honors for three consecutive years
+ - Served as Technical Director of the Computer Science Association, organized multiple tech workshops
+ - Contributed to open-source projects, earned GitHub Campus Expert certification
+
`,
+ },
+ ],
+ skillContent: `
+
+ - Frontend Frameworks: React, Vue.js, Next.js, Nuxt.js and other SSR frameworks
+ - Languages: TypeScript, JavaScript(ES6+), HTML5, CSS3
+ - UI/Styling: TailwindCSS, Sass/Less, CSS Modules, Styled-components
+ - State Management: Redux, Vuex, Zustand, Jotai, React Query
+ - Build Tools: Webpack, Vite, Rollup, Babel, ESLint
+ - Testing: Jest, React Testing Library, Cypress
+ - Performance: Browser rendering principles, performance metrics monitoring, code splitting, lazy loading
+ - Version Control: Git, SVN
+ - Technical Leadership: Team management experience, led technology selection and architecture design for large projects
+
+
`,
+ experience: [
+ {
+ id: "1",
+ company: "ByteDance",
+ position: "Senior Frontend Engineer",
+ date: "2021/7 - Present",
+ visible: true,
+ details: `
+ - Responsible for development and maintenance of TikTok Creator Platform, leading technical solution design for core features
+ - Optimized build configuration, reducing build time from 8 minutes to 2 minutes, improving team development efficiency
+ - Designed and implemented component library, increasing code reuse by 70%, significantly reducing development time
+ - Led performance optimization project, reducing platform first-screen loading time by 50%, integrated APM monitoring system
+ - Mentored junior engineers, organized technical sharing sessions to improve overall team technical capabilities
+
`,
+ },
+ ],
+ draggingProjectId: null,
+ projects: [
+ {
+ id: "p1",
+ name: "TikTok Creator Platform",
+ role: "Frontend Lead",
+ date: "2022/6 - 2023/12",
+ description: `
+ - React-based analytics and content management platform serving millions of creators
+ - Includes data analytics, content management, and revenue management subsystems
+ - Implemented Redux for state management, enabling efficient handling of complex data flows
+ - Used Ant Design component library to ensure UI consistency and user experience
+ - Implemented code splitting and lazy loading strategies to optimize loading performance
+
`,
+ visible: true,
+ },
+ {
+ id: "p2",
+ name: "WeChat Mini Program Developer Tools",
+ role: "Core Developer",
+ date: "2020/3 - 2021/6",
+ description: `
+ - All-in-one solution for mini program development, debugging, and publishing
+ - Cross-platform desktop application built with Electron
+ - Supports multiple platforms including Windows, macOS, and Linux
+ - Provides real-time error logging and performance analysis tools
+ - Integrates third-party plugins and SDKs for custom functionality
+
`,
+ visible: true,
+ },
+ {
+ id: "p3",
+ name: "Frontend Monitoring Platform",
+ role: "Technical Lead",
+ date: "9/2021 - 5/2022",
+ description: `
+ - Complete frontend monitoring solution including error tracking, performance monitoring, and user behavior analysis
+ - Built with Vue and Element UI, providing real-time monitoring data and visualization tools
+ - Supports various monitoring metrics including error logs, performance indicators, and user behavior analysis
+ - Provides detailed error logs and performance analysis tools to help developers identify and optimize issues
+ - Integrates third-party plugins and SDKs for custom functionality
+
`,
+ visible: true,
+ },
+ ],
+ menuSections: [
+ {
+ id: "basic",
+ title: "Profile",
+ icon: "👤",
+ enabled: true,
+ order: 0,
+ },
+ {
+ id: "skills",
+ title: "Skills",
+ icon: "⚡",
+ enabled: true,
+ order: 1,
+ },
+ {
+ id: "experience",
+ title: "Experience",
+ icon: "💼",
+ enabled: true,
+ order: 2,
+ },
+ {
+ id: "projects",
+ title: "Experience",
+ icon: "🚀",
+ enabled: true,
+ order: 3,
+ },
+ {
+ id: "education",
+ title: "Education",
+ icon: "🎓",
+ enabled: true,
+ order: 4,
+ },
+ ],
+ customData: {},
+ activeSection: "basic",
+ globalSettings: initialGlobalSettings,
+};
diff --git a/src/store/useResumeStore.ts b/src/store/useResumeStore.ts
index 82916fd..cd04e6d 100644
--- a/src/store/useResumeStore.ts
+++ b/src/store/useResumeStore.ts
@@ -9,11 +9,15 @@ import {
Project,
CustomItem,
ResumeData,
- MenuSection
+ MenuSection,
} from "../types/resume";
import { DEFAULT_TEMPLATES } from "@/config";
-import { initialResumeState } from "@/config/initialResumeData";
+import {
+ initialResumeState,
+ initialResumeStateEn,
+} from "@/config/initialResumeData";
import { generateUUID } from "@/utils/uuid";
+import { getLocale } from "next-intl/server";
interface ResumeStore {
resumes: Record;
activeResumeId: string | null;
@@ -93,7 +97,7 @@ const syncResumeToFile = async (
const fileName = `${resumeData.title}.json`;
const fileHandle = await dirHandle.getFileHandle(fileName, {
- create: true
+ create: true,
});
const writable = await fileHandle.createWritable();
await writable.write(JSON.stringify(resumeData, null, 2));
@@ -111,27 +115,37 @@ export const useResumeStore = create(
activeResume: null,
createResume: (templateId = null) => {
+ // 判断当前语言环境
+ const locale =
+ typeof window !== "undefined"
+ ? window.navigator.language.split("-")[0]
+ : "en";
+ console.log("locale", locale);
+
+ const initialResumeData =
+ locale === "en" ? initialResumeStateEn : initialResumeState;
+
const id = generateUUID();
const template = templateId
? DEFAULT_TEMPLATES.find((t) => t.id === templateId)
: DEFAULT_TEMPLATES[0];
const newResume: ResumeData = {
- ...initialResumeState,
+ ...initialResumeData,
id,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
templateId: template?.id,
- title: `新建简历 ${id.slice(0, 6)}`
+ title: `新建简历 ${id.slice(0, 6)}`,
};
set((state) => ({
resumes: {
...state.resumes,
- [id]: newResume
+ [id]: newResume,
},
activeResumeId: id,
- activeResume: newResume
+ activeResume: newResume,
}));
syncResumeToFile(newResume);
@@ -146,7 +160,7 @@ export const useResumeStore = create(
const updatedResume = {
...resume,
- ...data
+ ...data,
};
syncResumeToFile(updatedResume, resume);
@@ -154,12 +168,12 @@ export const useResumeStore = create(
return {
resumes: {
...state.resumes,
- [resumeId]: updatedResume
+ [resumeId]: updatedResume,
},
activeResume:
state.activeResumeId === resumeId
? updatedResume
- : state.activeResume
+ : state.activeResume,
};
});
},
@@ -169,8 +183,8 @@ export const useResumeStore = create(
set((state) => ({
resumes: {
...state.resumes,
- [resume.id]: resume
- }
+ [resume.id]: resume,
+ },
}));
},
@@ -188,7 +202,7 @@ export const useResumeStore = create(
return {
resumes: rest,
activeResumeId: null,
- activeResume: null
+ activeResume: null,
};
});
@@ -218,7 +232,7 @@ export const useResumeStore = create(
id: newId,
title: `${originalResume.title} (复制)`,
createdAt: new Date().toISOString(),
- updatedAt: new Date().toISOString()
+ updatedAt: new Date().toISOString(),
};
get().updateResume(newId, duplicatedResume);
get().setActiveResume(newId);
@@ -239,16 +253,16 @@ export const useResumeStore = create(
...state.activeResume,
basic: {
...state.activeResume.basic,
- ...data
- }
+ ...data,
+ },
};
const newState = {
resumes: {
...state.resumes,
- [state.activeResume.id]: updatedResume
+ [state.activeResume.id]: updatedResume,
},
- activeResume: updatedResume
+ activeResume: updatedResume,
};
syncResumeToFile(updatedResume, state.activeResume);
@@ -380,13 +394,13 @@ export const useResumeStore = create(
);
const reorderedSections = [
basicInfoSection,
- ...newOrder.filter((section) => section.id !== "basic")
+ ...newOrder.filter((section) => section.id !== "basic"),
].map((section, index) => ({
...section,
- order: index
+ order: index,
}));
get().updateResume(activeResumeId, {
- menuSections: reorderedSections as MenuSection[]
+ menuSections: reorderedSections as MenuSection[],
});
}
},
@@ -431,9 +445,9 @@ export const useResumeStore = create(
subtitle: "",
dateRange: "",
description: "",
- visible: true
- }
- ]
+ visible: true,
+ },
+ ],
};
get().updateResume(activeResumeId, { customData: updatedCustomData });
}
@@ -445,7 +459,7 @@ export const useResumeStore = create(
const currentResume = get().resumes[activeResumeId];
const updatedCustomData = {
...currentResume.customData,
- [sectionId]: items
+ [sectionId]: items,
};
get().updateResume(activeResumeId, { customData: updatedCustomData });
}
@@ -474,9 +488,9 @@ export const useResumeStore = create(
subtitle: "",
dateRange: "",
description: "",
- visible: true
- }
- ]
+ visible: true,
+ },
+ ],
};
get().updateResume(activeResumeId, { customData: updatedCustomData });
}
@@ -490,7 +504,7 @@ export const useResumeStore = create(
...currentResume.customData,
[sectionId]: currentResume.customData[sectionId].map((item) =>
item.id === itemId ? { ...item, ...updates } : item
- )
+ ),
};
get().updateResume(activeResumeId, { customData: updatedCustomData });
}
@@ -504,7 +518,7 @@ export const useResumeStore = create(
...currentResume.customData,
[sectionId]: currentResume.customData[sectionId].filter(
(item) => item.id !== itemId
- )
+ ),
};
get().updateResume(activeResumeId, { customData: updatedCustomData });
}
@@ -516,8 +530,8 @@ export const useResumeStore = create(
updateResume(activeResumeId, {
globalSettings: {
...activeResume?.globalSettings,
- ...settings
- }
+ ...settings,
+ },
});
}
},
@@ -528,8 +542,8 @@ export const useResumeStore = create(
updateResume(activeResumeId, {
globalSettings: {
...get().activeResume?.globalSettings,
- themeColor: color
- }
+ themeColor: color,
+ },
});
}
},
@@ -549,37 +563,37 @@ export const useResumeStore = create(
themeColor: template.colorScheme.primary,
sectionSpacing: template.spacing.sectionGap,
paragraphSpacing: template.spacing.itemGap,
- pagePadding: template.spacing.contentPadding
+ pagePadding: template.spacing.contentPadding,
},
basic: {
...resumes[activeResumeId].basic,
- layout: template.basic.layout
- }
+ layout: template.basic.layout,
+ },
};
set({
resumes: {
...resumes,
- [activeResumeId]: updatedResume
+ [activeResumeId]: updatedResume,
},
- activeResume: updatedResume
+ activeResume: updatedResume,
});
},
addResume: (resume: ResumeData) => {
set((state) => ({
resumes: {
...state.resumes,
- [resume.id]: resume
+ [resume.id]: resume,
},
- activeResumeId: resume.id
+ activeResumeId: resume.id,
}));
syncResumeToFile(resume);
return resume.id;
- }
+ },
}),
{
- name: "resume-storage"
+ name: "resume-storage",
}
)
);