upd
This commit is contained in:
+100
-43
@@ -1,7 +1,15 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { useEffect, useState } from "react";
|
||||
import SelectUser from "./SelectUser";
|
||||
import MoreIcon from "./icons/MoreIcon";
|
||||
import api from "../utils/api";
|
||||
|
||||
interface CardProps {
|
||||
companyId: string;
|
||||
buildId: string;
|
||||
scheduledSessionId: string;
|
||||
scheduleSessionStartAt: string;
|
||||
client: {
|
||||
name: string;
|
||||
phone: string;
|
||||
@@ -12,57 +20,106 @@ interface CardProps {
|
||||
name: string;
|
||||
avatar: string;
|
||||
};
|
||||
managers: any[];
|
||||
handleSelect: (scheduledSessionId: string, managerId: string) => void;
|
||||
}
|
||||
|
||||
function Card({ client, manager }: CardProps) {
|
||||
function Card({
|
||||
companyId,
|
||||
buildId,
|
||||
scheduledSessionId,
|
||||
scheduleSessionStartAt,
|
||||
client,
|
||||
manager,
|
||||
managers,
|
||||
handleSelect,
|
||||
}: CardProps) {
|
||||
const [isShow, setIsShow] = useState<boolean>(false);
|
||||
const [availableManagers, setAvailableManagers] = useState<any[]>();
|
||||
|
||||
async function getAvailableManagers() {
|
||||
const result: any[] = await api
|
||||
.get(
|
||||
`companies/${companyId}/builds/${buildId}/scheduled_sessions/${scheduledSessionId}/availableManagers?startAt=${scheduleSessionStartAt}`
|
||||
)
|
||||
.json();
|
||||
|
||||
const filteredManagers = managers.filter(
|
||||
(manager) => !result.includes(manager.id)
|
||||
);
|
||||
|
||||
setAvailableManagers(filteredManagers);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!isShow) return;
|
||||
getAvailableManagers();
|
||||
}, [isShow]);
|
||||
|
||||
return (
|
||||
<div className="w-[264px] h-[128px] px-3 py-2 bg-white border-r border-b border-[#DAE0E5] flex flex-col gap-2">
|
||||
<div className="flex justify-between">
|
||||
<p className="text-sm font-semibold">{client.name}</p>
|
||||
{manager ? (
|
||||
<div className="bg-[#DAF2E4] rounded-full px-2 h-[20px] flex items-center gap-1">
|
||||
<div className="w-1 h-1 rounded-full bg-[#27AE60]"></div>
|
||||
<p className="text-[10px] font-semibold text-[#27AE60] pt-0.5">
|
||||
Сеанс начат
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="bg-[#F2DADA] rounded-full px-2 h-[20px] flex items-center gap-1">
|
||||
<div className="w-1 h-1 rounded-full bg-[#EB5757]"></div>
|
||||
<p className="text-[10px] font-semibold text-[#EB5757] pt-0.5">
|
||||
Нет менеджена
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="border-b border-[#DAE0E5] pb-2">
|
||||
<p className="text-xs text-[#77828C] leading-tight">{client.phone}</p>
|
||||
<p className="text-xs text-[#77828C] leading-tight">{client.email}</p>
|
||||
</div>
|
||||
<div className="flex justify-between items-center py-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="relative flex flex-col gap-2">
|
||||
<div className="w-[264px] h-[128px] px-3 py-2 bg-white border-r border-b border-[#DAE0E5] flex flex-col gap-2">
|
||||
<div className="flex justify-between">
|
||||
<p className="text-sm font-semibold">{client.name}</p>
|
||||
{manager ? (
|
||||
<div className="relative">
|
||||
<img
|
||||
src={manager.avatar}
|
||||
alt=""
|
||||
className="w-6 h-6 rounded-full"
|
||||
/>
|
||||
<div className="absolute right-0 bottom-0 bg-[#27AE60] border border-white rounded-full w-2 h-2"></div>
|
||||
<div className="bg-[#DAF2E4] rounded-full px-2 h-[20px] flex items-center gap-1">
|
||||
<div className="w-1 h-1 rounded-full bg-[#27AE60]"></div>
|
||||
<p className="text-[10px] font-semibold text-[#27AE60] pt-0.5">
|
||||
Сеанс начат
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="w-6 h-6 bg-[#ccc] rounded-full"></div>
|
||||
<div className="bg-[#F2DADA] rounded-full px-2 h-[20px] flex items-center gap-1">
|
||||
<div className="w-1 h-1 rounded-full bg-[#EB5757]"></div>
|
||||
<p className="text-[10px] font-semibold text-[#EB5757] pt-0.5">
|
||||
Нет менеджера
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
<p className="text-xs font-semibold">
|
||||
{manager ? manager.name : "Не назначен"}
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => alert("Чё тыкаешь? В разработке еще!!")}
|
||||
className="p-1 text-[#77828C] hover:bg-neutral-100 rounded-lg"
|
||||
>
|
||||
<MoreIcon />
|
||||
</button>
|
||||
<div className="border-b border-[#DAE0E5] pb-2">
|
||||
<p className="text-xs text-[#77828C] leading-tight">{client.phone}</p>
|
||||
<p className="text-xs text-[#77828C] leading-tight">{client.email}</p>
|
||||
</div>
|
||||
<div className="flex justify-between items-center py-1">
|
||||
<div className=" flex items-center gap-2">
|
||||
{manager ? (
|
||||
<div className="relative">
|
||||
<img
|
||||
src={manager.avatar}
|
||||
alt=""
|
||||
className="w-6 h-6 rounded-full"
|
||||
/>
|
||||
{/* <div className="absolute right-0 bottom-0 bg-[#27AE60] border border-white rounded-full w-2 h-2"></div> */}
|
||||
</div>
|
||||
) : (
|
||||
<div className="w-6 h-6 bg-[#ccc] rounded-full"></div>
|
||||
)}
|
||||
<p className="text-xs font-semibold">
|
||||
{manager ? manager.name : "Не назначен"}
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setIsShow(!isShow)}
|
||||
className="p-1 text-[#77828C] hover:bg-neutral-100 rounded-lg"
|
||||
>
|
||||
<MoreIcon />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="absolute bottom-[2px] left-[272px] z-10">
|
||||
{availableManagers?.length && (
|
||||
<SelectUser
|
||||
shown={isShow}
|
||||
selectedManagerId={manager?.id}
|
||||
managers={availableManagers}
|
||||
handleClick={(managerId) => (
|
||||
handleSelect(scheduledSessionId, managerId), setIsShow(false)
|
||||
)}
|
||||
handleShown={() => setIsShow((prev) => !prev)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
interface SelectUserProps {
|
||||
shown: boolean;
|
||||
selectedManagerId?: string;
|
||||
managers: any[];
|
||||
handleClick: (managerId: string) => void;
|
||||
handleShown: () => void;
|
||||
}
|
||||
|
||||
import { Transition } from "react-transition-group";
|
||||
import CheckIcon from "./icons/CheckIcon";
|
||||
import useOutsideClick from "../hooks/useOutsideClick";
|
||||
|
||||
function SelectUser({
|
||||
shown,
|
||||
selectedManagerId,
|
||||
managers,
|
||||
handleClick,
|
||||
handleShown,
|
||||
}: SelectUserProps) {
|
||||
const selectUserRef = useOutsideClick(handleShown);
|
||||
|
||||
return (
|
||||
<Transition in={shown} timeout={150} mountOnEnter unmountOnExit>
|
||||
{(state) => (
|
||||
<div
|
||||
ref={selectUserRef}
|
||||
className={`bg-white w-[280px] max-h-[126px] overflow-auto rounded-lg py-2 flex flex-col gap-1 transition-opacity ${state}`}
|
||||
style={{ boxShadow: "0px 1px 4px 0px rgba(0, 0, 0, 0.16)" }}
|
||||
>
|
||||
{managers.map((manager) => (
|
||||
<button
|
||||
onClick={() => handleClick(manager.id)}
|
||||
className="px-4 flex justify-between gap-2 w-full py-1 transition-colors hover:bg-[#E6ECF2]"
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="relative">
|
||||
<img
|
||||
src={
|
||||
manager.avatar ||
|
||||
"https://as2.ftcdn.net/v2/jpg/00/64/67/27/1000_F_64672736_U5kpdGs9keUll8CRQ3p3YaEv2M6qkVY5.jpg"
|
||||
}
|
||||
alt=""
|
||||
className="w-6 h-6 rounded-full"
|
||||
/>
|
||||
{/* <div className="absolute right-0 bottom-0 bg-[#27AE60] border border-white rounded-full w-2 h-2"></div> */}
|
||||
</div>
|
||||
<p className="text-xs">{manager.name}</p>
|
||||
</div>
|
||||
{manager.id === selectedManagerId && (
|
||||
<div className="text-[#49A1F5]">
|
||||
<CheckIcon />
|
||||
</div>
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</Transition>
|
||||
);
|
||||
}
|
||||
|
||||
export default SelectUser;
|
||||
@@ -0,0 +1,20 @@
|
||||
function CheckIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M19.7474 7.33565C20.1143 7.74843 20.0771 8.3805 19.6644 8.74742L10.6644 16.7474C10.2686 17.0992 9.66729 17.0815 9.29289 16.7071L4.29289 11.7071C3.90237 11.3166 3.90237 10.6834 4.29289 10.2929C4.68342 9.90238 5.31658 9.90238 5.70711 10.2929L10.0404 14.6262L18.3356 7.2526C18.7484 6.88568 19.3805 6.92286 19.7474 7.33565Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default CheckIcon;
|
||||
@@ -0,0 +1,21 @@
|
||||
function ChevronDown() {
|
||||
return (
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M7 11L12 16L17 11"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default ChevronDown;
|
||||
@@ -0,0 +1,23 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
function useOutsideClick(callback: () => void) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
if (ref.current && !ref.current.contains(event.target as Node)) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("mousedown", handleClickOutside);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("mousedown", handleClickOutside);
|
||||
};
|
||||
}, [callback]);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
export default useOutsideClick;
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import Card from "../components/Card";
|
||||
import EmptyCard from "../components/EmptyCard";
|
||||
import TabButton from "../components/TabButton";
|
||||
@@ -48,6 +48,7 @@ function DashboardPage() {
|
||||
);
|
||||
const [isLoadingScheduledSessions, setIsLoadingScheduledSessions] =
|
||||
useState(true);
|
||||
const scheduledSessionsRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// const [selectedDate, setSelectedDate] = useState(
|
||||
// format(new Date(), "d MMMM, yyyy", { locale: ru })
|
||||
@@ -73,7 +74,6 @@ function DashboardPage() {
|
||||
|
||||
try {
|
||||
const result: any = await api.get(`companies/${user.companyId}`).json();
|
||||
console.log("getCompany result: ", result);
|
||||
setCompany(result);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
@@ -92,7 +92,6 @@ function DashboardPage() {
|
||||
const result: any = await api
|
||||
.get(`companies/${user.companyId}/builds`)
|
||||
.json();
|
||||
console.log("getBuilds result: ", result);
|
||||
setBuilds(result);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
@@ -109,7 +108,6 @@ function DashboardPage() {
|
||||
|
||||
try {
|
||||
const result: any = await api.get(`companies/${company.id}/users`).json();
|
||||
console.log("getManagers result: ", result);
|
||||
setManagers(result);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
@@ -118,20 +116,18 @@ function DashboardPage() {
|
||||
}
|
||||
}
|
||||
|
||||
async function getScheduledSessions() {
|
||||
async function getScheduledSessions(useLoader?: boolean) {
|
||||
if (!company) {
|
||||
console.log("No ScheduledSessions");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("selectedBuild", selectedBuild);
|
||||
|
||||
if (!selectedBuild || !selectedBuild.id) {
|
||||
console.log("No selectedBuild");
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoadingScheduledSessions(true);
|
||||
if (useLoader) setIsLoadingScheduledSessions(true);
|
||||
|
||||
try {
|
||||
const result: any = await api
|
||||
@@ -141,16 +137,15 @@ function DashboardPage() {
|
||||
}/scheduled_sessions?date=${selectedDate.toISOString()}`
|
||||
)
|
||||
.json();
|
||||
console.log("getScheduledSessions result: ", result);
|
||||
|
||||
setScheduledSessions(result);
|
||||
setIsLoadingScheduledSessions(false);
|
||||
} catch (error) {
|
||||
setIsLoadingScheduledSessions(false);
|
||||
if (error instanceof Error) {
|
||||
console.log("Error: ", error.message);
|
||||
}
|
||||
}
|
||||
|
||||
if (useLoader) setIsLoadingScheduledSessions(false);
|
||||
}
|
||||
|
||||
function logout() {
|
||||
@@ -185,6 +180,36 @@ function DashboardPage() {
|
||||
setGeneratedScheduledSessions(arr);
|
||||
}
|
||||
|
||||
async function updateScheduledSessionManager(
|
||||
scheduledSessionId: string,
|
||||
managerId: string
|
||||
) {
|
||||
if (!company || !scheduledSessions) return;
|
||||
|
||||
try {
|
||||
const result: any = await api
|
||||
.put(
|
||||
`companies/${company.id}/scheduled_sessions/${scheduledSessionId}`,
|
||||
{
|
||||
json: { userId: managerId },
|
||||
}
|
||||
)
|
||||
.json();
|
||||
|
||||
console.log(scheduledSessions, result);
|
||||
|
||||
setScheduledSessions(
|
||||
scheduledSessions.map((scheduledSession) =>
|
||||
scheduledSession.id === result.id ? result : scheduledSession
|
||||
)
|
||||
);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
console.log("Error: ", error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getCompany();
|
||||
|
||||
@@ -210,18 +235,27 @@ function DashboardPage() {
|
||||
|
||||
useEffect(() => {
|
||||
if (!managers || !selectedDate || !selectedBuild) return;
|
||||
getScheduledSessions();
|
||||
getScheduledSessions(true);
|
||||
|
||||
console.log(selectedBuild);
|
||||
const interval = setInterval(() => {
|
||||
getScheduledSessions();
|
||||
}, 3000);
|
||||
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
};
|
||||
}, [managers, selectedDate, selectedBuild]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!scheduledSessions) return;
|
||||
generateScheduledSessions();
|
||||
|
||||
console.log(scheduledSessions);
|
||||
}, [scheduledSessions]);
|
||||
|
||||
useEffect(() => {
|
||||
// setIsLoadingScheduledSessions(true);
|
||||
scheduledSessionsRef.current?.scrollTo({ top: 0, behavior: "smooth" });
|
||||
}, [selectedDate, selectedBuild]);
|
||||
|
||||
return (
|
||||
<div className="main h-screen flex">
|
||||
<div className="left flex flex-col w-full">
|
||||
@@ -282,6 +316,7 @@ function DashboardPage() {
|
||||
</div>
|
||||
|
||||
<div
|
||||
ref={scheduledSessionsRef}
|
||||
className={`overflow-y-auto overflow-x-hidden flex-1 bg-[#F2F2F2] border-r border-[#DAE0E5]`}
|
||||
>
|
||||
<Transition
|
||||
@@ -299,43 +334,65 @@ function DashboardPage() {
|
||||
)}
|
||||
</Transition>
|
||||
|
||||
{!isLoadingScheduledSessions &&
|
||||
{company &&
|
||||
selectedBuild &&
|
||||
user &&
|
||||
managers?.length &&
|
||||
generatedScheduledSessions?.map(
|
||||
(generatedScheduledSession, index) => (
|
||||
<div key={index} className="flex">
|
||||
{generatedScheduledSession.map((scheduledSession, index2) => {
|
||||
if (index2 === 0) {
|
||||
return (
|
||||
<div
|
||||
key={index2}
|
||||
className="w-[84px] h-[128px] flex justify-center items-center text-sm font-semibold bg-[#F0F1F2] border-r border-b border-[#DAE0E5]"
|
||||
>
|
||||
{format(scheduledSession, "HH:mm")}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
if (Object.keys(scheduledSession).length) {
|
||||
return (
|
||||
<Card
|
||||
key={index2}
|
||||
client={{
|
||||
name: scheduledSession.clientName,
|
||||
phone: scheduledSession.clientPhone,
|
||||
email: scheduledSession.clientEmail,
|
||||
}}
|
||||
manager={managers?.find(
|
||||
(manager) =>
|
||||
manager.id === scheduledSession.userId
|
||||
)}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return <EmptyCard key={index2} />;
|
||||
(generatedScheduledSession, index) => {
|
||||
return (
|
||||
<div key={index} className="flex">
|
||||
{generatedScheduledSession.map(
|
||||
(scheduledSession, index2) => {
|
||||
if (index2 === 0) {
|
||||
return (
|
||||
<div
|
||||
key={index2}
|
||||
className="w-[84px] h-[128px] flex justify-center items-center text-sm font-semibold bg-[#F0F1F2] border-r border-b border-[#DAE0E5]"
|
||||
>
|
||||
{format(scheduledSession, "HH:mm")}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
if (Object.keys(scheduledSession).length) {
|
||||
const selectedManager = managers.find(
|
||||
(manager) => manager.id == scheduledSession.userId
|
||||
);
|
||||
|
||||
return (
|
||||
<Card
|
||||
key={index2}
|
||||
companyId={company.id}
|
||||
buildId={selectedBuild.id}
|
||||
scheduledSessionId={scheduledSession.id}
|
||||
scheduleSessionStartAt={
|
||||
scheduledSession.startAt
|
||||
}
|
||||
client={{
|
||||
name: scheduledSession.clientName,
|
||||
phone: scheduledSession.clientPhone,
|
||||
email: scheduledSession.clientEmail,
|
||||
}}
|
||||
manager={selectedManager}
|
||||
managers={managers}
|
||||
// managers={managers}
|
||||
handleSelect={(scheduledSessionId, managerId) =>
|
||||
updateScheduledSessionManager(
|
||||
scheduledSessionId,
|
||||
managerId
|
||||
)
|
||||
}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return <EmptyCard key={index2} />;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,8 +4,7 @@ import Company from "../models/Company.js";
|
||||
const appRouter = Router();
|
||||
|
||||
appRouter.post("/", async (_req, res) => {
|
||||
const companies = await Company.find();
|
||||
console.log(companies);
|
||||
await Company.find();
|
||||
|
||||
res.json({ route: "app" });
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Router } from "express";
|
||||
import Company from "../models/Company.js";
|
||||
import { parseISO, startOfDay, endOfDay } from "date-fns";
|
||||
import ScheduledSession from "../models/ScheduledSession.js";
|
||||
|
||||
const companiesRouter = Router();
|
||||
|
||||
@@ -82,4 +83,102 @@ companiesRouter.get(
|
||||
}
|
||||
);
|
||||
|
||||
companiesRouter.put(
|
||||
"/:id/scheduled_sessions/:scheduledSessionId",
|
||||
async (req, res) => {
|
||||
if (req.params.id != res.locals.user.companyId) {
|
||||
res.json({ error: "Access denied!" });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const scheduledSession = await ScheduledSession.findById(
|
||||
req.params.scheduledSessionId
|
||||
);
|
||||
|
||||
const scheduledSessionAtSameTime = await ScheduledSession.find({
|
||||
startAt: scheduledSession?.startAt,
|
||||
userId: req.body.userId,
|
||||
});
|
||||
|
||||
if (scheduledSessionAtSameTime.length) {
|
||||
res.json({ error: "Scheduled session at same time" });
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedScheduledSession = await ScheduledSession.findOneAndUpdate(
|
||||
{
|
||||
_id: req.params.scheduledSessionId,
|
||||
companyId: req.params.id,
|
||||
},
|
||||
req.body,
|
||||
{
|
||||
new: true,
|
||||
upsert: true,
|
||||
}
|
||||
);
|
||||
|
||||
res.json(updatedScheduledSession);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
res.json({ error });
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
companiesRouter.get(
|
||||
"/:id/builds/:buildId/scheduled_sessions/:scheduledSessionId/availableManagers",
|
||||
async (req, res) => {
|
||||
if (!req.query.startAt) {
|
||||
res.json({ error: "No dateTime" });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const scheduledSession = await ScheduledSession.findById(
|
||||
req.params.scheduledSessionId
|
||||
);
|
||||
|
||||
const scheduledSessionsAtSameTime = await ScheduledSession.find({
|
||||
companyId: req.params.id,
|
||||
buildId: req.params.buildId,
|
||||
startAt: req.query.startAt,
|
||||
});
|
||||
|
||||
const { users }: any = await Company.findById(req.params.id).populate(
|
||||
"users"
|
||||
);
|
||||
|
||||
let userIds = users.map((user: any) => user.id);
|
||||
|
||||
console.log(scheduledSession?.userId);
|
||||
|
||||
for (const userId of userIds) {
|
||||
console.log(userId);
|
||||
}
|
||||
|
||||
let sessionsUserIds: any[] = [];
|
||||
|
||||
for (const session of scheduledSessionsAtSameTime) {
|
||||
if (session.userId) {
|
||||
sessionsUserIds.push(session.userId.toString());
|
||||
}
|
||||
}
|
||||
|
||||
const filteredUserIds = userIds.filter(
|
||||
(userId: any) => !sessionsUserIds.includes(userId)
|
||||
);
|
||||
|
||||
filteredUserIds.push(scheduledSession?.userId);
|
||||
|
||||
res.json(filteredUserIds);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
res.json({ error });
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export default companiesRouter;
|
||||
|
||||
Reference in New Issue
Block a user