sending comments fixes pxls

This commit is contained in:
2025-06-09 19:04:18 +05:00
parent 29a29d53a0
commit 364db1adf7
7 changed files with 93 additions and 79 deletions
+8
View File
@@ -38,6 +38,14 @@ function ModalContainer() {
};
}, []);
useEffect(() => {
if (!modal) return;
document.body.style.overflow = "hidden";
return () => {
document.body.style.overflow = "auto";
};
}, [modal]);
return (
<AnimatePresence>
{modal && (
+23 -25
View File
@@ -14,32 +14,30 @@ function NewInput({
}: NewInputProps) {
return (
<div className="relative">
<div className="relative">
<input
{...props}
placeholder=""
className={clsx(
isError
? "hover:ring-[#FF4517] focus:ring-[#FF4517]"
: "hover:ring-[#7B60F3] focus:ring-[#7B60F3]",
"peer bg-[#F6F6F6] rounded-xl px-[1.111vw] pt-[19px] pb-[11px] outline-none ring-1 ring-transparent transition-all inline-block w-full h-[3.889vw] text-s"
)}
/>
{placeholder && (
<span
className="absolute caption-m font-medium text-[#7D7D7D] left-[1.111vw] top-1/2 -translate-y-1/2 pointer-events-none transition-all duration-300
peer-focus:caption-xs peer-focus:font-medium peer-focus:top-[0.556vw] peer-focus:translate-y-0
peer-[:not(:placeholder-shown)]:caption-xs peer-[:not(:placeholder-shown)]:font-medium peer-[:not(:placeholder-shown)]:top-[0.278vw] peer-[:not(:placeholder-shown)]:translate-y-0"
>
{placeholder}
</span>
<input
{...props}
placeholder=""
className={clsx(
isError
? "hover:ring-[#FF4517] focus:ring-[#FF4517]"
: "hover:ring-[#7B60F3] focus:ring-[#7B60F3]",
"peer bg-[#F6F6F6] rounded-[0.833vw] px-[1.111vw] pt-[19px] pb-[11px] outline-none ring-1 ring-transparent transition-all inline-block w-full h-[3.889vw] text-m"
)}
{isError && (
<p className="caption-s font-medium text-[#FF4517] mt-[0.556vw]">
{errorMessage}
</p>
)}
</div>
/>
{placeholder && (
<span
className="absolute caption-m font-medium text-[#7D7D7D] left-[1.111vw] top-1/2 -translate-y-1/2 pointer-events-none transition-all duration-300
peer-focus:caption-xs peer-focus:top-[0.556vw] peer-focus:translate-y-0
peer-[:not(:placeholder-shown)]:caption-xs peer-[:not(:placeholder-shown)]:top-[0.556vw] peer-[:not(:placeholder-shown)]:translate-y-0"
>
{placeholder}
</span>
)}
{isError && (
<p className="caption-s font-medium text-[#FF4517] mt-[0.556vw]">
{errorMessage}
</p>
)}
</div>
);
}
+30 -9
View File
@@ -2,7 +2,8 @@ import { useRef } from "react";
import SendIcon from "./icons/SendIcon";
import NewButton from "./NewButton";
import { IComment } from "../types/IComments";
import { useQueryClient } from "@tanstack/react-query";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import api from "../utils/api";
function SessionComments({
comments,
@@ -13,8 +14,6 @@ function SessionComments({
}) {
const textareaRef = useRef<HTMLTextAreaElement>(null);
const formRef = useRef<HTMLFormElement>(null);
const queryClient = useQueryClient();
const handleTextareaInput = () => {
const textarea = textareaRef.current;
@@ -39,27 +38,49 @@ function SessionComments({
textarea.scrollHeight > (225 / 1440) * innerWidth ? "auto" : "hidden";
};
const queryClient = useQueryClient();
const { mutate: createComment } = useMutation({
mutationFn: (comment: string) =>
api.post("comments", {
json: {
sessionId: sessionId,
text: comment,
},
}),
onSuccess: () => queryClient.invalidateQueries({ queryKey: ["sessions"] }),
});
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
console.log("submit");
const textarea = textareaRef.current;
if (!textarea?.value) return;
createComment(textarea.value);
textarea.value = "";
handleTextareaInput();
};
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (e.key === "Enter" && !e.shiftKey) {
if (e.key === "Enter") {
e.preventDefault();
handleSubmit(e as unknown as React.FormEvent<HTMLFormElement>);
}
};
return (
<div className="flex-1 flex flex-col">
<div className="outline flex flex-col flex-1 outline-[#D6D6D6]">
<div className="relative h-full">
{comments.length > 0 ? (
<div>Комменты</div>
) : (
<div className="flex flex-col gap-[1.111vw] items-center justify-center h-full">
<img src="/images/smile-ghost.png" alt="ghost" />
<img
src="/images/smile-ghost.png"
className="w-[13.889vw]"
alt="ghost"
/>
<div className="flex flex-col gap-[0.556vw] items-center">
<h3 className="title-m font-medium">Оставьте заметку</h3>
<p className="caption-s font-medium text-[#BDBDBD] text-center whitespace-pre-line">
@@ -87,7 +108,7 @@ function SessionComments({
onInput={handleTextareaInput}
onKeyDown={handleKeyDown}
/>
<NewButton variant="cta" size="large">
<NewButton variant="cta" size="large" type="submit">
<span className="w-[1.111vw] h-[1.111vw] text-white">
<SendIcon />
</span>
+8 -21
View File
@@ -120,20 +120,6 @@ export default function CreateSessionModal({ targetServerId }: Props) {
}
endSession(undefined, {
// onSuccess: () => {
// createClient(undefined, {
// onSuccess: (client) => {
// createSession({
// clientId: client.id,
// serverId: selectedServer.id,
// appId: selectedApp.id,
// });
// },
// onError: (error) => {
// console.log(error);
// },
// });
// },
onError: (error) => {
console.log("Ошибка при завершении сессии:", error);
},
@@ -141,14 +127,13 @@ export default function CreateSessionModal({ targetServerId }: Props) {
}
useEffect(() => {
console.log(servers, selectedServer, selectedApp, isSessionExists);
if (
selectedServer &&
servers?.find((server) => server.id === selectedServer?.id)?.sessions?.[0]
?.status === "ended" &&
selectedApp &&
isSessionExists
) {
)
createClient(undefined, {
onSuccess: (client) => {
createSession({
@@ -158,7 +143,6 @@ export default function CreateSessionModal({ targetServerId }: Props) {
});
},
});
}
}, [
selectedApp,
servers,
@@ -172,7 +156,7 @@ export default function CreateSessionModal({ targetServerId }: Props) {
return (
<form
className="relative 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}
>
@@ -245,11 +229,15 @@ export default function CreateSessionModal({ targetServerId }: Props) {
<NewButton
type="submit"
disabled={
!ref.current?.checkValidity() || !selectedServer || !selectedApp
!ref.current?.checkValidity() ||
!selectedServer ||
!selectedApp ||
servers?.find((server) => server.id === selectedServer?.id)
?.sessions?.[0]?.status === "ending"
}
variant="cta"
size="large"
className="sticky bottom-[1.111vw]"
className="sticky bottom-0"
>
<div className="rounded-full bg-[#9184F6] in-disabled:bg-transparent px-[0.278vw] py-[0.208vw] size-[1.111vw]">
<div className="w-[0.694vw] h-[0.556vw]">
@@ -262,4 +250,3 @@ export default function CreateSessionModal({ targetServerId }: Props) {
</form>
);
}
+18 -18
View File
@@ -27,52 +27,52 @@ function EditTable({ table }: { table: IServer }) {
setModal(null);
},
});
return (
<div className='bg-[#F0F0F0] rounded-4xl w-[25vw] flex flex-col justify-center items-center'>
<h3 className='title-s font-medium py-[1.806vw]'>Редатирование стола</h3>
<div className='bg-[url("/images/Table.png")] bg-no-repeat bg-contain bg-center w-full h-[6.944vw]'></div>
<div className='bg-[#FFFFFF] w-full rounded-4xl p-[1.389vw] flex flex-col gap-[0.833vw]'>
<div className='space-y-[0.556vw]'>
<div className="bg-[#F0F0F0] rounded-4xl w-[25vw] flex flex-col justify-center items-center">
<h3 className="title-s font-medium py-[1.806vw]">Редактирование стола</h3>
<div className="bg-[url(/images/Table.png)] bg-no-repeat bg-contain bg-center w-full h-[6.944vw]"></div>
<div className="bg-[#FFFFFF] w-full rounded-4xl p-[1.389vw] flex flex-col gap-[0.833vw]">
<div className="space-y-[0.556vw]">
<NewInput
placeholder='Название стола*'
placeholder="Название стола*"
value={tableName}
onChange={(e) => setTableName(e.target.value)}
isError={tableName.length > 16}
errorMessage='Не больше 16 символов'
errorMessage="Не больше 16 символов"
/>
<p className='caption-s text-[#BDBDBD] font-medium w-full tracking-[-0.02em]'>
<p className="caption-s text-[#BDBDBD] font-medium w-full tracking-[-0.02em]">
Придумайте название до 16 символов, например «Тузик»
</p>
</div>
<div className='space-y-[0.556vw]'>
<div className="space-y-[0.556vw]">
<NewInput
placeholder='Описание'
placeholder="Описание"
value={tableDescription}
onChange={(e) => setTableDescription(e.target.value)}
isError={tableDescription.length > 20}
errorMessage='Не больше 20 символов'
errorMessage="Не больше 20 символов"
/>
<p className='caption-s text-[#BDBDBD] font-medium w-full tracking-[-0.02em]'>
<p className="caption-s text-[#BDBDBD] font-medium w-full tracking-[-0.02em]">
Придумайте описание до 20 символов, например «Расположен в офисе»
</p>
</div>
<div className='flex flex-col gap-[0.556vw]'>
<div className="flex flex-col gap-[0.556vw]">
<NewButton
variant='cta'
variant="cta"
disabled={
tableName.length < 1 ||
tableName.length > 16 ||
tableDescription.length > 20
}
className='flex justify-center'
className="flex justify-center"
onClick={() => updateTable()}
>
<p>Сохранить изменения</p>
</NewButton>
<NewButton
variant='primary'
className='flex justify-center'
variant="primary"
className="flex justify-center"
onClick={() => setModal(null)}
>
<p>Отменить</p>
+4 -4
View File
@@ -15,7 +15,7 @@ function SessionModal({ session }: { session: ISession }) {
return (
<div className="bg-[#FFFFFF] w-[49.722vw] rounded-4xl">
<div className="w-full flex justify-center items-center h-[4.861vw]">
<div className="title-s font-medium flex">
<div className="title-s flex font-medium">
<p>{format(session.createdAt, "dd MMMM yyyy", { locale: ru })}</p>
<p>,&nbsp;{format(session.createdAt, "HH:mm")}</p>
</div>
@@ -69,7 +69,7 @@ function SessionModal({ session }: { session: ISession }) {
<ClientCard client={session.client} />
</div>
<div className="flex flex-col gap-[1.111vw] bg-white rounded-3xl p-[1.111vw]">
<h3 className="title-s font-medium flex">
<h3 className="title-s flex font-medium">
Речевая&nbsp;
<span className="text-[#7B60F3] flex">
аналитика&nbsp;
@@ -105,8 +105,8 @@ function SessionModal({ session }: { session: ISession }) {
</NewButton>
</div>
<div className="flex flex-col gap-[1.111vw] bg-white rounded-3xl p-[1.111vw]">
<h3 className="title-s font-medium flex">
Документы по сеансу <Badge count={4} />
<h3 className="title-s flex items-center font-medium gap-[0.556vw]">
<span>Документы по сеансу</span> <Badge count={4} />
</h3>
<div className="flex w-full gap-[0.556vw]">
<NewButton variant="primary" size="large" className="w-full">
+2 -2
View File
@@ -5,10 +5,10 @@ function getIntervalDuration(start: Date, end: Date) {
start: start,
end: end,
});
const hours = (duration.hours || 0).toString().padStart(2, "0");
const hours = (duration.hours || 0).toString();
const minutes = (duration.minutes || 0).toString().padStart(2, "0");
const seconds = (duration.seconds || 0).toString().padStart(2, "0");
return `${hours}:${minutes}:${seconds}`;
return `${+hours ? `${hours}:` : ""}${minutes}:${seconds}`;
}
export default getIntervalDuration;