Files
crm.stream.graff.tech/client/src/pages/AdminCompanyPage.tsx
T
2025-03-26 13:33:37 +05:00

191 lines
5.8 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 */
import { useEffect, useState } from "react";
import api from "../utils/api";
import IError from "../types/IError";
import Button from "../components/Button";
import useModalStore from "../stores/useModalStore";
import ModalContainer from "../components/ModalContainer";
import { useNavigate, useParams } from "react-router-dom";
import IBuild from "../types/IBuild";
import CreateBuildModal from "../components/modals/CreateBuildModal";
import IUser from "../types/IUser";
import CreateUserModal from "../components/modals/CreateUserModal";
import { Transition } from "react-transition-group";
import SpinnerIcon from "../components/icons/SpinnerIcon";
import MoreIcon from "../components/icons/MoreIcon";
import EditUserModal from "../components/modals/EditUserModal";
function AdminCompanyPage() {
const { companyId } = useParams();
const [builds, setBuilds] = useState<IBuild[]>();
const [users, setUsers] = useState<IUser[]>();
const { setModal } = useModalStore();
const navigate = useNavigate();
const [isLoading, setIsLoading] = useState<boolean>(true);
async function getBuilds() {
if (!companyId) return;
try {
const result: IBuild[] | IError = await api
.get(`admin/builds?companyId=${companyId}`)
.json();
if ("error" in result) {
alert(result.error);
return;
}
setBuilds(result);
} catch (error) {
alert((error as Error).message);
}
}
async function getUsers() {
if (!companyId) return;
try {
const result: IUser[] | IError = await api
.get(`admin/users?companyId=${companyId}`)
.json();
if ("error" in result) {
alert(result.error);
return;
}
setUsers(result);
} catch (error) {
alert((error as Error).message);
}
}
useEffect(() => {
getBuilds();
getUsers();
}, []);
useEffect(() => {
if (!users || !builds) {
return;
}
setIsLoading(false);
}, [users, builds]);
return (
<div className="flex flex-col min-h-screen gap-8 p-8 bg-gray-100">
<div className="flex gap-8">
<Button
variant="secondary"
size="medium"
className="border border-gray-300"
onClick={() => navigate("..")}
>
Назад
</Button>
</div>
<div className="space-y-4">
<div className="flex items-center gap-4">
<p className="text-xl font-semibold">Жилые комплексы</p>
<Button
onClick={() =>
companyId && setModal(<CreateBuildModal companyId={companyId} />)
}
>
Добавить ЖК
</Button>
</div>
<div className="grid grid-cols-4 gap-4 pb-8 border-b border-gray-300">
{builds &&
builds.map((build) => (
<div className="relative overflow-hidden bg-white rounded-xl">
<img
src=""
alt=""
className="object-cover bg-gray-400 aspect-video"
/>
<div className="absolute text-left text-white bottom-4 left-6">
<p className="text-xl font-semibold">{build.name}</p>
<p className="">
Сборка приложения:{" "}
<span className="font-semibold">{build.build}</span>
</p>
</div>
</div>
))}
</div>
</div>
<div className="pb-8 space-y-4 border-b border-gray-300">
<div className="flex items-center gap-4">
<p className="text-xl font-semibold">Пользователи</p>
<Button
onClick={() =>
companyId && setModal(<CreateUserModal companyId={companyId} />)
}
>
Добавить пользователя
</Button>
</div>
<div className="grid grid-cols-5 gap-4">
{users &&
users.map((user) => (
<div
key={user.id}
className="flex items-start justify-between gap-4 p-4 rounded-lg shadow"
>
<div className="flex gap-4">
<img
src={user.avatar || "/images/no-avatar.png"}
alt=""
className="w-8 h-8 bg-gray-500 rounded-full"
/>
<div className="text-sm">
<p>{user.name}</p>
<p>{user.username}</p>
<p>Роль: {user.role}</p>
<p>
Связанные ЖК:{" "}
{builds
?.filter((build) => user.buildIds?.includes(build.id))
.map((build) => build.name)
.join(", ") || "Нет связанных сборок"}
</p>
</div>
</div>
<Button
variant="secondary"
icon={<MoreIcon className="w-5 h-5" />}
onlyIcon
onClick={() =>
companyId &&
setModal(
<EditUserModal companyId={companyId} userId={user.id} />
)
}
/>
</div>
))}
</div>
</div>
<ModalContainer />
<Transition in={isLoading} timeout={150} mountOnEnter unmountOnExit>
{(state) => (
<div
className={`fixed top-0 left-0 w-full h-full flex items-center justify-center bg-black bg-opacity-50 transition-all ${state}`}
>
<SpinnerIcon />
</div>
)}
</Transition>
</div>
);
}
export default AdminCompanyPage;