1+ // import { useSuspenseQuery } from '@tanstack/react-query';
2+ // import { useEffect, useState } from 'react';
3+
4+ // import { gatheringAPIService } from '@/app/invite/gathering/[gatheringId]/src/service';
5+ // import { CardFrame } from '@/app/proposal/[proposalId]/detail/components/GatheringProposalContent';
6+ // import AppInstallBanner from '@/shared/components/AppInstallBanner';
7+ // import { useParam } from '@/shared/hooks/useParam';
8+ // import { cn } from '@/shared/lib';
9+
10+ // const BANNER_KEY = 'gathering-banner-dismissed-at';
11+ // const BANNER_RESHOW_MINUTES = 30;
12+
13+ // const InviteGatheringContent = () => {
14+ // const gatheringId = Number(useParam('gatheringId'));
15+
16+ // const { data: proposalDetail } = useSuspenseQuery({
17+ // queryKey: ['getGatheringName', gatheringId],
18+ // queryFn: () => gatheringAPIService.getGatheringName(gatheringId),
19+ // });
20+
21+ // const [showBanner, setShowBanner] = useState(false);
22+
23+ // const handleCloseBanner = () => {
24+ // localStorage.setItem(BANNER_KEY, Date.now().toString());
25+ // setShowBanner(false);
26+ // };
27+
28+ // useEffect(() => {
29+ // const dismissedAt = localStorage.getItem(BANNER_KEY);
30+ // const now = Date.now();
31+
32+ // if (!dismissedAt) {
33+ // setShowBanner(true);
34+ // } else {
35+ // const dismissedTime = parseInt(dismissedAt, 10);
36+ // const thirtyMinutes = BANNER_RESHOW_MINUTES * 60 * 1000;
37+ // if (now - dismissedTime > thirtyMinutes) {
38+ // setShowBanner(true);
39+ // }
40+ // }
41+ // }, []);
42+
43+ // return (
44+ // <>
45+ // {showBanner && <AppInstallBanner onClose={handleCloseBanner} /> }
46+
47+ // <h2
48+ // className={cn(
49+ // 'serif-title-22-M font-bold text-gray-900',
50+ // showBanner ? 'mt-[6.875rem]' : 'mt-[1.875rem]'
51+ // )}
52+ // >
53+ // 모임에
54+ // <br />
55+ // 참여하시겠어요?
56+ // </h2>
57+
58+ // <div className="relative mt-[70px] flex flex-col items-center justify-center">
59+ // <div className="h-[320px] w-[278px] rounded-[10px] bg-gray-50" />
60+ // <div
61+ // className={cn(
62+ // 'absolute bottom-[-80px] left-1/2 h-[421px] w-[408px] -translate-x-1/2 translate-y-0'
63+ // )}
64+ // >
65+ // <div className="relative size-full">
66+ // <div className="absolute inset-0 z-0">
67+ // <CardFrame />
68+ // </div>
69+
70+ // {proposalDetail.data.gatheringName && (
71+ // <div className="serif-body-16-M absolute left-1/2 top-[180px] z-[1] -translate-x-1/2 text-center text-gray-900">
72+ // {proposalDetail.data.gatheringName}
73+ // </div>
74+ // )}
75+ // </div>
76+ // </div>
77+ // </div>
78+ // </>
79+ // );
80+ // };
81+
82+ // export default InviteGatheringContent;
83+
84+ 'use client' ;
85+
186import { useSuspenseQuery } from '@tanstack/react-query' ;
2- import { useEffect , useState } from 'react' ;
87+ import { useState } from 'react' ;
88+
89+ import { gatheringAPIService } from '../service' ;
390
4- import { gatheringAPIService } from '@/app/invite/gathering/[gatheringId]/src/service' ;
591import { CardFrame } from '@/app/proposal/[proposalId]/detail/components/GatheringProposalContent' ;
692import AppInstallBanner from '@/shared/components/AppInstallBanner' ;
793import { useParam } from '@/shared/hooks/useParam' ;
894import { cn } from '@/shared/lib' ;
995
10- const BANNER_KEY = 'gathering-banner-dismissed-at' ;
11- const BANNER_RESHOW_MINUTES = 30 ;
96+ // const BANNER_KEY = 'gathering-banner-dismissed-at';
97+ // const BANNER_RESHOW_MINUTES = 30;
1298
1399const InviteGatheringContent = ( ) => {
14100 const gatheringId = Number ( useParam ( 'gatheringId' ) ) ;
@@ -18,50 +104,50 @@ const InviteGatheringContent = () => {
18104 queryFn : ( ) => gatheringAPIService . getGatheringName ( gatheringId ) ,
19105 } ) ;
20106
21- const [ showBanner , setShowBanner ] = useState ( false ) ;
107+ const [ showBanner , setShowBanner ] = useState ( true ) ;
22108
23109 const handleCloseBanner = ( ) => {
24- localStorage . setItem ( BANNER_KEY , Date . now ( ) . toString ( ) ) ;
110+ // localStorage.setItem(BANNER_KEY, Date.now().toString());
25111 setShowBanner ( false ) ;
26112 } ;
27113
28- useEffect ( ( ) => {
29- const dismissedAt = localStorage . getItem ( BANNER_KEY ) ;
30- const now = Date . now ( ) ;
31-
32- if ( ! dismissedAt ) {
33- setShowBanner ( true ) ;
34- } else {
35- const dismissedTime = parseInt ( dismissedAt , 10 ) ;
36- const thirtyMinutes = BANNER_RESHOW_MINUTES * 60 * 1000 ;
37- if ( now - dismissedTime > thirtyMinutes ) {
38- setShowBanner ( true ) ;
39- }
40- }
41- } , [ ] ) ;
114+ // useEffect(() => {
115+ // const dismissedAt = localStorage.getItem(BANNER_KEY);
116+ // const now = Date.now();
117+ // if (!dismissedAt) {
118+ // setShowBanner(true);
119+ // } else {
120+ // const dismissedTime = parseInt(dismissedAt, 10);
121+ // const thirtyMinutes = BANNER_RESHOW_MINUTES * 60 * 1000;
122+ // if (now - dismissedTime > thirtyMinutes) {
123+ // setShowBanner(true);
124+ // }
125+ // }
126+ // }, []);
42127
43128 return (
44129 < >
45130 { showBanner && < AppInstallBanner onClose = { handleCloseBanner } /> }
46131
132+ { /* 배너 노출 시: safe-area 포함하여 충분한 상단 여백 확보 */ }
47133 < h2
48134 className = { cn (
49135 'serif-title-22-M font-bold text-gray-900' ,
50- showBanner ? 'mt-[6.875rem ]' : 'mt-[1.875rem]'
136+ showBanner ? 'mt-[calc(110px+env(safe-area-inset-top,0px)) ]' : 'mt-[1.875rem]'
51137 ) }
52138 >
53139 모임에
54140 < br />
55141 참여하시겠어요?
56142 </ h2 >
57143
58- < div className = "relative mt-[70px] flex flex-col items-center justify-center" >
144+ { /* 카드/프레임 영역 */ }
145+ < div className = "relative mt-[56px] flex flex-col items-center justify-center" >
146+ { /* 카드 배경 박스 (그림자/여백 안정화) */ }
59147 < div className = "h-[320px] w-[278px] rounded-[10px] bg-gray-50" />
60- < div
61- className = { cn (
62- 'absolute bottom-[-80px] left-1/2 h-[421px] w-[408px] -translate-x-1/2 translate-y-0'
63- ) }
64- >
148+
149+ { /* 프레임을 살짝 겹치게 띄워서 시각적 포커스 */ }
150+ < div className = "pointer-events-none absolute bottom-[-80px] left-1/2 h-[421px] w-[408px] -translate-x-1/2" >
65151 < div className = "relative size-full" >
66152 < div className = "absolute inset-0 z-0" >
67153 < CardFrame />
@@ -75,6 +161,9 @@ const InviteGatheringContent = () => {
75161 </ div >
76162 </ div >
77163 </ div >
164+
165+ { /* 본문 끝에서 한 번 더 하단 여백 확보 (작은 기기 대비) */ }
166+ < div className = "h-8" />
78167 </ >
79168 ) ;
80169} ;
0 commit comments