Files
crm.stream.graff.tech/client/src/components/Card.tsx
T
2024-11-06 21:14:16 +05:00

188 lines
6.1 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-explicit-any */
import { useEffect, useState } from "react";
import SelectUser from "./SelectUser";
import MoreIcon from "./icons/MoreIcon";
import api from "../utils/api";
import Button from "./Button";
import { Link } from "react-router-dom";
import IUser from "../types/IUser";
import useAuthStore from "../stores/useAuthStore";
import EntryIcon from "./icons/EntryIcon";
import { isAfter, subMinutes } from "date-fns";
interface CardProps {
companyId: string;
buildId: string;
scheduledSessionId: string;
scheduleSessionStartAt: string;
client?: {
name: string;
phone: string;
email: string;
};
manager?: IUser;
managers: IUser[];
handleSelect: (scheduledSessionId: string, managerId: string | null) => void;
}
function Card({
companyId,
buildId,
scheduledSessionId,
scheduleSessionStartAt,
client,
manager,
managers,
handleSelect,
}: CardProps) {
const { user } = useAuthStore();
const [isShow, setIsShow] = useState<boolean>(false);
const [availableManagers, setAvailableManagers] = useState<IUser[]>();
async function getAvailableManagers() {
const result: any[] = await api
.get(
`companies/${companyId}/builds/${buildId}/scheduledSessions/${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="relative flex flex-col gap-2">
<div className="w-[264px] h-[164px] px-3 py-2 bg-white border-r border-b border-[#DAE0E5] flex flex-col justify-between gap-2">
<div className="space-y-2">
<div className="flex justify-between">
<div className="">
<p className="text-[10px] font-semibold text-[#77828C]">Клиент</p>
<p className="text-sm">{client?.name || "Имя не указано"}</p>
</div>
{manager ? (
<div className="bg-[#E6F2FE] rounded-full px-2 h-[20px] flex items-center gap-1">
<div className="w-1 h-1 rounded-full bg-[#49A1F5]"></div>
<p className="text-[10px] font-semibold text-[#49A1F5]">
Готов
</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>
<p className="text-xs text-[#77828C] leading-tight">
{client?.phone || "Телефон не указан"}
</p>
<p className="text-xs text-[#77828C] leading-tight">
{client?.email || "Email не указан"}
</p>
</div>
</div>
<div className="flex justify-between items-center pt-2 py-1 border-t border-[#DAE0E5] h-[45px]">
<div className="flex items-center gap-2">
{manager ? (
<img
src={manager.avatar || "/images/no-avatar.png"}
alt=""
className="w-6 h-6 rounded-full"
/>
) : (
<div className="w-6 h-6 bg-[#E6ECF2] rounded-full"></div>
)}
<p className="text-xs font-semibold">
{manager ? manager.name : "Не назначен"}
</p>
</div>
<div className="flex gap-2">
{user?.role === "manager" &&
(manager ? (
isAfter(
new Date(),
subMinutes(new Date(scheduleSessionStartAt), 10)
) ? (
<Link
to={`${
import.meta.env.VITE_STREAM_URL
}/scheduled/${scheduledSessionId}?admin=true`}
target="_blank"
>
<Button>Начать</Button>
</Link>
) : (
manager.id === user.id && (
<Button
variant="secondary"
onClick={() => handleSelect(scheduledSessionId, null)}
>
Отменить
</Button>
)
)
) : (
<Button
variant="secondary"
onClick={() => handleSelect(scheduledSessionId, user.id)}
>
Выбрать
</Button>
))}
{user?.role === "admin" && (
<div className="flex gap-1">
{manager && (
<Link
to={`${
import.meta.env.VITE_STREAM_URL
}/scheduled/${scheduledSessionId}?admin=true`}
target="_blank"
>
<Button variant="secondary" icon={<EntryIcon />} onlyIcon />
</Link>
)}
<button
onClick={() => setIsShow(!isShow)}
className="p-1 text-[#77828C] hover:bg-neutral-100 rounded-lg"
>
<MoreIcon />
</button>
</div>
)}
</div>
</div>
</div>
<div className="absolute z-10 pl-[calc(264px+8px)]">
{availableManagers && availableManagers.length > 0 && (
<SelectUser
shown={isShow}
selectedManagerId={manager?.id}
managers={availableManagers}
handleClick={(managerId) => (
handleSelect(scheduledSessionId, managerId), setIsShow(false)
)}
handleShown={() => setIsShow((prev) => !prev)}
/>
)}
</div>
</div>
);
}
export default Card;