diff --git a/src/components/Notification/NotificationCard.tsx b/src/components/Notification/NotificationCard.tsx index 2b748ca4..802c3a8d 100644 --- a/src/components/Notification/NotificationCard.tsx +++ b/src/components/Notification/NotificationCard.tsx @@ -4,6 +4,8 @@ import { useDeleteNotification } from '@/hooks/useDeleteNotification'; import cn from '@/lib/cn'; import relativeTime from '@/utils/relativeTime'; import IconClose from '@assets/svg/close'; +import { useRouter } from 'next/navigation'; +import { toast } from 'sonner'; type NotificationStatus = 'confirmed' | 'declined'; @@ -12,6 +14,7 @@ interface NotificationCardProps { id: number; createdAt: string; onDelete: (id: number) => void; + onCardClick?: () => void; } const statusColorMap: Record< @@ -50,14 +53,16 @@ export default function NotificationCard({ createdAt, id, onDelete, + onCardClick, }: NotificationCardProps) { - const { mutate: deleteNotification } = useDeleteNotification(); + const { mutateAsync: deleteNotification } = useDeleteNotification(); + const router = useRouter(); const formattedContent = content.replace(/(\(\d{4}-\d{2}-\d{2})\s+/, '$1\n'); - const handleDelete = () => { + const handleDelete = async () => { + await deleteNotification(id); onDelete(id); - deleteNotification(id); }; const keywordMatch = Object.entries(statusKeywordMap).find(([k]) => @@ -66,6 +71,19 @@ export default function NotificationCard({ const status = keywordMatch?.[1]; + const handleCardClick = async () => { + try { + await deleteNotification(id); + onDelete(id); + onCardClick?.(); + router.push('/mypage/reservations'); + } catch { + toast.error( + '알림 확인 중 문제가 발생했습니다. 잠시 후 다시 시도해 주세요.', + ); + } + }; + return (
@@ -79,8 +97,8 @@ export default function NotificationCard({ )}
-

- {formattedContent.split(/(승인|거절)/).map((text, i) => { - const matchedStatus = statusKeywordMap[text]; - return ( - - {text} - - ); - })} -

+
+

+ {formattedContent.split(/(승인|거절)/).map((text, i) => { + const matchedStatus = statusKeywordMap[text]; + return ( + + {text} + + ); + })} +

-

{relativeTime(createdAt)}

+

{relativeTime(createdAt)}

+
); } diff --git a/src/components/Notification/NotificationCardList.tsx b/src/components/Notification/NotificationCardList.tsx index 0c741adc..1aa958e0 100644 --- a/src/components/Notification/NotificationCardList.tsx +++ b/src/components/Notification/NotificationCardList.tsx @@ -8,6 +8,7 @@ import { toast } from 'sonner'; type NotificationCardListProps = { notification: Notification['notifications']; + onCardClick?: () => void; }; /** @@ -26,6 +27,7 @@ type NotificationCardListProps = { */ export default function NotificationCardList({ notification, + onCardClick, }: NotificationCardListProps) { // 현재 화면에 표시할 알림 목록 상태 const [currentNotifications, setCurrentNotifications] = @@ -143,6 +145,7 @@ export default function NotificationCardList({ prev.filter((item) => item.id !== id), ) } + onCardClick={onCardClick} /> ))} diff --git a/src/components/Notification/NotificationDropdown.tsx b/src/components/Notification/NotificationDropdown.tsx index d9e43e0d..11b33077 100644 --- a/src/components/Notification/NotificationDropdown.tsx +++ b/src/components/Notification/NotificationDropdown.tsx @@ -68,7 +68,10 @@ export default function NotificationDropdown({ )} {!isLoading && data && ( - + )} ); diff --git a/src/hooks/useDeleteNotification.ts b/src/hooks/useDeleteNotification.ts index 66f95f46..ad715076 100644 --- a/src/hooks/useDeleteNotification.ts +++ b/src/hooks/useDeleteNotification.ts @@ -1,5 +1,6 @@ import { privateInstance } from '@/apis/privateInstance'; import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { toast } from 'sonner'; /** * 특정 알림을 삭제하는 비동기 함수입니다. @@ -40,5 +41,9 @@ export const useDeleteNotification = () => { onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['notifications'] }); }, + + onError: () => { + toast.error('알림 삭제를 실패했습니다.'); + }, }); };