diff --git a/client/src/components/Button.tsx b/client/src/components/Button.tsx index 50d17d3..a175470 100644 --- a/client/src/components/Button.tsx +++ b/client/src/components/Button.tsx @@ -30,12 +30,12 @@ function Button({ disabled={disabled || loading} type={type} onClick={handleClick} - className={`relative outline-none rounded-lg transition-all font-semibold flex justify-center items-center gap-1 active:bg-[#49A1F5] disabled:bg-[#F2F2F2] disabled:text-[#CCCCCC] ${ + className={`relative outline-none rounded-lg transition-all font-semibold flex justify-center items-center gap-1 disabled:bg-[#F2F2F2] disabled:text-[#CCCCCC] ${ (color === "primary" && "bg-[#49A1F5] text-white hover:bg-[#4190DB]") || (color === "secondary" && - "bg-[#F0F1F2] text-[#77828C] hover:bg-[#E6ECF2] active:text-white") || + "bg-[#F0F1F2] text-[#77828C] hover:bg-[#E6ECF2]") || (color === "tertiary" && - "text-[#77828C] hover:bg-[#E6ECF2] active:text-white") + "text-[#77828C] hover:bg-[#E6ECF2]") } ${ (size === "small" && `h-8 ${ diff --git a/client/src/components/Calendar.tsx b/client/src/components/Calendar.tsx new file mode 100644 index 0000000..9c50422 --- /dev/null +++ b/client/src/components/Calendar.tsx @@ -0,0 +1,113 @@ +import { + addMonths, + format, + getDaysInMonth, + getISODay, + isEqual, + isToday, + setDate, + startOfDay, + startOfMonth, + subMonths, +} from "date-fns"; +import { useEffect, useState } from "react"; +import ChevronLeftIcon from "./icons/ChevronLeftIcon"; +import ChevronRightIcon from "./icons/ChevronRightIcon"; +import _ from "lodash"; +import { ru } from "date-fns/locale"; + +interface Props { + defaultValue?: Date; + onChange?: (date: Date) => void; +} + +function Calendar({ defaultValue, onChange }: Props) { + const [selectedDate, setSelectedDate] = useState( + startOfDay(defaultValue || new Date()) + ); + const [selectedMonth, setSelectedMonth] = useState( + startOfMonth(defaultValue || new Date()) + ); + + function selectPrevMonth() { + setSelectedMonth(subMonths(selectedMonth, 1)); + } + + function selectNextMonth() { + setSelectedMonth(addMonths(selectedMonth, 1)); + } + + function hadndleClick(date: Date) { + setSelectedDate(date); + onChange && onChange(date); + } + + useEffect(() => { + if (!defaultValue) return; + setSelectedDate(startOfDay(defaultValue)); + }, [defaultValue]); + + useEffect(() => { + setSelectedMonth(startOfMonth(selectedDate)); + }, [selectedDate]); + + return ( +
+
+ +

+ {_.capitalize(format(selectedMonth, "LLLL, yyyy", { locale: ru }))} +

+ +
+
+ {["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"].map((value, index) => ( +
+ {value} +
+ ))} +
+
+ {Array.from({ length: getISODay(selectedMonth) - 1 }).map( + (_, index) => ( +
+ ) + )} + {Array.from({ length: getDaysInMonth(selectedMonth) }).map( + (_, index) => ( + + ) + )} +
+
+ ); +} + +export default Calendar; diff --git a/client/src/components/EmptyCard.tsx b/client/src/components/EmptyCard.tsx index b87c2b5..c423666 100644 --- a/client/src/components/EmptyCard.tsx +++ b/client/src/components/EmptyCard.tsx @@ -1,13 +1,25 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import useModalStore from "../stores/useModalStore"; import Button from "./Button"; import PlusIcon from "./icons/PlusIcon"; +import CreateScheduledSessionModal from "./modals/CreateScheduledSessionModal"; + + function EmptyCard() { + const { setModal } = useModalStore(); + return (
diff --git a/client/src/components/Label.tsx b/client/src/components/Label.tsx index 271f76e..c408cf1 100644 --- a/client/src/components/Label.tsx +++ b/client/src/components/Label.tsx @@ -4,7 +4,7 @@ interface LabelProps { function Label({ value }: LabelProps) { return ( - +

{value}

); } diff --git a/client/src/components/icons/ChevronRightIcon.tsx b/client/src/components/icons/ChevronRightIcon.tsx index 4773896..aa88603 100644 --- a/client/src/components/icons/ChevronRightIcon.tsx +++ b/client/src/components/icons/ChevronRightIcon.tsx @@ -1,4 +1,4 @@ -function ChevronLeftIcon() { +function ChevronRightIcon() { return ( + + + ); +} + +export default ChevronUpIcon; diff --git a/client/src/components/modals/CreateScheduleModal.tsx b/client/src/components/modals/CreateScheduleModal.tsx index c4af0d5..c582e1b 100644 --- a/client/src/components/modals/CreateScheduleModal.tsx +++ b/client/src/components/modals/CreateScheduleModal.tsx @@ -181,7 +181,7 @@ function CreateScheduleModal({
setWeekends(options)} />
diff --git a/client/src/components/modals/CreateScheduledSessionModal.tsx b/client/src/components/modals/CreateScheduledSessionModal.tsx new file mode 100644 index 0000000..2ab83e0 --- /dev/null +++ b/client/src/components/modals/CreateScheduledSessionModal.tsx @@ -0,0 +1,90 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import { format } from "date-fns"; +import Button from "../Button"; +import CloseIcon from "../icons/CloseIcon"; +import Input from "../Input"; +import Label from "../Label"; +import useModalStore from "../../stores/useModalStore"; + +function CreateScheduledSessionModal() { + const { setModal } = useModalStore(); + + return ( +
+
+

Запланировать демонстрацию

+ +
+
+
+
+

Демонстрация

+
+
+
+

Дата и время

+

{format(new Date(), "dd.MM.yyyy HH:mm")}

+
+
+

Длительность сеанса

+

30 мин.

+
+
+

Жилой комплекс

+

Название ЖК

+
+
+
+
+
+
+
+
+

Укажите данные клиента*

+

+ На указанный почтовый адрес будет отправлена информация + необходимая для подключения +

+
+

+ *не обязательно +

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+ ); +} + +export default CreateScheduledSessionModal; diff --git a/client/src/pages/DashboardPage.tsx b/client/src/pages/DashboardPage.tsx index d55534d..d6195ca 100644 --- a/client/src/pages/DashboardPage.tsx +++ b/client/src/pages/DashboardPage.tsx @@ -26,6 +26,8 @@ import ModalContainer from "../components/ModalContainer"; import CreateScheduleModal from "../components/modals/CreateScheduleModal"; import MoreIcon from "../components/icons/MoreIcon"; import ISchedule from "../types/ISchedule"; +import Calendar from "../components/Calendar"; +import ChevronUpIcon from "../components/icons/ChevronUpIcon"; function DashboardPage() { const [user, setAccessToken] = useAuthStore((state) => [ @@ -66,43 +68,48 @@ function DashboardPage() { setSelectedDate(new Date()); } + // useEffect(() => { + // console.log("schedules", schedules); + + // if (!selectedDate || !selectedBuild || !schedules?.length) return; + + // const foundSchedule = schedules.find( + // (schedule) => + // isWithinInterval(selectedDate, { + // start: new Date(schedule.startDate), + // end: addDays(new Date(schedule.startDate), 14), + // }) && selectedBuild.id === schedule.buildId + // ); + + // console.log("foundSchedule", foundSchedule); + + // if (foundSchedule) { + // const startDateTime = parse( + // foundSchedule.startTime, + // "HH:mm", + // selectedDate + // ); + // const endDateTime = parse(foundSchedule.endTime, "HH:mm", selectedDate); + // const step = foundSchedule.sessionDuration + foundSchedule.sessionBreak; + + // setDateTimes( + // eachMinuteOfInterval( + // { + // start: startDateTime, + // end: endDateTime, + // }, + // { step } + // ) + // ); + // } else { + // setDateTimes(undefined); + // setGeneratedScheduledSessions(undefined); + // } + // }, [selectedDate, selectedBuild, schedules]); + useEffect(() => { - console.log("schedules", schedules); - - if (!selectedDate || !selectedBuild || !schedules?.length) return; - - const foundSchedule = schedules.find( - (schedule) => - isWithinInterval(selectedDate, { - start: new Date(schedule.startDate), - end: addDays(new Date(schedule.startDate), 14), - }) && selectedBuild.id === schedule.buildId - ); - - console.log("foundSchedule", foundSchedule); - - if (foundSchedule) { - const startDateTime = parse( - foundSchedule.startTime, - "HH:mm", - selectedDate - ); - const endDateTime = parse(foundSchedule.endTime, "HH:mm", selectedDate); - const step = foundSchedule.sessionDuration + foundSchedule.sessionBreak; - - setDateTimes( - eachMinuteOfInterval( - { - start: startDateTime, - end: endDateTime, - }, - { step } - ) - ); - } else { - setDateTimes(undefined); - setGeneratedScheduledSessions(undefined); - } + if (!schedules) return; + // const schedule = schedules.find(schedule => schedule.startDate); }, [selectedDate, selectedBuild, schedules]); async function getCompany() { @@ -402,7 +409,7 @@ function DashboardPage() { return (
{format(scheduledSession, "HH:mm")}
@@ -466,8 +473,15 @@ function DashboardPage() {
-
-

Календарь

+
+
+

Календарь

+
+ setSelectedDate(date)} + />
diff --git a/server/src/routes/scheduledSessions.ts b/server/src/routes/scheduledSessions.ts index c41b730..98843fb 100644 --- a/server/src/routes/scheduledSessions.ts +++ b/server/src/routes/scheduledSessions.ts @@ -221,29 +221,9 @@ scheduledSessionsRouter.put("/:id", async (req, res) => { const scheduledSessionId = req.params.id; let { - startAt, - endAt, activeSessionId, }: { startAt: string; endAt: string; activeSessionId: string } = req.body; - if (!startAt && !endAt) { - return res.json({ - status: "error", - message: "Parameter `startAt` or `duration` is required, or both", - }); - } - - if (startAt && !isValid(parseISO(startAt))) { - return res.json({ - status: "error", - message: "Invalid value of the `startAt` parameter", - }); - } - - // function isInteger(num: number) { - // return (num ^ 0) === num; - // } - const scheduledSession = await ScheduledSession.findById(scheduledSessionId); if (!scheduledSession) { @@ -256,7 +236,7 @@ scheduledSessionsRouter.put("/:id", async (req, res) => { try { const scheduledSession = await ScheduledSession.findByIdAndUpdate( scheduledSessionId, - { startAt, endAt, activeSessionId }, + { activeSessionId }, { new: true } ); diff --git a/server/src/routes/schedules.ts b/server/src/routes/schedules.ts index 17aad05..dc8e61e 100644 --- a/server/src/routes/schedules.ts +++ b/server/src/routes/schedules.ts @@ -7,12 +7,11 @@ schedulesRouter.get( "/companies/:companyId/builds/:buildId", async (req, res) => { const { companyId, buildId } = req.params; - const date = new Date(); + // const date = new Date(); const schedules = await Schedule.find({ companyId, buildId, - startDate: { $lte: date }, }); if (!schedules.length) { @@ -24,7 +23,6 @@ schedulesRouter.get( const schedule = await Schedule.findOne({ companyId, buildId, - startDate: { $lte: date }, }); res.json(schedule);