upd
This commit is contained in:
@@ -33,24 +33,20 @@ function CalendarPage() {
|
||||
const [scheduledSessions, setScheduledSessions] = useState<any[]>([]);
|
||||
|
||||
async function selectDate(value: any) {
|
||||
await getScheduledSessions(value);
|
||||
await getScheduledSessions("653675f420af0dadee9003ec", value);
|
||||
|
||||
setDate(value);
|
||||
setStep((prev) => prev + 1);
|
||||
}
|
||||
|
||||
async function getScheduledSessions(value: Date) {
|
||||
const username = params.username;
|
||||
|
||||
async function getScheduledSessions(buildId: string, date: Date) {
|
||||
const result: any[] = await ky
|
||||
.get(
|
||||
`${
|
||||
import.meta.env.VITE_COORD_URL
|
||||
}/scheduled_sessions/${username}?date=${value.toISOString()}`
|
||||
`https://crm.stream.graff.tech/api/scheduled_sessions/${buildId}?date=${date.toISOString()}`
|
||||
)
|
||||
.json();
|
||||
|
||||
console.log(scheduledSessions);
|
||||
console.log(result);
|
||||
|
||||
setScheduledSessions(result);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
add,
|
||||
differenceInDays,
|
||||
eachDayOfInterval,
|
||||
endOfMonth,
|
||||
format,
|
||||
getDay,
|
||||
isAfter,
|
||||
isBefore,
|
||||
isEqual,
|
||||
isWithinInterval,
|
||||
parse,
|
||||
parseISO,
|
||||
startOfToday,
|
||||
} from "date-fns";
|
||||
import { enUS, ru } from "date-fns/locale";
|
||||
@@ -17,6 +23,7 @@ import { Trans } from "react-i18next";
|
||||
import i18n from "../i18n";
|
||||
|
||||
interface CalendarProps {
|
||||
schedules: any[];
|
||||
handleSelect: (day: Date) => void;
|
||||
}
|
||||
|
||||
@@ -24,7 +31,7 @@ function classNames(...classes: (string | boolean)[]) {
|
||||
return classes.filter(Boolean).join(" ");
|
||||
}
|
||||
|
||||
function Calendar({ handleSelect }: CalendarProps) {
|
||||
function Calendar({ schedules, handleSelect }: CalendarProps) {
|
||||
const today = startOfToday();
|
||||
const [selectedDay, setSelectedDay] = useState<Date | null>(null);
|
||||
const [currentMonth, setCurrentMonth] = useState(format(today, "MMM-yyyy"));
|
||||
@@ -46,9 +53,11 @@ function Calendar({ handleSelect }: CalendarProps) {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedDay !== null) {
|
||||
console.log(schedules);
|
||||
|
||||
if (!selectedDay) return;
|
||||
|
||||
handleSelect(selectedDay);
|
||||
}
|
||||
}, [selectedDay]);
|
||||
|
||||
return (
|
||||
@@ -89,7 +98,16 @@ function Calendar({ handleSelect }: CalendarProps) {
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
disabled={day < today}
|
||||
disabled={
|
||||
day < today ||
|
||||
schedules.some(
|
||||
(schedule) =>
|
||||
!isWithinInterval(day, {
|
||||
start: parseISO(schedule.startDate),
|
||||
end: parseISO(schedule.endDate),
|
||||
})
|
||||
)
|
||||
}
|
||||
onClick={() => setSelectedDay(day)}
|
||||
className={classNames(
|
||||
selectedDay !== null &&
|
||||
|
||||
@@ -1,23 +1,47 @@
|
||||
/* 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 Calendar from "./Calendar";
|
||||
import CloseIcon from "./icons/CloseIcon";
|
||||
import { useEffect, useState } from "react";
|
||||
import ky from "ky";
|
||||
|
||||
function SidebarTab1() {
|
||||
const [currentTab, setCurrentTab, setIsOpen, setSelectedDay] =
|
||||
const [currentTab, setCurrentTab, setIsOpen, setSelectedDay, buildId] =
|
||||
useSidebarTabStore((state) => [
|
||||
state.currentTab,
|
||||
state.setCurrentTab,
|
||||
state.setIsOpen,
|
||||
state.setSelectedDay,
|
||||
state.buildId,
|
||||
]);
|
||||
const [schedules, setSchedules] = useState<any[]>();
|
||||
|
||||
function handleSelectDay(day: Date) {
|
||||
setSelectedDay(day);
|
||||
setCurrentTab(currentTab + 1);
|
||||
}
|
||||
|
||||
async function getSchedules() {
|
||||
try {
|
||||
const result: any[] = await ky
|
||||
.get(`http://localhost:3001/schedules/builds/${buildId}`)
|
||||
.json();
|
||||
|
||||
setSchedules(result);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
console.log("Error: ", error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getSchedules();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="sm:p-8 p-6 flex flex-col justify-between sm:gap-8 gap-6 min-h-full">
|
||||
<div>
|
||||
@@ -50,7 +74,14 @@ function SidebarTab1() {
|
||||
</div>
|
||||
|
||||
<div className="sm:mt-8 mt-6">
|
||||
<Calendar handleSelect={(day) => handleSelectDay(day)} />
|
||||
{schedules ? (
|
||||
<Calendar
|
||||
schedules={schedules}
|
||||
handleSelect={(day) => handleSelectDay(day)}
|
||||
/>
|
||||
) : (
|
||||
"Загрузка данных..."
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
/* 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 { format } from "date-fns";
|
||||
import { eachMinuteOfInterval, format, parse, parseISO } from "date-fns";
|
||||
import i18n from "../i18n";
|
||||
import { enUS, ru } from "date-fns/locale";
|
||||
import ky from "ky";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
function SidebarTab2() {
|
||||
const [
|
||||
@@ -15,6 +19,7 @@ function SidebarTab2() {
|
||||
setSelectedTime,
|
||||
selectedDay,
|
||||
selectedTime,
|
||||
buildId,
|
||||
] = useSidebarTabStore((state) => [
|
||||
state.currentTab,
|
||||
state.setCurrentTab,
|
||||
@@ -22,13 +27,84 @@ function SidebarTab2() {
|
||||
state.setSelectedTime,
|
||||
state.selectedDay,
|
||||
state.selectedTime,
|
||||
state.buildId,
|
||||
]);
|
||||
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 getSchedule() {
|
||||
if (!selectedDay) return;
|
||||
|
||||
try {
|
||||
const result: { [key: string]: any } = await ky
|
||||
.get(
|
||||
`http://localhost:3001/schedules/builds/${buildId}?date=${selectedDay.toISOString()}`
|
||||
)
|
||||
.json();
|
||||
|
||||
setSchedule(result);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
console.log("Error: ", error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function generateScheduleTimes() {
|
||||
if (!schedule || !scheduledSessions) return;
|
||||
|
||||
const step = schedule.sessionDuration + schedule.sessionBreak;
|
||||
const times = eachMinuteOfInterval(
|
||||
{
|
||||
start: parse(schedule.startTime, "HH:mm", new Date()),
|
||||
end: parse(schedule.endTime, "HH:mm", new Date()),
|
||||
},
|
||||
{ step }
|
||||
);
|
||||
|
||||
const formatTimes = times.map((time) => ({
|
||||
value: format(time, "HH:mm"),
|
||||
active:
|
||||
scheduledSessions.filter(
|
||||
(scheduledSession) => scheduledSession.startAt === time.toISOString()
|
||||
).length < 3,
|
||||
}));
|
||||
|
||||
setScheduleTimes(formatTimes);
|
||||
}
|
||||
|
||||
async function getScheduledSessions() {
|
||||
if (!selectedDay) return;
|
||||
|
||||
const result: any[] = await ky
|
||||
.get(
|
||||
`http://localhost:3001/scheduled_sessions/builds/${buildId}?date=${selectedDay?.toISOString()}`
|
||||
)
|
||||
.json();
|
||||
|
||||
setScheduledSessions(result);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getScheduledSessions();
|
||||
}, [selectedDay]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!scheduledSessions) return;
|
||||
|
||||
getSchedule();
|
||||
}, [scheduledSessions]);
|
||||
|
||||
useEffect(() => {
|
||||
generateScheduleTimes();
|
||||
}, [schedule]);
|
||||
|
||||
return (
|
||||
<div className="sm:p-8 p-6 flex flex-col justify-between sm:gap-8 gap-6 min-h-full">
|
||||
<div>
|
||||
@@ -59,20 +135,21 @@ function SidebarTab2() {
|
||||
|
||||
<div className="border-b border-[#798FFF] p-4 text-center">
|
||||
<p className="leading-none font-gilroy font-semibold text-sm">
|
||||
{selectedTime ? (
|
||||
selectedTime
|
||||
) : (
|
||||
<Trans i18nKey={"sidebar.time"}>Время</Trans>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6">
|
||||
{scheduleTimes && scheduleTimes.length > 0 ? (
|
||||
<TimeSelector
|
||||
handleSelect={(time: string) => handleSelectTime(time)}
|
||||
times={scheduleTimes}
|
||||
handleSelect={(time) => handleSelectTime(time)}
|
||||
/>
|
||||
) : (
|
||||
"Загрузка данных..."
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,32 +1,12 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { Trans } from "react-i18next";
|
||||
import useSidebarStore from "../stores/useSidebarStore";
|
||||
|
||||
interface TimeSelectorProps {
|
||||
times: any[];
|
||||
handleSelect: (time: string) => void;
|
||||
}
|
||||
|
||||
function TimeSelector({ handleSelect }: TimeSelectorProps) {
|
||||
const [selectedTime] = useSidebarStore((state) => [state.selectedTime]);
|
||||
|
||||
const times = [
|
||||
{ value: "10:00", active: true },
|
||||
{ value: "10:30", active: false },
|
||||
{ value: "11:00", active: true },
|
||||
{ value: "11:30", active: true },
|
||||
{ value: "12:00", active: true },
|
||||
{ value: "12:30", active: true },
|
||||
{ value: "13:00", active: true },
|
||||
{ value: "13:30", active: true },
|
||||
{ value: "14:00", active: false },
|
||||
{ value: "14:30", active: false },
|
||||
{ value: "15:30", active: true },
|
||||
{ value: "15:00", active: true },
|
||||
{ value: "16:30", active: true },
|
||||
{ value: "16:00", active: true },
|
||||
{ value: "17:30", active: true },
|
||||
{ value: "17:00", active: true },
|
||||
];
|
||||
|
||||
function TimeSelector({ times, handleSelect }: TimeSelectorProps) {
|
||||
return (
|
||||
<>
|
||||
<div className="grid grid-cols-4 gap-2 font-medium">
|
||||
@@ -37,9 +17,6 @@ function TimeSelector({ handleSelect }: TimeSelectorProps) {
|
||||
disabled={!time.active}
|
||||
className={[
|
||||
"min-w-[40px] h-10 text-[#798FFF] text-sm rounded-full border border-[#798FFF] flex justify-center items-center transition-colors hover:bg-[#798FFF] hover:bg-opacity-20 hover:text-white disabled:text-[#3D425C] disabled:hover:bg-transparent disabled:border-transparent",
|
||||
time.value === selectedTime
|
||||
? "bg-[#798FFF] text-white"
|
||||
: "text-[#798FFF]",
|
||||
].join(" ")}
|
||||
>
|
||||
{time.value}
|
||||
|
||||
@@ -16,6 +16,8 @@ interface SidebarState {
|
||||
setPhone: (phone: string) => void;
|
||||
email: string;
|
||||
setEmail: (email: string) => void;
|
||||
buildId: string;
|
||||
setBuildId: (buildId: string) => void;
|
||||
}
|
||||
|
||||
const useSidebarStore = create<SidebarState>()(
|
||||
@@ -36,6 +38,8 @@ const useSidebarStore = create<SidebarState>()(
|
||||
setPhone: (phone) => set(() => ({ phone })),
|
||||
email: "",
|
||||
setEmail: (email) => set(() => ({ email })),
|
||||
buildId: "653675f420af0dadee9003ec",
|
||||
setBuildId: (buildId) => set(() => ({ buildId })),
|
||||
})
|
||||
// {
|
||||
// name: "tab-storage",
|
||||
|
||||
Reference in New Issue
Block a user