Files
stream.graff.tech-client/src/CalendarPage.tsx
T
2023-10-25 13:24:38 +05:00

358 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
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-unused-vars */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { FormEvent, useEffect, useState } from "react";
import Calendar from "react-calendar";
import "react-calendar/dist/Calendar.css";
import "./CalendarPage.css";
import {
format,
isBefore,
differenceInBusinessDays,
setHours,
getHours,
setMinutes,
getMinutes,
setSeconds,
setMilliseconds,
} from "date-fns";
import ru from "date-fns/locale/ru";
import ky from "ky";
import { useParams } from "react-router-dom";
import InputMask from "react-input-mask";
function CalendarPage() {
const params = useParams();
const [step, setStep] = useState<number>(1);
const [date, setDate] = useState<Date>(new Date());
const [name, setName] = useState<string>("");
const [email, setEmail] = useState<string>("");
const [phone, setPhone] = useState<string>("");
const [link, setLink] = useState<string>("");
const [datesAndTimes, setDatesAndTimes] = useState<any[]>([]);
const [scheduledSessions, setScheduledSessions] = useState<any[]>([]);
async function selectDate(value: any) {
await getScheduledSessions("653675f420af0dadee9003ec", value);
setDate(value);
setStep((prev) => prev + 1);
}
async function getScheduledSessions(buildId: string, date: Date) {
const result: any[] = await ky
.get(
`https://crm.stream.graff.tech/api/scheduled_sessions/${buildId}?date=${date.toISOString()}`
)
.json();
console.log(result);
setScheduledSessions(result);
}
function selectTime(value: any) {
let newDate = date;
newDate = setHours(date, getHours(value));
newDate = setMinutes(newDate, getMinutes(value));
newDate = setSeconds(newDate, 0);
newDate = setMilliseconds(newDate, 0);
setDate(newDate);
setStep((prev) => prev + 1);
}
async function addSchedule(e: FormEvent) {
e.preventDefault();
const username = params.username;
const title = "nksJukovaDev";
const startAt = date;
try {
const result: any = await ky
.post(`${import.meta.env.VITE_COORD_URL}/scheduled_sessions`, {
json: {
username,
name,
email,
phone,
title,
startAt,
},
})
.json();
if (!result.userInviteLink) {
alert(result.error);
return;
}
setLink(result.userInviteLink);
setName("");
setEmail("");
setPhone("");
setStep(4);
} catch (error: any) {
alert(error.message);
}
}
async function getSessionScheduleSettings() {
const username = params.username;
try {
const result: any = await ky
.get(
`${
import.meta.env.VITE_COORD_URL
}/session_schedule_settings/${username}`
)
.json();
if (result.error) {
console.log("Error: ", result.error);
return;
}
const { datesAndTimes } = result;
console.log(datesAndTimes);
setDatesAndTimes(datesAndTimes);
} catch (error) {
if (error instanceof Error) {
console.log(error.message);
}
}
}
useEffect(() => {
getSessionScheduleSettings();
}, []);
return (
<div className="min-h-screen flex justify-center items-center p-8 rounded-lg text-white">
{step === 1 && (
<div className="space-y-8 w-80">
<p className="text-4xl font-gilroy">
Выберите
<br />
дату
</p>
<Calendar onChange={selectDate} value={date} minDate={new Date()} />
</div>
)}
{step === 2 && (
<div className="space-y-8">
<p className="text-4xl font-gilroy">
Выберите
<br />
время
</p>
<div className="space-y-4">
<button
onClick={() => setStep((prev) => prev - 1)}
className="text-[#C5C7CE] flex items-center gap-1 bg-[#1C1D21] p-1 pr-4 text-xs rounded"
>
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M15 19L8 12L15 5"
stroke="#C5C7CE"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
<span>Выбор даты</span>
</button>
<p className="text-xl font-gilroy">
{format(date, "dd MMMM", { locale: ru })}
</p>
<div className="grid grid-cols-4">
{datesAndTimes.map(
(dateAndTime: { value: Date; active: true }, index: number) =>
!differenceInBusinessDays(date, new Date()) ? (
isBefore(new Date(), new Date(dateAndTime.value)) && (
<button
key={index}
onClick={() => selectTime(new Date(dateAndTime.value))}
className="px-3 py-2 text-center rounded hover:bg-[#23242A] disabled:hover:bg-inherit disabled:opacity-25"
disabled={
scheduledSessions.filter(
(session) => session.startAt === dateAndTime.value
).length >= 3
}
>
{format(new Date(dateAndTime.value), "HH:mm")}
</button>
)
) : (
<button
key={index}
onClick={() => selectTime(new Date(dateAndTime.value))}
className="px-3 py-2 text-center rounded hover:bg-[#23242A] disabled:hover:bg-inherit disabled:opacity-25"
disabled={
scheduledSessions.filter(
(session) => session.startAt === dateAndTime.value
).length >= 3
}
>
{format(new Date(dateAndTime.value), "HH:mm")}
</button>
)
)}
</div>
</div>
</div>
)}
{step === 3 && (
<div className="space-y-8 w-80">
<p className="text-4xl font-gilroy">
Расскажите
<br />о себе
</p>
<div className="space-y-4">
<button
onClick={() => setStep((prev) => prev - 1)}
className="text-[#C5C7CE] flex items-center gap-1 bg-[#1C1D21] p-1 pr-4 text-xs rounded"
>
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M15 19L8 12L15 5"
stroke="#C5C7CE"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
<span>Выбор времени</span>
</button>
<p className="text-xl font-gilroy">
{format(date, "dd MMMM HH:mm", { locale: ru })}
</p>
<form onSubmit={addSchedule} className="space-y-12">
<div className="space-y-4">
<div className="space-y-1">
<p className="text-[#C5C7CE]">Имя</p>
<input
required
type="text"
className="px-4 py-3 bg-[#23242A] rounded outline-none w-full"
placeholder="Константин"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</div>
<div className="space-y-1">
<p className="text-[#C5C7CE]">Email</p>
<input
required
type="email"
className="px-4 py-3 bg-[#23242A] rounded outline-none w-full"
placeholder="example@mail.ru"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div className="space-y-1">
<p className="text-[#C5C7CE]">Телефон</p>
<InputMask
mask={"+999999999999999"}
maskChar={null}
required
type="tel"
className="px-4 py-3 bg-[#23242A] rounded outline-none w-full"
placeholder="+79009998877"
value={phone}
onChange={(e) => setPhone(e.target.value)}
/>
</div>
</div>
<button
type="submit"
className="px-4 py-2 bg-gradient w-full rounded"
>
Запланировать
</button>
</form>
</div>
</div>
)}
{step === 4 && (
<div className="space-y-8 w-80">
<p className="text-4xl font-gilroy">
Просмотр
<br />
запланирован
</p>
<div className="space-y-12">
<p className="text-[#C5C7CE]">
Ссылка для подключения и другая дополнительная информация будут
отправлены на ваш почтовый адрес.
</p>
<div className="space-y-4">
<div className="space-y-1">
<p>Скопируйте ссылку для поключения</p>
<input
type="text"
className="px-4 py-3 bg-[#23242A] rounded outline-none w-full"
defaultValue={link}
/>
</div>
<p className="text-center">или</p>
<a
href={link}
target="_blank"
className="inline-block px-4 py-2 bg-gradient w-full rounded text-center"
>
Подключиться
</a>
<div className="h-0.5 bg-[#23242A]"></div>
<a
onClick={() => setStep(1)}
href="#"
className="inline-block px-4 py-2 w-full rounded text-center bg-[#1C1D21] text-[#C5C7CE]"
>
На сайт жилого комплекса
</a>
</div>
</div>
</div>
)}
</div>
);
}
export default CalendarPage;