feat: create task form
This commit is contained in:
@@ -31,14 +31,14 @@ const markStyle = tv({
|
||||
const Task: FunctionComponent<TaskProps> = ({ name, checked = false, onClick = () => {} }: TaskProps) => {
|
||||
return (
|
||||
// Временное действие для тестирования
|
||||
<button onClick={onClick} class="w-[95%]">
|
||||
<div class={classes.task}>
|
||||
<div class="w-[95%]">
|
||||
<div class={classes.task} onClick={onClick}>
|
||||
<div class={taskStyle({ checked })}>
|
||||
<p class={markStyle({ checked })}>✓</p>
|
||||
</div>
|
||||
{name}
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -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 ? (
|
||||
|
||||
Reference in New Issue
Block a user