From 6ae4b1bf9a6a340b2febc1939f6c9fd353878bdc Mon Sep 17 00:00:00 2001 From: siyue Date: Wed, 30 Oct 2024 22:20:55 +0800 Subject: [PATCH] feat: basic custom fields --- .../src/components/editor/EditPanel.tsx | 56 +----- .../src/components/editor/PreviewPanel.tsx | 3 +- .../src/components/editor/SidePanel.tsx | 2 +- .../components/editor/basic/BasicPanel.tsx | 159 ++++++++++++++++++ apps/fronted/src/store/useResumeStore.ts | 3 +- apps/fronted/src/types/resume.ts | 7 + 6 files changed, 173 insertions(+), 57 deletions(-) create mode 100644 apps/fronted/src/components/editor/basic/BasicPanel.tsx diff --git a/apps/fronted/src/components/editor/EditPanel.tsx b/apps/fronted/src/components/editor/EditPanel.tsx index 9a760d1..db49ac0 100644 --- a/apps/fronted/src/components/editor/EditPanel.tsx +++ b/apps/fronted/src/components/editor/EditPanel.tsx @@ -20,6 +20,7 @@ import { cn } from "@/lib/utils"; import { Button } from "@/components/ui/button"; import Field from "./Field"; import ProjectItem from "./project/ProjectItem"; +import BasicPanel from "./basic/BasicPanel"; interface Project { id: string; @@ -66,60 +67,7 @@ export function EditPanel() { const renderFields = () => { switch (activeSection) { case "basic": - return ( -
- updateBasicInfo({ name: value })} - placeholder="请输入你的姓名" - required - /> - updateBasicInfo({ title: value })} - placeholder="期望职位" - required - /> - updateBasicInfo({ birthDate: value })} - type="date" - /> -
- updateBasicInfo({ email: value })} - placeholder="your@email.com" - required - /> - updateBasicInfo({ phone: value })} - placeholder="手机号码" - required - /> -
- updateBasicInfo({ location: value })} - placeholder="城市" - required - /> - updateBasicInfo({ summary: value })} - type="textarea" - placeholder="简单介绍一下自己..." - /> -
- ); + return ; case "projects": return ( diff --git a/apps/fronted/src/components/editor/PreviewPanel.tsx b/apps/fronted/src/components/editor/PreviewPanel.tsx index 39735d4..60a4a2f 100644 --- a/apps/fronted/src/components/editor/PreviewPanel.tsx +++ b/apps/fronted/src/components/editor/PreviewPanel.tsx @@ -525,7 +525,8 @@ export function PreviewPanel() { basic.location, basic.birthDate ? new Date(basic.birthDate).toLocaleDateString() - : "" + : "", + ...(basic.customFields?.map((field) => field.value) || []) // 添加自定义字段的值 ] .filter(Boolean) .map((item, index, array) => ( diff --git a/apps/fronted/src/components/editor/SidePanel.tsx b/apps/fronted/src/components/editor/SidePanel.tsx index a8071ec..df6f3d8 100644 --- a/apps/fronted/src/components/editor/SidePanel.tsx +++ b/apps/fronted/src/components/editor/SidePanel.tsx @@ -133,7 +133,7 @@ export function SidePanel() {
diff --git a/apps/fronted/src/components/editor/basic/BasicPanel.tsx b/apps/fronted/src/components/editor/basic/BasicPanel.tsx new file mode 100644 index 0000000..2d45e79 --- /dev/null +++ b/apps/fronted/src/components/editor/basic/BasicPanel.tsx @@ -0,0 +1,159 @@ +import React, { useState } from "react"; +import { PlusCircle, X } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import Field from "../Field"; +import { useResumeStore } from "@/store/useResumeStore"; +import { Input } from "@/components/ui/input"; +import { platform } from "os"; +import { cn } from "@/lib/utils"; + +const BasicPanel = () => { + const { basic, updateBasicInfo, theme } = useResumeStore(); + const [fields, setFields] = useState(basic.customFields); + const [newLabel, setNewLabel] = useState(""); + const [newValue, setNewValue] = useState(""); + + const addCustomField = () => { + const newField = { + id: crypto.randomUUID(), + label: newLabel, + value: newValue, + required: false, + placeholder: "" + }; + setFields([...fields, newField]); + updateBasicInfo({ + ...basic, + customFields: [...fields, newField] + }); + }; + + const updateField = (id: string, updates: { value: string }) => { + setFields( + fields.map((field) => + field.id === id ? { ...field, ...updates } : field + ) + ); + updateBasicInfo({ customFields: fields }); + }; + + const deleteField = (id) => { + setFields(fields.filter((field) => field.id !== id)); + updateBasicInfo({ + customFields: fields.filter((field) => field.id !== id) + }); + }; + + return ( +
+ updateBasicInfo({ name: value })} + placeholder="请输入你的姓名" + required + /> + updateBasicInfo({ title: value })} + placeholder="期望职位" + required + /> + updateBasicInfo({ birthDate: value })} + type="date" + /> +
+ updateBasicInfo({ email: value })} + placeholder="your@email.com" + required + /> + updateBasicInfo({ phone: value })} + placeholder="手机号码" + required + /> +
+ updateBasicInfo({ location: value })} + placeholder="城市" + required + /> + updateBasicInfo({ summary: value })} + type="textarea" + placeholder="简单介绍一下自己..." + /> + + {/* 自定义字段 */} + {fields.map((field) => ( +
+ updateField(field.id, { value })} + placeholder={field.placeholder} + /> + +
+ ))} + + {/* 新字段输入区 */} +
+ setNewLabel(e.target.value)} + placeholder="字段名称" + className={cn( + "w-1/3", + theme === "dark" + ? "bg-neutral-900 border-neutral-700 text-neutral-200 placeholder:text-neutral-500" + : "bg-white border-gray-200 text-gray-900 placeholder:text-gray-500" + )} + /> + setNewValue(e.target.value)} + placeholder="字段值" + className={cn( + "w-1/3", + theme === "dark" + ? "bg-neutral-900 border-neutral-700 text-neutral-200 placeholder:text-neutral-500" + : "bg-white border-gray-200 text-gray-900 placeholder:text-gray-500" + )} + /> + +
+
+ ); +}; + +export default BasicPanel; diff --git a/apps/fronted/src/store/useResumeStore.ts b/apps/fronted/src/store/useResumeStore.ts index 2623cdf..9bed541 100644 --- a/apps/fronted/src/store/useResumeStore.ts +++ b/apps/fronted/src/store/useResumeStore.ts @@ -65,7 +65,8 @@ const initialState = { phone: "13800138000", location: "北京市", summary: "5年前端开发经验...", - birthDate: "1995-01-01" + birthDate: "1995-01-01", + customFields: [] }, education: [ { diff --git a/apps/fronted/src/types/resume.ts b/apps/fronted/src/types/resume.ts index 731f1e2..3715b7c 100644 --- a/apps/fronted/src/types/resume.ts +++ b/apps/fronted/src/types/resume.ts @@ -6,6 +6,13 @@ export interface BasicInfo { phone: string; location: string; summary: string; + customFields: Array<{ + id: string; + label: string; + value: string; + required: boolean; + placeholder: string; + }>; } export interface Education {