feat: tag delete
This commit is contained in:
@@ -2,9 +2,11 @@ import { IAPITag } from "@/pages/profile_tasks.dto";
|
|||||||
import apiClient from "@/services/api";
|
import apiClient from "@/services/api";
|
||||||
import { cn } from "@/utils/class-merge";
|
import { cn } from "@/utils/class-merge";
|
||||||
import { BookOpenIcon, CheckIcon, DocumentDuplicateIcon, PlusCircleIcon } from "@heroicons/react/24/outline";
|
import { BookOpenIcon, CheckIcon, DocumentDuplicateIcon, PlusCircleIcon } from "@heroicons/react/24/outline";
|
||||||
|
import { XMarkIcon } from "@heroicons/react/24/solid";
|
||||||
import { FunctionComponent } from "preact";
|
import { FunctionComponent } from "preact";
|
||||||
import { Dispatch, StateUpdater, useEffect, useRef, useState } from "preact/hooks";
|
import { Dispatch, StateUpdater, useEffect, useRef, useState } from "preact/hooks";
|
||||||
import Button from "./ui/Button";
|
import Button from "./ui/Button";
|
||||||
|
import Dialog from "./ui/Dialog";
|
||||||
import ModalWindow, { ModalWindowProps } from "./ui/Modal";
|
import ModalWindow, { ModalWindowProps } from "./ui/Modal";
|
||||||
|
|
||||||
export interface ITags {
|
export interface ITags {
|
||||||
@@ -40,6 +42,8 @@ const ModalTags: FunctionComponent<ModalTagsProps> = ({
|
|||||||
const [showSecondTags, setShowSecondTags] = useState(false);
|
const [showSecondTags, setShowSecondTags] = useState(false);
|
||||||
const [showAddFirstTag, setShowAddFirstTag] = useState(false);
|
const [showAddFirstTag, setShowAddFirstTag] = useState(false);
|
||||||
const [showAddSecondTag, setShowAddSecondTag] = useState(false);
|
const [showAddSecondTag, setShowAddSecondTag] = useState(false);
|
||||||
|
const [showErrorDialog, setShowErrorDialog] = useState(false);
|
||||||
|
const [errorMessage, setErrorMessage] = useState<string[]>([]);
|
||||||
const addFirstTagRef = useRef<HTMLInputElement>(null);
|
const addFirstTagRef = useRef<HTMLInputElement>(null);
|
||||||
const addSecondTagRef = useRef<HTMLInputElement>(null);
|
const addSecondTagRef = useRef<HTMLInputElement>(null);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -51,6 +55,7 @@ const ModalTags: FunctionComponent<ModalTagsProps> = ({
|
|||||||
|
|
||||||
const handleCreateTag = async () => {
|
const handleCreateTag = async () => {
|
||||||
if (!addFirstTagRef.current?.value && !addSecondTagRef.current?.value) return;
|
if (!addFirstTagRef.current?.value && !addSecondTagRef.current?.value) return;
|
||||||
|
|
||||||
const data: { subject_name?: string; taskType_name?: string } = {};
|
const data: { subject_name?: string; taskType_name?: string } = {};
|
||||||
if (addFirstTagRef.current && addFirstTagRef.current.value) data.subject_name = addFirstTagRef.current.value;
|
if (addFirstTagRef.current && addFirstTagRef.current.value) data.subject_name = addFirstTagRef.current.value;
|
||||||
if (addSecondTagRef.current && addSecondTagRef.current.value) data.taskType_name = addSecondTagRef.current.value;
|
if (addSecondTagRef.current && addSecondTagRef.current.value) data.taskType_name = addSecondTagRef.current.value;
|
||||||
@@ -71,139 +76,193 @@ const ModalTags: FunctionComponent<ModalTagsProps> = ({
|
|||||||
setShowAddSecondTag(false);
|
setShowAddSecondTag(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (addFirstTagRef.current) addFirstTagRef.current.value = "";
|
||||||
|
if (addSecondTagRef.current) addSecondTagRef.current.value = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDeleteTag = async (id: number) => {
|
||||||
|
const data: { subject_id?: number; taskType_id?: number } = {};
|
||||||
|
if (showFirstTags) data.subject_id = id;
|
||||||
|
if (showSecondTags) data.taskType_id = id;
|
||||||
|
const response = await apiClient<{ error?: string }>(`/api/tags/delete_tag/`, {
|
||||||
|
method: "DELETE",
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
});
|
||||||
|
if (!response.error) {
|
||||||
|
refreshTags();
|
||||||
|
} else {
|
||||||
|
setShowErrorDialog(true);
|
||||||
|
const match = response.error?.match(/\[(.+)\]/);
|
||||||
|
if (match) setErrorMessage(match[1].split(", ").map((s) => s.trim().replace(/'/g, "")));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalWindow
|
<>
|
||||||
isOpen={isOpen}
|
<Dialog
|
||||||
{...rest}
|
isOpen={showErrorDialog}
|
||||||
setIsOpen={setIsOpen}
|
setIsOpen={setShowErrorDialog}
|
||||||
onClose={() => {
|
title="Ошибка!"
|
||||||
onClose!();
|
confirmation={false}
|
||||||
setShowFirstTags(false);
|
cancelText="Ок"
|
||||||
setShowSecondTags(false);
|
>
|
||||||
setShowAddFirstTag(false);
|
<div class="flex flex-col items-start gap-1">
|
||||||
setShowAddSecondTag(false);
|
<p class="mb-6 text-sm sm:text-[1rem]">
|
||||||
}}
|
Данный тег есть в других задачах. Поменяйте теги в них и повторите операцию.
|
||||||
className="relative h-[14rem] justify-between py-4 md:h-[14rem] md:w-[25rem]"
|
</p>
|
||||||
zIndex={70}
|
<p class="text-sm sm:text-[1rem]">Задачи с этим тегом:</p>
|
||||||
>
|
<ul class="ms-6 list-disc">
|
||||||
<p class="text-2xl font-semibold">Теги</p>
|
{errorMessage.map((s, i) => (
|
||||||
<div class="flex w-[85%] flex-col gap-2 md:w-full">
|
<li key={i}>{s}</li>
|
||||||
<Button
|
))}
|
||||||
className="flex w-full flex-row items-center justify-center gap-1 text-[1rem]!"
|
</ul>
|
||||||
onClick={() => {
|
</div>
|
||||||
setShowFirstTags(!showFirstTags);
|
</Dialog>
|
||||||
setShowSecondTags(false);
|
<ModalWindow
|
||||||
setShowAddFirstTag(false);
|
isOpen={isOpen}
|
||||||
setShowAddSecondTag(false);
|
{...rest}
|
||||||
}}
|
setIsOpen={setIsOpen}
|
||||||
>
|
onClose={() => {
|
||||||
<BookOpenIcon class="size-6" />
|
onClose!();
|
||||||
{tagsList?.first?.find((tag) => tag.id === value?.first)?.name || "Предмет"}
|
setShowFirstTags(false);
|
||||||
</Button>
|
setShowSecondTags(false);
|
||||||
<Button
|
setShowAddFirstTag(false);
|
||||||
className="flex w-full flex-row items-center justify-center gap-1 text-[1rem]! break-words"
|
setShowAddSecondTag(false);
|
||||||
onClick={() => {
|
}}
|
||||||
setShowSecondTags(!showSecondTags);
|
className="relative h-[14rem] justify-between py-4 md:h-[14rem] md:w-[25rem]"
|
||||||
setShowFirstTags(false);
|
zIndex={70}
|
||||||
setShowAddFirstTag(false);
|
>
|
||||||
setShowAddSecondTag(false);
|
<p class="text-2xl font-semibold">Теги</p>
|
||||||
}}
|
<div class="flex w-[85%] flex-col gap-2 md:w-full">
|
||||||
>
|
<Button
|
||||||
<DocumentDuplicateIcon class="size-6" />
|
className="flex w-full flex-row items-center justify-center gap-1 text-[1rem]!"
|
||||||
{tagsList?.second?.find((tag) => tag.id === value?.second)?.name || "Тема"}
|
onClick={() => {
|
||||||
</Button>
|
setShowFirstTags(!showFirstTags);
|
||||||
{showFirstTags && (
|
setShowSecondTags(false);
|
||||||
<div class="absolute top-full left-0 mt-3 ml-2 flex h-fit w-[18rem] flex-col items-center gap-3 md:top-0 md:left-full md:mt-0 md:ml-5">
|
setShowAddFirstTag(false);
|
||||||
<div class="flex h-fit max-h-[45vh] w-full flex-col gap-3 overflow-y-auto rounded-[4rem] bg-white px-8 py-4 text-xs">
|
setShowAddSecondTag(false);
|
||||||
{tagsList?.first.map((tag) => (
|
}}
|
||||||
<div
|
>
|
||||||
class="flex cursor-pointer flex-row gap-2"
|
<BookOpenIcon class="size-6" />
|
||||||
onClick={() =>
|
{tagsList?.first?.find((tag) => tag.id === value?.first)?.name || "Предмет"}
|
||||||
onChange?.((prev) => {
|
</Button>
|
||||||
return { ...prev, first: tag.id };
|
<Button
|
||||||
})
|
className="flex w-full flex-row items-center justify-center gap-1 text-[1rem]! break-words"
|
||||||
}
|
onClick={() => {
|
||||||
>
|
setShowSecondTags(!showSecondTags);
|
||||||
|
setShowFirstTags(false);
|
||||||
|
setShowAddFirstTag(false);
|
||||||
|
setShowAddSecondTag(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DocumentDuplicateIcon class="size-6" />
|
||||||
|
{tagsList?.second?.find((tag) => tag.id === value?.second)?.name || "Тема"}
|
||||||
|
</Button>
|
||||||
|
{showFirstTags && (
|
||||||
|
<div class="absolute top-full left-0 mt-3 ml-2 flex h-fit w-[18rem] flex-col items-center gap-3 md:top-0 md:left-full md:mt-0 md:ml-5">
|
||||||
|
<div class="flex h-fit max-h-[15rem] w-full flex-col gap-3 overflow-y-auto rounded-[4rem] bg-white px-8 py-4 text-xs">
|
||||||
|
{tagsList?.first.map((tag) => (
|
||||||
<div
|
<div
|
||||||
class={cn(
|
class="flex cursor-pointer flex-row items-center gap-2"
|
||||||
"pointer-events-none flex aspect-square size-4 flex-col items-center justify-center rounded-full border-1 border-black text-white select-none",
|
onClick={() =>
|
||||||
{
|
onChange?.((prev) => {
|
||||||
"bg-black": value?.first === tag.id,
|
return { ...prev, first: tag.id };
|
||||||
}
|
})
|
||||||
)}
|
}
|
||||||
>
|
>
|
||||||
✓
|
<div
|
||||||
|
class={cn(
|
||||||
|
"pointer-events-none flex aspect-square size-4 flex-col items-center justify-center rounded-full border-1 border-black text-white select-none",
|
||||||
|
{
|
||||||
|
"bg-black": value?.first === tag.id,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
✓
|
||||||
|
</div>
|
||||||
|
<p class="flex-1">{tag.name}</p>
|
||||||
|
<XMarkIcon
|
||||||
|
class="size-4 cursor-pointer"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
handleDeleteTag(tag.id);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p>{tag.name}</p>
|
))}
|
||||||
</div>
|
<button
|
||||||
))}
|
class="mt-2 flex w-full cursor-pointer flex-row items-center gap-2"
|
||||||
<button
|
onClick={() => {
|
||||||
class="mt-2 flex w-full cursor-pointer flex-row items-center gap-2"
|
setShowAddFirstTag(!showAddFirstTag);
|
||||||
onClick={() => {
|
setTimeout(() => addFirstTagRef.current?.focus(), 100);
|
||||||
setShowAddFirstTag(!showAddFirstTag);
|
}}
|
||||||
setTimeout(() => addFirstTagRef.current?.focus(), 100);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<PlusCircleIcon class="size-5" />
|
|
||||||
<span>Добавить</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{showAddFirstTag && (
|
|
||||||
<div class="flex w-full flex-row items-center rounded-[4rem] bg-white px-8 py-4 text-xs">
|
|
||||||
<input placeholder="Введите текст" class="flex-1 outline-0" ref={addFirstTagRef} />
|
|
||||||
<CheckIcon class="size-6 cursor-pointer" onClick={handleCreateTag} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{showSecondTags && (
|
|
||||||
<div class="absolute top-full left-0 mt-3 ml-2 flex h-fit w-[18rem] flex-col items-center gap-3 md:top-0 md:left-full md:mt-0 md:ml-5">
|
|
||||||
<div class="flex h-fit max-h-[45vh] w-full flex-col gap-3 overflow-y-auto rounded-[4rem] bg-white px-8 py-4 text-xs">
|
|
||||||
{tagsList?.second.map((tag) => (
|
|
||||||
<div
|
|
||||||
class="flex cursor-pointer flex-row gap-2"
|
|
||||||
onClick={() =>
|
|
||||||
onChange?.((prev) => {
|
|
||||||
return { ...prev, second: tag.id };
|
|
||||||
})
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<div
|
<PlusCircleIcon class="size-5" />
|
||||||
class={cn(
|
<span>Добавить</span>
|
||||||
"pointer-events-none flex aspect-square size-4 flex-col items-center justify-center rounded-full border-1 border-black text-white select-none",
|
</button>
|
||||||
{
|
|
||||||
"bg-black": value?.second === tag.id,
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
✓
|
|
||||||
</div>
|
|
||||||
<p>{tag.name}</p>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
<button
|
|
||||||
class="mt-2 flex w-full cursor-pointer flex-row items-center gap-2"
|
|
||||||
onClick={() => {
|
|
||||||
setShowAddSecondTag(!showAddSecondTag);
|
|
||||||
setTimeout(() => addSecondTagRef.current?.focus(), 100);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<PlusCircleIcon class="size-5" />
|
|
||||||
<span>Добавить</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{showAddSecondTag && (
|
|
||||||
<div class="flex w-full flex-row items-center rounded-[4rem] bg-white px-8 py-4 text-xs">
|
|
||||||
<input placeholder="Введите текст" class="flex-1 outline-0" ref={addSecondTagRef} />
|
|
||||||
<CheckIcon class="size-6 cursor-pointer" onClick={handleCreateTag} />
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
{showAddFirstTag && (
|
||||||
</div>
|
<div class="flex w-full flex-row items-center rounded-[4rem] bg-white px-8 py-4 text-xs">
|
||||||
)}
|
<input placeholder="Введите текст" class="flex-1 outline-0" ref={addFirstTagRef} />
|
||||||
</div>
|
<CheckIcon class="size-6 cursor-pointer" onClick={handleCreateTag} />
|
||||||
</ModalWindow>
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{showSecondTags && (
|
||||||
|
<div class="absolute top-full left-0 mt-3 ml-2 flex h-fit w-[18rem] flex-col items-center gap-3 md:top-0 md:left-full md:mt-0 md:ml-5">
|
||||||
|
<div class="flex h-fit max-h-[15rem] w-full flex-col gap-3 overflow-y-auto rounded-[4rem] bg-white px-8 py-4 text-xs">
|
||||||
|
{tagsList?.second.map((tag) => (
|
||||||
|
<div
|
||||||
|
class="flex cursor-pointer flex-row gap-2"
|
||||||
|
onClick={() =>
|
||||||
|
onChange?.((prev) => {
|
||||||
|
return { ...prev, second: tag.id };
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class={cn(
|
||||||
|
"pointer-events-none flex aspect-square size-4 flex-col items-center justify-center rounded-full border-1 border-black text-white select-none",
|
||||||
|
{
|
||||||
|
"bg-black": value?.second === tag.id,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
✓
|
||||||
|
</div>
|
||||||
|
<p class="flex-1">{tag.name}</p>
|
||||||
|
<XMarkIcon
|
||||||
|
class="size-4 cursor-pointer"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
handleDeleteTag(tag.id);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<button
|
||||||
|
class="mt-2 flex w-full cursor-pointer flex-row items-center gap-2"
|
||||||
|
onClick={() => {
|
||||||
|
setShowAddSecondTag(!showAddSecondTag);
|
||||||
|
setTimeout(() => addSecondTagRef.current?.focus(), 100);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<PlusCircleIcon class="size-5" />
|
||||||
|
<span>Добавить</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{showAddSecondTag && (
|
||||||
|
<div class="flex w-full flex-row items-center rounded-[4rem] bg-white px-8 py-4 text-xs">
|
||||||
|
<input placeholder="Введите текст" class="flex-1 outline-0" ref={addSecondTagRef} />
|
||||||
|
<CheckIcon class="size-6 cursor-pointer" onClick={handleCreateTag} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</ModalWindow>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,20 +5,21 @@ interface DialogProps {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
setIsOpen: (isOpen: boolean) => void;
|
setIsOpen: (isOpen: boolean) => void;
|
||||||
title: string;
|
title: string;
|
||||||
content: string;
|
onConfirm?: () => void;
|
||||||
onConfirm: () => void;
|
|
||||||
confirmText?: string;
|
confirmText?: string;
|
||||||
cancelText?: string;
|
cancelText?: string;
|
||||||
|
confirmation?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Dialog: FunctionComponent<DialogProps> = ({
|
const Dialog: FunctionComponent<DialogProps> = ({
|
||||||
isOpen,
|
isOpen,
|
||||||
setIsOpen,
|
setIsOpen,
|
||||||
title,
|
title,
|
||||||
content,
|
children,
|
||||||
onConfirm,
|
onConfirm = () => {},
|
||||||
confirmText = "Подтвердить",
|
confirmText = "Подтвердить",
|
||||||
cancelText = "Отмена",
|
cancelText = "Отмена",
|
||||||
|
confirmation = true,
|
||||||
}) => {
|
}) => {
|
||||||
if (!isOpen) return null;
|
if (!isOpen) return null;
|
||||||
|
|
||||||
@@ -26,20 +27,28 @@ const Dialog: FunctionComponent<DialogProps> = ({
|
|||||||
<div class="fixed inset-0 z-150 flex items-center justify-center bg-black/50">
|
<div class="fixed inset-0 z-150 flex items-center justify-center bg-black/50">
|
||||||
<div class="w-full max-w-md rounded-[4rem] bg-white p-6 shadow-lg">
|
<div class="w-full max-w-md rounded-[4rem] bg-white p-6 shadow-lg">
|
||||||
<h2 class="mb-4 text-xl font-semibold">{title}</h2>
|
<h2 class="mb-4 text-xl font-semibold">{title}</h2>
|
||||||
<p class="mb-6 text-sm sm:text-[1rem]">{content}</p>
|
{children}
|
||||||
<div class="flex justify-end gap-4">
|
<div class="flex justify-end gap-4">
|
||||||
<Button onClick={() => setIsOpen(false)} className="bg-gray-200 text-gray-800 hover:bg-gray-300">
|
{confirmation ? (
|
||||||
{cancelText}
|
<>
|
||||||
</Button>
|
<Button onClick={() => setIsOpen(false)} className="bg-gray-200 text-gray-800 hover:bg-gray-300">
|
||||||
<Button
|
{cancelText}
|
||||||
onClick={() => {
|
</Button>
|
||||||
onConfirm();
|
<Button
|
||||||
setIsOpen(false);
|
onClick={() => {
|
||||||
}}
|
onConfirm();
|
||||||
color="red"
|
setIsOpen(false);
|
||||||
>
|
}}
|
||||||
{confirmText}
|
color="red"
|
||||||
</Button>
|
>
|
||||||
|
{confirmText}
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<Button onClick={() => setIsOpen(false)} className="bg-gray-200 text-gray-800 hover:bg-gray-300">
|
||||||
|
{cancelText}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -538,11 +538,12 @@ const ProfileCalendar: FunctionComponent = () => {
|
|||||||
isOpen={showDeleteDialog}
|
isOpen={showDeleteDialog}
|
||||||
setIsOpen={setShowDeleteDialog}
|
setIsOpen={setShowDeleteDialog}
|
||||||
title="Удаление задачи"
|
title="Удаление задачи"
|
||||||
content="Вы уверены, что хотите удалить эту задачу?"
|
|
||||||
onConfirm={handleDeleteTask}
|
onConfirm={handleDeleteTask}
|
||||||
confirmText="Удалить"
|
confirmText="Удалить"
|
||||||
cancelText="Отмена"
|
cancelText="Отмена"
|
||||||
/>
|
>
|
||||||
|
<p class="mb-6 text-sm sm:text-[1rem]">"Вы уверены, что хотите удалить эту задачу?"</p>
|
||||||
|
</Dialog>
|
||||||
<Calendar
|
<Calendar
|
||||||
value={currentDate}
|
value={currentDate}
|
||||||
onChange={(e) => setCurrentDate(e ? e.value! : new Date())}
|
onChange={(e) => setCurrentDate(e ? e.value! : new Date())}
|
||||||
|
|||||||
@@ -154,7 +154,6 @@ const ProfileTasks: FunctionComponent = () => {
|
|||||||
}
|
}
|
||||||
if ((!editContent?.subject.id || !editContent.taskType.id) && (!tags.first || !tags.second)) {
|
if ((!editContent?.subject.id || !editContent.taskType.id) && (!tags.first || !tags.second)) {
|
||||||
setError("subject", { message: "Выберите теги" });
|
setError("subject", { message: "Выберите теги" });
|
||||||
setError("taskType", { message: "Выберите теги" });
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -631,11 +630,12 @@ const ProfileTasks: FunctionComponent = () => {
|
|||||||
isOpen={showDeleteDialog}
|
isOpen={showDeleteDialog}
|
||||||
setIsOpen={setShowDeleteDialog}
|
setIsOpen={setShowDeleteDialog}
|
||||||
title="Удаление задачи"
|
title="Удаление задачи"
|
||||||
content="Вы уверены, что хотите удалить эту задачу?"
|
|
||||||
onConfirm={handleDeleteTask}
|
onConfirm={handleDeleteTask}
|
||||||
confirmText="Удалить"
|
confirmText="Удалить"
|
||||||
cancelText="Отмена"
|
cancelText="Отмена"
|
||||||
/>
|
>
|
||||||
|
<p class="mb-6 text-sm sm:text-[1rem]">"Вы уверены, что хотите удалить эту задачу?"</p>
|
||||||
|
</Dialog>
|
||||||
{!searchQuery && !filterTags.first && !filterTags.second && !filterTags.overdue ? (
|
{!searchQuery && !filterTags.first && !filterTags.second && !filterTags.overdue ? (
|
||||||
filteredTasks.length > 0 ? (
|
filteredTasks.length > 0 ? (
|
||||||
<>
|
<>
|
||||||
@@ -892,7 +892,7 @@ const ProfileTasks: FunctionComponent = () => {
|
|||||||
<span>{subjectChoices.find((s) => s.id === filterTags.first)?.name || "Предмет"}</span>
|
<span>{subjectChoices.find((s) => s.id === filterTags.first)?.name || "Предмет"}</span>
|
||||||
</div>
|
</div>
|
||||||
{openFirstList && (
|
{openFirstList && (
|
||||||
<div class="absolute top-full right-0 z-50 w-64 rounded-lg bg-white p-2 shadow-lg md:top-0 md:right-full md:mr-2">
|
<div class="absolute top-full right-0 z-50 max-h-[15rem] w-64 overflow-y-auto rounded-lg bg-white p-2 shadow-lg md:top-0 md:right-full md:mr-2">
|
||||||
{example_tags.first.map((tag) => {
|
{example_tags.first.map((tag) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -936,7 +936,7 @@ const ProfileTasks: FunctionComponent = () => {
|
|||||||
<span>{taskTypeChoices.find((s) => s.id === filterTags.second)?.name || "Задача"}</span>
|
<span>{taskTypeChoices.find((s) => s.id === filterTags.second)?.name || "Задача"}</span>
|
||||||
</div>
|
</div>
|
||||||
{openSecondList && (
|
{openSecondList && (
|
||||||
<div class="absolute top-full right-0 z-50 w-64 rounded-lg bg-white p-2 shadow-lg md:top-0 md:right-full md:mr-2">
|
<div class="absolute top-full right-0 z-50 max-h-[15rem] w-64 overflow-y-auto rounded-lg bg-white p-2 shadow-lg md:top-0 md:right-full md:mr-2">
|
||||||
{example_tags.second.map((tag) => (
|
{example_tags.second.map((tag) => (
|
||||||
<div
|
<div
|
||||||
key={`taskType_${tag.id}`}
|
key={`taskType_${tag.id}`}
|
||||||
|
|||||||
Reference in New Issue
Block a user