11import { Progress , Button } from '@pinback/design-system/ui' ;
22import { useState , useEffect , lazy , Suspense } from 'react' ;
33import { motion , AnimatePresence } from 'framer-motion' ;
4+ import SocialLoginStep from './step/SocialLoginStep' ;
45const StoryStep = lazy ( ( ) => import ( './step/StoryStep' ) ) ;
56const AlarmStep = lazy ( ( ) => import ( './step/AlarmStep' ) ) ;
67const MacStep = lazy ( ( ) => import ( './step/MacStep' ) ) ;
78const FinalStep = lazy ( ( ) => import ( './step/FinalStep' ) ) ;
8-
99import { cva } from 'class-variance-authority' ;
1010import { usePostSignUp } from '@shared/apis/queries' ;
11- const stepProgress = [ { progress : 30 } , { progress : 60 } , { progress : 100 } ] ;
12- import { AlarmsType } from '@constants/alarms' ;
13- import { normalizeTime } from '@pages/onBoarding/utils/formatRemindTime' ;
11+ import { useNavigate , useLocation } from 'react-router-dom' ;
1412import { firebaseConfig } from '../../../../firebase-config' ;
1513import { initializeApp } from 'firebase/app' ;
1614import { getMessaging , getToken } from 'firebase/messaging' ;
1715import { registerServiceWorker } from '@pages/onBoarding/utils/registerServiceWorker' ;
18- import { useLocation } from 'react-router-dom' ;
16+ import { AlarmsType } from '@constants/alarms' ;
17+ import { normalizeTime } from '@pages/onBoarding/utils/formatRemindTime' ;
18+ const stepProgress = [ { progress : 33 } , { progress : 66 } , { progress : 100 } ] ;
19+ import {
20+ Step ,
21+ stepOrder ,
22+ StepType ,
23+ storySteps ,
24+ } from '@pages/onBoarding/constants/onboardingSteps' ;
25+
1926const variants = {
2027 slideIn : ( direction : number ) => ( {
2128 x : direction > 0 ? 200 : - 200 ,
@@ -27,6 +34,7 @@ const variants = {
2734 opacity : 0 ,
2835 } ) ,
2936} ;
37+
3038const CardStyle = cva (
3139 'bg-white-bg flex h-[54.8rem] w-[63.2rem] flex-col items-center justify-between rounded-[2.4rem] pt-[3.2rem]' ,
3240 {
@@ -39,36 +47,41 @@ const CardStyle = cva(
3947 defaultVariants : { overflow : false } ,
4048 }
4149) ;
50+
4251const MainCard = ( ) => {
43- const [ step , setStep ] = useState ( 0 ) ;
52+ const navigate = useNavigate ( ) ;
53+ const location = useLocation ( ) ;
54+ const { mutate : postSignData } = usePostSignUp ( ) ;
55+
56+ const [ step , setStep ] = useState < StepType > ( Step . STORY_0 ) ;
4457 const [ direction , setDirection ] = useState ( 0 ) ;
4558 const [ alarmSelected , setAlarmSelected ] = useState < 1 | 2 | 3 > ( 1 ) ;
4659 const [ isMac , setIsMac ] = useState ( false ) ;
47- // api 구간
48- const { mutate : postSignData } = usePostSignUp ( ) ;
49-
50- // 익스텐션에서부터 이메일 받아오는 구간!
5160 const [ userEmail , setUserEmail ] = useState ( '' ) ;
52- const location = useLocation ( ) ;
61+ const [ remindTime , setRemindTime ] = useState ( '09:00' ) ;
62+ const [ fcmToken , setFcmToken ] = useState < string | null > ( null ) ;
5363
5464 useEffect ( ( ) => {
5565 const params = new URLSearchParams ( location . search ) ;
56- const emailParam = params . get ( 'email' ) ;
57- if ( emailParam ) {
58- setUserEmail ( emailParam ) ;
59- localStorage . setItem ( 'email' , emailParam ) ;
66+ const storedEmail = localStorage . getItem ( 'email' ) ;
67+ if ( storedEmail ) {
68+ setUserEmail ( storedEmail ) ;
69+ }
70+
71+ const stepParam = params . get ( 'step' ) as StepType ;
72+ if ( stepParam && Object . values ( Step ) . includes ( stepParam ) ) {
73+ setStep ( stepParam ) ;
6074 }
6175 } , [ location . search ] ) ;
6276
63- // FCM 구간
64- const [ fcmToken , setFcmToken ] = useState < string | null > ( null ) ;
6577 const app = initializeApp ( firebaseConfig ) ;
6678 const messaging = getMessaging ( app ) ;
6779
6880 const requestFCMToken = async ( ) : Promise < string | null > => {
6981 try {
7082 const permission = await Notification . requestPermission ( ) ;
7183 registerServiceWorker ( ) ;
84+
7285 if ( permission !== 'granted' ) {
7386 alert ( '알림 권한 허용이 필요합니다!' ) ;
7487 return null ;
@@ -107,80 +120,92 @@ const MainCard = () => {
107120 }
108121 } ) ( ) ;
109122 } , [ ] ) ;
123+
110124 const renderStep = ( ) => {
111125 switch ( step ) {
112- case 0 :
113- case 1 :
114- case 2 :
115- return < StoryStep step = { step as 0 | 1 | 2 } /> ;
116- case 3 :
126+ case Step . STORY_0 :
127+ case Step . STORY_1 :
128+ case Step . STORY_2 :
129+ return (
130+ < StoryStep step = { Number ( step . replace ( 'STORY_' , '' ) ) as 0 | 1 | 2 } />
131+ ) ;
132+ case Step . SOCIAL_LOGIN :
133+ return < SocialLoginStep /> ;
134+ case Step . ALARM :
117135 return (
118136 < AlarmStep selected = { alarmSelected } setSelected = { setAlarmSelected } />
119137 ) ;
120- case 4 :
121- if ( isMac ) return < MacStep /> ;
138+ case Step . MAC :
139+ return < MacStep /> ;
140+ case Step . FINAL :
122141 return < FinalStep /> ;
123- case 5 :
124- if ( isMac ) return < FinalStep /> ;
125- return null ;
126142 default :
127143 return < FinalStep /> ;
128144 }
129145 } ;
130146
131- const [ remindTime , setRemindTime ] = useState ( '09:00' ) ;
132147 const nextStep = async ( ) => {
133- if ( step === 3 ) {
134- if ( alarmSelected == 1 ) {
135- setRemindTime ( '09:00' ) ;
136- } else if ( alarmSelected == 2 ) {
137- setRemindTime ( '20:00' ) ;
138- } else {
148+ const idx = stepOrder . indexOf ( step ) ;
149+ const next = stepOrder [ idx + 1 ] ;
150+ const isAlarmStep = step === Step . ALARM ;
151+ const isFinalStep = step === Step . FINAL ;
152+ const isMacStep = next === Step . MAC ;
153+ const shouldSkipMacStep = isMacStep && ! isMac ;
154+
155+ if ( isAlarmStep ) {
156+ if ( alarmSelected === 1 ) setRemindTime ( '09:00' ) ;
157+ else if ( alarmSelected === 2 ) setRemindTime ( '20:00' ) ;
158+ else {
139159 const raw = AlarmsType [ alarmSelected - 1 ] . time ;
140160 setRemindTime ( normalizeTime ( raw ) ) ;
141161 }
162+ }
142163
164+ if ( shouldSkipMacStep ) {
143165 setDirection ( 1 ) ;
144- setStep ( ( prev ) => prev + 1 ) ;
166+ setStep ( Step . FINAL ) ;
167+ navigate ( `/onboarding?step=${ Step . FINAL } ` ) ;
145168 return ;
146169 }
147- if ( ( isMac && step < 5 ) || ( ! isMac && step < 4 ) ) {
148- setDirection ( 1 ) ;
149- setStep ( ( prev ) => prev + 1 ) ;
150- } else if ( ( isMac && step === 5 ) || ( ! isMac && step == 4 ) ) {
170+
171+ if ( isFinalStep ) {
151172 postSignData (
173+ { email : userEmail , remindDefault : remindTime , fcmToken } ,
152174 {
153- email : userEmail ,
154- remindDefault : remindTime ,
155- fcmToken : fcmToken ,
156- } ,
157- {
158- onSuccess : ( ) => {
159- window . location . href = '/' ;
160- } ,
175+ onSuccess : ( ) => ( window . location . href = '/' ) ,
161176 onError : ( ) => {
162177 const savedEmail = localStorage . getItem ( 'email' ) ;
163- if ( savedEmail ) {
164- window . location . href = '/' ;
165- }
178+ if ( savedEmail ) window . location . href = '/' ;
166179 } ,
167180 }
168181 ) ;
182+ return ;
169183 }
184+
185+ setDirection ( 1 ) ;
186+ setStep ( next ) ;
187+ navigate ( `/onboarding?step=${ next } ` ) ;
170188 } ;
171189
172190 const prevStep = ( ) => {
173- if ( step > 0 ) {
191+ const idx = stepOrder . indexOf ( step ) ;
192+ if ( idx > 0 ) {
193+ const previous = stepOrder [ idx - 1 ] ;
174194 setDirection ( - 1 ) ;
175- setStep ( ( prev ) => prev - 1 ) ;
195+ setStep ( previous ) ;
196+ navigate ( `/onboarding?step=${ previous } ` ) ;
176197 }
177198 } ;
178199
179200 return (
180- < div className = { CardStyle ( { overflow : step === 3 && alarmSelected === 3 } ) } >
181- { step < 3 && (
201+ < div
202+ className = { CardStyle ( {
203+ overflow : step === Step . ALARM && alarmSelected === 3 ,
204+ } ) }
205+ >
206+ { storySteps . includes ( step ) && (
182207 < Progress
183- value = { stepProgress [ step ] . progress }
208+ value = { stepProgress [ storySteps . indexOf ( step ) ] . progress }
184209 variant = "profile"
185210 className = "w-[15.6rem]"
186211 />
@@ -204,26 +229,27 @@ const MainCard = () => {
204229 </ div >
205230
206231 < div className = "mb-[4.8rem] mt-[1.2rem] flex w-full justify-between px-[3.2rem]" >
207- { step < 4 && step > 0 && (
232+ { ! ( [ Step . STORY_0 , Step . SOCIAL_LOGIN ] as StepType [ ] ) . includes ( step ) && (
208233 < Button
209234 variant = "secondary"
210235 size = "medium"
211- isDisabled = { step === 0 }
212236 className = "w-[4.8rem]"
213237 onClick = { prevStep }
214238 >
215239 뒤로
216240 </ Button >
217241 ) }
218- < Button
219- variant = "primary"
220- size = "medium"
221- isDisabled = { step === 6 }
222- className = "ml-auto w-[4.8rem]"
223- onClick = { nextStep }
224- >
225- 다음
226- </ Button >
242+
243+ { step !== Step . SOCIAL_LOGIN && (
244+ < Button
245+ variant = "primary"
246+ size = "medium"
247+ className = "ml-auto w-[4.8rem]"
248+ onClick = { nextStep }
249+ >
250+ 다음
251+ </ Button >
252+ ) }
227253 </ div >
228254 </ div >
229255 ) ;
0 commit comments