Files
stream.graff.tech-client/src/components/SidebarTab2.tsx
T
2024-11-06 21:14:50 +05:00

211 lines
5.9 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-irregular-whitespace */
import { Trans } from "react-i18next";
import useSidebarTabStore from "../stores/useSidebarStore";
import TimeSelector from "./TimeSelector";
import CloseIcon from "./icons/CloseIcon";
import {
eachMinuteOfInterval,
format,
isAfter,
parse,
} from "date-fns";
import i18n from "../i18n";
import { enUS, ru } from "date-fns/locale";
import ky from "ky";
import { useEffect, useState } from "react";
import LoaderIcon from "./icons/LoaderIcon";
function SidebarTab2() {
const {
currentTab,
setCurrentTab,
setIsOpen,
setSelectedTime,
selectedDay,
companyId,
buildId,
} = useSidebarTabStore();
const [build, setBuild] = useState<{ [key: string]: any }>();
const [scheduledSessions, setScheduledSessions] = useState<any[]>();
const [schedule, setSchedule] = useState<{ [key: string]: any }>();
const [scheduleTimes, setScheduleTimes] = useState<any[]>();
function handleSelectTime(time: string) {
setSelectedTime(time);
setCurrentTab(currentTab + 1);
}
async function getBuild() {
const result: { [key: string]: any } = await ky
.get(`${import.meta.env.VITE_CRM_API_URL}/builds/${buildId}`)
.json();
setBuild(result);
}
async function getScheduledSessions() {
if (!selectedDay) return;
const result: any[] = await ky
.get(
`${
import.meta.env.VITE_CRM_API_URL
}/scheduledSessions/companies/${companyId}/builds/${buildId}?date=${format(
selectedDay,
"yyyy-MM-dd"
)}`
)
.json();
setScheduledSessions(result);
}
async function getSchedule() {
if (!selectedDay) return;
try {
const result: { [key: string]: any } = await ky
.get(
`${
import.meta.env.VITE_CRM_API_URL
}/schedules/companies/${companyId}/builds/${buildId}?date=${format(
selectedDay,
"yyyy-MM-dd"
)}`
)
.json();
setSchedule(result);
} catch (error) {
if (error instanceof Error) {
console.log("Error: ", error.message);
}
}
}
function generateScheduleTimes() {
if (!selectedDay || !build || !scheduledSessions || !schedule) return;
const step = schedule.sessionDuration + schedule.sessionBreak;
console.log("selectedDay", selectedDay);
const times = eachMinuteOfInterval(
{
start: parse(schedule.startTime, "HH:mm", selectedDay),
end: parse(schedule.endTime, "HH:mm", selectedDay),
},
{ step }
);
console.log("scheduledSessions", scheduledSessions);
const formatTimes = times.map((time) => ({
value: format(time, "HH:mm"),
active:
isAfter(time, new Date()) &&
scheduledSessions.filter(
(scheduledSession) => scheduledSession.startAt === time.toISOString()
).length < build.sessionLimit,
}));
setScheduleTimes(formatTimes);
}
useEffect(() => {
getBuild();
}, [selectedDay]);
useEffect(() => {
if (!build) return;
getScheduledSessions();
}, [build]);
useEffect(() => {
if (!scheduledSessions) return;
getSchedule();
}, [scheduledSessions]);
useEffect(() => {
if (!schedule) return;
generateScheduleTimes();
}, [schedule]);
return (
<div className="flex flex-col justify-between min-h-full gap-6 p-6 sm:p-8 sm:gap-8">
<div>
<div className="flex items-start justify-between">
<p className="text-2xl font-semibold leading-snug text-gradient font-gilroy w-fit">
<Trans i18nKey={"sidebar.title1"}>Дата и время</Trans>
</p>
<button
onClick={() => setIsOpen(false)}
className="transition-opacity hover:opacity-50"
>
<CloseIcon />
</button>
</div>
<div className="mt-2">
<div className="grid grid-cols-2 gap-2">
<div className="border-b border-[#3D425C] p-4 text-center">
<p className="text-sm font-semibold leading-none font-gilroy">
{selectedDay &&
format(
selectedDay,
"dd MMMM",
i18n.language === "ru" ? { locale: ru } : { locale: enUS }
)}
</p>
</div>
<div className="border-b border-[#798FFF] p-4 text-center">
<p className="text-sm font-semibold leading-none font-gilroy">
<Trans i18nKey={"sidebar.time"}>Время</Trans>
</p>
</div>
</div>
</div>
<div className="mt-6">
{scheduleTimes && scheduleTimes.length > 0 ? (
<TimeSelector
times={scheduleTimes || []}
handleSelect={(time) => handleSelectTime(time)}
/>
) : (
<LoaderIcon className="w-6 h-6 2xl:w-8 2xl:h-8 animate-spin" />
)}
</div>
</div>
<div className="flex flex-col gap-4 sm:gap-6">
<p className="text-xs leading-tight text-center opacity-50">
<Trans i18nKey={"sidebar.notice"}>
Запись на демонстрацию работает в ознакомительном режиме и не
сохраняет введенные данные
</Trans>
</p>
<div className="flex gap-2 sm:gap-4">
<button
onClick={() => setCurrentTab(currentTab - 1)}
className="px-6 sm:py-4 py-3.5 border border-[#3D425C] rounded-full font-medium group w-full"
>
<span className="text-sm transition-opacity opacity-80 group-hover:opacity-100 sm:text-base">
<Trans i18nKey={"sidebar.buttonBack"}>Назад</Trans>
</span>
</button>
</div>
</div>
</div>
);
}
export default SidebarTab2;