diff --git a/client/src/components/Toast/ToastContainer.tsx b/client/src/components/Toast/ToastContainer.tsx index 781ecdc5..8cdd0f29 100644 --- a/client/src/components/Toast/ToastContainer.tsx +++ b/client/src/components/Toast/ToastContainer.tsx @@ -1,3 +1,4 @@ +import { AnimatePresence } from "framer-motion"; import { useToastStore } from "@stores/useToastStore"; import { Toast } from "./Toast"; import { ToastContainerStyle } from "./ToastContainer.style"; @@ -7,14 +8,16 @@ export const ToastContainer = () => { return (
- {toasts.map((toast) => ( - removeToast(toast.id)} - /> - ))} + + {toasts.map((toast) => ( + removeToast(toast.id)} + /> + ))} +
); }; diff --git a/client/src/components/sidebar/Sidebar.tsx b/client/src/components/sidebar/Sidebar.tsx index fb9077be..a9bb76a7 100644 --- a/client/src/components/sidebar/Sidebar.tsx +++ b/client/src/components/sidebar/Sidebar.tsx @@ -7,7 +7,6 @@ import { useModal } from "@components/modal/useModal"; import { MAX_VISIBLE_PAGE } from "@src/constants/page"; import { AuthButton } from "@src/features/auth/AuthButton"; import { useSocketStore } from "@src/stores/useSocketStore"; -import { useToastStore } from "@src/stores/useToastStore"; import { Page } from "@src/types/page"; import { useIsSidebarOpen, useSidebarActions } from "@stores/useSidebarStore"; import { animation, contentVariants, sidebarVariants } from "./Sidebar.animation"; @@ -43,7 +42,6 @@ export const Sidebar = ({ const { isOpen, openModal, closeModal } = useModal(); const { sendPageDeleteOperation, clientId } = useSocketStore(); - const { addToast } = useToastStore(); const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [pageToDelete, setPageToDelete] = useState(null); @@ -69,11 +67,10 @@ export const Sidebar = ({ return; } - addToast(`페이지(${pageToDelete!.title})가 삭제되었습니다.`); - sendPageDeleteOperation({ type: "pageDelete", workspaceId: "default", + pageTitle: pageToDelete!.title, pageId, clientId, }); diff --git a/client/src/features/workSpace/hooks/usePagesManage.ts b/client/src/features/workSpace/hooks/usePagesManage.ts index 94299d5b..9aeec259 100644 --- a/client/src/features/workSpace/hooks/usePagesManage.ts +++ b/client/src/features/workSpace/hooks/usePagesManage.ts @@ -8,6 +8,7 @@ import { Page as CRDTPage } from "@noctaCrdt/Page"; import { WorkSpace } from "@noctaCrdt/WorkSpace"; import { useEffect, useState, useRef, useCallback } from "react"; import { useSocketStore } from "@src/stores/useSocketStore"; +import { useToastStore } from "@src/stores/useToastStore"; import { Page } from "@src/types/page"; const PAGE_OFFSET = 60; @@ -17,6 +18,7 @@ export const usePagesManage = (workspace: WorkSpace | null, clientId: number | n const { subscribeToPageOperations, sendPageCreateOperation, sendPageUpdateOperation } = useSocketStore(); const subscriptionRef = useRef(false); + const { addToast } = useToastStore(); useEffect(() => { if (!workspace) return; if (subscriptionRef.current) return; @@ -52,6 +54,7 @@ export const usePagesManage = (workspace: WorkSpace | null, clientId: number | n addPage(newPage); }, onRemotePageDelete: (operation) => { + addToast(`${operation.clientId}번 유저가 페이지(${operation.pageTitle})를 삭제하였습니다.`); workspace.remotePageDelete?.({ pageId: operation.pageId, workspaceId: operation.workspaceId, diff --git a/client/src/stores/useToastStore.ts b/client/src/stores/useToastStore.ts index 2be5146a..56758a24 100644 --- a/client/src/stores/useToastStore.ts +++ b/client/src/stores/useToastStore.ts @@ -9,10 +9,19 @@ interface ToastStore { export const useToastStore = create((set) => ({ toasts: [], - addToast: (message, duration = 3000) => + addToast: (message, duration = 3000) => { + const id = Date.now(); set((state) => ({ - toasts: [...state.toasts, { id: Date.now(), message, duration }], - })), + toasts: [...state.toasts, { id, message, duration }], + })); + // duration 후에 자동으로 해당 toast 제거 + setTimeout(() => { + set((state) => ({ + toasts: state.toasts.filter((toast) => toast.id !== id), + })); + }, duration); + }, + removeToast: (id) => set((state) => ({ toasts: state.toasts.filter((toast) => toast.id !== id),