Compare commits
4 Commits
0b068f7232
...
db73f498f6
| Author | SHA1 | Date | |
|---|---|---|---|
| db73f498f6 | |||
| be7a58b93f | |||
| 4db7276166 | |||
| ae9eef1131 |
10
bun.lock
10
bun.lock
@@ -18,7 +18,7 @@
|
|||||||
"react-hook-form": "^7.56.1",
|
"react-hook-form": "^7.56.1",
|
||||||
"tailwind-merge": "^3.0.2",
|
"tailwind-merge": "^3.0.2",
|
||||||
"tailwind-variants": "^1.0.0",
|
"tailwind-variants": "^1.0.0",
|
||||||
"tailwindcss": "^4.0.17",
|
"tailwindcss": "^4.1.5",
|
||||||
"uuid": "^11.1.0",
|
"uuid": "^11.1.0",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -713,7 +713,7 @@
|
|||||||
|
|
||||||
"tailwind-variants": ["tailwind-variants@1.0.0", "", { "dependencies": { "tailwind-merge": "3.0.2" }, "peerDependencies": { "tailwindcss": "*" } }, "sha512-2WSbv4ulEEyuBKomOunut65D8UZwxrHoRfYnxGcQNnHqlSCp2+B7Yz2W+yrNDrxRodOXtGD/1oCcKGNBnUqMqA=="],
|
"tailwind-variants": ["tailwind-variants@1.0.0", "", { "dependencies": { "tailwind-merge": "3.0.2" }, "peerDependencies": { "tailwindcss": "*" } }, "sha512-2WSbv4ulEEyuBKomOunut65D8UZwxrHoRfYnxGcQNnHqlSCp2+B7Yz2W+yrNDrxRodOXtGD/1oCcKGNBnUqMqA=="],
|
||||||
|
|
||||||
"tailwindcss": ["tailwindcss@4.0.17", "", {}, "sha512-OErSiGzRa6rLiOvaipsDZvLMSpsBZ4ysB4f0VKGXUrjw2jfkJRd6kjRKV2+ZmTCNvwtvgdDam5D7w6WXsdLJZw=="],
|
"tailwindcss": ["tailwindcss@4.1.5", "", {}, "sha512-nYtSPfWGDiWgCkwQG/m+aX83XCwf62sBgg3bIlNiiOcggnS1x3uVRDAuyelBFL+vJdOPPCGElxv9DjHJjRHiVA=="],
|
||||||
|
|
||||||
"tapable": ["tapable@2.2.1", "", {}, "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="],
|
"tapable": ["tapable@2.2.1", "", {}, "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="],
|
||||||
|
|
||||||
@@ -767,6 +767,12 @@
|
|||||||
|
|
||||||
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
|
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
|
||||||
|
|
||||||
|
"@tailwindcss/node/tailwindcss": ["tailwindcss@4.0.17", "", {}, "sha512-OErSiGzRa6rLiOvaipsDZvLMSpsBZ4ysB4f0VKGXUrjw2jfkJRd6kjRKV2+ZmTCNvwtvgdDam5D7w6WXsdLJZw=="],
|
||||||
|
|
||||||
|
"@tailwindcss/postcss/tailwindcss": ["tailwindcss@4.0.17", "", {}, "sha512-OErSiGzRa6rLiOvaipsDZvLMSpsBZ4ysB4f0VKGXUrjw2jfkJRd6kjRKV2+ZmTCNvwtvgdDam5D7w6WXsdLJZw=="],
|
||||||
|
|
||||||
|
"@tailwindcss/vite/tailwindcss": ["tailwindcss@4.0.17", "", {}, "sha512-OErSiGzRa6rLiOvaipsDZvLMSpsBZ4ysB4f0VKGXUrjw2jfkJRd6kjRKV2+ZmTCNvwtvgdDam5D7w6WXsdLJZw=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="],
|
"@typescript-eslint/typescript-estree/semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="],
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
"react-hook-form": "^7.56.1",
|
"react-hook-form": "^7.56.1",
|
||||||
"tailwind-merge": "^3.0.2",
|
"tailwind-merge": "^3.0.2",
|
||||||
"tailwind-variants": "^1.0.0",
|
"tailwind-variants": "^1.0.0",
|
||||||
"tailwindcss": "^4.0.17",
|
"tailwindcss": "^4.1.5",
|
||||||
"uuid": "^11.1.0"
|
"uuid": "^11.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import { Dispatch, StateUpdater, useState } from "preact/hooks";
|
|||||||
import { Calendar, CalendarPassThroughMethodOptions } from "primereact/calendar";
|
import { Calendar, CalendarPassThroughMethodOptions } from "primereact/calendar";
|
||||||
import { FormEvent } from "primereact/ts-helpers";
|
import { FormEvent } from "primereact/ts-helpers";
|
||||||
import Button from "./ui/Button";
|
import Button from "./ui/Button";
|
||||||
import ModalWindow from "./ui/Modal";
|
import ModalWindow, { ModalWindowProps } from "./ui/Modal";
|
||||||
|
|
||||||
interface ModalCalendarProps {
|
interface ModalCalendarProps extends ModalWindowProps {
|
||||||
isOpen?: boolean;
|
isOpen?: boolean;
|
||||||
setIsOpen?: Dispatch<StateUpdater<boolean>>;
|
setIsOpen?: Dispatch<StateUpdater<boolean>>;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
@@ -27,10 +27,18 @@ const TRANSITIONS = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const ModalCalendar: FunctionComponent<ModalCalendarProps> = ({ isOpen, setIsOpen, onClose, onChange, value }) => {
|
const ModalCalendar: FunctionComponent<ModalCalendarProps> = ({
|
||||||
|
isOpen,
|
||||||
|
setIsOpen,
|
||||||
|
onClose,
|
||||||
|
onChange,
|
||||||
|
value,
|
||||||
|
...rest
|
||||||
|
}) => {
|
||||||
const [showTime, setShowTime] = useState(false);
|
const [showTime, setShowTime] = useState(false);
|
||||||
return (
|
return (
|
||||||
<ModalWindow
|
<ModalWindow
|
||||||
|
{...rest}
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
setIsOpen={setIsOpen}
|
setIsOpen={setIsOpen}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
@@ -38,7 +46,6 @@ const ModalCalendar: FunctionComponent<ModalCalendarProps> = ({ isOpen, setIsOpe
|
|||||||
setShowTime(false);
|
setShowTime(false);
|
||||||
}}
|
}}
|
||||||
className="md:h-[40rem] md:w-[30rem]"
|
className="md:h-[40rem] md:w-[30rem]"
|
||||||
zIndex={60}
|
|
||||||
>
|
>
|
||||||
<div class="w-full flex-1 self-start">
|
<div class="w-full flex-1 self-start">
|
||||||
<Calendar
|
<Calendar
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ import { BookOpenIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline
|
|||||||
import { FunctionComponent } from "preact";
|
import { FunctionComponent } from "preact";
|
||||||
import { Dispatch, StateUpdater, useEffect, useState } from "preact/hooks";
|
import { Dispatch, StateUpdater, useEffect, useState } from "preact/hooks";
|
||||||
import Button from "./ui/Button";
|
import Button from "./ui/Button";
|
||||||
import ModalWindow from "./ui/Modal";
|
import ModalWindow, { ModalWindowProps } from "./ui/Modal";
|
||||||
|
|
||||||
export interface ITags {
|
export interface ITags {
|
||||||
first: string;
|
first: string;
|
||||||
second: string;
|
second: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ModalTagsProps {
|
interface ModalTagsProps extends ModalWindowProps {
|
||||||
isOpen?: boolean;
|
isOpen?: boolean;
|
||||||
setIsOpen?: Dispatch<StateUpdater<boolean>>;
|
setIsOpen?: Dispatch<StateUpdater<boolean>>;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
@@ -22,7 +22,15 @@ interface ModalTagsProps {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const ModalTags: FunctionComponent<ModalTagsProps> = ({ isOpen, setIsOpen, onClose, onChange, value, tagsList }) => {
|
const ModalTags: FunctionComponent<ModalTagsProps> = ({
|
||||||
|
isOpen,
|
||||||
|
setIsOpen,
|
||||||
|
onClose,
|
||||||
|
onChange,
|
||||||
|
value,
|
||||||
|
tagsList,
|
||||||
|
...rest
|
||||||
|
}) => {
|
||||||
const [showFirstTags, setShowFirstTags] = useState(false);
|
const [showFirstTags, setShowFirstTags] = useState(false);
|
||||||
const [showSecondTags, setShowSecondTags] = useState(false);
|
const [showSecondTags, setShowSecondTags] = useState(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -34,6 +42,7 @@ const ModalTags: FunctionComponent<ModalTagsProps> = ({ isOpen, setIsOpen, onClo
|
|||||||
return (
|
return (
|
||||||
<ModalWindow
|
<ModalWindow
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
|
{...rest}
|
||||||
setIsOpen={setIsOpen}
|
setIsOpen={setIsOpen}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
onClose!();
|
onClose!();
|
||||||
|
|||||||
@@ -23,15 +23,12 @@ const Dialog: FunctionComponent<DialogProps> = ({
|
|||||||
if (!isOpen) return null;
|
if (!isOpen) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="fixed inset-0 z-50 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">{content}</p>
|
<p class="mb-6 text-sm sm:text-[1rem]">{content}</p>
|
||||||
<div class="flex justify-end gap-4">
|
<div class="flex justify-end gap-4">
|
||||||
<Button
|
<Button onClick={() => setIsOpen(false)} className="bg-gray-200 text-gray-800 hover:bg-gray-300">
|
||||||
onClick={() => setIsOpen(false)}
|
|
||||||
className="bg-gray-200 text-gray-800 hover:bg-gray-300"
|
|
||||||
>
|
|
||||||
{cancelText}
|
{cancelText}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { cn } from "@/utils/class-merge";
|
|||||||
import { FunctionComponent } from "preact";
|
import { FunctionComponent } from "preact";
|
||||||
import { Dispatch, StateUpdater, useEffect } from "preact/hooks";
|
import { Dispatch, StateUpdater, useEffect } from "preact/hooks";
|
||||||
|
|
||||||
interface ModalWindowProps {
|
export interface ModalWindowProps {
|
||||||
isOpen?: boolean;
|
isOpen?: boolean;
|
||||||
setIsOpen?: Dispatch<StateUpdater<boolean>>;
|
setIsOpen?: Dispatch<StateUpdater<boolean>>;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { UrlsTitle } from "@/enums/urls";
|
|||||||
import { useAppContext } from "@/providers/AuthProvider";
|
import { useAppContext } from "@/providers/AuthProvider";
|
||||||
import { cn } from "@/utils/class-merge";
|
import { cn } from "@/utils/class-merge";
|
||||||
import { calculatePoints, getCurrentStatus } from "@/utils/status-system";
|
import { calculatePoints, getCurrentStatus } from "@/utils/status-system";
|
||||||
|
import { ArrowRightStartOnRectangleIcon, Cog8ToothIcon } from "@heroicons/react/24/outline";
|
||||||
import { FunctionComponent } from "preact";
|
import { FunctionComponent } from "preact";
|
||||||
import { useLocation } from "preact-iso";
|
import { useLocation } from "preact-iso";
|
||||||
import { useEffect, useState } from "preact/hooks";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
@@ -33,8 +34,8 @@ const ProfileSettings: FunctionComponent = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('storage', handleStorage);
|
window.addEventListener("storage", handleStorage);
|
||||||
return () => window.removeEventListener('storage', handleStorage);
|
return () => window.removeEventListener("storage", handleStorage);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -58,17 +59,18 @@ const ProfileSettings: FunctionComponent = () => {
|
|||||||
<div class={classes.profile_container}>
|
<div class={classes.profile_container}>
|
||||||
<div class={classes.settings_block}>
|
<div class={classes.settings_block}>
|
||||||
<div class={classes.settings_block__buttons}>
|
<div class={classes.settings_block__buttons}>
|
||||||
<Button>Сменить тему</Button>
|
<Button className="flex flex-row items-center justify-center gap-2">
|
||||||
<Button>Настройки</Button>
|
<Cog8ToothIcon class="size-8" /> Настройки
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
color="secondary"
|
className="flex flex-row items-center justify-center gap-2 bg-[linear-gradient(180.00deg,rgba(246,255,211,0.7),rgba(195,229,253,0.7)_100%)]"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
isLoggedIn.value = false;
|
isLoggedIn.value = false;
|
||||||
localStorage.setItem("loggedIn", "false");
|
localStorage.setItem("loggedIn", "false");
|
||||||
route("/login", true);
|
route("/login", true);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Выйти
|
<ArrowRightStartOnRectangleIcon class="size-8" /> Выйти
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
@apply mb-3 w-full text-3xl font-semibold md:mb-12 md:text-5xl;
|
@apply mb-3 flex w-full flex-row items-center justify-between text-xl font-semibold sm:text-3xl md:mb-12 md:text-5xl;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tasks_container {
|
.tasks_container {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//! Файл большой, потому что было лень делить на компоненты
|
||||||
import Task from "@/components/task";
|
import Task from "@/components/task";
|
||||||
|
|
||||||
import ModalCalendar from "@/components/ModalCalendar";
|
import ModalCalendar from "@/components/ModalCalendar";
|
||||||
@@ -211,6 +212,7 @@ const ProfileTasks: FunctionComponent = () => {
|
|||||||
return (
|
return (
|
||||||
<div class={classes.container}>
|
<div class={classes.container}>
|
||||||
<ModalTags
|
<ModalTags
|
||||||
|
zIndex={70}
|
||||||
isOpen={openModalTags}
|
isOpen={openModalTags}
|
||||||
setIsOpen={setOpenModalTags}
|
setIsOpen={setOpenModalTags}
|
||||||
tagsList={example_tags}
|
tagsList={example_tags}
|
||||||
@@ -221,6 +223,7 @@ const ProfileTasks: FunctionComponent = () => {
|
|||||||
onChange={setTags}
|
onChange={setTags}
|
||||||
/>
|
/>
|
||||||
<ModalCalendar
|
<ModalCalendar
|
||||||
|
zIndex={80}
|
||||||
isOpen={openModalCalendar}
|
isOpen={openModalCalendar}
|
||||||
setIsOpen={setOpenModalCalendar}
|
setIsOpen={setOpenModalCalendar}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
@@ -230,6 +233,7 @@ const ProfileTasks: FunctionComponent = () => {
|
|||||||
value={calendarDate!}
|
value={calendarDate!}
|
||||||
/>
|
/>
|
||||||
<ModalWindow
|
<ModalWindow
|
||||||
|
zIndex={60}
|
||||||
isOpen={openModal}
|
isOpen={openModal}
|
||||||
setIsOpen={setIsOpen}
|
setIsOpen={setIsOpen}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
@@ -365,15 +369,15 @@ const ProfileTasks: FunctionComponent = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div class="flex w-full flex-1 flex-row items-start justify-between">
|
<div class="flex w-full flex-1 flex-row items-start justify-between">
|
||||||
<div class="me-4 flex h-full flex-1 flex-col gap-1">
|
<div class="flex flex-1 flex-col gap-1 pe-2">
|
||||||
<input
|
<input
|
||||||
class="text-2xl outline-0"
|
class="w-full text-2xl outline-0"
|
||||||
maxLength={20}
|
maxLength={20}
|
||||||
placeholder="Название"
|
placeholder="Название"
|
||||||
{...register("name", { required: "Заполните название" })}
|
{...register("name", { required: "Заполните название" })}
|
||||||
/>
|
/>
|
||||||
<textarea
|
<textarea
|
||||||
class="mb-10 w-full flex-1 resize-none outline-0"
|
class="h-[5rem] w-full resize-none outline-0"
|
||||||
placeholder="Описание"
|
placeholder="Описание"
|
||||||
maxLength={200}
|
maxLength={200}
|
||||||
{...register("description")}
|
{...register("description")}
|
||||||
@@ -388,13 +392,13 @@ const ProfileTasks: FunctionComponent = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row gap-3 self-start">
|
<div class="flex flex-row gap-3 self-start">
|
||||||
<CalendarDaysIcon
|
<CalendarDaysIcon
|
||||||
class="size-10 cursor-pointer"
|
class="size-8 cursor-pointer"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setOpenModalCalendar(true);
|
setOpenModalCalendar(true);
|
||||||
setCalendarDate(calendarDate ?? new Date());
|
setCalendarDate(calendarDate ?? new Date());
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<BookmarkIcon class="ms-4 size-10 cursor-pointer" onClick={() => setOpenModalTags(true)} />
|
<BookmarkIcon class="size-8 cursor-pointer" onClick={() => setOpenModalTags(true)} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{errors.name && <p class="text-red-500">{errors.name.message}</p>}
|
{errors.name && <p class="text-red-500">{errors.name.message}</p>}
|
||||||
@@ -428,7 +432,33 @@ const ProfileTasks: FunctionComponent = () => {
|
|||||||
{!searchQuery && !filterTags.first && !filterTags.second ? (
|
{!searchQuery && !filterTags.first && !filterTags.second ? (
|
||||||
filteredTasks.length > 0 ? (
|
filteredTasks.length > 0 ? (
|
||||||
<>
|
<>
|
||||||
<div class={classes.header}>Сегодня: {getDate}</div>
|
<div class={classes.header}>
|
||||||
|
Сегодня: {getDate}
|
||||||
|
<div class="flex flex-row items-center gap-2 md:hidden">
|
||||||
|
{!openSearchModal && (
|
||||||
|
<div
|
||||||
|
class="flex aspect-square h-12 cursor-pointer flex-col items-center justify-center rounded-full bg-[rgba(206,232,251,0.7)] text-xl text-gray-600 shadow-[0px_4px_4px_0px_rgba(0,0,0,0.25)] hover:bg-[rgba(206,232,251,0.9)]"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
if (!openSearchModal) setOpenFilterModal(false);
|
||||||
|
setOpenSearchModal(!openSearchModal);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MagnifyingGlassIcon class="size-6" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div class="flex aspect-square h-12 cursor-pointer flex-col items-center justify-center rounded-full bg-[rgba(206,232,251,0.7)] text-xl text-gray-600 shadow-[0px_4px_4px_0px_rgba(0,0,0,0.25)] hover:bg-[rgba(206,232,251,0.9)]">
|
||||||
|
<FunnelIcon
|
||||||
|
class="size-6"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
if (!openFilterModal) setOpenSearchModal(false);
|
||||||
|
setOpenFilterModal(!openFilterModal);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class={classes.tasks_container}>
|
<div class={classes.tasks_container}>
|
||||||
{groupTasksByDate.today.length > 0 ? (
|
{groupTasksByDate.today.length > 0 ? (
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
@@ -501,8 +531,32 @@ const ProfileTasks: FunctionComponent = () => {
|
|||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
<div class={classes.tasks_container}>
|
<div class={classes.tasks_container}>
|
||||||
<div class="mb-8 w-full text-3xl font-semibold md:text-5xl">
|
<div class="mb-8 flex w-full flex-row items-center justify-between text-xl font-semibold sm:text-3xl md:text-5xl">
|
||||||
{searchQuery ? "Результаты поиска" : "Результаты фильтрации"}
|
{searchQuery ? "Результаты поиска" : "Результаты фильтрации"}
|
||||||
|
<div class="flex flex-row items-center gap-2 md:hidden">
|
||||||
|
{!openSearchModal && (
|
||||||
|
<div
|
||||||
|
class="flex aspect-square h-12 cursor-pointer flex-col items-center justify-center rounded-full bg-[rgba(206,232,251,0.7)] text-xl text-gray-600 shadow-[0px_4px_4px_0px_rgba(0,0,0,0.25)] hover:bg-[rgba(206,232,251,0.9)]"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
if (!openSearchModal) setOpenFilterModal(false);
|
||||||
|
setOpenSearchModal(!openSearchModal);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MagnifyingGlassIcon class="size-6" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div class="flex aspect-square h-12 cursor-pointer flex-col items-center justify-center rounded-full bg-[rgba(206,232,251,0.7)] text-xl text-gray-600 shadow-[0px_4px_4px_0px_rgba(0,0,0,0.25)] hover:bg-[rgba(206,232,251,0.9)]">
|
||||||
|
<FunnelIcon
|
||||||
|
class="size-6"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
if (!openFilterModal) setOpenSearchModal(false);
|
||||||
|
setOpenFilterModal(!openFilterModal);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{filteredTasks.length > 0 ? (
|
{filteredTasks.length > 0 ? (
|
||||||
filteredTasks.map((task) => (
|
filteredTasks.map((task) => (
|
||||||
@@ -562,7 +616,7 @@ const ProfileTasks: FunctionComponent = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{openSearchModal && (
|
{openSearchModal && (
|
||||||
<div class="absolute right-24 bottom-28 z-50 w-80 rounded-lg bg-white p-4 shadow-lg md:right-[24rem] md:bottom-28">
|
<div class="fixed bottom-28 z-50 w-full rounded-lg bg-white p-4 shadow-lg md:absolute md:right-[24rem] md:mx-0 md:w-80">
|
||||||
{/* Пофиксить разфокус при вводе */}
|
{/* Пофиксить разфокус при вводе */}
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<MagnifyingGlassIcon class="size-6 text-gray-400" />
|
<MagnifyingGlassIcon class="size-6 text-gray-400" />
|
||||||
@@ -576,7 +630,6 @@ const ProfileTasks: FunctionComponent = () => {
|
|||||||
setSearchQuery((e.target as HTMLInputElement).value);
|
setSearchQuery((e.target as HTMLInputElement).value);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{searchQuery && (
|
|
||||||
<XMarkIcon
|
<XMarkIcon
|
||||||
class="size-5 cursor-pointer text-gray-400 hover:text-gray-600"
|
class="size-5 cursor-pointer text-gray-400 hover:text-gray-600"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -584,20 +637,22 @@ const ProfileTasks: FunctionComponent = () => {
|
|||||||
setOpenSearchModal(false);
|
setOpenSearchModal(false);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{openFilterModal && (
|
{openFilterModal && (
|
||||||
<div class="absolute right-24 bottom-28 z-50 w-80 rounded-lg bg-white p-4 shadow-lg md:right-[24rem] md:bottom-28">
|
<div class="fixed top-[50%] z-50 w-full rounded-[2rem] bg-white p-4 shadow-lg md:absolute md:top-auto md:right-[24rem] md:bottom-28 md:w-80">
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="text-lg font-semibold">Фильтры</div>
|
<div class="text-center text-lg font-semibold">Фильтры</div>
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div
|
<div
|
||||||
class={cn("flex cursor-pointer items-center gap-2 rounded-lg bg-[rgba(206,232,251,0.7)] px-4 py-2", {
|
class={cn(
|
||||||
|
"flex cursor-pointer items-center justify-center gap-2 rounded-lg bg-[rgba(206,232,251,0.7)] px-4 py-2",
|
||||||
|
{
|
||||||
"bg-[rgba(206,232,251,0.9)]": filterTags.first,
|
"bg-[rgba(206,232,251,0.9)]": filterTags.first,
|
||||||
})}
|
}
|
||||||
|
)}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setOpenFirstList(!openFirstList);
|
setOpenFirstList(!openFirstList);
|
||||||
setOpenSecondList(false);
|
setOpenSecondList(false);
|
||||||
@@ -607,7 +662,7 @@ const ProfileTasks: FunctionComponent = () => {
|
|||||||
<span>{filterTags.first || "Предмет"}</span>
|
<span>{filterTags.first || "Предмет"}</span>
|
||||||
</div>
|
</div>
|
||||||
{openFirstList && (
|
{openFirstList && (
|
||||||
<div class="absolute top-0 right-full z-50 mr-2 w-64 rounded-lg bg-white p-2 shadow-lg">
|
<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">
|
||||||
{example_tags.first.map((tag) => (
|
{example_tags.first.map((tag) => (
|
||||||
<div
|
<div
|
||||||
key={tag}
|
key={tag}
|
||||||
@@ -634,9 +689,12 @@ const ProfileTasks: FunctionComponent = () => {
|
|||||||
|
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div
|
<div
|
||||||
class={cn("flex cursor-pointer items-center gap-2 rounded-lg bg-[rgba(206,232,251,0.7)] px-4 py-2", {
|
class={cn(
|
||||||
|
"flex cursor-pointer items-center justify-center gap-2 rounded-lg bg-[rgba(206,232,251,0.7)] px-4 py-2",
|
||||||
|
{
|
||||||
"bg-[rgba(206,232,251,0.9)]": filterTags.second,
|
"bg-[rgba(206,232,251,0.9)]": filterTags.second,
|
||||||
})}
|
}
|
||||||
|
)}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setOpenSecondList(!openSecondList);
|
setOpenSecondList(!openSecondList);
|
||||||
setOpenFirstList(false);
|
setOpenFirstList(false);
|
||||||
@@ -646,7 +704,7 @@ const ProfileTasks: FunctionComponent = () => {
|
|||||||
<span>{filterTags.second || "Задача"}</span>
|
<span>{filterTags.second || "Задача"}</span>
|
||||||
</div>
|
</div>
|
||||||
{openSecondList && (
|
{openSecondList && (
|
||||||
<div class="absolute top-0 right-full z-50 mr-2 w-64 rounded-lg bg-white p-2 shadow-lg">
|
<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">
|
||||||
{example_tags.second.map((tag) => (
|
{example_tags.second.map((tag) => (
|
||||||
<div
|
<div
|
||||||
key={tag}
|
key={tag}
|
||||||
|
|||||||
Reference in New Issue
Block a user