Skip to content

Commit 8de2150

Browse files
committed
[style] 메인페이지 아코디언 오류 수정
1 parent deefde9 commit 8de2150

File tree

5 files changed

+94
-45
lines changed

5 files changed

+94
-45
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { useEffect, useRef, useState } from 'react';
2+
import { getApi } from '@/app/api/config/appConfig';
3+
4+
export function useSSENotification(isLoggedIn: boolean) {
5+
const [hasNewNotification, setHasNewNotification] = useState(false);
6+
const eventSourceRef = useRef<EventSource | null>(null);
7+
const isConnectingRef = useRef(false);
8+
9+
useEffect(() => {
10+
// 로그인 안 했으면 연결 안 함
11+
if (!isLoggedIn) {
12+
if (eventSourceRef.current) {
13+
console.log('🔌 로그아웃으로 인한 SSE 연결 종료');
14+
eventSourceRef.current.close();
15+
eventSourceRef.current = null;
16+
isConnectingRef.current = false;
17+
}
18+
return;
19+
}
20+
21+
// 이미 연결 중이거나 연결되어 있으면 중복 방지
22+
if (isConnectingRef.current || eventSourceRef.current) {
23+
console.log('⚠️ 이미 SSE 연결 중 또는 연결됨');
24+
return;
25+
}
26+
27+
isConnectingRef.current = true;
28+
console.log('🔌 SSE 연결 시작...');
29+
30+
const eventSource = new EventSource(`${getApi}/me/subscribe`, {
31+
withCredentials: true,
32+
});
33+
34+
eventSourceRef.current = eventSource;
35+
36+
eventSource.onopen = () => {
37+
console.log('✅ SSE 연결 성공!');
38+
isConnectingRef.current = false;
39+
};
40+
41+
eventSource.onmessage = (event) => {
42+
console.log('📢 새 알림 도착:', event.data);
43+
setHasNewNotification(true);
44+
};
45+
46+
eventSource.onerror = (error) => {
47+
console.error('❌ SSE 에러:', error);
48+
console.log('연결 상태:', eventSource.readyState);
49+
50+
isConnectingRef.current = false;
51+
52+
if (eventSource.readyState === EventSource.CLOSED) {
53+
console.log('🔄 SSE 연결이 닫혔습니다');
54+
eventSourceRef.current = null;
55+
}
56+
};
57+
58+
// cleanup 함수
59+
return () => {
60+
console.log('🔌 컴포넌트 언마운트로 인한 SSE 연결 종료');
61+
if (eventSourceRef.current) {
62+
eventSourceRef.current.close();
63+
eventSourceRef.current = null;
64+
}
65+
isConnectingRef.current = false;
66+
};
67+
}, [isLoggedIn]); // isLoggedIn만 의존성으로
68+
69+
const clearNotification = () => {
70+
setHasNewNotification(false);
71+
};
72+
73+
return { hasNewNotification, clearNotification };
74+
}

src/domains/main/components/mainSlide/components/mobile/MobileAbv.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ function MobileAbv() {
5353
<h2 className="text-xl sm:text-2xl font-black text-white">내 알콜도수 UP</h2>
5454
<button
5555
type="button"
56-
className={clsx(`block duration-300 sm:hidden`, isClick ? 'rotate-135' : 'rotate-0')}
56+
className={clsx(`block z-1 duration-300 sm:hidden`, isClick ? 'rotate-[135deg]' : 'rotate-0')}
5757
onClick={() => setIsClick(!isClick)}
5858
>
5959
<Add />

src/domains/main/components/mainSlide/components/mobile/MobileSlideCommunity.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ function MobileSlideCommunity() {
1616
<h2 className="text-xl sm:text-2xl font-black text-white">함께 나누는 칵테일 이야기</h2>
1717
<button
1818
type="button"
19-
className={clsx(`block duration-300 sm:hidden`, isClick ? 'rotate-135' : 'rotate-0')}
19+
className={clsx(
20+
`block duration-300 z-1 sm:hidden`,
21+
isClick ? 'rotate-[135deg]' : 'rotate-0'
22+
)}
2023
onClick={() => setIsClick(!isClick)}
2124
>
2225
<Add />

src/domains/main/components/mainSlide/components/mobile/MobileSlideTest.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,15 @@ function MobileSlideTest() {
2525
<h2 className="text-xl sm:text-2xl font-black text-white">AI기반 취향테스트</h2>
2626
<button
2727
type="button"
28-
className={clsx(`block duration-300 sm:hidden`, isClick ? 'rotate-135' : 'rotate-0')}
29-
onClick={() => setIsClick(!isClick)}
28+
className={clsx(
29+
`block duration-300 z-1 sm:hidden`,
30+
isClick ? 'rotate-[135deg]' : 'rotate-0'
31+
)}
32+
onClick={() => {
33+
setIsClick(!isClick);
34+
}}
3035
>
31-
<Add />
36+
<Add className="pointer-events-none" />
3237
</button>
3338
</header>
3439
<div

src/shared/components/header/HeaderBtn.tsx

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,51 +6,18 @@ import { useRouter } from 'next/navigation';
66
import tw from '@/shared/utills/tw';
77
import { useAuthStore } from '@/domains/shared/store/auth';
88
import { setPreLoginPath } from '@/domains/shared/auth/utils/setPreLoginPath';
9-
import { useEffect, useState } from 'react';
9+
import { useState } from 'react';
1010
import LogoutConfirm from '@/domains/login/components/LogoutConfirm';
11-
import { getApi } from '@/app/api/config/appConfig';
11+
import { useSSENotification } from '@/domains/main/api/useSSENotification';
12+
1213

1314
function HeaderBtn({ pathname }: { pathname: string }) {
1415
const { isLoggedIn } = useAuthStore();
1516
const router = useRouter();
1617
const [logoutModalOpen, setLogoutModalOpen] = useState(false);
17-
const [hasNewNotification, setHasNotification] = useState(false);
18-
19-
useEffect(() => {
20-
if (!isLoggedIn) return;
21-
22-
console.log('🔌 SSE 연결 시작...');
23-
const eventSource = new EventSource(`${getApi}/me/subscribe`, { withCredentials: true });
24-
25-
eventSource.onopen = () => {
26-
console.log('✅ SSE 연결 성공!');
27-
};
28-
29-
eventSource.onmessage = (event) => {
30-
console.log('📢 새 알림 도착:', event.data);
31-
setHasNotification(true);
32-
};
33-
34-
eventSource.onerror = (error) => {
35-
console.error('❌ SSE 에러:', error);
36-
console.log('연결 상태:', eventSource.readyState); // 0: CONNECTING, 1: OPEN, 2: CLOSED
37-
eventSource.close();
38-
};
39-
40-
return () => {
41-
console.log('🔌 SSE 연결 종료');
42-
eventSource.close();
43-
};
44-
}, [isLoggedIn]);
45-
46-
useEffect(() => {
47-
const timer = setTimeout(() => {
48-
console.log('🧪 테스트 알림 발생');
49-
setHasNotification(true);
50-
}, 5000);
51-
52-
return () => clearTimeout(timer);
53-
}, []);
18+
19+
20+
const {hasNewNotification,clearNotification} = useSSENotification(isLoggedIn)
5421

5522
const navButtons = [
5623
{
@@ -59,7 +26,7 @@ function HeaderBtn({ pathname }: { pathname: string }) {
5926
className: pathname === '/mypage/my-alarm' ? 'text-tertiary' : 'text-current',
6027
hiddenMobile: true,
6128
onClick: () => {
62-
setHasNotification(false);
29+
clearNotification()
6330
router.push('/mypage/my-alarm');
6431
},
6532
showBadge: true,

0 commit comments

Comments
 (0)