refactor: Enhance survey hook and integrate spinner functionality
- Refactored useSurvey hook to utilize useAxios for API calls. - Added spinner visibility management in EdgeProvider to improve loading feedback. - Cleaned up imports and organized code structure for better readability.
This commit is contained in:
parent
0e7de68f29
commit
2c5ddad29b
93
src/hooks/useAxios.ts
Normal file
93
src/hooks/useAxios.ts
Normal file
@ -0,0 +1,93 @@
|
||||
import axios from 'axios'
|
||||
import { useSpinnerStore } from '@/store/spinnerStore'
|
||||
|
||||
export const useAxios = () => {
|
||||
const { setIsShow } = useSpinnerStore()
|
||||
|
||||
const axiosInstance = (url: string | null | undefined) => {
|
||||
const baseURL = url || process.env.NEXT_PUBLIC_API_URL
|
||||
const instance = axios.create({
|
||||
baseURL,
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
},
|
||||
})
|
||||
|
||||
instance.interceptors.request.use(
|
||||
(config) => {
|
||||
// console.log('🚀 ~ config:', config)
|
||||
setIsShow(true)
|
||||
return config
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error)
|
||||
},
|
||||
)
|
||||
|
||||
instance.interceptors.response.use(
|
||||
(response) => {
|
||||
response.data = transferResponse(response)
|
||||
setIsShow(false)
|
||||
return response
|
||||
},
|
||||
(error) => {
|
||||
// 에러 처리 로직
|
||||
return Promise.reject(error)
|
||||
},
|
||||
)
|
||||
|
||||
return instance
|
||||
}
|
||||
|
||||
// response데이터가 array, object에 따라 분기하여 키 변환
|
||||
const transferResponse = (response: any) => {
|
||||
if (!response.data) return response.data
|
||||
|
||||
// 배열인 경우 각 객체의 키를 변환
|
||||
if (Array.isArray(response.data)) {
|
||||
return response.data.map((item: any) => transformObjectKeys(item))
|
||||
}
|
||||
|
||||
// 단일 객체인 경우
|
||||
return transformObjectKeys(response.data)
|
||||
}
|
||||
|
||||
// camel case object 반환
|
||||
const transformObjectKeys = (obj: any): any => {
|
||||
if (Array.isArray(obj)) {
|
||||
return obj.map(transformObjectKeys)
|
||||
}
|
||||
|
||||
if (obj !== null && typeof obj === 'object') {
|
||||
return Object.keys(obj).reduce((acc: any, key: string) => {
|
||||
let transformedKey = key
|
||||
|
||||
// Handle uppercase snake_case (e.g., USER_NAME -> userName)
|
||||
// Handle lowercase snake_case (e.g., user_name -> userName)
|
||||
if (/^[A-Z_]+$/.test(key) || /^[a-z_]+$/.test(key)) {
|
||||
transformedKey = snakeToCamel(key)
|
||||
}
|
||||
// Handle single uppercase word (e.g., ROLE -> role)
|
||||
else if (/^[A-Z]+$/.test(key)) {
|
||||
transformedKey = key.toLowerCase()
|
||||
}
|
||||
// Preserve existing camelCase
|
||||
|
||||
acc[transformedKey] = transformObjectKeys(obj[key])
|
||||
return acc
|
||||
}, {})
|
||||
}
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
const snakeToCamel = (str: string): string => {
|
||||
return str.toLowerCase().replace(/([-_][a-z])/g, (group) => group.toUpperCase().replace('-', '').replace('_', ''))
|
||||
}
|
||||
|
||||
return {
|
||||
axiosInstance,
|
||||
transferResponse,
|
||||
transformObjectKeys,
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,10 @@
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import type { SurveyBasicInfo, SurveyDetailInfo, SurveyDetailRequest, SurveyDetailCoverRequest, SurveyRegistRequest } from '@/types/Survey'
|
||||
import { axiosInstance } from '@/libs/axios'
|
||||
import { useSurveyFilterStore } from '@/store/surveyFilterStore'
|
||||
import { queryStringFormatter } from '@/utils/common-utils'
|
||||
import { useSessionStore } from '@/store/session'
|
||||
import { useMemo } from 'react'
|
||||
import { AxiosResponse } from 'axios'
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { useSurveyFilterStore } from '@/store/surveyFilterStore'
|
||||
import { useSessionStore } from '@/store/session'
|
||||
import { useAxios } from './useAxios'
|
||||
import { queryStringFormatter } from '@/utils/common-utils'
|
||||
|
||||
export const requiredFields = [
|
||||
{
|
||||
@ -75,6 +74,7 @@ export function useServey(id?: number): {
|
||||
const queryClient = useQueryClient()
|
||||
const { keyword, searchOption, isMySurvey, sort, offset } = useSurveyFilterStore()
|
||||
const { session } = useSessionStore()
|
||||
const { axiosInstance } = useAxios()
|
||||
|
||||
const {
|
||||
data: surveyListData,
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { useSpinnerStore } from '@/store/spinnerStore'
|
||||
import axios from 'axios'
|
||||
|
||||
export const axiosInstance = (url: string | null | undefined) => {
|
||||
|
||||
@ -8,6 +8,8 @@ import { usePopupController } from '@/store/popupController'
|
||||
import { useSideNavState } from '@/store/sideNavState'
|
||||
import { useSessionStore } from '@/store/session'
|
||||
import { tracking } from '@/libs/tracking'
|
||||
import Spinner from '@/components/ui/common/Spinner'
|
||||
import { useSpinnerStore } from '@/store/spinnerStore'
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
@ -28,6 +30,7 @@ export default function EdgeProvider({ children, sessionData }: EdgeProviderProp
|
||||
const { reset } = useSideNavState()
|
||||
const { setAlertMsg, setAlertBtn, setAlert, setAlert2, setAlert2BtnYes, setAlert2BtnNo } = usePopupController()
|
||||
const { session, setSession } = useSessionStore()
|
||||
const { isShow, setIsShow } = useSpinnerStore()
|
||||
|
||||
/**
|
||||
* 사용자 이벤트 트래킹 처리
|
||||
@ -110,5 +113,10 @@ export default function EdgeProvider({ children, sessionData }: EdgeProviderProp
|
||||
handlePageEvent(pathname)
|
||||
}, [pathname])
|
||||
|
||||
return <>{children}</>
|
||||
return (
|
||||
<>
|
||||
{children}
|
||||
{isShow && <Spinner />}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
21
src/store/spinnerStore.ts
Normal file
21
src/store/spinnerStore.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { create } from 'zustand'
|
||||
|
||||
type SpinnerState = {
|
||||
isShow: boolean
|
||||
setIsShow: (isShow: boolean) => void
|
||||
resetCount: () => void
|
||||
}
|
||||
|
||||
type InitialState = {
|
||||
isShow: boolean
|
||||
}
|
||||
|
||||
const initialState: InitialState = {
|
||||
isShow: false,
|
||||
}
|
||||
|
||||
export const useSpinnerStore = create<SpinnerState>((set) => ({
|
||||
...initialState,
|
||||
setIsShow: (isShow: boolean) => set({ isShow }),
|
||||
resetCount: () => set(initialState),
|
||||
}))
|
||||
Loading…
x
Reference in New Issue
Block a user