Skip to content

Commit

Permalink
refactor: 온보딩 (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
ddhelop committed Oct 31, 2024
1 parent 555b7e0 commit 200edde
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 28 deletions.
1 change: 0 additions & 1 deletion src/app/login/onboarding-agree/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import OnBoardingAgree from '@/features/onBoarding/components/OnBoardingAgree'
import OnBoardingInfo from '@/features/onBoarding/components/OnBoardingInfo'
import OnBoaridngHeader from '@/features/onBoarding/components/OnBoaridngHeader'

export default function OnBoardingAgreePage() {
Expand Down
26 changes: 26 additions & 0 deletions src/features/onBoarding/api/memberApi.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,29 @@ export async function submitMemberInfo(data: MemberInfo, accessToken: string) {
console.error('Error submitting member info:', error)
}
}

// src/features/member/api/memberApi.ts

import { ConsentInfo } from '../types/memberTypes'

export async function submitConsentInfo(data: ConsentInfo, accessToken: string) {
try {
const response = await fetch(`${process.env.NEXT_PUBLIC_LINKIT_SERVER_URL}/api/v1/member/consent`, {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=UTF-8',
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify(data),
credentials: 'include',
})

if (!response.ok) {
throw new Error(`Error submitting consent info: ${response.statusText}`)
}

return await response.json()
} catch (error) {
console.error('Error submitting consent info:', error)
}
}
29 changes: 6 additions & 23 deletions src/features/onBoarding/components/OnBoardingAgree.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,12 @@
'use client'

import { useState } from 'react'
import { Button } from '@/shared/ui/Button/Button'
import Image from 'next/image'
import { useOnBoardingAgree } from '../hooks/useOnBoardingAgree'

export default function OnBoardingAgree() {
const [allChecked, setAllChecked] = useState(false) // "모두 동의하기" 상태
const [checkedItems, setCheckedItems] = useState([false, false, false, false]) // 개별 항목 체크 상태

// 필수 항목 (첫 3개 항목) 체크 여부 확인
const isNextEnabled = checkedItems.slice(0, 3).every(Boolean)

// 개별 체크박스 클릭 핸들러
const handleCheckClick = (index: number) => {
const updatedItems = [...checkedItems]
updatedItems[index] = !updatedItems[index]
setCheckedItems(updatedItems)
setAllChecked(updatedItems.every(Boolean))
}

// 모두 동의하기 버튼 클릭 핸들러
const handleAllCheckClick = () => {
const newState = !allChecked
setAllChecked(newState)
setCheckedItems(checkedItems.map(() => newState))
}
const { allChecked, checkedItems, isNextEnabled, handleCheckClick, handleAllCheckClick, submitConsentInfoHandler } =
useOnBoardingAgree()

return (
<div className="flex w-full flex-col items-center">
Expand Down Expand Up @@ -55,7 +37,7 @@ export default function OnBoardingAgree() {
'(필수) 만 14세 이상입니다',
'(선택) 광고성 정보 수신 동의',
].map((item, index) => (
<div key={index} className={`flex items-center justify-between gap-6 rounded-xl `}>
<div key={index} className={`flex items-center justify-between gap-6 rounded-xl`}>
<div onClick={() => handleCheckClick(index)} className="flex cursor-pointer items-center gap-6">
<div
className={`rounded-[0.6rem] border border-grey40 p-[0.54rem] ${
Expand All @@ -82,7 +64,8 @@ export default function OnBoardingAgree() {
mode="main"
size="lg"
animationMode="main"
disabled={!isNextEnabled} // 필수 항목들이 체크되었을 때만 활성화
disabled={!isNextEnabled}
onClick={submitConsentInfoHandler} // 동의 정보를 제출하는 버튼
>
다음
</Button>
Expand Down
13 changes: 9 additions & 4 deletions src/features/onBoarding/components/OnBoardingComplete.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Button } from '@/shared/ui/Button/Button'
import Image from 'next/image'
import Link from 'next/link'

export default function OnBoardingComplete() {
return (
Expand All @@ -13,10 +14,14 @@ export default function OnBoardingComplete() {
<p className="text-sm text-grey50">나머지 정보를 입력해 프로필을 완성해 보세요</p>
</div>

<Button animationMode="main" className="mt-[5.13rem] w-[50%] rounded-lg bg-main text-lg text-white">
프로필 작성하기
</Button>
<p className="mt-8 cursor-pointer font-normal text-grey60 underline">나중에 입력하기</p>
<Link href={'/myResume'} className="flex w-full justify-center">
<Button animationMode="main" className="mt-[5.13rem] w-[50%] rounded-lg bg-main text-lg text-white">
프로필 작성하기
</Button>
</Link>
<Link href={'/'} className="mt-8 cursor-pointer font-normal text-grey60 underline">
나중에 입력하기
</Link>
</div>
</div>
</>
Expand Down
57 changes: 57 additions & 0 deletions src/features/onBoarding/hooks/useOnBoardingAgree.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// src/features/member/hooks/useOnBoardingAgree.ts

import { useState } from 'react'
import { useRouter } from 'next/navigation'
import { useSetRecoilState } from 'recoil'
import { accessTokenState } from '@/context/recoil-context'
import { submitConsentInfo } from '../api/memberApi'
import { ConsentInfo } from '../types/memberTypes'

export function useOnBoardingAgree() {
const router = useRouter()
const setAccessToken = useSetRecoilState(accessTokenState)
const [allChecked, setAllChecked] = useState(false)
const [checkedItems, setCheckedItems] = useState([false, false, false, false])

const isNextEnabled = checkedItems.slice(0, 3).every(Boolean)

const handleCheckClick = (index: number) => {
const updatedItems = [...checkedItems]
updatedItems[index] = !updatedItems[index]
setCheckedItems(updatedItems)
setAllChecked(updatedItems.every(Boolean))
}

const handleAllCheckClick = () => {
const newState = !allChecked
setAllChecked(newState)
setCheckedItems(checkedItems.map(() => newState))
}

const submitConsentInfoHandler = async () => {
const accessToken = sessionStorage.getItem('accessToken') || ''

const data: ConsentInfo = {
isServiceUseAgree: checkedItems[0],
isPrivateInformAgree: checkedItems[1],
isAgeCheck: checkedItems[2],
isMarketingAgree: checkedItems[3],
}

const result = await submitConsentInfo(data, accessToken)

if (result) {
setAccessToken(accessToken) // Recoil 상태에 액세스 토큰 저장
router.push('/login/onboarding-complete') // 온보딩 완료 페이지로 이동
}
}

return {
allChecked,
checkedItems,
isNextEnabled,
handleCheckClick,
handleAllCheckClick,
submitConsentInfoHandler,
}
}
14 changes: 14 additions & 0 deletions src/features/onBoarding/types/memberTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,17 @@ export interface MemberInfo {
memberName: string
contact: string
}

// src/features/member/types/memberTypes.ts

export interface ConsentInfo {
isServiceUseAgree: boolean
isPrivateInformAgree: boolean
isAgeCheck: boolean
isMarketingAgree: boolean
}

export interface ConsentRequest {
data: ConsentInfo
accessToken: string
}

0 comments on commit 200edde

Please sign in to comment.