This commit is contained in:
2025-03-21 16:13:13 +05:00
parent 1a897f6026
commit d9556bae2d
6 changed files with 72 additions and 151 deletions
-72
View File
@@ -1,72 +0,0 @@
import Button from "./Button";
import SessionIcon from "./icons/SessionIcon";
import Input from "./Input";
import useQueryApps from "../queries/useQueryApps.ts";
import useQueryServers from "../queries/useQueryServers.ts";
import Select from "./Select.tsx";
export default function CreateSessionModal() {
const { data: apps } = useQueryApps();
const { data: servers } = useQueryServers();
return (
<div className="w-[27.222vw] h-full rounded-[0.833vw] bg-white p-[1.667vw] flex flex-col justify-between gap-[1.111vw]">
<div className="gap-y-[1.111vw] flex flex-col justify-between">
<div className="space-y-[0.556vw]">
<div className="rounded-[0.556vw] w-fit p-[0.833vw] bg-[#2D68F60D]">
<div className="min-w-[1.389vw] min-h-[1.389vw] text-[#2D68F6]">
<SessionIcon />
</div>
</div>
<p className="text-[1.389vw]">Создание сеанса</p>
<p className="text-[0.833vw] text-black/20">
Укажите данные клиента, выберите менеджера и стол
</p>
</div>
<hr className="border-black/10" />
<div className="flex justify-between items-center">
<p className="text-[0.972vw]">
Имя <span className="text-[#C6C6C699]">*</span>
</p>
<div className="outline outline-black/10 rounded-[0.556vw] w-[13.889vw]">
<Input placeholder="Константин" required />
</div>
</div>
<div className="flex justify-between items-center">
<p className="text-[0.972vw]">
Номер <span className="text-[#C6C6C699]">*</span>
</p>
<div className="outline outline-black/10 rounded-[0.556vw] w-[13.889vw]">
<Input placeholder="+ 7 (999) 99 99 99" required type="tel" />
</div>
</div>
<div className="flex justify-between items-center">
<p className="text-[0.972vw]">Электронная почта</p>
<div className="outline outline-black/10 rounded-[0.556vw] w-[13.889vw]">
<Input placeholder="sample@mail.ru" type="email" />
</div>
</div>
{apps && (
<div className="flex justify-between items-center">
<p className="text-[0.972vw]">Приложение</p>
<div className="outline outline-black/10 rounded-[0.556vw] w-[13.889vw]">
<Select
options={apps.map(({ id, name }) => ({ id, value: name }))}
/>
</div>
</div>
)}
<hr className="border-black/10" />
</div>
<div className="flex justify-between">
<Button className="bg-[#F9F9F9] px-[2.222vw] py-[0.556vw] !rounded-[0.556vw]">
<p className="text-black font-medium text-[0.972vw]">Отменить</p>
</Button>
<Button className="bg-[#2D68F6] px-[2.222vw] py-[0.556vw] !rounded-[0.556vw]">
<p className="text-[0.972vw] font-medium">Запустить сеанс</p>
</Button>
</div>
</div>
);
}
+35 -35
View File
@@ -1,79 +1,79 @@
/* eslint-disable react-hooks/exhaustive-deps */
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';
const duration = 300;
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";
function ModalContainer() {
const { modal, setModal, isOpen, setIsOpen } = useModalStore();
const { modal, setModal, position } = useModalStore();
const divRef = useRef<HTMLDivElement>(null);
const buttonRef = useRef<HTMLDivElement>(null);
const backdropRef = useRef<HTMLDivElement>(null);
const popoverRef = useRef<HTMLDivElement>(null);
const containerRef = useRef<HTMLDivElement>(null);
function handleResize() {
if (!popoverRef.current) return;
if (divRef.current!.clientHeight > popoverRef.current!.clientHeight) {
buttonRef.current!.style.height = `${divRef.current!.clientHeight}px`;
backdropRef.current!.style.height = `${divRef.current!.clientHeight}px`;
} else {
buttonRef.current!.style.height = `100%`;
backdropRef.current!.style.height = `100%`;
}
}
function handleKeydown(e: KeyboardEvent) {
if (e.key !== 'Escape') return;
setIsOpen(false);
if (e.key !== "Escape") return;
setModal(null);
}
useEffect(() => setIsOpen(!!modal), [modal]);
useEffect(() => {
if (isOpen) return;
setTimeout(() => {
setModal(null);
}, duration);
}, [isOpen]);
useEffect(() => {
window.addEventListener('resize', handleResize);
window.addEventListener('keydown', handleKeydown);
window.addEventListener("resize", handleResize);
window.addEventListener("keydown", handleKeydown);
return () => {
window.removeEventListener('resize', handleResize);
window.removeEventListener('keydown', handleKeydown);
window.removeEventListener("resize", handleResize);
window.removeEventListener("keydown", handleKeydown);
};
}, []);
return (
<AnimatePresence>
{isOpen && (
{modal && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className={`h-full transition-opacity duration-300`}
className="h-full"
>
<div
ref={popoverRef}
className="fixed inset-0 bg-black/70 overflow-y-auto flex flex-col items-end justify-center"
className={cn(
"fixed inset-0 bg-black/70 overflow-y-auto flex flex-col justify-center",
position === "center" && "items-center",
position === "right" && "items-end"
)}
>
<div className="max-h-full">
<div ref={divRef} className="p-[0.972vw] h-dvh">
<div ref={divRef} className="p-[0.972vw]">
<div
ref={buttonRef}
ref={backdropRef}
className="absolute inset-0 cursor-pointer"
onClick={() => setIsOpen(false)}
onClick={() => setModal(null)}
/>
<div className="relative w-full h-full">
<div
ref={containerRef}
className="relative w-full"
// style={{
// height: `calc(${backdropRef.current?.clientHeight}px - 0.972vw * 2)`,
// }}
>
{modal}
<Button
onlyIcon
className="absolute top-[1.667vw] right-[1.667vw] p-[0.556vw] !rounded-full bg-[#F9F9F9]"
onClick={() => setIsOpen(false)}
onClick={() => setModal(null)}
>
<span className="w-[1.389vw] h-[1.389vw] text-black">
<CloseIcon />
+5 -5
View File
@@ -1,7 +1,7 @@
import { IServer } from '../../types/IServer.ts';
import Button from '../Button.tsx';
import Input from '../Input.tsx';
import DisplayIcon from '../icons/DisplayIcon.tsx';
import { IServer } from "../../types/IServer.ts";
import Button from "../Button.tsx";
import Input from "../Input.tsx";
import DisplayIcon from "../icons/DisplayIcon.tsx";
interface Props {
servers: IServer[];
@@ -9,7 +9,7 @@ interface Props {
export default function CreateSessionModal({ servers }: Props) {
return (
<div className="w-[34.375vw] rounded-[0.833vw] bg-white min-h-full p-[1.667vw] flex flex-col justify-between gap-[1.111vw]">
<div 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]">
<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]">