11// src/pages/PostDetail.jsx
2- import React , { useEffect , useState , useMemo , useRef } from "react" ;
2+ import React , { useEffect , useState , useMemo , useRef , useCallback } from "react" ;
33import { useParams , useNavigate } from "react-router-dom" ;
44import "./PostDetail.css" ;
55import config from "../../config" ;
66
7+ const parseIntSafe = ( v ) => {
8+ const n = Number ( v ) ;
9+ return Number . isFinite ( n ) ? n : null ;
10+ } ;
11+
12+ const deriveCommentCount = ( resp , data ) => {
13+ try {
14+ const fromHeader = resp ?. headers ?. get ?. ( "X-Total-Count" ) ;
15+ const n = parseIntSafe ( fromHeader ) ;
16+ if ( n !== null ) return n ;
17+ } catch ( _ ) { }
18+
19+ if ( Array . isArray ( data ) ) return data . length ;
20+ if ( data && typeof data === "object" ) {
21+ if ( typeof data . totalElements === "number" ) return data . totalElements ;
22+ if ( typeof data . total === "number" ) return data . total ;
23+ if ( Array . isArray ( data . content ) ) return data . content . length ;
24+ }
25+ return 0 ;
26+ } ;
27+
728export default function PostDetail ( ) {
829 const { id } = useParams ( ) ; // /community/post/:id
930 const navigate = useNavigate ( ) ;
@@ -37,27 +58,10 @@ export default function PostDetail() {
3758 ? tokenRaw . startsWith ( "Bearer " ) ? tokenRaw : `Bearer ${ tokenRaw } `
3859 : null ;
3960
40- // ===== helpers =====
41- const parseIntSafe = ( v ) => {
42- const n = Number ( v ) ;
43- return Number . isFinite ( n ) ? n : null ;
44- } ;
45-
46- const deriveCommentCount = ( resp , data ) => {
47- try {
48- const fromHeader = resp ?. headers ?. get ?. ( "X-Total-Count" ) ;
49- const n = parseIntSafe ( fromHeader ) ;
50- if ( n !== null ) return n ;
51- } catch ( _ ) { }
52-
53- if ( Array . isArray ( data ) ) return data . length ;
54- if ( data && typeof data === "object" ) {
55- if ( typeof data . totalElements === "number" ) return data . totalElements ;
56- if ( typeof data . total === "number" ) return data . total ;
57- if ( Array . isArray ( data . content ) ) return data . content . length ;
58- }
59- return 0 ;
60- } ;
61+ const requestLogin = useCallback ( ( ) => {
62+ alert ( "로그인이 필요합니다." ) ;
63+ window . dispatchEvent ( new CustomEvent ( "dv:open-login-modal" ) ) ;
64+ } , [ ] ) ;
6165
6266 // 좋아요 수 및 내 상태 재조회
6367 const refreshLikeStatus = async ( ) => {
@@ -141,7 +145,7 @@ export default function PostDetail() {
141145 } , [ id , authHeader ] ) ; // ✅ navigate 제거
142146
143147 // 공통: 댓글 목록 다시 불러오기
144- const fetchComments = async ( ) => {
148+ const fetchComments = useCallback ( async ( ) => {
145149 try {
146150 setLoadingComments ( true ) ;
147151 const bust = Date . now ( ) ;
@@ -168,20 +172,19 @@ export default function PostDetail() {
168172 } finally {
169173 setLoadingComments ( false ) ;
170174 }
171- } ;
175+ } , [ authHeader , id ] ) ;
172176
173177 useEffect ( ( ) => {
174178 // authHeader가 있거나 없더라도 댓글은 로드 시도
175179 if ( ! id ) return ;
176180 fetchComments ( ) ;
177- } , [ id , authHeader ] ) ;
181+ } , [ id , authHeader , fetchComments ] ) ;
178182
179183
180184 // 좋아요 토글
181185 const handleToggleLike = async ( ) => {
182186 if ( ! authHeader ) {
183- alert ( "로그인이 필요합니다." ) ;
184- navigate ( "/login" ) ; // 로그인 페이지로 리다이렉트 (경로 가정)
187+ requestLogin ( ) ;
185188 return ;
186189 }
187190 if ( liking ) return ;
@@ -235,8 +238,7 @@ export default function PostDetail() {
235238 const handleCreateComment = async ( ) => {
236239 if ( ! newComment . trim ( ) ) return ;
237240 if ( ! authHeader ) {
238- alert ( "로그인이 필요합니다." ) ;
239- navigate ( "/login" ) ;
241+ requestLogin ( ) ;
240242 return ;
241243 }
242244
@@ -273,8 +275,7 @@ export default function PostDetail() {
273275 const handleCreateReply = async ( parentId ) => {
274276 if ( ! replyContent . trim ( ) ) return ;
275277 if ( ! authHeader ) {
276- alert ( "로그인이 필요합니다." ) ;
277- navigate ( "/login" ) ;
278+ requestLogin ( ) ;
278279 return ;
279280 }
280281
0 commit comments