Skip to content

Commit

Permalink
Merge pull request #138 from prgrms-web-devcourse-final-project/134-f…
Browse files Browse the repository at this point in the history
…eature/mypage-setting

[Feature] 알림 설정 기능 구현 (토글)
  • Loading branch information
kimjuyoung99 authored Dec 7, 2024
2 parents b356148 + 921b54f commit 64a73e2
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 38 deletions.
53 changes: 53 additions & 0 deletions src/apis/myPage/getSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { AxiosError } from 'axios'
import { APIResponse, ErrorResponse } from '~types/api'
import { axiosInstance } from '~apis/axiosInstance'
import { BooleanString } from '~types/common'

//Pick 유틸리티 타입으로는 중첩된 settings 객체 구조를 표현할 수 없어서 직접 타입 정의
export type GetSettingsResponse = {
memberId: number
isMatched: BooleanString
settings: {
WALK: {
notificationSettingId: number
type: 'WALK'
isAgreed: BooleanString
}
CHAT: {
notificationSettingId: number
type: 'CHAT'
isAgreed: BooleanString
}
}
}

export const getSettings = async (): Promise<APIResponse<GetSettingsResponse>> => {
try {
const { data } = await axiosInstance.get<APIResponse<GetSettingsResponse>>(`/notification-settings`)
console.log('알람 설정 불러오기 : ', data)
return data
} catch (error) {
if (error instanceof AxiosError) {
const { response } = error as AxiosError<ErrorResponse>

if (response) {
const { code, message } = response.data
switch (code) {
case 400:
throw new Error(message || '잘못된 요청입니다.')
case 401:
throw new Error(message || '인증에 실패했습니다.')
case 500:
throw new Error(message || '서버 오류가 발생했습니다.')
default:
throw new Error(message || '알 수 없는 오류가 발생했습니다.')
}
}
// 요청 자체가 실패한 경우
throw new Error('네트워크 연결을 확인해주세요')
}

console.error('예상치 못한 에러:', error)
throw new Error('다시 시도해주세요')
}
}
73 changes: 38 additions & 35 deletions src/apis/myPage/updateGangbuntta.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,42 @@
// import { AxiosError } from 'axios'
// import { APIResponse, ErrorResponse } from '~types/api'
// import { axiosInstance } from '~apis/axiosInstance'
import { AxiosError } from 'axios'
import { APIResponse, ErrorResponse } from '~types/api'
import { axiosInstance } from '~apis/axiosInstance'
import { BooleanString } from '~types/common'

// export type UpdateGangbunttaRequest = {}
export type UpdateGangbunttaRequest = { isMatched: BooleanString }
export type UpdateGangbunttaResponse = Pick<APIResponse<{ isMatched: BooleanString }>, 'code' | 'data'>

// export type UpdateGangbunttaResponse = Pick<APIResponse>
export const updateGangbuntta = async (
req: UpdateGangbunttaRequest
): Promise<APIResponse<UpdateGangbunttaResponse>> => {
try {
const { data } = await axiosInstance.patch<APIResponse<UpdateGangbunttaResponse>>(
`/member?isMatched=${req.isMatched}`
)
console.log('알림 상태변경 : ', data.data)
return data
} catch (error) {
if (error instanceof AxiosError) {
const { response } = error as AxiosError<ErrorResponse>

// export const updateGangbuntta = async (
// req: UpdateGangbunttaRequest
// ): Promise<APIResponse<UpdateGangbunttaResponse>> => {
// try {
// const { data } = await axiosInstance.patch<APIResponse<UpdateGangbunttaResponse>>(`/member`, req)
// return data
// } catch (error) {
// if (error instanceof AxiosError) {
// const { response } = error as AxiosError<ErrorResponse>
if (response) {
const { code, message } = response.data
switch (code) {
case 400:
throw new Error(message || '잘못된 요청입니다.')
case 401:
throw new Error(message || '인증에 실패했습니다.')
case 500:
throw new Error(message || '서버 오류가 발생했습니다.')
default:
throw new Error(message || '알 수 없는 오류가 발생했습니다.')
}
}
// 요청 자체가 실패한 경우
throw new Error('네트워크 연결을 확인해주세요')
}

// if (response) {
// const { code, message } = response.data
// switch (code) {
// case 400:
// throw new Error(message || '잘못된 요청입니다.')
// case 401:
// throw new Error(message || '인증에 실패했습니다.')
// case 500:
// throw new Error(message || '서버 오류가 발생했습니다.')
// default:
// throw new Error(message || '알 수 없는 오류가 발생했습니다.')
// }
// }
// // 요청 자체가 실패한 경우
// throw new Error('네트워크 연결을 확인해주세요')
// }

// console.error('예상치 못한 에러:', error)
// throw new Error('다시 시도해주세요')
// }
// }
console.error('예상치 못한 에러:', error)
throw new Error('다시 시도해주세요')
}
}
7 changes: 6 additions & 1 deletion src/components/Toggle/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { SettingsStoreKey, useSettingsStore } from '~stores/settingsStore'
import { updateSetting } from '~apis/myPage/updateSetting'
import { updateGangbuntta } from '~apis/myPage/updateGangbuntta'

import * as S from './styles'

type ToggleProps = {
Expand All @@ -15,7 +17,10 @@ export default function Toggle({ id, setting }: ToggleProps) {
try {
const newValue = e.target.checked
// setting이 'messages' 또는 'myWalkNotifications'인 경우에만 API 호출
if (setting === 'messages' || setting === 'myWalkNotifications') {
if (setting === 'gangbuntta') {
console.log('강번따 상태 변경 : ', newValue)
await updateGangbuntta({ isMatched: newValue ? 'TRUE' : 'FALSE' })
} else if (setting === 'messages' || setting === 'myWalkNotifications') {
await updateSetting({
type: setting === 'messages' ? 'CHAT' : 'WALK',
isAgreed: newValue ? 'TRUE' : 'FALSE',
Expand Down
25 changes: 23 additions & 2 deletions src/modals/SettingModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,34 @@ import { ActionButton } from '~components/Button/ActionButton'
import { deleteMember } from '~apis/myPage/deleteMember'
import { useNavigate } from 'react-router-dom'
// import { deleteLogoutMember } from '~apis/logout/deleteLogoutMember'

import { getSettings } from '~apis/myPage/getSettings'
import { useSettingsStore } from '~stores/settingsStore'
import { useEffect } from 'react'
export default function SettingModal() {
const { popModal } = useModalStore()
const navigate = useNavigate()
const setSetting = useSettingsStore(state => state.setSetting)

useEffect(() => {
const fetchSettings = async () => {
try {
const response = await getSettings()
const gangbunttaState = response.data.isMatched
const walkState = response.data.settings.WALK.isAgreed // WALK로 수정
const chatState = response.data.settings.CHAT.isAgreed // CHAT으로 수정 console.log('mywalkState : ', mywalkState)

setSetting('gangbuntta', gangbunttaState === 'TRUE')
setSetting('myWalkNotifications', walkState === 'TRUE')
setSetting('messages', chatState === 'TRUE')
} catch (error) {
console.error('설정 불러오기 실패:', error)
}
}
fetchSettings()
}, [setSetting])

const onClickLogout = async () => {
try {
// await deleteLogoutMember()
localStorage.removeItem('token')
alert('로그아웃 되었습니다.')
console.log('로그아웃 되었습니다.')
Expand Down
26 changes: 26 additions & 0 deletions src/types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,29 @@ export type Setting = {
type: NotificationType
isAgreed: BooleanString
}
export type ApiResponseIsMatched = {
code: number
status: string
message: string
data: string
}

// 중첩된 settings 객체를 위한 타입 정의
export type NotificationSettings = {
WALK: {
notificationSettingId: number
type: 'WALK'
isAgreed: BooleanString
}
CHAT: {
notificationSettingId: number
type: 'CHAT'
isAgreed: BooleanString
}
}

export type GetSettingsResponse = {
memberId: number
isMatched: BooleanString
settings: NotificationSettings
}

0 comments on commit 64a73e2

Please sign in to comment.