This commit is contained in:
2025-07-07 18:28:14 +05:00
parent ad5b6c9234
commit 41b8ab969d
8 changed files with 32 additions and 44 deletions
+9 -1
View File
@@ -1,11 +1,19 @@
import { Client } from "../types/Client";
import ChevronRightIcon from "./icons/ChevronRightIcon";
import Button from "./Button";
import useModalStore from "../stores/useModalStore";
import ClientModal from "./modals/ClientModal";
function ClientCard({ client }: { client: Client }) {
const { setModal } = useModalStore();
return (
<>
<Button variant="secondary" className="w-full">
<Button
variant="secondary"
className="w-full"
onClick={() => setModal(<ClientModal client={client} />)}
>
<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">{client.name}</p>
+6 -4
View File
@@ -10,6 +10,8 @@ function SearchInput(
) {
const ref = useRef<HTMLInputElement>(null);
const { setSearch, ...inputProps } = props;
return (
<div
className={clsx(
@@ -22,24 +24,24 @@ function SearchInput(
</span>
<input
className="outline-none focus:outline-none placeholder:button-m placeholder:font-medium placeholder:text-[#7D7D7D] button-m font-medium flex-1"
{...props}
{...inputProps}
ref={ref}
/>
</div>
<div
className={clsx(
"flex gap-[0.566vw] items-center transition-opacity",
!props.value && "opacity-0"
!inputProps.value && "opacity-0"
)}
>
<button
disabled={!props.value}
disabled={!inputProps.value}
className="outline-none cursor-pointer disabled:cursor-default"
onClick={() => {
if (ref.current) {
ref.current.value = "";
ref.current.focus();
props.setSearch(ref.current.value);
setSearch(ref.current.value);
}
}}
>
+1 -6
View File
@@ -22,12 +22,6 @@ function EndSessionModal({ session }: { session: Session }) {
api
.put(`sessions/${session.id}`, { json: { status: "ending" } })
.json<Session>(),
onMutate: () => {
// queryClient.invalidateQueries({ queryKey: ["sessions"] });
// queryClient.invalidateQueries({ queryKey: ["last-started"] });
// queryClient.invalidateQueries({ queryKey: ["servers"] });
setModal(null);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["servers"] });
queryClient.invalidateQueries({ queryKey: ["last-sessions"] });
@@ -73,6 +67,7 @@ function EndSessionModal({ session }: { session: Session }) {
className="w-full"
onClick={() => {
if (isSuccess) {
setPosition("right");
setModal(<SessionModal session={session} />);
} else {
endSession();
+8 -1
View File
@@ -13,6 +13,7 @@ import api from "../../utils/api";
import SessionFiles from "../SessionFiles";
import DownloadIcon from "../icons/DownloadIcon";
import ShareIcon from "../icons/ShareIcon";
import { Client } from "../../types/Client";
function SessionModal({ session }: { session: Session }) {
const { data: files } = useQuery({
@@ -27,6 +28,12 @@ function SessionModal({ session }: { session: Session }) {
.json<{ filename: string; size: number }[]>(),
});
const { data: client } = useQuery({
queryKey: ["clients", session.client.id],
queryFn: () => api.get(`clients/${session.client.id}`).json<Client>(),
enabled: !!session.client.id,
});
return (
<div className="bg-[#FFFFFF] w-[49.722vw] rounded-[2.222vw]">
<div className="w-full flex justify-center items-center h-[4.861vw] border-b-1 border-[#D6D6D6]">
@@ -81,7 +88,7 @@ function SessionModal({ session }: { session: Session }) {
</span>
</p>
</div>
<ClientCard client={session.client} />
{client && <ClientCard client={client} />}
</div>
<div className="flex flex-col gap-[1.111vw] bg-white rounded-[1.667vw] p-[1.111vw]">
<h3 className="title-s flex font-medium">
+6 -13
View File
@@ -1,8 +1,6 @@
import api from "../utils/api";
import Button from "../components/Button";
// import CloseIcon from "../components/icons/CloseIcon";
import SpinIcon from "../components/icons/SpinIcon";
// import MultySelect from "../components/MultySelect";
import SearchInput from "../components/SearchInput";
import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
@@ -16,7 +14,7 @@ import ClientModal from "../components/modals/ClientModal";
import clsx from "clsx";
function ClientsPage() {
const [limit, setLimit] = useState(10);
const [limit, setLimit] = useState(5);
const [search, setSearch] = useState<string | null>(null);
const { setModal, setPosition } = useModalStore();
@@ -28,13 +26,13 @@ function ClientsPage() {
});
const { data: clients, isLoading } = useQuery({
queryKey: ["clients", debouncedSearch],
queryKey: ["clients", debouncedSearch, limit],
queryFn: () =>
api
.get("clients", {
searchParams: debouncedSearch
? { search: debouncedSearch, limit }
: {},
: { limit },
})
.json<Client[]>(),
enabled: !!me,
@@ -48,14 +46,9 @@ function ClientsPage() {
searchParams: debouncedSearch ? { search: debouncedSearch } : {},
})
.json<number>(),
enabled: !!me,
});
// function reset() {
// setSearch("");
// }
return (
<div className="flex flex-col gap-[1.667vw] h-full">
<h1 className="title-l font-medium">Клиенты</h1>
@@ -120,7 +113,7 @@ function ClientsPage() {
>
<div
key={client.id}
className="flex justify-between items-center cursor-pointer aspace-y-[0.833vw] p-[1.111vw] hover:bg-[#F6F6F6] rounded-[0.833vw]"
className="flex justify-between items-center cursor-pointer p-[1.111vw] hover:bg-[#F6F6F6] rounded-[0.833vw]"
>
<div className="flex flex-col gap-[0.556vw]">
<p className="button-m font-medium">{client.name}</p>
@@ -152,8 +145,8 @@ function ClientsPage() {
size="large"
variant="primary"
className="w-full"
onClick={() => setLimit((prev) => prev + 10)}
disabled={!!clients?.length && limit >= clients.length}
onClick={() => setLimit((prev) => prev + 5)}
disabled={!!clients?.length && limit > clients.length}
>
Показать еще
</Button>
-14
View File
@@ -30,19 +30,6 @@ function DashboardPage() {
enabled: !!me,
});
// async function logout() {
// return await api.get("auth/logout").json();
// }
// async function handleClickLogout() {
// try {
// await logout();
// setToken(null);
// } catch (error) {
// toast.error((await (error as HTTPError).response.json<IError>()).error);
// }
// }
const navigate = useNavigate();
return (
@@ -60,7 +47,6 @@ function DashboardPage() {
</div>
</div>
</div>
<div className="w-full">
<div className="flex flex-col gap-[1.667vw]">
<h1 className="title-l font-medium">Последние сеансы</h1>
+1 -1
View File
@@ -83,7 +83,7 @@ function SessionsPage() {
}
return (
<div className=" flex flex-col gap-[1.667vw]">
<div className="flex flex-col gap-[1.667vw]">
<h1 className="title-l font-medium">Сеансы</h1>
<div className="p-[1.389vw] rounded-[2.222vw] shadow-[0_4px_40px_0_rgba(15,16,17,0.05),0_2px_2px_0_rgba(15,16,17,0.05)] w-full">
<div className="space-y-[1.111vw]">
+1 -4
View File
@@ -14,10 +14,7 @@ const useModalStore = create<State>()(
(set) => ({
modal: null,
setModal: (modal) => {
if (!modal) {
set({ position: "center" });
}
if (!modal) set({ position: "center" });
set({ modal });
},
position: "center",