From 2be9e0dc2b2a35a6ad6a149dce69f5ce1bec3431 Mon Sep 17 00:00:00 2001 From: Lanskikh Date: Thu, 5 Jun 2025 16:46:49 +0500 Subject: [PATCH] upd --- src/components/CurrentSessionCard.tsx | 21 +++- src/components/DesktopCard.tsx | 25 ++-- src/components/ProjectSelector.tsx | 23 ++-- src/components/modals/CreateSessionModal.tsx | 115 +++++++++++------- src/components/modals/CurrentSessionModal.tsx | 52 +++----- 5 files changed, 128 insertions(+), 108 deletions(-) diff --git a/src/components/CurrentSessionCard.tsx b/src/components/CurrentSessionCard.tsx index 824bff4..91401e1 100644 --- a/src/components/CurrentSessionCard.tsx +++ b/src/components/CurrentSessionCard.tsx @@ -5,6 +5,8 @@ import api from "../utils/api"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import ChevronRightIcon from "./icons/ChevronRightIcon"; import { motion } from "motion/react"; +import CurrentSessionModal from "./modals/CurrentSessionModal"; +import useModalStore from "../stores/useModalStore"; function CurrentSessionCard({ session, @@ -13,9 +15,11 @@ function CurrentSessionCard({ session: ISession; index: number; }) { + const { setModal } = useModalStore(); + const queryClient = useQueryClient(); - const { mutate: endSession } = useMutation({ + const { mutate: endSession, isPending } = useMutation({ mutationKey: ["sessions", session.id], mutationFn: () => api.put(`sessions/${session.id}`, { json: { status: "ending" } }), @@ -36,7 +40,14 @@ function CurrentSessionCard({ transition={{ bounce: 0, delay: index * 0.1 }} className="p-[1.389vw] rounded-[1.667vw] bg-white w-[18.889vw] flex flex-col gap-[0.833vw] shadow-[0px_4px_40px_0_rgba(0,0,0,0.05),0px_2px_2px_0_rgba(0,0,0,0.05)]" > -
+
{ + if (session.status === "started") { + setModal(); + } + }} + > @@ -58,7 +69,11 @@ function CurrentSessionCard({
- endSession()}> + endSession()} + disabled={isPending} + > Завершить сеанс diff --git a/src/components/DesktopCard.tsx b/src/components/DesktopCard.tsx index 88af1b6..bcad047 100644 --- a/src/components/DesktopCard.tsx +++ b/src/components/DesktopCard.tsx @@ -10,6 +10,7 @@ import UnlinkIcon from "./icons/UnlinkIcon"; import clsx from "clsx"; import ChevronRightIcon from "./icons/ChevronRightIcon"; import CurrentSessionModal from "./modals/CurrentSessionModal"; + interface IDesktopCardProps { server: IServer; } @@ -17,18 +18,6 @@ interface IDesktopCardProps { export default function DesktopCard({ server }: IDesktopCardProps) { const { setModal, setPosition } = useModalStore(); - // const { mutate: createSession } = useMutation({ - // mutationFn: () => - // api.post(`sessions`, { - // json: { - // serverId: server.id, - // clientId: "abcfd570-2fa8-4f55-957b-5007f84f8f96", - // appId: "b8a9995c-a799-4593-8f96-03942050cb21", - // }, - // }), - // onMutate: () => queryClient.invalidateQueries({ queryKey: ["sessions"] }), - // }); - async function handleClickCreateSession() { setPosition("right"); setModal(); @@ -62,12 +51,20 @@ export default function DesktopCard({ server }: IDesktopCardProps) {
- {server.sessions?.[0]?.status === "started" ? ( + {server.sessions?.[0]?.status === "starting" ? ( +
+ загрузка... +
+ ) : server.sessions?.[0]?.status === "started" ? (
{ - setModal(); + if (server.sessions?.length && server.sessions?.[0]) { + setModal( + + ); + } }} className="flex gap-[0.556vw] items-center" > diff --git a/src/components/ProjectSelector.tsx b/src/components/ProjectSelector.tsx index 2cf5279..6488801 100644 --- a/src/components/ProjectSelector.tsx +++ b/src/components/ProjectSelector.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useEffect, useState } from "react"; import { IApp } from "../types/IApp"; import ChevronLeftIcon from "./icons/ChevronLeftIcon"; import CloseIcon from "./icons/CloseIcon"; @@ -11,18 +11,22 @@ interface Props { projects: IApp[]; selectedProject: IApp | null; setSelectedProject: (project: IApp | null) => void; + activeProject: IApp | null; } function ProjectSelector({ projects, selectedProject, setSelectedProject, + activeProject, }: Props) { const [isOpen, setIsOpen] = useState(false); - const [pointedProject, setPointedProject] = useState( - selectedProject - ); + const [pointedProject, setPointedProject] = useState(null); + + useEffect(() => { + setPointedProject(selectedProject); + }, [selectedProject]); return ( <> @@ -86,16 +90,19 @@ function ProjectSelector({

{project.name}

- - - + {activeProject && + project.name === activeProject.name && ( + + + + )}

Доступно 128 квартир

- {pointedProject?.id === project.id ? ( + {pointedProject?.name === project.name ? (
diff --git a/src/components/modals/CreateSessionModal.tsx b/src/components/modals/CreateSessionModal.tsx index 17c9b23..6f0a9b8 100644 --- a/src/components/modals/CreateSessionModal.tsx +++ b/src/components/modals/CreateSessionModal.tsx @@ -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(), + refetchInterval: 1000, }); const targetServer = targetServerId @@ -38,6 +40,12 @@ export default function CreateSessionModal({ targetServerId }: Props) { ); const [selectedApp, setSelectedApp] = useState(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(); - }, + .json(), 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(null); @@ -165,13 +183,20 @@ export default function CreateSessionModal({ targetServerId }: Props) {

Выберите параметры сеанса

- {selectedServer?.apps && selectedServer?.apps?.length > 0 && ( - - )} + {selectedServer && + selectedServer?.apps && + selectedServer?.apps?.length > 0 && ( + + )}
{isSessionExists && (
diff --git a/src/components/modals/CurrentSessionModal.tsx b/src/components/modals/CurrentSessionModal.tsx index 90d44b7..1d83d0a 100644 --- a/src/components/modals/CurrentSessionModal.tsx +++ b/src/components/modals/CurrentSessionModal.tsx @@ -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(), - }); - - 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 (
@@ -63,13 +41,15 @@ function CurrentSessionModal({ server }: { server: IServer }) {
-

{server.name}

+

{session.server.name}

- + + + Сеанс идёт{" "} {(() => { 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 }) {

- {server.location} + {session.server.location}

@@ -98,12 +78,10 @@ function CurrentSessionModal({ server }: { server: IServer }) {

Клиент

-

- {currentSession.client.name} -

+

{session.client.name}

- {!currentSession.client.email && ( + {!session.client.email && (

Добавьте email

@@ -120,9 +98,7 @@ function CurrentSessionModal({ server }: { server: IServer }) {

Менеджер:

-

- {currentSession.owner.fullname} -

+

{session.owner.fullname}