This commit is contained in:
2025-03-24 12:24:58 +05:00
parent 15dbaab168
commit 143ba63e09
11 changed files with 232 additions and 134 deletions
+107 -55
View File
@@ -1,43 +1,74 @@
import { useEffect } from 'react';
import { useState } from 'react';
import { IServer } from '../../types/IServer.ts';
import Button from '../Button.tsx';
import DesktopSelect from '../DesktopSelect.tsx';
import Input from '../Input.tsx';
import DisplayIcon from '../icons/DisplayIcon.tsx';
import Select from '../Select.tsx';
import { useQueryClient } from '@tanstack/react-query';
import { IUser } from '../../types/IUser.ts';
import { IApp } from '../../types/IApp.ts';
import { IServer } from "../../types/IServer.ts";
import Button from "../Button.tsx";
import DesktopSelect from "../DesktopSelect.tsx";
import Input from "../Input.tsx";
import DisplayIcon from "../icons/DisplayIcon.tsx";
import Select from "../Select.tsx";
import { useState } from "react";
import { IApp } from "../../types/IApp.ts";
import api from "../../utils/api.ts";
import { ISession } from "../../types/ISession.ts";
import { IClient } from "../../types/IClient.ts";
import useModalStore from "../../stores/useModalStore.ts";
interface Props {
servers: IServer[];
}
export default function CreateSessionModal({ servers }: Props) {
const queryClient = useQueryClient();
const { setModal } = useModalStore();
const [name, setName] = useState("");
const [phone, setPhone] = useState("");
const [email, setEmail] = useState("");
const [selectedServer, setSelectedServer] = useState<IServer>();
const [selectedApp, setSelectedApp] = useState<IApp>();
const user = queryClient.getQueryData<IUser>(['me']);
async function createClient() {
console.log(name, phone, email);
const [selectedServer, setSelectedServer] = useState<IServer | undefined>(
servers.find(
({ sessions }) =>
!sessions || !sessions.length || sessions[0].status === 'ended'
)
);
return await api
.post("clients", {
json: {
name,
phone,
email,
},
})
.json<IClient>();
}
const [selectedApp, setSelectedApp] = useState<IApp | undefined>(
user?.company.apps.filter((app) => app.serverId === selectedServer?.id)[0]
);
async function createSession(clientId: string) {
return await api
.post("sessions", {
json: {
clientId,
serverId: selectedServer?.id,
appId: selectedApp?.id,
},
})
.json<ISession>();
}
useEffect(() => {
setSelectedApp(
user?.company.apps.filter((app) => app.serverId === selectedServer?.id)[0]
);
}, [selectedServer, user?.company.apps]);
async function handleClickCreateSession(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
if (!name || !phone || !selectedServer || !selectedApp) return;
try {
const client = await createClient();
await createSession(client.id);
setModal(null);
} catch (error) {
console.log(error);
}
}
return (
<div className="w-[34.375vw] rounded-[0.833vw] bg-white p-[1.667vw] flex flex-col min-h-[calc(100dvh-0.972vw*2)] justify-between gap-[1.111vw]">
<form
className="w-[34.375vw] rounded-[0.833vw] bg-white p-[1.667vw] flex flex-col min-h-[calc(100dvh-0.972vw*2)] justify-between gap-[1.111vw]"
onSubmit={handleClickCreateSession}
>
<div className="gap-y-[1.111vw] flex flex-col justify-between">
<div className="space-y-[0.556vw]">
<div className="p-[0.833vw] ring-[0.069vw] ring-[#E6E6E6] w-fit rounded-[0.556vw]">
@@ -56,7 +87,12 @@ export default function CreateSessionModal({ servers }: Props) {
Имя <span className="text-[#C6C6C699]">*</span>
</p>
<div className="outline outline-black/10 rounded-[0.556vw] w-[13.889vw]">
<Input placeholder="Константин" required />
<Input
placeholder="Константин"
required
value={name}
onChange={(e) => setName(e.target.value)}
/>
</div>
</div>
<div className="flex justify-between items-center">
@@ -64,60 +100,76 @@ export default function CreateSessionModal({ servers }: Props) {
Номер <span className="text-[#C6C6C699]">*</span>
</p>
<div className="outline outline-black/10 rounded-[0.556vw] w-[13.889vw]">
<Input placeholder="+ 7 (999) 99 99 99" required type="tel" />
<Input
placeholder="79221234567"
required
type="tel"
value={phone}
onChange={(e) => setPhone(e.target.value)}
/>
</div>
</div>
<div className="flex justify-between items-center">
<p className="text-[0.972vw]">Электронная почта</p>
<div className="outline outline-black/10 rounded-[0.556vw] w-[13.889vw]">
<Input placeholder="sample@mail.ru" type="email" />
<Input
placeholder="sample@mail.ru"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
</div>
<div className="flex flex-col gap-y-[0.556vw]">
<div className="flex justify-between items-center">
<p className="text-[0.972vw]">Стол</p>
{selectedServer && (
<DesktopSelect
servers={servers}
value={selectedServer}
onChange={setSelectedServer}
/>
)}
<DesktopSelect
servers={servers.filter(
({ sessions }) =>
!sessions ||
!sessions.length ||
sessions[0]?.status === "ended"
)}
value={selectedServer || undefined}
onChange={setSelectedServer}
/>
</div>
<p className="text-[0.694vw] text-black/30 w-[13.889vw] leading-[115%] self-end">
При запуске нового сеанса текущий будет завершен принудительно.
</p>
</div>
{user && selectedServer && (
{selectedServer && (
<div className="flex justify-between items-center">
<p className="text-[0.972vw]">Проекты</p>
<div className="outline outline-black/10 rounded-[0.556vw] w-[13.889vw]">
{selectedApp && (
<Select
options={user.company.apps
.filter((app) => app.serverId === selectedServer.id)
.map((app) => app.name)}
value={selectedApp?.name}
onChange={(option) =>
setSelectedApp(
user.company.apps.find((app) => app.name === option)
)
}
/>
)}
<Select
options={selectedServer.apps?.map((app) => app.name) || []}
onChange={(option) =>
setSelectedApp(
selectedServer.apps?.find((app) => app.name === option)
)
}
/>
</div>
</div>
)}
<hr className="border-black/10" />
</div>
<div className="flex justify-between">
<Button className="bg-[#F9F9F9] px-[2.222vw] py-[0.556vw] !rounded-[0.556vw]">
<Button
type="button"
className="bg-[#F9F9F9] px-[2.222vw] py-[0.556vw] !rounded-[0.556vw]"
onClick={() => setModal(null)}
>
<p className="text-black font-medium text-[0.972vw]">Отменить</p>
</Button>
<Button className="bg-[#EF3C26] px-[2.222vw] py-[0.556vw] !rounded-[0.556vw]">
<Button
type="submit"
className="bg-[#EF3C26] px-[2.222vw] py-[0.556vw] !rounded-[0.556vw]"
>
<p className="text-[0.972vw] font-medium">Запустить сеанс</p>
</Button>
</div>
</div>
</form>
);
}