feat: implement SessionComments component for user feedback and integrate it into SessionModal

This commit is contained in:
2025-06-09 17:59:18 +05:00
parent a4a3fde940
commit 4407702680
6 changed files with 132 additions and 33 deletions
+8 -8
View File
@@ -45,7 +45,7 @@ function ModalContainer() {
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className='h-full'
className="h-full"
>
<div
ref={popoverRef}
@@ -55,27 +55,27 @@ function ModalContainer() {
position === "right" && "items-end"
)}
>
<div className='max-h-full'>
<div ref={divRef} className='p-[0.972vw]'>
<div className="max-h-full">
<div ref={divRef} className="p-[0.972vw]">
<div
ref={backdropRef}
className='absolute inset-0 cursor-pointer'
className="absolute inset-0 cursor-pointer"
onClick={() => setModal(null)}
/>
<div
ref={containerRef}
className='relative w-full'
className="relative w-full"
// style={{
// height: `calc(${backdropRef.current?.clientHeight}px - 0.972vw * 2)`,
// }}
>
{modal}
<NewButton
variant='secondary'
className='absolute top-[1.389vw] right-[1.389vw] p-[0.556vw]'
variant="secondary"
className="absolute top-[1.389vw] right-[1.389vw] p-[0.556vw]"
onClick={() => setModal(null)}
>
<span className='w-[0.972vw] h-[0.972vw] text-[#7D7D7D]'>
<span className="w-[0.972vw] h-[0.972vw] text-[#7D7D7D]">
<CloseIcon />
</span>
</NewButton>
+100
View File
@@ -0,0 +1,100 @@
import { useRef } from "react";
import SendIcon from "./icons/SendIcon";
import NewButton from "./NewButton";
import { IComment } from "../types/IComments";
import { useQueryClient } from "@tanstack/react-query";
function SessionComments({
comments,
sessionId,
}: {
comments: IComment[];
sessionId: string;
}) {
const textareaRef = useRef<HTMLTextAreaElement>(null);
const formRef = useRef<HTMLFormElement>(null);
const queryClient = useQueryClient();
const handleTextareaInput = () => {
const textarea = textareaRef.current;
const form = formRef.current;
if (!textarea || !form) return;
textarea.style.height = "auto";
form.style.height = "auto";
const newHeight = Math.min(
textarea.scrollHeight + (32 / 1440) * innerWidth,
(225 / 1440) * innerWidth
);
const formHeight = Math.min(
form.clientHeight >= 80 ? newHeight + (32 / 1440) * innerWidth : 80,
(225 / 1440) * innerWidth
);
textarea.style.height = `${newHeight}px`;
form.style.height = `${formHeight}px`;
textarea.style.overflowY =
textarea.scrollHeight > (225 / 1440) * innerWidth ? "auto" : "hidden";
};
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
console.log("submit");
};
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
handleSubmit(e as unknown as React.FormEvent<HTMLFormElement>);
}
};
return (
<div className="flex-1 flex flex-col">
<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" />
<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">
{`В дальнейшем это поможет быстро найти
клиента и не запутаться.`}
</p>
</div>
</div>
)}
</div>
<form
ref={formRef}
className="flex gap-[2.222vw] bg-white justify-center items-start p-[1.111vw]"
onSubmit={handleSubmit}
>
<textarea
ref={textareaRef}
rows={1}
className="w-[17.083vw] outline-none font-medium text-s resize-none self-center"
placeholder="Расскажите, как все прошло"
style={{
wordWrap: "break-word",
overflowY: "hidden",
}}
onInput={handleTextareaInput}
onKeyDown={handleKeyDown}
/>
<NewButton variant="cta" size="large">
<span className="w-[1.111vw] h-[1.111vw] text-white">
<SendIcon />
</span>
</NewButton>
</form>
</div>
);
}
export default SessionComments;
+21
View File
@@ -0,0 +1,21 @@
function SendIcon() {
return (
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="m16 4-4.2 12-2.4-5.4L4 8.2z"
stroke="#fff"
strokeWidth={1.2}
strokeLinejoin="round"
/>
<path
d="m15 5-5.5 5.5"
stroke="#fff"
strokeWidth={1.2}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
export default SendIcon;
@@ -234,3 +234,4 @@ export default function CreateSessionModal({ targetServerId }: Props) {
</form>
);
}
+2 -20
View File
@@ -9,9 +9,9 @@ import Badge from "../Badge";
import ClientCard from "../ClientCard";
import DownloadIcon from "../icons/DownloadIcon";
import ShareIcon from "../icons/ShareIcon";
import SessionComments from "../SessionComments";
function SessionModal({ session }: { session: ISession }) {
console.log(session);
return (
<div className="bg-[#FFFFFF] w-[49.722vw] rounded-4xl">
<div className="w-full flex justify-center items-center h-[4.861vw]">
@@ -123,25 +123,7 @@ function SessionModal({ session }: { session: ISession }) {
</div>
</div>
</div>
<div className="flex-1 flex flex-col">
<div className="relative h-full">
{session.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" />
<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">
{`В дальнейшем это поможет быстро найти
клиента и не запутаться.`}
</p>
</div>
</div>
)}
</div>
<div className="h-[5.556vw] border-black border-t"></div>
</div>
<SessionComments comments={session.comments} sessionId={session.id} />
</div>
</div>
);
-5
View File
@@ -8,7 +8,6 @@ import { ISession } from "../types/ISession";
import SessionCard from "../components/SessionCard";
import NewButton from "../components/NewButton";
import ChevronRightIcon from "../components/icons/ChevronRightIcon";
import { useEffect } from "react";
function DashboardPage() {
const { data: me } = useQuery({
@@ -43,10 +42,6 @@ function DashboardPage() {
// }
// }
useEffect(() => {
console.log(sessions);
}, [sessions]);
return (
<div className="flex flex-col gap-[5vw] min-h-dvh">
<div className="w-full flex justify-between">