This commit is contained in:
2025-06-05 16:46:49 +05:00
parent 4091626bc8
commit 2be9e0dc2b
5 changed files with 128 additions and 108 deletions
+70 -45
View File
@@ -1,5 +1,5 @@
import { IServer } from "../../types/IServer.ts";
import { useRef, useState } from "react";
import { useEffect, useRef, useState } from "react";
import { IApp } from "../../types/IApp.ts";
import api from "../../utils/api.ts";
import { ISession } from "../../types/ISession.ts";
@@ -22,11 +22,13 @@ export default function CreateSessionModal({ targetServerId }: Props) {
const [phone, setPhone] = useState("");
const [email, setEmail] = useState("");
const [isSessionExists, setIsSessionExists] = useState(false);
const queryClient = useQueryClient();
const { data: servers } = useQuery({
queryKey: ["servers"],
queryFn: () => api.get("servers?withLastSession=true").json<IServer[]>(),
refetchInterval: 1000,
});
const targetServer = targetServerId
@@ -38,6 +40,12 @@ export default function CreateSessionModal({ targetServerId }: Props) {
);
const [selectedApp, setSelectedApp] = useState<IApp | null>(null);
useEffect(() => {
setSelectedApp(
selectedServer?.sessions?.[0]?.app || selectedServer?.apps?.[0] || null
);
}, [selectedServer]);
const { mutate: createClient } = useMutation({
mutationFn: () => {
return api
@@ -53,20 +61,27 @@ export default function CreateSessionModal({ targetServerId }: Props) {
});
const { mutate: createSession } = useMutation({
mutationFn: (clientId: string) => {
return api
mutationKey: ["create-session", selectedServer?.id],
mutationFn: ({
clientId,
serverId,
appId,
}: {
clientId: string;
serverId: string;
appId: string;
}) =>
api
.post("sessions", {
json: {
clientId,
serverId: selectedServer?.id,
appId: selectedApp?.id,
serverId,
appId,
},
})
.json<ISession>();
},
.json<ISession>(),
onMutate: () => {
queryClient.invalidateQueries({ queryKey: ["sessions"] });
queryClient.invalidateQueries({ queryKey: ["last-started"] });
queryClient.invalidateQueries({ queryKey: ["servers"] });
setModal(null);
},
@@ -86,40 +101,43 @@ export default function CreateSessionModal({ targetServerId }: Props) {
if (!name || !phone || !selectedServer || !selectedApp) return;
if (
selectedServer?.sessions?.[0]?.status === "started" &&
!isSessionExists
) {
if (selectedServer?.sessions?.[0]?.status !== "started") {
createClient(undefined, {
onSuccess: (client) => {
createSession({
clientId: client.id,
serverId: selectedServer.id,
appId: selectedApp.id,
});
},
});
return;
}
if (!isSessionExists) {
setIsSessionExists(true);
return;
}
if (isSessionExists) {
endSession(undefined, {
onSuccess: () => {
createClient(undefined, {
onSuccess: (client) => {
createSession(client.id);
},
onError: (error) => {
console.log(error);
},
});
},
onError: (error) => {
console.log("Ошибка при завершении сессии:", error);
},
});
} else {
createClient(undefined, {
onSuccess: (client) => {
createSession(client.id);
},
onError: (error) => {
console.log(error);
},
});
}
endSession(undefined, {
onSuccess: () => {
createClient(undefined, {
onSuccess: (client) => {
createSession({
clientId: client.id,
serverId: selectedServer.id,
appId: selectedApp.id,
});
},
onError: (error) => {
console.log(error);
},
});
},
onError: (error) => {
console.log("Ошибка при завершении сессии:", error);
},
});
}
const ref = useRef<HTMLFormElement>(null);
@@ -165,13 +183,20 @@ export default function CreateSessionModal({ targetServerId }: Props) {
</div>
<div className="flex flex-col gap-y-[0.833vw]">
<p className="title-s font-medium">Выберите параметры сеанса</p>
{selectedServer?.apps && selectedServer?.apps?.length > 0 && (
<ProjectSelector
projects={selectedServer?.apps || []}
selectedProject={selectedApp ?? selectedServer?.apps?.[0] ?? null}
setSelectedProject={setSelectedApp}
/>
)}
{selectedServer &&
selectedServer?.apps &&
selectedServer?.apps?.length > 0 && (
<ProjectSelector
activeProject={
selectedServer?.sessions?.[0]?.status === "started"
? selectedApp
: null
}
projects={selectedServer?.apps}
selectedProject={selectedApp}
setSelectedProject={setSelectedApp}
/>
)}
</div>
{isSessionExists && (
<div className="absolute inset-0 top-[11.806vw] bg-[#FFFFFF] flex flex-col gap-[1.111vw] items-center justify-center h-[31.458vw]">
+14 -38
View File
@@ -1,35 +1,25 @@
import { intervalToDuration } from "date-fns";
import { IServer } from "../../types/IServer";
import FlashIcon from "../icons/FlashIcon";
import NewButton from "../NewButton";
import ChevronRightIcon from "../icons/ChevronRightIcon";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import api from "../../utils/api";
import useModalStore from "../../stores/useModalStore";
import { ISession } from "../../types/ISession";
import { useEffect, useState } from "react";
function CurrentSessionModal({ server }: { server: IServer }) {
function CurrentSessionModal({ session }: { session: ISession }) {
const queryClient = useQueryClient();
const { setModal } = useModalStore();
const { mutate: endSession } = useMutation({
mutationKey: ["sessions", server.sessions?.[0]?.id],
mutationKey: ["sessions", session.id],
mutationFn: () =>
api.put(`sessions/${server.sessions?.[0]?.id}`, {
api.put(`sessions/${session.id}`, {
json: { status: "ending" },
}),
onMutate: () => queryClient.invalidateQueries({ queryKey: ["sessions"] }),
});
const { data: currentSession } = useQuery({
queryKey: ["sessions", server.sessions?.[0]?.id],
queryFn: () =>
api.get(`sessions/${server.sessions?.[0]?.id}`).json<ISession>(),
});
console.log(currentSession);
const [now, setNow] = useState(Date.now());
useEffect(() => {
@@ -39,19 +29,7 @@ function CurrentSessionModal({ server }: { server: IServer }) {
return () => clearInterval(interval);
}, []);
useEffect(() => {
if (!currentSession) return;
const duration = intervalToDuration({
start: currentSession.createdAt,
end: now,
});
const hours = (duration.hours || 0).toString().padStart(2, "0");
const minutes = (duration.minutes || 0).toString().padStart(2, "0");
const seconds = (duration.seconds || 0).toString().padStart(2, "0");
console.log(`${hours}:${minutes}:${seconds}`);
}, [currentSession, now]);
if (!currentSession) return null;
if (!session) return null;
return (
<div className="w-[25vw] bg-[#FFFFFF] rounded-4xl px-[1.389vw] pb-[1.389vw]">
@@ -63,13 +41,15 @@ function CurrentSessionModal({ server }: { server: IServer }) {
<div className='size-[4.444vw] bg-[#F6F6F6] rounded-xl bg-[url("/images/super-table.png")] bg-no-repeat bg-[length:2.222vw] bg-center'></div>
<div className="flex flex-col gap-[0.278vw] self-center ">
<div className="flex gap-[0.278vw]">
<p className="title-s font-medium">{server.name}</p>
<p className="title-s font-medium">{session.server.name}</p>
<p className="flex justify-center items-center gap-[0.139vw] caption-s font-medium text-[#7B60F3]">
<FlashIcon />
<span className="size-[0.833vw] text-[#7B60F3]">
<FlashIcon />
</span>
Сеанс идёт{" "}
{(() => {
const duration = intervalToDuration({
start: currentSession.createdAt,
start: session.createdAt,
end: now,
});
const hours = (duration.hours || 0)
@@ -87,7 +67,7 @@ function CurrentSessionModal({ server }: { server: IServer }) {
</div>
<div>
<p className="caption-s font-medium text-[#BDBDBD]">
{server.location}
{session.server.location}
</p>
</div>
</div>
@@ -98,12 +78,10 @@ function CurrentSessionModal({ server }: { server: IServer }) {
<NewButton variant="secondary" className="w-full">
<div className="flex flex-col gap-[0.278vw] w-full text-left h-[2.222vw]">
<p className="caption-s font-medium text-[#BDBDBD]">Клиент</p>
<p className="text-s font-medium">
{currentSession.client.name}
</p>
<p className="text-s font-medium">{session.client.name}</p>
</div>
<div className="flex gap-[0.556vw] items-center">
{!currentSession.client.email && (
{!session.client.email && (
<p className="caption-s font-medium text-[#7B60F3] whitespace-nowrap">
Добавьте email
</p>
@@ -120,9 +98,7 @@ function CurrentSessionModal({ server }: { server: IServer }) {
<div>
<div className="flex gap-[0.556vw]">
<p className="caption-s font-medium text-[#BDBDBD]">Менеджер:</p>
<p className="caption-s font-medium">
{currentSession.owner.fullname}
</p>
<p className="caption-s font-medium">{session.owner.fullname}</p>
</div>
<div className="flex gap-[0.556vw]">
<p className="caption-s font-medium text-[#BDBDBD]">