feat: add ghost image and enhance CreateSessionModal with session existence check and improved server handling
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -1,4 +1,3 @@
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { IServer } from "../types/IServer";
|
||||
import useModalStore from "../stores/useModalStore";
|
||||
import CreateSessionModal from "./modals/CreateSessionModal";
|
||||
@@ -17,8 +16,6 @@ interface IDesktopCardProps {
|
||||
|
||||
export default function DesktopCard({ server }: IDesktopCardProps) {
|
||||
const { setModal, setPosition } = useModalStore();
|
||||
const queryClient = useQueryClient();
|
||||
const servers = queryClient.getQueryData<IServer[]>(["servers"]);
|
||||
|
||||
// const { mutate: createSession } = useMutation({
|
||||
// mutationFn: () =>
|
||||
@@ -34,7 +31,7 @@ export default function DesktopCard({ server }: IDesktopCardProps) {
|
||||
|
||||
async function handleClickCreateSession() {
|
||||
setPosition("right");
|
||||
setModal(<CreateSessionModal servers={servers} targetServer={server} />);
|
||||
setModal(<CreateSessionModal targetServerId={server.id} />);
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -5,6 +5,10 @@ import api from "../utils/api";
|
||||
import CurrentSessionCard from "./CurrentSessionCard";
|
||||
import { ISession } from "../types/ISession";
|
||||
import { AnimatePresence } from "motion/react";
|
||||
import NewButton from "./NewButton";
|
||||
import PlusIcon from "./icons/PlusIcon";
|
||||
import useModalStore from "../stores/useModalStore";
|
||||
import CreateSessionModal from "./modals/CreateSessionModal";
|
||||
|
||||
function Layout() {
|
||||
const { data: currentStartedSessions } = useQuery({
|
||||
@@ -18,6 +22,8 @@ function Layout() {
|
||||
refetchInterval: 1000,
|
||||
});
|
||||
|
||||
const { setModal, setPosition } = useModalStore();
|
||||
|
||||
return (
|
||||
<div className="flex gap-[1.667vw] overflow-hidden">
|
||||
<div className="flex-1"></div>
|
||||
@@ -35,6 +41,19 @@ function Layout() {
|
||||
/>
|
||||
))}
|
||||
</AnimatePresence>
|
||||
<NewButton
|
||||
variant="cta"
|
||||
className="w-[18.889vw]"
|
||||
onClick={() => {
|
||||
setPosition("right");
|
||||
setModal(<CreateSessionModal targetServerId={null} />);
|
||||
}}
|
||||
>
|
||||
<span className="w-[1.111vw] h-[1.111vw] flex items-center justify-center">
|
||||
<PlusIcon />
|
||||
</span>
|
||||
Создать сеанс
|
||||
</NewButton>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -13,7 +13,6 @@ function TableSelector({
|
||||
selectedTable,
|
||||
onSelect,
|
||||
}: TableSelectorProps) {
|
||||
console.log(tables);
|
||||
return (
|
||||
<div className="flex gap-[0.556vw] overflow-x-auto -mx-[1.111vw] pl-[1.111vw] [scrollbar-width:none]">
|
||||
{tables.map((table) => (
|
||||
|
||||
@@ -10,27 +10,34 @@ import NewInput from "../NewInput.tsx";
|
||||
import StartSessionIcon from "../icons/StartSessionIcon.tsx";
|
||||
import NewButton from "../NewButton.tsx";
|
||||
import ProjectSelector from "../ProjectSelector.tsx";
|
||||
import { useQueryClient, useMutation } from "@tanstack/react-query";
|
||||
import { useQueryClient, useMutation, useQuery } from "@tanstack/react-query";
|
||||
|
||||
interface Props {
|
||||
servers: IServer[] | undefined;
|
||||
targetServer: IServer | null;
|
||||
targetServerId: string | null;
|
||||
}
|
||||
|
||||
export default function CreateSessionModal({
|
||||
servers,
|
||||
targetServer = null,
|
||||
}: Props) {
|
||||
export default function CreateSessionModal({ targetServerId }: Props) {
|
||||
const { setModal } = useModalStore();
|
||||
const [name, setName] = useState("");
|
||||
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[]>(),
|
||||
});
|
||||
|
||||
const targetServer = targetServerId
|
||||
? servers?.find((server) => server.id === targetServerId) || null
|
||||
: null;
|
||||
|
||||
const [selectedServer, setSelectedServer] = useState<IServer | null>(
|
||||
targetServer
|
||||
);
|
||||
const [selectedApp, setSelectedApp] = useState<IApp | null>(null);
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const { mutate: createClient } = useMutation({
|
||||
mutationFn: () => {
|
||||
return api
|
||||
@@ -65,26 +72,61 @@ export default function CreateSessionModal({
|
||||
},
|
||||
});
|
||||
|
||||
const { mutate: endSession } = useMutation({
|
||||
mutationKey: ["sessions", selectedServer?.sessions?.[0]?.id],
|
||||
mutationFn: () =>
|
||||
api.put(`sessions/${selectedServer?.sessions?.[0]?.id}`, {
|
||||
json: { status: "ending" },
|
||||
}),
|
||||
onMutate: () => queryClient.invalidateQueries({ queryKey: ["sessions"] }),
|
||||
});
|
||||
|
||||
async function handleClickCreateSession(e: React.FormEvent<HTMLFormElement>) {
|
||||
e.preventDefault();
|
||||
|
||||
if (!name || !phone || !selectedServer || !selectedApp) return;
|
||||
|
||||
createClient(undefined, {
|
||||
onSuccess: (client) => {
|
||||
createSession(client.id);
|
||||
},
|
||||
onError: (error) => {
|
||||
console.log(error);
|
||||
},
|
||||
});
|
||||
if (
|
||||
selectedServer?.sessions?.[0]?.status === "started" &&
|
||||
!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);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const ref = useRef<HTMLFormElement>(null);
|
||||
|
||||
return (
|
||||
<form
|
||||
className="rounded-[2.222vw] w-[25vw] min-h-[calc(100dvh-2.222vw)] bg-[#F0F0F0] flex flex-col overflow-hidden"
|
||||
className="relative rounded-[2.222vw] w-[25vw] min-h-[calc(100dvh-2.222vw)] bg-[#F0F0F0] flex flex-col overflow-hidden"
|
||||
onSubmit={handleClickCreateSession}
|
||||
ref={ref}
|
||||
>
|
||||
@@ -131,6 +173,22 @@ export default function CreateSessionModal({
|
||||
/>
|
||||
)}
|
||||
</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]">
|
||||
<img
|
||||
src="/images/ghost.png"
|
||||
alt="ghost error"
|
||||
className="w-[13.889vw] h-[11.806vw]"
|
||||
/>
|
||||
<div className="flex flex-col gap-[0.556vw] items-center">
|
||||
<h3 className="title-m font-medium">Есть текущий сеанс</h3>
|
||||
<p className="caption-s text-[#BDBDBD] text-center whitespace-pre-line">
|
||||
{`На выбранном столе есть текущий сеанс.
|
||||
При запуске нового текущий будет завершен.`}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<NewButton
|
||||
type="submit"
|
||||
disabled={
|
||||
|
||||
Reference in New Issue
Block a user