diff --git a/src/components/Input.tsx b/src/components/Input.tsx index a7024de..08e9c89 100644 --- a/src/components/Input.tsx +++ b/src/components/Input.tsx @@ -1,19 +1,22 @@ import clsx from "clsx"; +import SpinIcon from "./icons/SpinIcon"; interface NewInputProps extends React.InputHTMLAttributes { placeholder?: string; isError?: boolean; errorMessage?: string; + isLoading?: boolean; } function Input({ placeholder, isError, errorMessage, + isLoading, ...props }: NewInputProps) { return ( -
+
- {placeholder} + {placeholder + (props.required ? "*" : "")} )} {isError && ( @@ -38,6 +41,11 @@ function Input({ {errorMessage}

)} + {isLoading && ( +
+ +
+ )}
); } diff --git a/src/components/MultySelect.tsx b/src/components/MultySelect.tsx index aa819ec..0f89976 100644 --- a/src/components/MultySelect.tsx +++ b/src/components/MultySelect.tsx @@ -29,17 +29,15 @@ function MultySelect({ setIsSelectVisible(false); }); - useEffect(() => { - onSelect(selectedValues); - }, [selectedValues]); + useEffect(() => onSelect(selectedValues), [selectedValues]); const handleSelectClick = (item: T) => { const isItemSelected = selectedValues.some((val) => val.id === item.id); if (isItemSelected) { - setSelectedValues(selectedValues.filter((value) => value.id !== item.id)); + setSelectedValues((prev) => prev.filter((value) => value.id !== item.id)); } else { - setSelectedValues([...selectedValues, item]); + setSelectedValues((prev) => [...prev, item]); } }; @@ -51,9 +49,7 @@ function MultySelect({
setIsSelectVisible(!isSelectVisible)} > diff --git a/src/components/ProjectSelector.tsx b/src/components/ProjectSelector.tsx index ecb0f2e..08fa264 100644 --- a/src/components/ProjectSelector.tsx +++ b/src/components/ProjectSelector.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from "react"; -import { IApp } from "../types/App"; +import { App } from "../types/App"; import ChevronLeftIcon from "./icons/ChevronLeftIcon"; import CloseIcon from "./icons/CloseIcon"; import LightningIcon from "./icons/LightningIcon"; @@ -8,10 +8,10 @@ import CheckIcon from "./icons/CheckIcon"; import ChevronDownIcon from "./icons/ChevronDownIcon"; interface Props { - projects: IApp[]; - selectedProject: IApp | null; - setSelectedProject: (project: IApp | null) => void; - activeProject: IApp | null; + projects: App[]; + selectedProject: App | null; + setSelectedProject: (project: App | null) => void; + activeProject: App | null; } function ProjectSelector({ @@ -26,7 +26,7 @@ function ProjectSelector({ const [isOpen, setIsOpen] = useState(false); - const [pointedProject, setPointedProject] = useState(null); + const [pointedProject, setPointedProject] = useState(null); useEffect(() => { setPointedProject(selectedProject); diff --git a/src/components/icons/SpinIcon.tsx b/src/components/icons/SpinIcon.tsx index f64e60b..4ddaf11 100644 --- a/src/components/icons/SpinIcon.tsx +++ b/src/components/icons/SpinIcon.tsx @@ -15,8 +15,6 @@ function SpinIcon() { >
( targetServer ); - const [selectedApp, setSelectedApp] = useState(null); + const [selectedApp, setSelectedApp] = useState(null); useEffect(() => { setSelectedApp( @@ -48,9 +50,32 @@ export default function CreateSessionModal({ targetServerId }: Props) { ); }, [selectedServer]); + const debouncedPhone = useDebounce(phone, 500); + + const { data, isLoading, error } = useQuery({ + queryKey: ["get-user-by-phone", debouncedPhone], + queryFn: () => + api + .get("clients/by-phone", { + searchParams: debouncedPhone ? { phone: debouncedPhone } : {}, + }) + .json(), + enabled: !!debouncedPhone, + }); + + useEffect(() => { + if (!error && data) { + setName(data.name); + setEmail(data.email); + } else { + setName(null); + setEmail(null); + } + }, [data, error]); + const { mutate: createClient } = useMutation({ - mutationFn: () => { - return api + mutationFn: () => + api .post("clients", { json: { name, @@ -58,8 +83,7 @@ export default function CreateSessionModal({ targetServerId }: Props) { email, }, }) - .json(); - }, + .json(), }); const { mutate: createSession } = useMutation({ @@ -158,7 +182,7 @@ export default function CreateSessionModal({ targetServerId }: Props) { return (
@@ -166,7 +190,7 @@ export default function CreateSessionModal({ targetServerId }: Props) {

Новый сеанс

-
+
setPhone(e.target.value)} placeholder="Номер телефона" required + isLoading={isLoading} /> - setName(e.target.value)} - placeholder="Имя" - required - /> - setEmail(e.target.value)} - placeholder="Электронная почта" - /> + + {phone && ( + <> + + setName(e.target.value)} + placeholder="Имя" + required + /> + + + setEmail(e.target.value)} + placeholder="Электронная почта" + /> + + + )} +
@@ -232,7 +277,8 @@ export default function CreateSessionModal({ targetServerId }: Props) {
diff --git a/src/queries/useQueryApps.ts b/src/queries/useQueryApps.ts index b2e42b5..4c92983 100644 --- a/src/queries/useQueryApps.ts +++ b/src/queries/useQueryApps.ts @@ -1,10 +1,10 @@ -import { IApp } from "../types/App.ts"; +import { App } from "../types/App.ts"; import api from "../utils/api.ts"; import { useQuery } from "@tanstack/react-query"; export default function useQueryApps() { return useQuery({ queryKey: ["apps"], - queryFn: () => api.get("apps").json(), + queryFn: () => api.get("apps").json(), }); } diff --git a/src/types/App.ts b/src/types/App.ts index e26853d..89da5bb 100644 --- a/src/types/App.ts +++ b/src/types/App.ts @@ -1,4 +1,4 @@ -export interface IApp { +export interface App { id: string; name: string; fileName: string; diff --git a/src/types/Company.ts b/src/types/Company.ts index 551b268..43a9bdc 100644 --- a/src/types/Company.ts +++ b/src/types/Company.ts @@ -1,11 +1,11 @@ -import { IApp } from "./App"; +import { App } from "./App"; import { Server } from "./Server"; -import { IUser } from "./User"; +import { User } from "./User"; -export interface ICompany { +export interface Company { id: string; name: string; - apps?: IApp[]; + apps?: App[]; servers?: Server[]; - users?: IUser[]; + users?: User[]; } diff --git a/src/types/Server.ts b/src/types/Server.ts index 5bdf97f..beff257 100644 --- a/src/types/Server.ts +++ b/src/types/Server.ts @@ -1,4 +1,4 @@ -import { IApp as App } from "./App"; +import { App as App } from "./App"; import { Session } from "./Session"; export interface Server { diff --git a/src/types/Session.ts b/src/types/Session.ts index 6c8a420..a38b5f5 100644 --- a/src/types/Session.ts +++ b/src/types/Session.ts @@ -1,4 +1,4 @@ -import { IApp as App } from "./App"; +import { App as App } from "./App"; import { Comment } from "./Comment"; import { IOwner as Owner } from "./Owner"; import { Server } from "./Server"; diff --git a/src/types/User.ts b/src/types/User.ts index c70cb6e..c81f1ff 100644 --- a/src/types/User.ts +++ b/src/types/User.ts @@ -1,9 +1,9 @@ -import { ICompany } from "./Company"; +import { Company } from "./Company"; -export interface IUser { +export interface User { id: string; email: string; fullname: string; companyId: string; - company?: ICompany; + company?: Company; }