@@ -73,20 +73,79 @@ const Header = ({ isDark, setIsDark, isLoggedIn, nickname, onLoginModalOpen }) =
7373 }
7474 } ;
7575
76- const handleNotificationRead = async ( id ) => {
77- try {
78- const token = localStorage . getItem ( 'token' ) ;
79- await fetch ( `${ config . API_BASE_URL } /api/notifications/${ id } /read` , {
80- method : 'PUT' ,
81- headers : {
82- 'Authorization' : `Bearer ${ token } `
76+ const resolveNotificationId = useCallback ( ( notification ) => {
77+ if ( ! notification ) return null ;
78+ return (
79+ notification . id ??
80+ notification . notificationId ??
81+ notification . notificationNo ??
82+ notification . notificationSeq ??
83+ null
84+ ) ;
85+ } , [ ] ) ;
86+
87+ const handleNotificationRead = useCallback (
88+ async ( id ) => {
89+ if ( ! id ) return false ;
90+ try {
91+ const token = localStorage . getItem ( 'token' ) ;
92+ if ( ! token ) {
93+ console . error ( "Error marking notification as read: missing auth token" ) ;
94+ return false ;
8395 }
84- } ) ;
85- fetchNotifications ( ) ;
86- } catch ( error ) {
87- console . error ( "Error marking notification as read:" , error ) ;
88- }
89- } ;
96+ const response = await fetch ( `${ config . API_BASE_URL } /api/notifications/${ id } /read` , {
97+ method : 'PUT' ,
98+ headers : {
99+ 'Authorization' : `Bearer ${ token } `
100+ }
101+ } ) ;
102+
103+ if ( ! response . ok ) {
104+ throw new Error ( `Failed to mark notification as read: ${ response . status } ` ) ;
105+ }
106+
107+ let didMark = false ;
108+ setNotifications ( ( prev ) =>
109+ prev . map ( ( item ) => {
110+ const itemId = resolveNotificationId ( item ) ;
111+ if ( itemId && itemId === id && ! item . read ) {
112+ didMark = true ;
113+ return { ...item , read : true } ;
114+ }
115+ return item ;
116+ } )
117+ ) ;
118+
119+ if ( didMark ) {
120+ setUnreadCount ( ( prev ) => Math . max ( prev - 1 , 0 ) ) ;
121+ }
122+
123+ return true ;
124+ } catch ( error ) {
125+ console . error ( "Error marking notification as read:" , error ) ;
126+ return false ;
127+ }
128+ } ,
129+ [ resolveNotificationId ]
130+ ) ;
131+
132+ const handleNotificationNavigate = useCallback (
133+ async ( notification ) => {
134+ if ( ! notification ) return ;
135+
136+ const notificationId = resolveNotificationId ( notification ) ;
137+ await handleNotificationRead ( notificationId ) ;
138+
139+ if ( notification . postId ) {
140+ navigate ( `/community/post/${ notification . postId } ` ) ;
141+ }
142+
143+ setIsNotificationMenuOpen ( false ) ;
144+ setIsViewAll ( false ) ;
145+ setCurrentPage ( 1 ) ;
146+ } ,
147+ [ handleNotificationRead , navigate , resolveNotificationId ]
148+ ) ;
90149
91150 const handleViewAll = ( ) => {
92151 setIsViewAll ( true ) ;
@@ -162,17 +221,38 @@ const Header = ({ isDark, setIsDark, isLoggedIn, nickname, onLoginModalOpen }) =
162221 </ button >
163222 ) }
164223 { displayNotifications . length > 0 ? (
165- displayNotifications . map ( notification => (
166- < div
167- key = { notification . id }
168- className = { `notification-item ${ ! notification . read ? 'unread' : 'read' } ` }
169- onClick = { ( ) => handleNotificationRead ( notification . id ) }
170- >
171- < span className = "notification-message" >
172- { notification . message }
173- </ span >
174- </ div >
175- ) )
224+ displayNotifications . map ( ( notification , index ) => {
225+ const notificationId = resolveNotificationId ( notification ) ;
226+ const key = notificationId ?? `notification-${ index } ` ;
227+ const isUnread = ! notification . read ;
228+ const disableRead = ! notificationId || ! isUnread ;
229+
230+ return (
231+ < div
232+ key = { key }
233+ className = { `notification-item ${ isUnread ? 'unread' : 'read' } ` }
234+ >
235+ < button
236+ type = "button"
237+ className = "notification-message"
238+ onClick = { ( ) => handleNotificationNavigate ( notification ) }
239+ >
240+ { notification . message }
241+ </ button >
242+ < button
243+ type = "button"
244+ className = "notification-read-btn"
245+ disabled = { disableRead }
246+ onClick = { async ( e ) => {
247+ e . stopPropagation ( ) ;
248+ await handleNotificationRead ( notificationId ) ;
249+ } }
250+ >
251+ 읽음
252+ </ button >
253+ </ div >
254+ ) ;
255+ } )
176256 ) : (
177257 < div className = "no-notifications" > 알림이 없습니다.</ div >
178258 ) }
0 commit comments