Skip to content

Commit 64a73e2

Browse files
authored
Merge pull request #138 from prgrms-web-devcourse-final-project/134-feature/mypage-setting
[Feature] 알림 설정 기능 구현 (토글)
2 parents b356148 + 921b54f commit 64a73e2

File tree

5 files changed

+146
-38
lines changed

5 files changed

+146
-38
lines changed

src/apis/myPage/getSettings.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { AxiosError } from 'axios'
2+
import { APIResponse, ErrorResponse } from '~types/api'
3+
import { axiosInstance } from '~apis/axiosInstance'
4+
import { BooleanString } from '~types/common'
5+
6+
//Pick 유틸리티 타입으로는 중첩된 settings 객체 구조를 표현할 수 없어서 직접 타입 정의
7+
export type GetSettingsResponse = {
8+
memberId: number
9+
isMatched: BooleanString
10+
settings: {
11+
WALK: {
12+
notificationSettingId: number
13+
type: 'WALK'
14+
isAgreed: BooleanString
15+
}
16+
CHAT: {
17+
notificationSettingId: number
18+
type: 'CHAT'
19+
isAgreed: BooleanString
20+
}
21+
}
22+
}
23+
24+
export const getSettings = async (): Promise<APIResponse<GetSettingsResponse>> => {
25+
try {
26+
const { data } = await axiosInstance.get<APIResponse<GetSettingsResponse>>(`/notification-settings`)
27+
console.log('알람 설정 불러오기 : ', data)
28+
return data
29+
} catch (error) {
30+
if (error instanceof AxiosError) {
31+
const { response } = error as AxiosError<ErrorResponse>
32+
33+
if (response) {
34+
const { code, message } = response.data
35+
switch (code) {
36+
case 400:
37+
throw new Error(message || '잘못된 요청입니다.')
38+
case 401:
39+
throw new Error(message || '인증에 실패했습니다.')
40+
case 500:
41+
throw new Error(message || '서버 오류가 발생했습니다.')
42+
default:
43+
throw new Error(message || '알 수 없는 오류가 발생했습니다.')
44+
}
45+
}
46+
// 요청 자체가 실패한 경우
47+
throw new Error('네트워크 연결을 확인해주세요')
48+
}
49+
50+
console.error('예상치 못한 에러:', error)
51+
throw new Error('다시 시도해주세요')
52+
}
53+
}

src/apis/myPage/updateGangbuntta.ts

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,42 @@
1-
// import { AxiosError } from 'axios'
2-
// import { APIResponse, ErrorResponse } from '~types/api'
3-
// import { axiosInstance } from '~apis/axiosInstance'
1+
import { AxiosError } from 'axios'
2+
import { APIResponse, ErrorResponse } from '~types/api'
3+
import { axiosInstance } from '~apis/axiosInstance'
4+
import { BooleanString } from '~types/common'
45

5-
// export type UpdateGangbunttaRequest = {}
6+
export type UpdateGangbunttaRequest = { isMatched: BooleanString }
7+
export type UpdateGangbunttaResponse = Pick<APIResponse<{ isMatched: BooleanString }>, 'code' | 'data'>
68

7-
// export type UpdateGangbunttaResponse = Pick<APIResponse>
9+
export const updateGangbuntta = async (
10+
req: UpdateGangbunttaRequest
11+
): Promise<APIResponse<UpdateGangbunttaResponse>> => {
12+
try {
13+
const { data } = await axiosInstance.patch<APIResponse<UpdateGangbunttaResponse>>(
14+
`/member?isMatched=${req.isMatched}`
15+
)
16+
console.log('알림 상태변경 : ', data.data)
17+
return data
18+
} catch (error) {
19+
if (error instanceof AxiosError) {
20+
const { response } = error as AxiosError<ErrorResponse>
821

9-
// export const updateGangbuntta = async (
10-
// req: UpdateGangbunttaRequest
11-
// ): Promise<APIResponse<UpdateGangbunttaResponse>> => {
12-
// try {
13-
// const { data } = await axiosInstance.patch<APIResponse<UpdateGangbunttaResponse>>(`/member`, req)
14-
// return data
15-
// } catch (error) {
16-
// if (error instanceof AxiosError) {
17-
// const { response } = error as AxiosError<ErrorResponse>
22+
if (response) {
23+
const { code, message } = response.data
24+
switch (code) {
25+
case 400:
26+
throw new Error(message || '잘못된 요청입니다.')
27+
case 401:
28+
throw new Error(message || '인증에 실패했습니다.')
29+
case 500:
30+
throw new Error(message || '서버 오류가 발생했습니다.')
31+
default:
32+
throw new Error(message || '알 수 없는 오류가 발생했습니다.')
33+
}
34+
}
35+
// 요청 자체가 실패한 경우
36+
throw new Error('네트워크 연결을 확인해주세요')
37+
}
1838

19-
// if (response) {
20-
// const { code, message } = response.data
21-
// switch (code) {
22-
// case 400:
23-
// throw new Error(message || '잘못된 요청입니다.')
24-
// case 401:
25-
// throw new Error(message || '인증에 실패했습니다.')
26-
// case 500:
27-
// throw new Error(message || '서버 오류가 발생했습니다.')
28-
// default:
29-
// throw new Error(message || '알 수 없는 오류가 발생했습니다.')
30-
// }
31-
// }
32-
// // 요청 자체가 실패한 경우
33-
// throw new Error('네트워크 연결을 확인해주세요')
34-
// }
35-
36-
// console.error('예상치 못한 에러:', error)
37-
// throw new Error('다시 시도해주세요')
38-
// }
39-
// }
39+
console.error('예상치 못한 에러:', error)
40+
throw new Error('다시 시도해주세요')
41+
}
42+
}

src/components/Toggle/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { SettingsStoreKey, useSettingsStore } from '~stores/settingsStore'
22
import { updateSetting } from '~apis/myPage/updateSetting'
3+
import { updateGangbuntta } from '~apis/myPage/updateGangbuntta'
4+
35
import * as S from './styles'
46

57
type ToggleProps = {
@@ -15,7 +17,10 @@ export default function Toggle({ id, setting }: ToggleProps) {
1517
try {
1618
const newValue = e.target.checked
1719
// setting이 'messages' 또는 'myWalkNotifications'인 경우에만 API 호출
18-
if (setting === 'messages' || setting === 'myWalkNotifications') {
20+
if (setting === 'gangbuntta') {
21+
console.log('강번따 상태 변경 : ', newValue)
22+
await updateGangbuntta({ isMatched: newValue ? 'TRUE' : 'FALSE' })
23+
} else if (setting === 'messages' || setting === 'myWalkNotifications') {
1924
await updateSetting({
2025
type: setting === 'messages' ? 'CHAT' : 'WALK',
2126
isAgreed: newValue ? 'TRUE' : 'FALSE',

src/modals/SettingModal/index.tsx

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,34 @@ import { ActionButton } from '~components/Button/ActionButton'
88
import { deleteMember } from '~apis/myPage/deleteMember'
99
import { useNavigate } from 'react-router-dom'
1010
// import { deleteLogoutMember } from '~apis/logout/deleteLogoutMember'
11-
11+
import { getSettings } from '~apis/myPage/getSettings'
12+
import { useSettingsStore } from '~stores/settingsStore'
13+
import { useEffect } from 'react'
1214
export default function SettingModal() {
1315
const { popModal } = useModalStore()
1416
const navigate = useNavigate()
17+
const setSetting = useSettingsStore(state => state.setSetting)
18+
19+
useEffect(() => {
20+
const fetchSettings = async () => {
21+
try {
22+
const response = await getSettings()
23+
const gangbunttaState = response.data.isMatched
24+
const walkState = response.data.settings.WALK.isAgreed // WALK로 수정
25+
const chatState = response.data.settings.CHAT.isAgreed // CHAT으로 수정 console.log('mywalkState : ', mywalkState)
26+
27+
setSetting('gangbuntta', gangbunttaState === 'TRUE')
28+
setSetting('myWalkNotifications', walkState === 'TRUE')
29+
setSetting('messages', chatState === 'TRUE')
30+
} catch (error) {
31+
console.error('설정 불러오기 실패:', error)
32+
}
33+
}
34+
fetchSettings()
35+
}, [setSetting])
36+
1537
const onClickLogout = async () => {
1638
try {
17-
// await deleteLogoutMember()
1839
localStorage.removeItem('token')
1940
alert('로그아웃 되었습니다.')
2041
console.log('로그아웃 되었습니다.')

src/types/api.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,3 +218,29 @@ export type Setting = {
218218
type: NotificationType
219219
isAgreed: BooleanString
220220
}
221+
export type ApiResponseIsMatched = {
222+
code: number
223+
status: string
224+
message: string
225+
data: string
226+
}
227+
228+
// 중첩된 settings 객체를 위한 타입 정의
229+
export type NotificationSettings = {
230+
WALK: {
231+
notificationSettingId: number
232+
type: 'WALK'
233+
isAgreed: BooleanString
234+
}
235+
CHAT: {
236+
notificationSettingId: number
237+
type: 'CHAT'
238+
isAgreed: BooleanString
239+
}
240+
}
241+
242+
export type GetSettingsResponse = {
243+
memberId: number
244+
isMatched: BooleanString
245+
settings: NotificationSettings
246+
}

0 commit comments

Comments
 (0)