fix: react component control problem

This commit is contained in:
JOYCEQL
2024-12-08 19:14:20 +08:00
committed by qingchen
parent 45df666a32
commit 0d7586bf80
6 changed files with 68 additions and 41 deletions
@@ -19,7 +19,9 @@ import {
export function EditPanel() {
const { activeResume, updateMenuSections } = useResumeStore();
const { activeSection, menuSections = [] } = activeResume || {};
if (!activeResume) return;
const { activeSection = "", menuSections = [] } = activeResume || {};
const renderFields = () => {
switch (activeSection) {
case "basic":
+5 -5
View File
@@ -6,7 +6,7 @@ import { motion } from "framer-motion";
import {
Popover,
PopoverContent,
PopoverTrigger
PopoverTrigger,
} from "@/components/ui/popover";
import { Calendar } from "@/components/ui/calendar";
import { Input } from "@/components/ui/input";
@@ -30,7 +30,7 @@ const Field: React.FC<FieldProps> = ({
type = "text",
placeholder,
required,
className
className,
}) => {
const renderLabel = () => (
<span
@@ -96,7 +96,7 @@ const Field: React.FC<FieldProps> = ({
{required && <span className="text-red-500">*</span>}
</span>
<motion.textarea
value={value}
value={value || ""}
onChange={(e) => onChange(e.target.value)}
placeholder={placeholder}
className={inputStyles}
@@ -114,7 +114,7 @@ const Field: React.FC<FieldProps> = ({
{renderLabel()}
<div className="mt-1.5">
<RichTextEditor
content={value}
content={value || ""}
onChange={onChange}
placeholder={placeholder}
/>
@@ -136,7 +136,7 @@ const Field: React.FC<FieldProps> = ({
</span>
<Input
type="text"
value={value}
value={value || ""}
onChange={(e) => onChange(e.target.value)}
placeholder={placeholder}
className={inputStyles}
@@ -62,30 +62,42 @@ const CustomField: React.FC<CustomFieldProps> = ({
onChange={(value) => onUpdate({ ...field, icon: value })}
/>
</div>
<Field
label=""
value={field.label}
onChange={(value) => onUpdate({ ...field, label: value })}
placeholder="字段名称"
className={cn(
"bg-neutral-50 dark:bg-neutral-900",
"border-neutral-200 dark:border-neutral-700",
"focus:border-blue-500 dark:focus:border-blue-400",
"placeholder-neutral-400 dark:placeholder-neutral-500"
)}
/>
<Field
label=""
value={field.value}
onChange={(value) => onUpdate({ ...field, value })}
placeholder="字段内容"
className={cn(
"bg-neutral-50 dark:bg-neutral-900",
"border-neutral-200 dark:border-neutral-700",
"focus:border-blue-500 dark:focus:border-blue-400",
"placeholder-neutral-400 dark:placeholder-neutral-500"
)}
/>
<div className="col-span-2">
<Field
value={field.label ?? ""}
onChange={(value) =>
onUpdate({
...field,
label: value,
})
}
placeholder="标签"
className={cn(
"bg-neutral-50 dark:bg-neutral-900",
"border-neutral-200 dark:border-neutral-700",
"focus:border-blue-500 dark:focus:border-blue-400",
"placeholder-neutral-400 dark:placeholder-neutral-500"
)}
/>
</div>
<div className="col-span-2">
<Field
value={field.value ?? ""}
onChange={(value) =>
onUpdate({
...field,
value: value,
})
}
placeholder="值"
className={cn(
"bg-neutral-50 dark:bg-neutral-900",
"border-neutral-200 dark:border-neutral-700",
"focus:border-blue-500 dark:focus:border-blue-400",
"placeholder-neutral-400 dark:placeholder-neutral-500"
)}
/>
</div>
{field.visible ? (
<Eye
@@ -254,7 +266,7 @@ const BasicPanel: React.FC = () => {
<div className="flex-1">
<Field
label=""
value={(basic?.[field.key] as string) || ""}
value={(basic?.[field.key] as string) ?? ""}
onChange={(value) =>
updateBasicInfo({
...basic,
@@ -357,7 +357,7 @@ const HeadingSelect = ({ editor }) => {
);
};
const RichTextEditor = ({ content, onChange }: RichTextEditorProps) => {
const RichTextEditor = ({ content = "", onChange }: RichTextEditorProps) => {
const editor = useEditor({
extensions: [
StarterKit.configure({
+13 -2
View File
@@ -10,6 +10,7 @@ import {
Project,
CustomItem,
ResumeData,
MenuSection,
} from "../types/resume";
interface ResumeStore {
@@ -400,9 +401,19 @@ export const useResumeStore = create<ResumeStore>()(
},
reorderSections: (newOrder) => {
const { activeResumeId } = get();
const { activeResumeId, resumes } = get();
if (activeResumeId) {
get().updateResume(activeResumeId, { menuSections: newOrder });
const currentResume = resumes[activeResumeId];
const basicInfoSection = currentResume.menuSections.find(
(section) => section.id === "basic"
);
const reorderedSections = [
basicInfoSection,
...newOrder.filter((section) => section.id !== "basic"),
];
get().updateResume(activeResumeId, {
menuSections: reorderedSections as MenuSection[],
});
}
},
+9 -7
View File
@@ -163,6 +163,14 @@ export const THEME_COLORS = [
"#dc2626",
];
export interface MenuSection {
id: string;
title: string;
icon: string;
enabled: boolean;
order: number;
}
export interface ResumeData {
id: string;
title: string;
@@ -178,13 +186,7 @@ export interface ResumeData {
activeSection: string;
colorTheme: string;
draggingProjectId: string | null;
menuSections: {
id: string;
title: string;
icon: string;
enabled: boolean;
order: number;
}[];
menuSections: MenuSection[];
globalSettings: GlobalSettings;
}