upd table selector

This commit is contained in:
2025-06-03 16:34:34 +05:00
parent 379eae3a7b
commit 02b07f4f12
7 changed files with 134 additions and 35 deletions
+23 -23
View File
@@ -41,59 +41,59 @@ export default function DesktopCard({ server }: IDesktopCardProps) {
async function handleClickCreateSession() {
setPosition("right");
setModal(<CreateSessionModal servers={servers} />);
setModal(<CreateSessionModal servers={servers} targetServer={server} />);
}
return (
<div className='flex flex-col gap-[0.833vw] aspect-[300/211] w-[20.833vw] h-[14.653vw]'>
<div className="flex flex-col gap-[0.833vw] aspect-[300/211] w-[20.833vw] h-[14.653vw]">
<div className='relative w-full h-[8.056vw] aspect-[300/116] bg-[#F6F6F6] rounded-3xl bg-[url("/images/Table.png")] bg-no-repeat bg-[top_1.111vw_left_50%] bg-[length:8.125vw]'>
<NewButton
variant='secondary'
size='medium'
className='absolute top-[0.347vw] right-[0.347vw] cursor-pointer flex items-center justify-center'
variant="secondary"
size="medium"
className="absolute top-[0.347vw] right-[0.347vw] cursor-pointer flex items-center justify-center"
>
<span className='text-[#7D7D7D] w-[0.972vw] h-[0.972vw]'>
<span className="text-[#7D7D7D] w-[0.972vw] h-[0.972vw]">
<CogIcon />
</span>
</NewButton>
</div>
<div className='flex self-center justify-between items-start'>
<div className='space-y-[0.278vw] text-center'>
<p className='leading-none font-[500] text-[1.111vw] title-s'>
<div className="flex self-center justify-between items-start">
<div className="space-y-[0.278vw] text-center">
<p className="leading-none font-[500] text-[1.111vw] title-s">
{server.name}
</p>
<p className='caption-s text-[#7D7D7D]'>{server.location}</p>
<p className="caption-s text-[#7D7D7D]">{server.location}</p>
</div>
</div>
<div className='flex gap-[0.278vw] justify-center -mt-[0.278vw]'>
<div className="flex gap-[0.278vw] justify-center -mt-[0.278vw]">
{server.sessions?.[0]?.status === "started" ? (
<div className='flex items-center gap-[0.278vw]'>
<div className="flex items-center gap-[0.278vw]">
<NewButton
variant='primary'
variant="primary"
onClick={() => endSession()}
className='flex gap-[0.556vw] items-center'
className="flex gap-[0.556vw] items-center"
>
<span className='w-[0.972vw] h-[0.972vw] flex items-center justify-center'>
<span className="w-[0.972vw] h-[0.972vw] flex items-center justify-center">
<FlashIcon />
</span>
<p className='button-s font-medium'>Идёт сеанс</p>
<span className='w-[0.972vw] h-[0.972vw] flex items-center justify-center'>
<p className="button-s font-medium">Идёт сеанс</p>
<span className="w-[0.972vw] h-[0.972vw] flex items-center justify-center">
<ChevronLeftIcon />
</span>
</NewButton>
</div>
) : (
<NewButton
variant='cta'
size='medium'
className='self-center'
variant="cta"
size="medium"
className="self-center"
onClick={handleClickCreateSession}
>
<div className='flex gap-[0.556vw] items-center justify-center'>
<span className='w-[0.972vw] h-[0.972vw] flex items-center justify-center'>
<div className="flex gap-[0.556vw] items-center justify-center">
<span className="w-[0.972vw] h-[0.972vw] flex items-center justify-center">
<PlusIcon />
</span>
<p className='button-s'>Создать сеанс</p>
<p className="button-s">Создать сеанс</p>
</div>
</NewButton>
)}
+7 -6
View File
@@ -3,8 +3,8 @@ import { useEffect, useRef } from "react";
import useModalStore from "../stores/useModalStore";
import { AnimatePresence, motion } from "motion/react";
import CloseIcon from "./icons/CloseIcon";
import Button from "./Button";
import { clsx as cn } from "clsx";
import NewButton from "./NewButton";
function ModalContainer() {
const { modal, setModal, position } = useModalStore();
@@ -70,15 +70,16 @@ function ModalContainer() {
// }}
>
{modal}
<Button
onlyIcon
className="absolute top-[1.667vw] right-[1.667vw] p-[0.556vw] !rounded-full bg-[#F9F9F9]"
<NewButton
className="absolute top-[1.667vw] right-[1.667vw] p-[0.556vw] bg-[#F9F9F9]"
size="small"
variant="secondary"
onClick={() => setModal(null)}
>
<span className="w-[1.389vw] h-[1.389vw] text-black">
<span className="w-[1.389vw] h-[1.389vw] text-[#7D7D7D]">
<CloseIcon />
</span>
</Button>
</NewButton>
</div>
</div>
</div>
+5
View File
@@ -0,0 +1,5 @@
function ProjectSelector() {
return <div></div>;
}
export default ProjectSelector;
+50
View File
@@ -0,0 +1,50 @@
import clsx from "clsx";
import { IServer } from "../types/IServer";
import LightningIcon from "./icons/LightningIcon";
interface TableSelectorProps {
tables: IServer[];
selectedTable: IServer | null;
onSelect: (table: IServer) => void;
}
function TableSelector({
tables,
selectedTable,
onSelect,
}: TableSelectorProps) {
return (
<div className="flex gap-[0.556vw] overflow-x-auto -mx-[1.111vw] pl-[1.111vw] [scrollbar-width:none]">
{tables.map((table) => (
<button
key={table.id}
disabled={table.status === "offline"}
onClick={(e) => {
e.preventDefault();
onSelect(table);
}}
className={clsx(
"rounded-[0.833vw] outline-none p-[1.111vw] space-y-[0.278vw] disabled:text-[#D6D6D6] disabled:cursor-not-allowed enabled:cursor-pointer enabled:hover:bg-[#F0F0F0] transition-colors shrink-0",
selectedTable?.id === table.id && "bg-[#F6F6F6]"
)}
>
<p className="button-m font-medium">{table.name}</p>
{table.status === "offline" ? (
<p className="text-[#D6D6D6]">Недоступен</p>
) : table.sessions?.[0].status === "ended" ? (
<p className="text-[#29AF61] caption-s">Свободен</p>
) : (
<div className="flex gap-[0.139vw] items-center">
<span className="size-[0.883vw] text-[#7B60F3]">
<LightningIcon />
</span>
<p className="caption-s text-[#7B60F3] font-medium">Идет сеанс</p>
</div>
)}
</button>
))}
</div>
);
}
export default TableSelector;
+12
View File
@@ -0,0 +1,12 @@
function LightningIcon() {
return (
<svg viewBox="0 0 12 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M5.226 2.3H8.17l-1.8 2.94h2.455L4.899 10.7l.818-3.99H3.426z"
fill="currentColor"
/>
</svg>
);
}
export default LightningIcon;
+36 -6
View File
@@ -10,18 +10,25 @@ import api from "../../utils/api.ts";
import { ISession } from "../../types/ISession.ts";
import { IClient } from "../../types/IClient.ts";
import useModalStore from "../../stores/useModalStore.ts";
import TableSelector from "../TableSelector.tsx";
interface Props {
servers: IServer[] | undefined;
targetServer: IServer | null;
}
export default function CreateSessionModal({ servers }: Props) {
export default function CreateSessionModal({
servers,
targetServer = null,
}: Props) {
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 [selectedServer, setSelectedServer] = useState<IServer | null>(
targetServer
);
const [selectedApp, setSelectedApp] = useState<IApp | null>(null);
async function createClient() {
console.log(name, phone, email);
@@ -66,10 +73,33 @@ export default function CreateSessionModal({ servers }: Props) {
return (
<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]"
className="rounded-[2.222vw] w-[25vw] min-h-[calc(100dvh-2.222vw)] bg-[#F0F0F0] flex flex-col overflow-hidden"
onSubmit={handleClickCreateSession}
>
<div className="gap-y-[1.111vw] flex flex-col justify-between">
<div className="w-full h-[4.861vw] flex items-center justify-center">
<p className="title-s font-medium">Новый сеанс</p>
</div>
<div className="w-full h-[6.944vw] bg-[url(/images/Table.png)] bg-no-repeat bg-top bg-[length:9.306vw]" />
<div className="bg-white rounded-t-[2.222vw] p-[1.389vw] flex flex-col gap-y-[1.667vw] flex-1 overflow-y-auto">
<TableSelector
tables={servers || []}
selectedTable={selectedServer}
onSelect={setSelectedServer}
/>
<div className="flex flex-col gap-y-[0.833vw]">
<p className="title-s font-medium">Укажите данные клиента</p>
<div className="flex flex-col gap-y-[0.556vw]">
<Input placeholder="Номер телефона" required />
<Input placeholder="Имя" required />
<Input placeholder="Электронная почта" />
</div>
</div>
<div className="flex flex-col gap-y-[0.833vw]">
<p className="title-s font-medium">Выберите параметры сеанса</p>
</div>
</div>
{/* <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]">
<div className="w-[1.389vw] h-[1.389vw]">
@@ -169,7 +199,7 @@ export default function CreateSessionModal({ servers }: Props) {
>
<p className="text-[0.972vw] font-medium">Запустить сеанс</p>
</Button>
</div>
</div> */}
</form>
);
}
+1
View File
@@ -9,4 +9,5 @@ export interface IServer {
companyId: string;
sessions?: ISession[];
apps?: IApp[];
status: "online" | "offline";
}