upd
This commit is contained in:
@@ -1,14 +1,8 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { useEffect, useState } from "react";
|
||||
import { ChangeEvent, useEffect, useState } from "react";
|
||||
import Timeline from "./Timeline";
|
||||
import {
|
||||
format,
|
||||
getDate,
|
||||
setDate,
|
||||
setHours,
|
||||
startOfDay,
|
||||
} from "date-fns";
|
||||
import { format, getDate, setDate, setHours, startOfDay } from "date-fns";
|
||||
// import useEventStore from "../stores/useEventStore";
|
||||
import Button from "./Button";
|
||||
import CloseIcon from "./icons/CloseIcon";
|
||||
@@ -16,15 +10,17 @@ import Input from "./Input";
|
||||
import Label from "./Label";
|
||||
import api from "../utils/api";
|
||||
import useStore from "../stores/useStore";
|
||||
import Select2 from "./Select2";
|
||||
import IScheduledSession from "../types/IScheduledSession";
|
||||
|
||||
interface Props {
|
||||
selectedDay: Date;
|
||||
slots: number;
|
||||
events: any[];
|
||||
events: IScheduledSession[];
|
||||
}
|
||||
|
||||
function Schedule({ selectedDay, slots, events }: Props) {
|
||||
const { selectedBuild } = useStore();
|
||||
const { company, builds, selectedBuild, setSelectedBuild } = useStore();
|
||||
const [draftMode, setDraftMode] = useState<boolean>(false);
|
||||
const [slot, setSlot] = useState<number>();
|
||||
const [startAt, setStartAt] = useState<Date>();
|
||||
@@ -77,6 +73,7 @@ function Schedule({ selectedDay, slots, events }: Props) {
|
||||
await api
|
||||
.post(`scheduled_sessions`, {
|
||||
json: {
|
||||
companyId: company!.id,
|
||||
buildId: selectedBuild?.id,
|
||||
slot,
|
||||
startAt,
|
||||
@@ -97,9 +94,17 @@ function Schedule({ selectedDay, slots, events }: Props) {
|
||||
// setModal(null);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!builds) return;
|
||||
|
||||
setSelectedBuild(builds[0]);
|
||||
|
||||
console.log(builds);
|
||||
}, [builds]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("events", events);
|
||||
}, []);
|
||||
}, [events]);
|
||||
|
||||
return (
|
||||
<div className="relative h-screen overflow-y-auto bg-[#F2F2F2] text-sm">
|
||||
@@ -114,7 +119,7 @@ function Schedule({ selectedDay, slots, events }: Props) {
|
||||
key={index}
|
||||
className="border-r border-b border-[#DAE0E5] w-[264px] h-10 flex items-center pl-3 bg-[#F0F1F2]"
|
||||
>
|
||||
<p className="font-semibold">Слот {index + 1}</p>
|
||||
<p className="font-semibold">Сервер {index + 1}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -166,6 +171,24 @@ function Schedule({ selectedDay, slots, events }: Props) {
|
||||
<div className="px-4 space-y-2">
|
||||
<p className="font-semibold">Демонстрация</p>
|
||||
<div className="">
|
||||
<div className="py-1 space-y-1 text-xs">
|
||||
<p className="text-[#77828C]">Выберите ЖК</p>
|
||||
<Select2
|
||||
defaultValue={selectedBuild?.build}
|
||||
options={builds.map((build) => ({
|
||||
value: build.build,
|
||||
text: build.name,
|
||||
}))}
|
||||
onChange={(e: ChangeEvent<HTMLSelectElement>) =>
|
||||
setSelectedBuild(
|
||||
builds.find(
|
||||
(build) =>
|
||||
build.build === e.target.selectedOptions[0].value
|
||||
)!
|
||||
)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="grid items-center grid-cols-2 gap-4 py-1 text-xs">
|
||||
<p className="text-[#77828C]">Дата и время</p>
|
||||
<p className="">{format(startAt, "dd.MM.yyyy HH:mm")}</p>
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import { ChangeEvent } from "react";
|
||||
|
||||
interface IOption {
|
||||
value: string;
|
||||
text: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
defaultValue?: string;
|
||||
options: IOption[];
|
||||
onChange: (e: ChangeEvent<HTMLSelectElement>) => void;
|
||||
}
|
||||
|
||||
function Select2({ defaultValue, options, onChange }: Props) {
|
||||
function handleChange(e: ChangeEvent<HTMLSelectElement>) {
|
||||
onChange(e);
|
||||
}
|
||||
|
||||
return (
|
||||
<select
|
||||
onChange={handleChange}
|
||||
defaultValue={defaultValue}
|
||||
className="px-2 py-2.5 outline-none rounded-lg border border-[#DAE0E5] focus:border-[#49A1F5] transition-colors text-sm w-full h-10"
|
||||
>
|
||||
{options.map((option, index) => (
|
||||
<option key={index} value={option.value}>
|
||||
{option.text}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
);
|
||||
}
|
||||
|
||||
export default Select2;
|
||||
@@ -4,9 +4,11 @@ import { useState, MouseEvent, useEffect, useRef } from "react";
|
||||
import TimelineSlot from "./TimelineSlot";
|
||||
import { addMinutes, differenceInMinutes, format, startOfDay } from "date-fns";
|
||||
import Button from "./Button";
|
||||
import IScheduledSession from "../types/IScheduledSession";
|
||||
import useStore from "../stores/useStore";
|
||||
|
||||
interface Props {
|
||||
timelineEvents: any[];
|
||||
timelineEvents: IScheduledSession[];
|
||||
slot: number;
|
||||
draftMode: boolean;
|
||||
onChangeDraftMode: (draftMode: boolean) => void;
|
||||
@@ -33,6 +35,7 @@ function Timeline({
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const [startAt, setStartAt] = useState<string>();
|
||||
const [duration, setDuration] = useState<number>(30); // min
|
||||
const { builds } = useStore();
|
||||
|
||||
function handleMouseDown(e: MouseEvent<HTMLDivElement>) {
|
||||
if (draftMode) return;
|
||||
@@ -168,10 +171,13 @@ function Timeline({
|
||||
}}
|
||||
>
|
||||
<div className="flex flex-col justify-between h-full">
|
||||
<p>
|
||||
{format(new Date(event.startAt), "HH:mm")} -{" "}
|
||||
{format(new Date(event.endAt), "HH:mm")}
|
||||
</p>
|
||||
<div className="space-y-1">
|
||||
<p>
|
||||
{format(new Date(event.startAt), "HH:mm")} -{" "}
|
||||
{format(new Date(event.endAt), "HH:mm")}
|
||||
</p>
|
||||
<p>{builds.find((build) => build.id === event.buildId)?.name}</p>
|
||||
</div>
|
||||
<a
|
||||
href={`https://stream.graff.tech/scheduled/${event.id}?admin=true`}
|
||||
target="_blank"
|
||||
|
||||
@@ -55,7 +55,7 @@ function CreateScheduledSessionModal({ buildId, startAt, duration }: Props) {
|
||||
onSubmit={addSchesuledSession}
|
||||
>
|
||||
<div className="p-2 pl-6 flex justify-between items-center border-b border-[#DAE0E5]">
|
||||
<p className="font-semibold text-sm">Запланировать демонстрацию</p>
|
||||
<p className="text-sm font-semibold">Запланировать демонстрацию</p>
|
||||
<span className="text-[#77828C]">
|
||||
<Button
|
||||
color="tertiary"
|
||||
@@ -68,18 +68,18 @@ function CreateScheduledSessionModal({ buildId, startAt, duration }: Props) {
|
||||
<div className="px-6 py-8 space-y-8 border-b border-[#DAE0E5]">
|
||||
<div className="flex gap-4">
|
||||
<div className="w-[240px]">
|
||||
<p className="font-semibold text-sm">Демонстрация</p>
|
||||
<p className="text-sm font-semibold">Демонстрация</p>
|
||||
</div>
|
||||
<div className="w-[296px]">
|
||||
<div className="grid grid-cols-2 gap-4 text-xs py-1">
|
||||
<div className="grid grid-cols-2 gap-4 py-1 text-xs">
|
||||
<p className="text-[#77828C]">Дата и время</p>
|
||||
<p className="">{format(startAt, "dd.MM.yyyy HH:mm")}</p>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4 text-xs py-1">
|
||||
<div className="grid grid-cols-2 gap-4 py-1 text-xs">
|
||||
<p className="text-[#77828C]">Длительность сеанса</p>
|
||||
<p className="">{duration} мин.</p>
|
||||
</div>
|
||||
{/* <div className="grid grid-cols-2 gap-4 text-xs py-1">
|
||||
{/* <div className="grid grid-cols-2 gap-4 py-1 text-xs">
|
||||
<p className="text-[#77828C]">Жилой комплекс</p>
|
||||
<p className="">Название ЖК</p>
|
||||
</div> */}
|
||||
@@ -90,7 +90,7 @@ function CreateScheduledSessionModal({ buildId, startAt, duration }: Props) {
|
||||
<div className="w-[240px]">
|
||||
<div className="flex flex-col justify-between h-full">
|
||||
<div className="space-y-2">
|
||||
<p className="font-semibold text-sm">Укажите данные клиента*</p>
|
||||
<p className="text-sm font-semibold">Укажите данные клиента*</p>
|
||||
<p className="text-xs text-[#77828C]">
|
||||
На указанный почтовый адрес будет отправлена информация
|
||||
необходимая для подключения
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import {
|
||||
eachMinuteOfInterval,
|
||||
format,
|
||||
parse,
|
||||
addDays,
|
||||
subDays,
|
||||
isEqual,
|
||||
} from "date-fns";
|
||||
import { format, addDays, subDays } from "date-fns";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import TabButton from "../components/TabButton";
|
||||
import api from "../utils/api";
|
||||
import { ru } from "date-fns/locale";
|
||||
import useStore from "../stores/useStore";
|
||||
@@ -24,6 +16,7 @@ import ChevronRightIcon from "../components/icons/ChevronRightIcon";
|
||||
import IUser from "../types/IUser";
|
||||
import IError from "../types/IError";
|
||||
import Schedule from "../components/Schedule";
|
||||
import IScheduledSession from "../types/IScheduledSession";
|
||||
|
||||
function DashboardPage() {
|
||||
const { user } = useAuthStore();
|
||||
@@ -31,20 +24,19 @@ function DashboardPage() {
|
||||
company,
|
||||
setCompany,
|
||||
selectedBuild,
|
||||
setSelectedBuild,
|
||||
builds,
|
||||
setBuilds,
|
||||
managers,
|
||||
setManagers,
|
||||
schedules,
|
||||
setSchedules,
|
||||
selectedDay,
|
||||
setSelectedDay,
|
||||
} = useStore();
|
||||
const [, setDuration] = useState<number>();
|
||||
const [scheduledSessions, setScheduledSessions] = useState<any[]>();
|
||||
const [, setGeneratedScheduledSessions] = useState<any[]>();
|
||||
const [dateTimes, setDateTimes] = useState<Date[]>();
|
||||
// const [, setDuration] = useState<number>();
|
||||
const [scheduledSessions, setScheduledSessions] = useState<
|
||||
IScheduledSession[]
|
||||
>([]);
|
||||
// const [, setGeneratedScheduledSessions] = useState<any[]>();
|
||||
// const [dateTimes, setDateTimes] = useState<Date[]>();
|
||||
const [, setCurrentTime] = useState<string>(format(new Date(), "HH:mm"));
|
||||
const [, setIsLoadingScheduledSessions] = useState(true);
|
||||
const scheduledSessionsRef = useRef<HTMLDivElement>(null);
|
||||
@@ -61,78 +53,6 @@ function DashboardPage() {
|
||||
setSelectedDay(new Date());
|
||||
}
|
||||
|
||||
function findSessionsByTime(time: Date) {
|
||||
if (!scheduledSessions || !scheduledSessions.length) return [];
|
||||
|
||||
const foundScheduledSessions = scheduledSessions?.filter(
|
||||
(scheduledSession) => isEqual(new Date(scheduledSession.startAt), time)
|
||||
);
|
||||
|
||||
return foundScheduledSessions;
|
||||
}
|
||||
|
||||
function generateScheduledSessions() {
|
||||
if (!selectedBuild) return;
|
||||
|
||||
const newGeneratedScheduledSession: any[] = [];
|
||||
|
||||
dateTimes?.forEach((time) => {
|
||||
const foundSessionsByTime = findSessionsByTime(time);
|
||||
const sessions: any[] = [];
|
||||
|
||||
if (foundSessionsByTime) {
|
||||
sessions.push(...foundSessionsByTime);
|
||||
}
|
||||
|
||||
for (
|
||||
let index = 0;
|
||||
index < selectedBuild.sessionLimit - foundSessionsByTime.length;
|
||||
index++
|
||||
) {
|
||||
sessions.push({});
|
||||
}
|
||||
|
||||
newGeneratedScheduledSession.push({
|
||||
time,
|
||||
sessions,
|
||||
});
|
||||
});
|
||||
|
||||
setGeneratedScheduledSessions(newGeneratedScheduledSession);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!scheduledSessions || !selectedBuild || !selectedDay) return;
|
||||
generateScheduledSessions();
|
||||
}, [scheduledSessions, selectedBuild, selectedDay]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!schedules || !selectedDay || !selectedBuild) return;
|
||||
|
||||
console.log("schedules", schedules);
|
||||
|
||||
const foundSchedule = schedules.find(
|
||||
(schedule) => schedule.buildId === selectedBuild.id
|
||||
);
|
||||
|
||||
if (!foundSchedule) {
|
||||
setDateTimes([]);
|
||||
return;
|
||||
}
|
||||
|
||||
const step = foundSchedule.sessionDuration + foundSchedule.sessionBreak; // 35
|
||||
const newTimes = eachMinuteOfInterval(
|
||||
{
|
||||
start: parse(foundSchedule.startTime, "HH:mm", new Date(selectedDay)), // 11:00
|
||||
end: parse(foundSchedule.endTime, "HH:mm", new Date(selectedDay)), // 20:00
|
||||
},
|
||||
{ step }
|
||||
);
|
||||
|
||||
setDateTimes(newTimes);
|
||||
setDuration(foundSchedule.sessionDuration);
|
||||
}, [schedules, selectedDay, selectedBuild]);
|
||||
|
||||
async function getCompany() {
|
||||
if (!user) {
|
||||
console.log("No User", user);
|
||||
@@ -141,6 +61,7 @@ function DashboardPage() {
|
||||
|
||||
try {
|
||||
const result: any = await api.get(`companies/${user.companyId}`).json();
|
||||
|
||||
setCompany(result);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
@@ -159,6 +80,7 @@ function DashboardPage() {
|
||||
const result: any = await api
|
||||
.get(`companies/${user.companyId}/builds`)
|
||||
.json();
|
||||
|
||||
setBuilds(result);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
@@ -196,22 +118,19 @@ function DashboardPage() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!selectedBuild || !selectedBuild.id) {
|
||||
console.log("No selectedBuild");
|
||||
return;
|
||||
}
|
||||
|
||||
if (useLoader) setIsLoadingScheduledSessions(true);
|
||||
|
||||
try {
|
||||
const result: any = await api
|
||||
.get(
|
||||
`companies/${company.id}/builds/${
|
||||
selectedBuild.id
|
||||
`companies/${
|
||||
company.id
|
||||
}/scheduled_sessions?date=${selectedDay.toISOString()}`
|
||||
)
|
||||
.json();
|
||||
|
||||
console.log(result);
|
||||
|
||||
setScheduledSessions(result);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
@@ -222,44 +141,6 @@ function DashboardPage() {
|
||||
if (useLoader) setIsLoadingScheduledSessions(false);
|
||||
}
|
||||
|
||||
// async function updateScheduledSessionManager(
|
||||
// scheduledSessionId: string,
|
||||
// managerId: string | null
|
||||
// ) {
|
||||
// if (!company || !scheduledSessions) return;
|
||||
|
||||
// try {
|
||||
// const result: any = await api
|
||||
// .put(
|
||||
// `companies/${company.id}/scheduled_sessions/${scheduledSessionId}`,
|
||||
// {
|
||||
// json: { userId: managerId },
|
||||
// }
|
||||
// )
|
||||
// .json();
|
||||
|
||||
// setScheduledSessions(
|
||||
// scheduledSessions.map((scheduledSession) =>
|
||||
// scheduledSession.id === result.id ? result : scheduledSession
|
||||
// )
|
||||
// );
|
||||
// } catch (error) {
|
||||
// if (error instanceof Error) {
|
||||
// console.log("Error: ", error.message);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
async function getSchedules() {
|
||||
if (!company || !selectedBuild) return;
|
||||
|
||||
const result: any[] = await api
|
||||
.get(`companies/${company.id}/builds/${selectedBuild.id}/schedules`)
|
||||
.json();
|
||||
|
||||
setSchedules(result);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getCompany();
|
||||
|
||||
@@ -274,16 +155,19 @@ function DashboardPage() {
|
||||
|
||||
useEffect(() => {
|
||||
if (!company) return;
|
||||
|
||||
getBuilds();
|
||||
}, [company]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!builds) return;
|
||||
setSelectedBuild(builds[0]);
|
||||
|
||||
getManagers();
|
||||
}, [builds]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!managers || !selectedDay || !selectedBuild) return;
|
||||
if (!managers || !selectedDay || !company || !builds) return;
|
||||
|
||||
getScheduledSessions(true);
|
||||
|
||||
const interval = setInterval(() => {
|
||||
@@ -293,35 +177,17 @@ function DashboardPage() {
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
};
|
||||
}, [managers, selectedDay, selectedBuild]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!company || !selectedBuild) return;
|
||||
|
||||
getSchedules();
|
||||
getManagers();
|
||||
}, [selectedBuild]);
|
||||
}, [managers, selectedDay, company, builds]);
|
||||
|
||||
useEffect(() => {
|
||||
scheduledSessionsRef.current?.scrollTo({ top: 0, behavior: "smooth" });
|
||||
}, [selectedDay, selectedBuild]);
|
||||
}, [selectedDay]);
|
||||
|
||||
return (
|
||||
<div className="flex h-screen main">
|
||||
<div className="flex flex-col w-full left">
|
||||
<div className="flex bg-[#F0F1F2]">
|
||||
<Menu />
|
||||
{builds?.map((build) => (
|
||||
<TabButton
|
||||
key={build.id}
|
||||
handleClick={() => setSelectedBuild(build)}
|
||||
active={
|
||||
(selectedBuild && build.id === selectedBuild?.id) || false
|
||||
}
|
||||
>
|
||||
{build.name}
|
||||
</TabButton>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between items-center px-4 py-2 h-12 border-r border-b border-[#DAE0E5]">
|
||||
@@ -436,10 +302,10 @@ function DashboardPage() {
|
||||
)}
|
||||
</div> */}
|
||||
|
||||
{selectedBuild?.sessionLimit && scheduledSessions && (
|
||||
{company && scheduledSessions && (
|
||||
<Schedule
|
||||
selectedDay={selectedDay}
|
||||
slots={selectedBuild.sessionLimit}
|
||||
slots={company.sessionLimit}
|
||||
events={scheduledSessions}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
interface ICompany {
|
||||
id: string;
|
||||
name: string;
|
||||
sessionLimit: number;
|
||||
}
|
||||
|
||||
export default ICompany;
|
||||
|
||||
@@ -2,6 +2,7 @@ interface IScheduledSession {
|
||||
id: string;
|
||||
companyId: string;
|
||||
buildId: string;
|
||||
slot: number;
|
||||
startAt: string;
|
||||
endAt: string;
|
||||
client?: unknown;
|
||||
|
||||
@@ -21,14 +21,14 @@ companySchema.virtual("users", {
|
||||
foreignField: "companyId",
|
||||
});
|
||||
|
||||
companySchema.virtual("scheduledSessions", {
|
||||
ref: "Scheduled_Session",
|
||||
companySchema.virtual("builds", {
|
||||
ref: "Build",
|
||||
localField: "_id",
|
||||
foreignField: "companyId",
|
||||
});
|
||||
|
||||
companySchema.virtual("builds", {
|
||||
ref: "Build",
|
||||
companySchema.virtual("scheduledSessions", {
|
||||
ref: "Scheduled_Session",
|
||||
localField: "_id",
|
||||
foreignField: "companyId",
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@ const scheduledSessionSchema = new Schema(
|
||||
companyId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "Company",
|
||||
// required: true,
|
||||
required: true,
|
||||
},
|
||||
buildId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
|
||||
@@ -68,7 +68,7 @@ router.get("/:id/builds/:buildId/users", async (req, res) => {
|
||||
res.json(users);
|
||||
});
|
||||
|
||||
router.get("/:id/builds/:buildId/scheduled_sessions", async (req, res) => {
|
||||
router.get("/:id/scheduled_sessions", async (req, res) => {
|
||||
if (req.params.id != res.locals.user.companyId) {
|
||||
res.json({ error: "Access denied" });
|
||||
return;
|
||||
@@ -82,22 +82,16 @@ router.get("/:id/builds/:buildId/scheduled_sessions", async (req, res) => {
|
||||
const date = parseISO(req.query.date as string);
|
||||
|
||||
const company: any = await Company.findById(req.params.id).populate({
|
||||
path: "builds",
|
||||
path: "scheduledSessions",
|
||||
match: {
|
||||
_id: req.params.buildId,
|
||||
},
|
||||
populate: {
|
||||
path: "scheduledSessions",
|
||||
match: {
|
||||
startAt: {
|
||||
$gte: startOfDay(date),
|
||||
$lte: endOfDay(date),
|
||||
},
|
||||
startAt: {
|
||||
$gte: startOfDay(date),
|
||||
$lte: endOfDay(date),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const { scheduledSessions } = company.builds[0];
|
||||
const { scheduledSessions } = company;
|
||||
|
||||
res.json(scheduledSessions);
|
||||
});
|
||||
|
||||
@@ -75,9 +75,9 @@ router.get("/:buildId", async (req, res) => {
|
||||
});
|
||||
|
||||
router.post("/", async (req, res) => {
|
||||
const { buildId, slot, startAt, client, duration } = req.body;
|
||||
const { companyId, buildId, slot, startAt, client, duration } = req.body;
|
||||
|
||||
if (!buildId || !startAt || !slot) {
|
||||
if (!companyId || !buildId || !startAt || !slot) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "Parameters `buildId`, `startAt`, `slot` are required!", // Параметры `buildId`, `startAt`, `slot` обязательны!
|
||||
@@ -104,6 +104,7 @@ router.post("/", async (req, res) => {
|
||||
|
||||
if (duration) {
|
||||
const scheduledSessions = await ScheduledSession.find({
|
||||
companyId,
|
||||
buildId,
|
||||
slot,
|
||||
startAt: {
|
||||
@@ -141,6 +142,7 @@ router.post("/", async (req, res) => {
|
||||
}
|
||||
|
||||
const scheduledSession = await ScheduledSession.create({
|
||||
companyId,
|
||||
buildId,
|
||||
slot,
|
||||
startAt: startAtISO,
|
||||
|
||||
Reference in New Issue
Block a user