This commit is contained in:
ditiqi 2025-02-21 16:57:22 +08:00
parent 2769bac7f8
commit e93fbbcb53
7 changed files with 139 additions and 58 deletions

View File

@ -1,6 +1,5 @@
import MindEditor from "@web/src/components/common/editor/MindEditor";
// import MindElixir, { MindElixirInstance } from "mind-elixir";
import { useEffect, useRef } from "react";
export default function PathsPage() {
return <MindEditor></MindEditor>
return <MindEditor></MindEditor>;
}

View File

@ -3,24 +3,24 @@ import { useRef, useEffect } from "react";
import MindElixir from "mind-elixir";
export default function MindEditor() {
const me = useRef<MindElixirInstance>();
useEffect(() => {
const instance = new MindElixir({
el: "#map",
direction: MindElixir.SIDE,
draggable: true, // default true
contextMenu: true, // default true
toolBar: true, // default true
nodeMenu: true, // default true
keypress: true // default true
});
// instance.install(NodeMenu);
instance.init(MindElixir.new("新主题"));
me.current = instance;
}, []);
return <div >
<div id="map" style={{ width: "100%" }} />
</div>
const me = useRef<MindElixirInstance>();
useEffect(() => {
const instance = new MindElixir({
el: "#map",
direction: MindElixir.SIDE,
draggable: true, // default true
contextMenu: true, // default true
toolBar: true, // default true
nodeMenu: true, // default true
keypress: true, // default true
});
// instance.install(NodeMenu);
instance.init(MindElixir.new("新主题"));
me.current = instance;
}, []);
return (
<div>
<div id="map" style={{ width: "100%" }} />
</div>
);
}

View File

@ -70,21 +70,6 @@ export function FormArrayField({
{...inputProps}
placeholder={placeholder}
style={{ width: "100%" }}
// suffix={
// inputProps.maxLength && (
// <Typography.Text type="secondary">
// {inputProps.maxLength -
// (
// Form.useWatch(
// [
// name,
// field.name,
// ]
// ) || ""
// ).length}
// </Typography.Text>
// )
// }
onChange={(e) => {
// 更新 items 状态
const newItems = [...items];

View File

@ -0,0 +1,102 @@
import React, { useState } from "react";
import { Input, Button } from "antd";
import { DeleteOutlined } from "@ant-design/icons";
interface InputListProps {
initialValue?: string[];
onChange?: (value: string[]) => void;
placeholder?: string;
}
const InputList: React.FC<InputListProps> = ({
initialValue,
onChange,
placeholder = "请输入内容",
}) => {
// Internal state management with fallback to initial value or empty array
const [inputValues, setInputValues] = useState<string[]>(
initialValue && initialValue.length > 0 ? initialValue : [""]
);
// Handle individual input value change
const handleInputChange = (index: number, newValue: string) => {
const newValues = [...inputValues];
newValues[index] = newValue;
// Update internal state
setInputValues(newValues);
// Call external onChange if provided
onChange?.(newValues);
};
// Handle delete operation
const handleDelete = (index: number) => {
const newValues = inputValues.filter((_, i) => i !== index);
// Ensure at least one input remains
const finalValues = newValues.length === 0 ? [""] : newValues;
// Update internal state
setInputValues(finalValues);
// Call external onChange if provided
onChange?.(finalValues);
};
// Add new input field
const handleAdd = () => {
const newValues = [...inputValues, ""];
// Update internal state
setInputValues(newValues);
// Call external onChange if provided
onChange?.(newValues);
};
return (
<div className="space-y-2">
{inputValues.map((item, index) => (
<div key={index} className="flex items-center space-x-2 group">
<Input
value={item}
onChange={(e) =>
handleInputChange(index, e.target.value)
}
placeholder={placeholder}
className="flex-grow"
/>
{inputValues.length > 1 && (
<Button
type="text"
icon={<DeleteOutlined />}
danger
className="opacity-0 group-hover:opacity-100"
onClick={() => handleDelete(index)}
/>
)}
</div>
))}
<div className="flex items-center space-x-2 group">
<Button
type="dashed"
block
onClick={handleAdd}
className="w-full">
</Button>
{inputValues.length > 1 && (
<Button
type="text"
icon={<DeleteOutlined />}
danger
className="opacity-0"
/>
)}
</div>
</div>
);
};
export default InputList;

View File

@ -3,6 +3,7 @@ import { CourseLevel, CourseLevelLabel } from "@nice/common";
import { convertToOptions } from "@nice/client";
import TermSelect from "../../../term/term-select";
import { useCourseEditor } from "../context/CourseEditorContext";
import AvatarUploader from "@web/src/components/common/uploader/AvatarUploader";
const { TextArea } = Input;
@ -27,14 +28,12 @@ export function CourseBasicForm() {
]}>
<Input placeholder="请输入课程标题" />
</Form.Item>
<Form.Item
name="subTitle"
label="课程副标题"
rules={[{ max: 10, message: "副标题最多10个字符" }]}>
<Input placeholder="请输入课程副标题" />
</Form.Item>
<Form.Item name="content" label="课程描述">
<TextArea
placeholder="请输入课程描述"
@ -58,9 +57,6 @@ export function CourseBasicForm() {
taxonomyId={tax.id}></TermSelect>
</Form.Item>
))}
{/* <Form.Item name="level" label="">
<Select placeholder="请选择难度等级" options={levelOptions} />
</Form.Item> */}
</div>
);
}

View File

@ -16,9 +16,7 @@ import {
message,
} from "antd";
import React, { useCallback, useEffect, useState } from "react";
import {
useSortable,
} from "@dnd-kit/sortable";
import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { Lecture, LectureType, PostType } from "@nice/common";
import { usePost } from "@nice/client";
@ -101,7 +99,7 @@ export const SortableSection: React.FC<SortableSectionProps> = ({
<div ref={setNodeRef} style={style} className="mb-4">
<Collapse>
<Collapse.Panel
disabled={!field.id} // 添加此行以禁用未创建章节的展开
collapsible={!field.id ? "disabled" : undefined} // 添加此行以禁用未创建章节的展开
header={
editing ? (
<Form

View File

@ -1,20 +1,21 @@
import { FormArrayField } from "@web/src/components/common/form/FormArrayField";
import { useFormContext } from "react-hook-form";
import { CourseFormData } from "../context/CourseEditorContext";
import InputList from "@web/src/components/common/input/InputList";
import { useState } from "react";
import { Form } from "antd";
export function CourseGoalForm() {
// const { register, formState: { errors }, watch, handleSubmit } = useFormContext<CourseFormData>();
const [inputValues, setInputValues] = useState<string[]>([""]);
return (
<form className="max-w-2xl mx-auto space-y-6 p-6">
<FormArrayField
name="requirements"
label="前置要求"
placeholder="添加要求"></FormArrayField>
<FormArrayField
name="objectives"
label="学习目标"
placeholder="添加目标"></FormArrayField>
</form>
<div className="max-w-2xl mx-auto space-y-6 p-6">
<Form.Item name="requirements" label="前置要求">
<InputList placeholder="请输入前置要求"></InputList>
</Form.Item>
<Form.Item name="objectives" label="学习目标">
<InputList placeholder="请输入学习目标"></InputList>
</Form.Item>
</div>
);
}