This commit is contained in:
2023-10-25 13:24:38 +05:00
parent efd370e79e
commit 6aac2a1811
6 changed files with 154 additions and 51 deletions
+4 -8
View File
@@ -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);
}
+22 -4
View File
@@ -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 &&
+33 -2
View File
@@ -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>
+83 -6
View File
@@ -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>
+3 -26
View File
@@ -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}
+4
View File
@@ -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",