This commit is contained in:
2024-10-30 20:57:32 +05:00
parent d6809ff538
commit 2435aa2814
46 changed files with 802 additions and 334 deletions
+13 -13
View File
@@ -75,13 +75,13 @@ function AdminCompanyPage() {
}, [users, builds]);
return (
<div className="min-h-screen flex flex-col gap-8 bg-gray-100 p-8">
<div className="flex flex-col min-h-screen gap-8 p-8 bg-gray-100">
<div className="flex gap-8">
<Button
color="secondary"
variant="secondary"
size="medium"
className="border border-gray-300"
handleClick={() => navigate("..")}
onClick={() => navigate("..")}
>
Назад
</Button>
@@ -90,23 +90,23 @@ function AdminCompanyPage() {
<div className="flex items-center gap-4">
<p className="text-xl font-semibold">Жилые комплексы</p>
<Button
handleClick={() =>
onClick={() =>
companyId && setModal(<CreateBuildModal companyId={companyId} />)
}
>
Добавить ЖК
</Button>
</div>
<div className="grid grid-cols-4 gap-4 border-b border-gray-300 pb-8">
<div className="grid grid-cols-4 gap-4 pb-8 border-b border-gray-300">
{builds &&
builds.map((build) => (
<div className="relative bg-white rounded-xl overflow-hidden">
<div className="relative overflow-hidden bg-white rounded-xl">
<img
src=""
alt=""
className="aspect-video bg-gray-400 object-cover"
className="object-cover bg-gray-400 aspect-video"
/>
<div className="absolute bottom-4 left-6 text-white text-left">
<div className="absolute text-left text-white bottom-4 left-6">
<p className="text-xl font-semibold">{build.name}</p>
<p className="">
Сборка приложения:{" "}
@@ -121,11 +121,11 @@ function AdminCompanyPage() {
))}
</div>
</div>
<div className="space-y-4 border-b border-gray-300 pb-8">
<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
handleClick={() =>
onClick={() =>
companyId && setModal(<CreateUserModal companyId={companyId} />)
}
>
@@ -143,7 +143,7 @@ function AdminCompanyPage() {
<img
src={user.avatar || "/images/no-avatar.png"}
alt=""
className="w-8 h-8 rounded-full bg-gray-500"
className="w-8 h-8 bg-gray-500 rounded-full"
/>
<div className="text-sm">
@@ -161,10 +161,10 @@ function AdminCompanyPage() {
</div>
<Button
color="secondary"
variant="secondary"
icon={<MoreIcon />}
onlyIcon
handleClick={() =>
onClick={() =>
companyId &&
setModal(
<EditUserModal companyId={companyId} userId={user.id} />
+5 -5
View File
@@ -46,10 +46,10 @@ function AdminPage() {
}, [companies]);
return (
<div className="min-h-screen flex flex-col gap-8 bg-gray-100 p-8">
<div className="flex flex-col min-h-screen gap-8 p-8 bg-gray-100">
<div className="flex items-center gap-4">
<p className="text-xl font-semibold">Компании</p>
<Button handleClick={() => setModal(<CreateCompanyModal />)}>
<Button onClick={() => setModal(<CreateCompanyModal />)}>
Добавить компанию
</Button>
</div>
@@ -57,15 +57,15 @@ function AdminPage() {
{companies &&
companies.map((company) => (
<button
className="relative bg-white rounded-xl overflow-hidden"
className="relative overflow-hidden bg-white rounded-xl"
onClick={() => navigate(`${company.id}`)}
>
<img
src=""
alt=""
className="aspect-video bg-gray-400 object-cover"
className="object-cover bg-gray-400 aspect-video"
/>
<p className="text-xl font-semibold text-white absolute bottom-4 left-6">
<p className="absolute text-xl font-semibold text-white bottom-4 left-6">
{company.name}
</p>
</button>
+15 -111
View File
@@ -17,13 +17,13 @@ import IUser from "../types/IUser";
import IError from "../types/IError";
import Schedule from "../components/Schedule";
import IScheduledSession from "../types/IScheduledSession";
import toast, { Toaster } from "react-hot-toast";
function DashboardPage() {
const { user } = useAuthStore();
const {
company,
setCompany,
selectedBuild,
builds,
setBuilds,
managers,
@@ -55,7 +55,7 @@ function DashboardPage() {
async function getCompany() {
if (!user) {
console.log("No User", user);
// console.log("No User", user);
return;
}
@@ -64,15 +64,13 @@ function DashboardPage() {
setCompany(result);
} catch (error) {
if (error instanceof Error) {
console.log("Error: ", error.message);
}
toast.error((error as Error).message);
}
}
async function getBuilds() {
if (!user) {
console.log("No User", user);
// console.log("No User", user);
return;
}
@@ -83,20 +81,18 @@ function DashboardPage() {
setBuilds(result);
} catch (error) {
if (error instanceof Error) {
console.log("Error: ", error.message);
}
toast.error((error as Error).message);
}
}
async function getManagers() {
if (!company || !selectedBuild) {
if (!company) {
return;
}
try {
const result: IUser[] | IError = await api
.get(`users?companyId=${company.id}&buildIds=${selectedBuild.id}`)
.get(`companies/${company.id}/users`)
.json();
if ("error" in result) {
@@ -104,8 +100,6 @@ function DashboardPage() {
return;
}
console.log("result", result);
setManagers(result);
} catch (error) {
alert((error as Error).message);
@@ -114,7 +108,7 @@ function DashboardPage() {
async function getScheduledSessions(useLoader?: boolean) {
if (!company) {
console.log("No ScheduledSessions");
// console.log("No ScheduledSessions");
return;
}
@@ -129,13 +123,9 @@ function DashboardPage() {
)
.json();
console.log(result);
setScheduledSessions(result);
} catch (error) {
if (error instanceof Error) {
console.log("Error: ", error.message);
}
toast.error((error as Error).message);
}
if (useLoader) setIsLoadingScheduledSessions(false);
@@ -200,110 +190,23 @@ function DashboardPage() {
</p>
<div className="flex gap-1">
<Button
handleClick={selectPrevDay}
icon={<ChevronLeftIcon />}
color="secondary"
variant="secondary"
onlyIcon
onClick={selectPrevDay}
/>
<Button
handleClick={selectNextDay}
variant="secondary"
icon={<ChevronRightIcon />}
color="secondary"
onlyIcon
onClick={selectNextDay}
/>
</div>
<Button handleClick={selectCurrentDate}>Сегодня</Button>
<Button onClick={selectCurrentDate}>Сегодня</Button>
</div>
</div>
{/* <div className="flex bg-[#F2F2F2]">
<div className="w-[84px] h-[40px] flex justify-center items-center text-sm font-semibold bg-white border-r border-b border-[#DAE0E5]">
{currentTime}
</div>
{selectedBuild &&
[...Array(selectedBuild.sessionLimit)].map((_, index) => (
<div key={index}>
<div className="w-[264px] h-[40px] px-3 flex items-center text-sm font-semibold bg-[#F0F1F2] border-r border-b border-[#DAE0E5]">
Слот {index + 1}
</div>
</div>
))}
</div> */}
{/* <div
ref={scheduledSessionsRef}
className={`overflow-y-auto overflow-x-hidden flex-1 bg-[#F2F2F2] border-r border-[#DAE0E5]`}
>
<Transition
in={isLoadingScheduledSessions}
timeout={150}
mountOnEnter
unmountOnExit
>
{(state) => (
<div
className={`fixed z-10 top-0 left-0 w-full h-full bg-black bg-opacity-80 transition-opacity flex justify-center items-center text-white ${state}`}
>
<SpinnerIcon />
</div>
)}
</Transition>
{generatedScheduledSessions?.map(
(generatedScheduledSession, index) => (
<div key={index} className="flex">
<div className="w-[84px] h-[164px] flex justify-center items-center text-sm font-semibold bg-white border-r border-b border-[#DAE0E5]">
<p>{format(generatedScheduledSession.time, "HH:mm")}</p>
</div>
<div className="flex">
{company &&
managers &&
selectedBuild &&
generatedScheduledSession.sessions.map(
(session: any, index2: number) => {
const selectedManager = managers.find(
(manager) => manager.id == session.userId
);
if (!_.isEmpty(session)) {
return (
<Card
key={index2}
companyId={company.id}
buildId={selectedBuild.id}
scheduledSessionId={session.id}
scheduleSessionStartAt={session.startAt}
client={session.client}
manager={selectedManager}
managers={managers}
handleSelect={(scheduledSessionId, managerId) =>
updateScheduledSessionManager(
scheduledSessionId,
managerId
)
}
/>
);
} else {
return (
<EmptyCard
key={index2}
buildId={selectedBuild?.id}
startAt={generatedScheduledSession.time}
duration={duration!}
/>
);
}
}
)}
</div>
</div>
)
)}
</div> */}
{company && scheduledSessions && (
<Schedule
selectedDay={selectedDay}
@@ -332,6 +235,7 @@ function DashboardPage() {
</div>
<ModalContainer />
<Toaster />
</div>
);
}
+6 -11
View File
@@ -7,7 +7,7 @@ import Input from "../components/Input";
import Button from "../components/Button";
import { Link, useNavigate } from "react-router-dom";
import useAuthStore from "../stores/useAuthStore";
import toast from "react-hot-toast";
import toast, { Toaster } from "react-hot-toast";
import IError from "../types/IError";
import IUser from "../types/IUser";
import api from "../utils/api";
@@ -32,19 +32,11 @@ function LoginPage() {
if ("error" in result) {
setLoading(false);
toast.error(`Error: ${result.error}`);
toast.error(result.error);
return;
}
setUser({
id: result.id,
username: "username",
accessToken: result.accessToken,
companyId: result.companyId,
name: result.name,
role: result.role,
buildIds: result.buildIds,
});
setUser(result);
navigate("/dashboard");
} catch (error) {
@@ -88,6 +80,7 @@ function LoginPage() {
size="medium"
className="mt-10"
loading={loading}
widthFull
>
Войти
</Button>
@@ -102,6 +95,8 @@ function LoginPage() {
</div>
</div>
</div>
<Toaster />
</div>
);
}
+3 -3
View File
@@ -3,8 +3,8 @@ import Button from "../components/Button";
function RegistrationPage() {
return (
<div className="min-h-screen flex flex-col justify-center items-center p-8 flex-1">
<div className=" bg-white rounded-lg shadow-md overflow-hidden">
<div className="flex flex-col items-center justify-center flex-1 min-h-screen p-8">
<div className="overflow-hidden bg-white rounded-lg shadow-md ">
<div className="flex flex-col gap-6 p-12 w-[528px]">
<p className="text-2xl font-semibold">Получение данных для входа</p>
@@ -22,7 +22,7 @@ function RegistrationPage() {
</div>
<Link to="/login">
<Button size="medium" color="secondary">
<Button variant="secondary" size="medium">
Назад
</Button>
</Link>