feat: create task form

This commit is contained in:
2025-04-23 16:09:41 +03:00
parent c1246939cd
commit b091e8d20d
2 changed files with 63 additions and 47 deletions

View File

@@ -18,7 +18,7 @@ import {
PencilIcon,
} from "@heroicons/react/24/outline";
import { FunctionComponent } from "preact";
import { useEffect, useMemo, useRef, useState } from "preact/hooks";
import { useEffect, useMemo, useState } from "preact/hooks";
import { Nullable } from "primereact/ts-helpers";
import { SubmitHandler, useForm } from "react-hook-form";
import { ITask, ITaskForm } from "./profile_tasks.dto";
@@ -58,9 +58,7 @@ const ProfileTasks: FunctionComponent = () => {
const [isEditModal, setIsEditModal] = useState(false); // Включено редактирование задачи
const [isCreating, setIsCreating] = useState(false); // Включено создание задачи
const [editContent, setEditContent] = useState<ITask | null>(null); // Содержимое редактируемой задачи
const taskNameRef = useRef<HTMLInputElement>(null);
const taskDescriptionRef = useRef<HTMLTextAreaElement>(null);
const [calendarDate, setCalendarDate] = useState<Nullable<Date>>();
const [calendarDate, setCalendarDate] = useState<Nullable<Date>>(); // Выбранная в календаре дата
const getDate = useMemo(() => {
const date = new Date();
const formatter = new Intl.DateTimeFormat("ru-RU", { month: "long", day: "numeric" });
@@ -81,17 +79,22 @@ const ProfileTasks: FunctionComponent = () => {
handleSubmit,
register,
reset,
setError,
formState: { errors },
} = useForm<ITaskForm>({
defaultValues: {
tags: [],
},
});
const saveEdited: SubmitHandler<ITaskForm> = (data) => {
if (!editContent) return;
const editedTask: ITask = { ...data, date: new Date(data.date) };
setTasks(tasks.map((task) => (task.id === editedTask.id ? editedTask : task)));
setIsEditModal(false);
const saveTask: SubmitHandler<ITaskForm> = (data) => {
if (!calendarDate) {
setError("date", { message: "Выберите дату" });
return;
}
const eTask: ITask = { ...data, date: calendarDate };
if (isCreating) setTasks([...tasks, eTask]);
else setTasks(tasks.map((task) => (task.id === eTask.id ? eTask : task)));
if (isCreating) setIsOpen(false);
};
useEffect(() => {
if (editContent) reset({ ...editContent, date: editContent.date.toISOString().slice(0, 16) });
@@ -100,6 +103,15 @@ const ProfileTasks: FunctionComponent = () => {
useEffect(() => {
if (calendarDate && editContent) setEditContent({ ...editContent, date: calendarDate });
}, [calendarDate]);
useEffect(() => {
reset({
name: "",
description: "",
date: "",
tags: ["Тег1", "Тег2"],
checked: false,
});
}, [isCreating]);
return (
<div class={classes.container}>
<ModalCalendar
@@ -123,7 +135,14 @@ const ProfileTasks: FunctionComponent = () => {
}}
>
{isEdit && editContent && (
<form class="flex h-full w-full flex-col items-start justify-between" onSubmit={(e) => e.preventDefault()}>
<form
class="flex h-full w-full flex-col items-start justify-between"
onSubmit={(e) => {
e.preventDefault();
if (isEditModal) handleSubmit(saveTask)();
else setIsEditModal(!isEditModal);
}}
>
<div class="flex w-full flex-row items-start justify-between">
<div class="flex flex-1 flex-col gap-1 pe-2">
<input
@@ -154,8 +173,10 @@ const ProfileTasks: FunctionComponent = () => {
<div
className="flex cursor-pointer flex-col items-center gap-3"
onClick={() => {
if (isEditModal) handleSubmit(saveEdited)();
else setIsEditModal(!isEditModal);
if (isEditModal) {
handleSubmit(saveTask)();
setIsEditModal(!isEditModal);
} else setIsEditModal(!isEditModal);
}}
>
{isEditModal ? (
@@ -210,16 +231,34 @@ const ProfileTasks: FunctionComponent = () => {
</form>
)}
{isCreating && (
<div class="flex h-full w-full flex-col items-start justify-between">
<form
class="flex h-full w-full flex-col items-start justify-between"
onSubmit={(e) => {
e.preventDefault();
handleSubmit((data) => saveTask({ ...data, id: tasks.length + 1 }))();
}}
>
<div class="flex w-full flex-row items-start justify-between">
<div class="me-4 flex flex-1 flex-col gap-1">
<input class="text-2xl outline-0" maxLength={20} placeholder="Название" ref={taskNameRef} />
<input
class="text-2xl outline-0"
maxLength={20}
placeholder="Название"
{...register("name", { required: "Заполните название" })}
/>
<textarea
class="h-[5rem] w-full resize-none outline-0"
maxLength={200}
placeholder="Описание"
ref={taskDescriptionRef}
maxLength={200}
{...register("description")}
/>
<input
type="datetime-local"
value={calendarDate ? calendarDate.toISOString().slice(0, 16) : ""}
hidden
{...register("date")}
/>
<input type="checkbox" checked={false} hidden {...register("checked")} />
</div>
<CalendarDaysIcon
class="size-10 cursor-pointer"
@@ -230,7 +269,9 @@ const ProfileTasks: FunctionComponent = () => {
/>
<BookmarkIcon class="ms-4 size-10 cursor-pointer" />
</div>
<div className="mb-8 flex h-16 flex-col items-center gap-6 self-center md:mb-0 md:flex-row">
{errors.name && <p class="text-red-500">{errors.name.message}</p>}
{errors.date && <p class="text-red-500">{errors.date.message}</p>}
<div className="mb-8 flex h-16 flex-col items-center gap-6 self-center md:mb-0 md:flex-row md:self-start">
<Button
className="text-sm"
onClick={() => {
@@ -239,36 +280,11 @@ const ProfileTasks: FunctionComponent = () => {
>
Отмена
</Button>
<Button
color="red"
onClick={() => {
if (taskNameRef.current && taskDescriptionRef.current) {
if (!taskNameRef.current.value || !taskDescriptionRef.current.value) {
alert("Заполните все поля");
return;
}
if (!calendarDate) {
alert("Заполните дату и время");
return;
}
const task: ITask = {
id: tasks.length + 1,
name: taskNameRef.current.value,
description: taskDescriptionRef.current.value,
date: calendarDate,
checked: false,
tags: ["Математика", "Домашнее задание"],
};
setTasks([...tasks, task]);
setIsOpen(false);
setCalendarDate(null);
}
}}
>
<Button color="red" type="submit">
Добавить задачу
</Button>
</div>
</div>
</form>
)}
</ModalWindow>
{tasks.length > 0 ? (