This commit is contained in:
2023-08-07 15:05:18 +05:00
commit 5e07a8952e
84 changed files with 8097 additions and 0 deletions
+361
View File
@@ -0,0 +1,361 @@
/* 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(value);
setDate(value);
setStep((prev) => prev + 1);
}
async function getScheduledSessions(value: Date) {
const username = params.username;
const result: any[] = await ky
.get(
`${
import.meta.env.VITE_COORD_URL
}/scheduled_sessions/${username}?date=${value.toISOString()}`
)
.json();
console.log(scheduledSessions);
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;