diff --git a/public/images/empty_ghost.png b/public/images/empty_ghost.png new file mode 100644 index 0000000..b59f875 Binary files /dev/null and b/public/images/empty_ghost.png differ diff --git a/src/components/Button.tsx b/src/components/Button.tsx index a927df7..27fd380 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -27,7 +27,7 @@ function Button({ onClick?.(e); }} className={clsx( - "transition-all flex outline-none 2xl:gap-[0.556vw] gap-2 items-center justify-center font-medium disabled:bg-[#F6F6F6] disabled:text-[#D6D6D6]", + "transition-all flex outline-none 2xl:gap-[0.556vw] gap-2 items-center justify-center font-medium disabled:bg-[#F6F6F6] disabled:!text-[#D6D6D6]", variant === "critical" && "text-[#FF4517] bg-[#FEF3F2] hover:bg-[#FEE4E2]", variant === "secondary" && diff --git a/src/components/SessionCommentItem.tsx b/src/components/SessionCommentItem.tsx index aeb8692..4107981 100644 --- a/src/components/SessionCommentItem.tsx +++ b/src/components/SessionCommentItem.tsx @@ -1,11 +1,64 @@ import { motion } from "motion/react"; import { Comment } from "../types/Comment"; -import { format } from "date-fns"; +import { format, isToday } from "date-fns"; +import { Session } from "../types/Session"; +import { ru } from "date-fns/locale"; +import ChevronRightIcon from "./icons/ChevronRightIcon"; +import useModalStore from "../stores/useModalStore"; +import SessionModal from "./modals/SessionModal"; +import { useQuery } from "@tanstack/react-query"; +import api from "../utils/api"; + +function SessionCommentItem({ + comment, + session, +}: { + comment: Comment; + session?: Session; +}) { + const { setModal } = useModalStore(); + + const { data: files } = useQuery({ + queryKey: ["file-list", comment.sessionId], + enabled: !!session, + queryFn: () => + api + .get("files", { + searchParams: { sessionId: comment.sessionId }, + }) + .json<{ filename: string; size: number }[]>(), + }); -function SessionCommentItem({ comment }: { comment: Comment }) { return (
+ {session && ( +
setModal()} + > +
+
+

+ Сеанс{" "} + {isToday(new Date(session.createdAt)) + ? "Сегодня" + : `от ${format(new Date(session.createdAt), "dd MMMM", { + locale: ru, + })}`} +

+ {files && ( +

+ {files?.length}{" "} + {files?.length === 1 ? "документ" : "документов"} +

+ )} +
+
+ +
+
+ )}

{comment.manager.fullname}

@@ -18,7 +71,7 @@ function SessionCommentItem({ comment }: { comment: Comment }) {

-
+
); } diff --git a/src/components/SessionComments.tsx b/src/components/SessionComments.tsx index bfab89a..86439c7 100644 --- a/src/components/SessionComments.tsx +++ b/src/components/SessionComments.tsx @@ -158,7 +158,7 @@ function SessionComments({ sessionId }: { sessionId: string }) { onKeyDown={handleKeyDown} /> diff --git a/src/components/icons/SendIcon.tsx b/src/components/icons/SendIcon.tsx index 6a699a6..f94ff4f 100644 --- a/src/components/icons/SendIcon.tsx +++ b/src/components/icons/SendIcon.tsx @@ -3,13 +3,13 @@ function SendIcon() {

{client.name}

-
+
@@ -123,8 +124,12 @@ function ClientModal({ client }: { client: Client }) {

-
-
+ {client.managers.map((manager) => ( +
+ ))}
-
+
+ {client.sessions + .filter((session) => session.comments.length) + .map((session) => ( +
+

+ {isToday(new Date(session.createdAt)) + ? "Сегодня" + : format(new Date(session.createdAt), "dd MMMM", { + locale: ru, + })} +

+
+ {session.comments.map((comment) => ( + + ))} +
+
+ ))} + {(client.sessions.length === 0 || + client.sessions.filter((session) => session.comments.length) + .length === 0) && ( +
+
+ +
+
+

+ Пока что пусто +

+

+ Здесь отображаются все комментарии по сеансам с текущим + клиентом +

+
+
+ )} +
); diff --git a/src/components/modals/CreateSessionModal.tsx b/src/components/modals/CreateSessionModal.tsx index 3696ae1..a8c6e5c 100644 --- a/src/components/modals/CreateSessionModal.tsx +++ b/src/components/modals/CreateSessionModal.tsx @@ -46,7 +46,7 @@ export default function CreateSessionModal({ targetServerId, client }: Props) { useEffect(() => { setSelectedApp( selectedServer?.sessions?.[0]?.app || - selectedServer?.apps?.[0].app || + selectedServer?.appsToServers?.[0].app || null ); }, [selectedServer]); @@ -244,15 +244,15 @@ export default function CreateSessionModal({ targetServerId, client }: Props) {

Выберите параметры сеанса

{selectedServer && - selectedServer?.apps && - selectedServer?.apps?.length > 0 && ( + selectedServer?.appsToServers && + selectedServer?.appsToServers?.length > 0 && ( app)} + projects={selectedServer?.appsToServers.map(({ app }) => app)} selectedProject={selectedApp} setSelectedProject={setSelectedApp} /> diff --git a/src/components/modals/EndSessionModal.tsx b/src/components/modals/EndSessionModal.tsx index c1f6d6d..b1e1529 100644 --- a/src/components/modals/EndSessionModal.tsx +++ b/src/components/modals/EndSessionModal.tsx @@ -1,28 +1,42 @@ -import { useMutation } from "@tanstack/react-query"; -import { useQueryClient } from "@tanstack/react-query"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; import useModalStore from "../../stores/useModalStore"; import { Session } from "../../types/Session"; import Button from "../Button"; import CurrentSessionModal from "./CurrentSessionModal"; import api from "../../utils/api"; import SpinIcon from "../icons/SpinIcon"; +import SessionModal from "./SessionModal"; +import { Server } from "../../types/Server"; function EndSessionModal({ session }: { session: Session }) { const queryClient = useQueryClient(); - const { setModal } = useModalStore(); + + const { setModal, setPosition } = useModalStore(); const { mutate: endSession, isPending } = useMutation({ mutationKey: ["sessions", session.id], mutationFn: () => - api.put(`sessions/${session.id}`, { json: { status: "ending" } }), + api + .put(`sessions/${session.id}`, { json: { status: "ending" } }) + .json(), onMutate: () => { - queryClient.invalidateQueries({ queryKey: ["sessions"] }); - queryClient.invalidateQueries({ queryKey: ["last-started"] }); - queryClient.invalidateQueries({ queryKey: ["servers"] }); + // queryClient.invalidateQueries({ queryKey: ["sessions"] }); + // queryClient.invalidateQueries({ queryKey: ["last-started"] }); + // queryClient.invalidateQueries({ queryKey: ["servers"] }); + setModal(null); }, onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["servers"] }); queryClient.invalidateQueries({ queryKey: ["last-sessions"] }); - setModal(null); + queryClient.invalidateQueries({ queryKey: ["sessions"] }); + const servers = queryClient.getQueryData(["servers"]); + const updatedSession = servers + ?.find((s) => s.id === session.serverId) + ?.sessions?.find((s) => s.id === session.id); + if (updatedSession) { + setPosition("right"); + setModal(); + } }, }); diff --git a/src/components/modals/SessionModal.tsx b/src/components/modals/SessionModal.tsx index b666658..9586110 100644 --- a/src/components/modals/SessionModal.tsx +++ b/src/components/modals/SessionModal.tsx @@ -15,8 +15,8 @@ import DownloadIcon from "../icons/DownloadIcon"; import ShareIcon from "../icons/ShareIcon"; function SessionModal({ session }: { session: Session }) { - const { data } = useQuery({ - queryKey: ["file-list"], + const { data: files } = useQuery({ + queryKey: ["file-list", session.id], queryFn: () => api .get("files", { @@ -122,13 +122,13 @@ function SessionModal({ session }: { session: Session }) {
- {data && ( + {files && (

Документы по сеансу - +

- +