perf: delete editor save button

This commit is contained in:
JOYCEQL
2024-11-22 15:23:28 +08:00
parent 7f3b628451
commit 48b2746240
4 changed files with 80 additions and 144 deletions
@@ -26,7 +26,7 @@ import {
interface EducationEditorProps {
education: Education;
onSave: (educaton: Education) => void;
onSave: (education: Education) => void;
onDelete: () => void;
onCancel: () => void;
}
@@ -40,41 +40,28 @@ const EducationEditor: React.FC<EducationEditorProps> = ({
education,
onSave
}) => {
const theme = useResumeStore((state) => state.theme);
const [data, setData] = useState<Education>(education);
const handleSave = (e: React.FormEvent) => {
e.preventDefault();
if (
!data.school ||
!data.major ||
!data.degree ||
!data.startDate ||
!data.endDate
)
return;
onSave(data);
const handleChange = (field: keyof Education, value: string) => {
onSave({
...education,
[field]: value
});
};
return (
<form onSubmit={handleSave} className="space-y-5">
<div className="space-y-5">
<div className="grid gap-5">
<div className="grid grid-cols-2 gap-4">
<Field
label="学校名称"
value={data.school}
onChange={(value) =>
setData((prev) => ({ ...prev, school: value }))
}
value={education.school}
onChange={(value) => handleChange("school", value)}
placeholder="学校名称"
required
/>
<Field
label="所在地"
value={data.location || ""}
onChange={(value) =>
setData((prev) => ({ ...prev, location: value }))
}
value={education.location || ""}
onChange={(value) => handleChange("location", value)}
placeholder="城市"
/>
</div>
@@ -82,40 +69,33 @@ const EducationEditor: React.FC<EducationEditorProps> = ({
<div className="grid grid-cols-2 gap-4">
<Field
label="专业"
value={data.major}
onChange={(value) => setData((prev) => ({ ...prev, major: value }))}
value={education.major}
onChange={(value) => handleChange("major", value)}
placeholder="专业名称"
required
/>
<Field
label="学历"
value={data.degree}
onChange={(value) =>
setData((prev) => ({ ...prev, degree: value }))
}
value={education.degree}
onChange={(value) => handleChange("degree", value)}
placeholder="学历"
required
/>
</div>
{/* 时间和GPA */}
<div className="grid grid-cols-2 gap-4">
<Field
label="开始时间"
value={data.startDate}
onChange={(value) =>
setData((prev) => ({ ...prev, startDate: value }))
}
value={education.startDate}
onChange={(value) => handleChange("startDate", value)}
type="date"
placeholder="YYYY-MM"
required
/>
<Field
label="结束时间"
value={data.endDate}
onChange={(value) =>
setData((prev) => ({ ...prev, endDate: value }))
}
value={education.endDate}
onChange={(value) => handleChange("endDate", value)}
type="date"
placeholder="YYYY-MM"
required
@@ -124,37 +104,20 @@ const EducationEditor: React.FC<EducationEditorProps> = ({
<Field
label="GPA"
value={data.gpa || ""}
onChange={(value) => setData((prev) => ({ ...prev, gpa: value }))}
value={education.gpa || ""}
onChange={(value) => handleChange("gpa", value)}
placeholder="选填"
/>
{/* 在校经历描述 */}
<Field
label="在校经历"
value={data.description}
onChange={(value) =>
setData((prev) => ({ ...prev, description: value }))
}
value={education.description}
onChange={(value) => handleChange("description", value)}
type="editor"
placeholder="描述你的在校表现、获奖经历等..."
/>
</div>
<div className="flex justify-end gap-2 pt-2">
<Button
type="submit"
size="sm"
className={cn(
theme === "dark"
? "bg-indigo-600 hover:bg-indigo-700 text-white"
: "bg-black hover:bg-neutral-800 text-white"
)}
>
</Button>
</div>
</form>
</div>
);
};
@@ -271,7 +234,6 @@ const EducationItem = ({ education }: { education: Education }) => {
"dark:hover:border-indigo-600"
)}
>
{/* 拖拽手柄区域 */}
<div
onPointerDown={(event) => {
if (expandedId === education.id) return;
@@ -295,7 +257,6 @@ const EducationItem = ({ education }: { education: Education }) => {
/>
</div>
{/* 内容区域 */}
<div className="flex-1 min-w-0">
<div
className={cn(
@@ -407,10 +368,7 @@ const EducationItem = ({ education }: { education: Education }) => {
/>
<EducationEditor
education={education}
onSave={(updatedEducation) => {
updateEducation(updatedEducation);
setExpandedId(null);
}}
onSave={updateEducation}
onDelete={() => {
deleteEducation(education.id);
setExpandedId(null);
@@ -114,67 +114,48 @@ const ProjectEditor: React.FC<ProjectEditorProps> = ({
experience,
onSave
}) => {
const theme = useResumeStore((state) => state.theme);
const [data, setData] = useState<Experience>(experience);
const handleSave = (e: React.FormEvent) => {
e.preventDefault();
if (!data.company || !data.position || !data.date) return;
onSave(data);
const handleChange = (field: keyof Experience, value: string) => {
onSave({
...experience,
[field]: value
});
};
return (
<form onSubmit={handleSave} className="space-y-5">
<div className="space-y-5">
<div className="grid gap-5">
<div className="grid grid-cols-2 gap-4">
<Field
label="公司名称"
value={data.company}
onChange={(value) =>
setData((prev) => ({ ...prev, company: value }))
}
value={experience.company}
onChange={(value) => handleChange("company", value)}
placeholder="项目名称"
required
/>
<Field
label="岗位"
value={data.position}
onChange={(value) =>
setData((prev) => ({ ...prev, position: value }))
}
value={experience.position}
onChange={(value) => handleChange("position", value)}
placeholder="如:前端工程师"
required
/>
</div>
<Field
label="开始时间-结束时间"
value={data.date}
onChange={(value) => setData((prev) => ({ ...prev, date: value }))}
value={experience.date}
onChange={(value) => handleChange("date", value)}
placeholder="如:2023.01 - 2023.06"
required
/>
<Field
label="主要职责"
value={data.details}
onChange={(value) => setData((prev) => ({ ...prev, details: value }))}
value={experience.details}
onChange={(value) => handleChange("details", value)}
type="editor"
placeholder="简要描述项目的背景和目标..."
/>
</div>
<div className="flex justify-end gap-2 pt-2">
<Button
type="submit"
size="sm"
className={cn(
theme === "dark"
? "bg-indigo-600 hover:bg-indigo-700 text-white"
: "bg-black hover:bg-neutral-800 text-white"
)}
>
</Button>
</div>
</form>
</div>
);
};
@@ -219,7 +200,6 @@ const ExperienceItem = ({ experience }: { experience: Experience }) => {
"dark:hover:border-indigo-600"
)}
>
{/* 拖拽手柄区域 */}
<div
onPointerDown={(event) => {
if (expandedId === experience.id) return;
@@ -250,7 +230,6 @@ const ExperienceItem = ({ experience }: { experience: Experience }) => {
/>
</div>
{/* 内容区域 */}
<div className="flex-1 min-w-0">
<div
className={cn(
@@ -346,10 +325,7 @@ const ExperienceItem = ({ experience }: { experience: Experience }) => {
/>
<ProjectEditor
experience={experience}
onSave={(updatedData) => {
updateExperience(updatedData);
setExpandedId(null);
}}
onSave={updateExperience}
onDelete={() => {
deleteExperience(experience.id);
setExpandedId(null);
@@ -122,65 +122,69 @@ const DeleteConfirmDialog: React.FC<DeleteConfirmDialogProps> = ({
};
const ProjectEditor: React.FC<ProjectEditorProps> = ({ project, onSave }) => {
const theme = useResumeStore((state) => state.theme);
const [data, setData] = useState<Project>(project);
const handleSave = (e: React.FormEvent) => {
e.preventDefault();
if (!data.name || !data.role || !data.date) return;
onSave(data);
const handleChange = (field: keyof Project, value: string) => {
onSave({
...project,
[field]: value
});
};
return (
<form onSubmit={handleSave} className="space-y-5">
<div className="space-y-5">
<div className="grid gap-5">
<div className="grid grid-cols-2 gap-4">
<Field
label="项目名称"
value={data.name}
onChange={(value) => setData((prev) => ({ ...prev, name: value }))}
value={project.name}
onChange={(value) => handleChange("name", value)}
placeholder="项目名称"
required
/>
<Field
label="担任角色"
value={data.role}
onChange={(value) => setData((prev) => ({ ...prev, role: value }))}
value={project.role}
onChange={(value) => handleChange("role", value)}
placeholder="如:前端负责人"
required
/>
</div>
<Field
label="项目时间"
value={data.date}
onChange={(value) => setData((prev) => ({ ...prev, date: value }))}
value={project.date}
onChange={(value) => handleChange("date", value)}
placeholder="如:2023.01 - 2023.06"
required
/>
<Field
label="项目描述"
value={data.description}
onChange={(value) =>
setData((prev) => ({ ...prev, description: value }))
}
value={project.description}
onChange={(value) => handleChange("description", value)}
type="editor"
placeholder="简要描述项目的背景和目标..."
/>
<Field
label="技术栈"
value={project.technologies}
onChange={(value) => handleChange("technologies", value)}
type="editor"
placeholder="使用的技术栈和工具..."
/>
<Field
label="主要职责"
value={project.responsibilities}
onChange={(value) => handleChange("responsibilities", value)}
type="editor"
placeholder="在项目中的主要职责..."
/>
<Field
label="项目成果"
value={project.achievements}
onChange={(value) => handleChange("achievements", value)}
type="editor"
placeholder="项目取得的成果..."
/>
</div>
<div className="flex justify-end gap-2 pt-2">
<Button
type="submit"
size="sm"
className={cn(
theme === "dark"
? "bg-indigo-600 hover:bg-indigo-700 text-white"
: "bg-black hover:bg-neutral-800 text-white"
)}
>
</Button>
</div>
</form>
</div>
);
};
@@ -353,7 +357,6 @@ const ProjectItem = ({ project }: { project: Project }) => {
project={project}
onSave={(updatedProject) => {
updateProjects(updatedProject);
setExpandedId(null);
}}
onDelete={() => {
deleteProject(project.id);
@@ -62,15 +62,14 @@ export function ExperienceSection({
{exp.date}
</span>
</div>
<p
<div
className="text-gray-600"
style={{
fontSize: `${globalSettings?.baseFontSize || 14}px`,
lineHeight: globalSettings?.lineHeight || 1.6
}}
>
{exp.details}
</p>
dangerouslySetInnerHTML={{ __html: exp.details }}
/>
</div>
)
)}