diff --git a/src/components/common/notification-modal/NotificationCard.tsx b/src/components/common/notification-modal/NotificationCard.tsx
index 1b92f235..51a8cc90 100644
--- a/src/components/common/notification-modal/NotificationCard.tsx
+++ b/src/components/common/notification-modal/NotificationCard.tsx
@@ -1,16 +1,17 @@
-import { useNavigate } from 'react-router-dom';
-import { putAlerts } from '@/api/alertApi';
+import { Link } from 'react-router-dom';
import calculateTimeDifference from '@/utils/calculateTimeDifference';
import formatWorkTime from '@/utils/formatWorkTime';
interface NotificationCardProps {
alertId: string; // 알림 id
+ shopId: string; // 가게 id
noticeId: string; // 공고 id
status: 'accepted' | 'rejected'; // 공고 지원 상태
restaurantName: string; // 음식점 이름
startsAt: string; // 공고 시작 시간 (ISO 8601 문자열)
workhour: number; // 근무 시간 (시간 단위)
createdAt: string; // 알림 생성 시간 (ISO 8601 문자열)
+ onMarkAsRead: (alertId: string) => void;
}
/*
@@ -21,39 +22,27 @@ interface NotificationCardProps {
export default function NotificationCard({
alertId,
+ shopId,
noticeId,
status,
restaurantName,
startsAt,
workhour,
createdAt,
+ onMarkAsRead,
}: NotificationCardProps) {
const formattedTime = formatWorkTime({
startsAt,
workhour,
});
- const navigate = useNavigate();
+
const formattedCreatedAt = calculateTimeDifference(createdAt);
const formattedStatus = status === 'accepted' ? '승인' : '거절';
const formattedStatusClass =
status === 'accepted' ? 'text-blue-20' : 'text-red-20';
- const handleClick = () => {
- const userId = localStorage.getItem('userId');
-
- if (!userId) {
- console.error('userId를 찾을 수 없습니다.');
- return;
- }
- try {
- putAlerts(userId, alertId); // 알림 읽음 처리
- navigate(`/${noticeId}`);
- } catch (error) {
- console.error(error);
- }
- };
return (
-
+
onMarkAsRead(alertId)}>
{status === 'accepted' ? (
@@ -67,6 +56,6 @@ export default function NotificationCard({
{formattedCreatedAt}
-
+
);
}
diff --git a/src/components/common/notification-modal/NotificationModal.tsx b/src/components/common/notification-modal/NotificationModal.tsx
index 67e2e546..4633d344 100644
--- a/src/components/common/notification-modal/NotificationModal.tsx
+++ b/src/components/common/notification-modal/NotificationModal.tsx
@@ -4,8 +4,8 @@ import type { AlertListItem } from '@/api/alertApi';
interface NotificationModalProps {
data?: AlertListItem[]; // 알림 데이터 배열
- count?: number; // 알림 개수
onClose: () => void; // x 버튼을 누를때 실행할 함수
+ onMarkAsRead: (alertId: string) => void;
}
/*
@@ -17,29 +17,32 @@ interface NotificationModalProps {
export default function NotificationModal({
data = [],
- count = 0,
onClose,
+ onMarkAsRead,
}: NotificationModalProps) {
+ const unreadData = data.filter((alertItem) => alertItem.item.read === false);
return (
-
알림 {count}개
+
알림 {unreadData.length}개
- {data.length > 0 &&
- data.map((data) => (
+ {unreadData.length > 0 &&
+ unreadData.map((alertItem) => (
))}
diff --git a/src/components/layout/Navbar.tsx b/src/components/layout/Navbar.tsx
index 801b2d9d..106d1c43 100644
--- a/src/components/layout/Navbar.tsx
+++ b/src/components/layout/Navbar.tsx
@@ -8,11 +8,16 @@ import alarmActive from '@/assets/icons/alarm-active.svg';
import alarmInactive from '@/assets/icons/alarm-inactive.svg';
export default function Navbar() {
- const { isLoggedIn, role, alarms, logout } = useContext(AuthContext);
+ const { isLoggedIn, role, alarms, logout, markAlertAsRead } =
+ useContext(AuthContext);
const [isShowModal, setIsShowModal] = useState(false);
const modalRef = useRef
(null);
const buttonRef = useRef(null);
+ const unreadAlarmCount = alarms.items.filter(
+ (alert) => !alert.item.read,
+ ).length;
+
// 바깥 클릭 시 모달 닫기
useEffect(() => {
function handleClickOutside(event: MouseEvent): void {
@@ -42,6 +47,11 @@ export default function Navbar() {
return () => document.removeEventListener('keydown', handleKeyDown);
}, []);
+ const handleNotificationClick = (alertId: string) => {
+ markAlertAsRead(alertId); // AuthContext의 함수를 호출해 알림을 읽음 처리
+ setIsShowModal(false); // Navbar의 state를 변경해 모달을 닫음
+ };
+
return (
)}
diff --git a/src/context/AuthContext.tsx b/src/context/AuthContext.tsx
index f1599482..a0d46a6b 100644
--- a/src/context/AuthContext.tsx
+++ b/src/context/AuthContext.tsx
@@ -1,5 +1,5 @@
import { createContext, useState, useEffect, type ReactNode } from 'react';
-import { getAlerts, type AlertViewResponse } from '@/api/alertApi';
+import { getAlerts, putAlerts, type AlertViewResponse } from '@/api/alertApi';
type UserRole = 'employer' | 'employee' | null;
interface AuthContextType {
@@ -8,6 +8,7 @@ interface AuthContextType {
alarms: AlertViewResponse; // 알림 정보
login: (token: string, role: UserRole, userId: string) => void; // 로그인 함수
logout: () => void; // 로그아웃 함수
+ markAlertAsRead: (alertId: string) => void;
}
const defaultAuthContext: AuthContextType = {
@@ -23,6 +24,7 @@ const defaultAuthContext: AuthContextType = {
},
login: () => {},
logout: () => {},
+ markAlertAsRead: () => {},
};
export const AuthContext = createContext(defaultAuthContext);
@@ -35,12 +37,24 @@ export function AuthProvider({ children }: { children: ReactNode }) {
);
useEffect(() => {
- const token = localStorage.getItem('accessToken');
- const role = localStorage.getItem('userRole') as UserRole;
- if (token && role) {
- setIsLoggedIn(true);
- setRole(role);
- }
+ const fetchAuth = async () => {
+ const token = localStorage.getItem('accessToken');
+ const userRole = localStorage.getItem('userRole') as UserRole;
+ const userId = localStorage.getItem('userId');
+
+ if (token && userRole && userId) {
+ setIsLoggedIn(true);
+ setRole(userRole);
+ try {
+ const alertRes = await getAlerts(userId);
+ setAlarms(alertRes);
+ } catch (error) {
+ console.error('앱 로딩 중 알림 가져오기 실패:', error);
+ }
+ }
+ };
+
+ fetchAuth();
}, []);
const login = async (token: string, role: UserRole, userId: string) => {
@@ -66,8 +80,29 @@ export function AuthProvider({ children }: { children: ReactNode }) {
setAlarms(defaultAuthContext.alarms);
};
+ const markAlertAsRead = async (alertId: string) => {
+ const userId = localStorage.getItem('userId');
+ if (!userId) {
+ console.error('읽음 처리 실패: userId를 찾을 수 없습니다.');
+ return;
+ }
+
+ setAlarms((prevAlarms) => ({
+ ...prevAlarms,
+ items: prevAlarms.items.filter((alert) => alert.item.id !== alertId),
+ }));
+
+ try {
+ await putAlerts(userId, alertId);
+ } catch (error) {
+ console.error('API - 알림 읽음 처리 실패:', error);
+ }
+ };
+
return (
-
+
{children}
);