173 lines
5.3 KiB
TypeScript
173 lines
5.3 KiB
TypeScript
import { useInfiniteQuery } from '@tanstack/react-query'
|
|
import { transformObjectKeys } from '@/libs/axios'
|
|
import { useSuitableStore } from '@/store/useSuitableStore'
|
|
import { useAxios } from './useAxios'
|
|
import { useCommCode } from './useCommCode'
|
|
import { SUITABLE_HEAD_CODE, type Suitable, type SuitableDetail, type SuitableIds } from '@/types/Suitable'
|
|
|
|
export function useSuitable() {
|
|
const { axiosInstance } = useAxios()
|
|
const { getCommCode } = useCommCode()
|
|
const {
|
|
itemPerPage,
|
|
suitableCommCode,
|
|
setSuitableCommCode,
|
|
selectedCategory,
|
|
clearSelectedCategory,
|
|
searchKeyword,
|
|
clearSearchKeyword,
|
|
selectedItems,
|
|
clearSelectedItems,
|
|
} = useSuitableStore()
|
|
|
|
const getSuitables = async ({
|
|
pageNumber,
|
|
category,
|
|
keyword,
|
|
}: {
|
|
pageNumber?: number
|
|
category?: string
|
|
keyword?: string
|
|
}): Promise<Suitable[]> => {
|
|
try {
|
|
const params: Record<string, string | number> = {
|
|
pageNumber: pageNumber || 1,
|
|
itemPerPage: itemPerPage,
|
|
}
|
|
if (category) params.category = category
|
|
if (keyword) params.keyword = keyword
|
|
|
|
const response = await axiosInstance(null).get<Suitable[]>('/api/suitable/list', { params })
|
|
return response.data
|
|
} catch (error) {
|
|
console.error('지붕재 데이터 로드 실패:', error)
|
|
return []
|
|
}
|
|
}
|
|
|
|
const getSuitableIds = async (): Promise<SuitableIds[]> => {
|
|
try {
|
|
const params: Record<string, string> = {}
|
|
if (selectedCategory) params.category = selectedCategory
|
|
if (searchKeyword) params.keyword = searchKeyword
|
|
const response = await axiosInstance(null).get<SuitableIds[]>('/api/suitable/pick', { params })
|
|
return response.data
|
|
} catch (error) {
|
|
console.error('지붕재 아이디 로드 실패:', error)
|
|
return []
|
|
}
|
|
}
|
|
|
|
const getSuitableDetails = async (ids: string, detailIds?: string): Promise<Suitable[]> => {
|
|
try {
|
|
const params: Record<string, string> = { ids: ids }
|
|
if (detailIds) params.detailIds = detailIds
|
|
const response = await axiosInstance(null).get<Suitable[]>('/api/suitable', { params })
|
|
return response.data
|
|
} catch (error) {
|
|
console.error('지붕재 상세 데이터 로드 실패:', error)
|
|
return []
|
|
}
|
|
}
|
|
|
|
const getSuitableCommCode = () => {
|
|
const headCodes = Object.values(SUITABLE_HEAD_CODE) as SUITABLE_HEAD_CODE[]
|
|
for (const code of headCodes) {
|
|
getCommCode(code).then((res) => {
|
|
setSuitableCommCode(code, res)
|
|
})
|
|
}
|
|
}
|
|
|
|
const toCodeName = (headCode: string, code: string): string => {
|
|
const commCode = suitableCommCode.get(headCode)
|
|
return commCode?.find((item) => item.code === code)?.codeJp || ''
|
|
}
|
|
|
|
const toSuitableDetail = (suitableDetailString: string): SuitableDetail[] => {
|
|
try {
|
|
const suitableDetailArray = transformObjectKeys(JSON.parse(suitableDetailString)) as SuitableDetail[]
|
|
if (!Array.isArray(suitableDetailArray)) {
|
|
throw new Error('suitableDetailArray is not an array')
|
|
}
|
|
return suitableDetailArray
|
|
} catch (error) {
|
|
console.error('지붕재 데이터 파싱 실패:', error)
|
|
return []
|
|
}
|
|
}
|
|
|
|
const toSuitableDetailIds = (suitableDetailString: string): Set<number> => {
|
|
try {
|
|
return new Set<number>(JSON.parse(suitableDetailString).map(({ id }: { id: number }) => id))
|
|
} catch (error) {
|
|
console.error('지붕재 데이터 파싱 실패:', error)
|
|
return new Set()
|
|
}
|
|
}
|
|
|
|
const {
|
|
data: suitables,
|
|
fetchNextPage,
|
|
hasNextPage,
|
|
isFetchingNextPage,
|
|
isLoading,
|
|
isError,
|
|
error,
|
|
} = useInfiniteQuery<Suitable[]>({
|
|
queryKey: ['suitables', 'list', selectedCategory, searchKeyword],
|
|
queryFn: async (context) => {
|
|
const pageParam = context.pageParam as number
|
|
if (pageParam === 1) clearSuitableSearch({ items: true })
|
|
return await getSuitables({
|
|
pageNumber: pageParam,
|
|
...(selectedCategory && { category: selectedCategory }),
|
|
...(searchKeyword && { keyword: searchKeyword }),
|
|
})
|
|
},
|
|
getNextPageParam: (lastPage: Suitable[], allPages: Suitable[][]) => {
|
|
return lastPage.length === itemPerPage ? allPages.length + 1 : undefined
|
|
},
|
|
initialPageParam: 1,
|
|
staleTime: 1000 * 60 * 10,
|
|
gcTime: 1000 * 60 * 10,
|
|
enabled: selectedCategory !== '' || searchKeyword !== '',
|
|
})
|
|
|
|
const serializeSelectedItems = (): Map<string, string> => {
|
|
const ids: string[] = []
|
|
const detailIds: string[] = []
|
|
for (const [key, value] of selectedItems) {
|
|
ids.push(String(key))
|
|
for (const id of value) detailIds.push(String(id))
|
|
}
|
|
return new Map<string, string>([
|
|
['ids', ids.join(',')],
|
|
['detailIds', detailIds.join(',')],
|
|
])
|
|
}
|
|
|
|
const clearSuitableSearch = ({ items = false, category = false, keyword = false }: { items?: boolean; category?: boolean; keyword?: boolean }) => {
|
|
if (items) clearSelectedItems()
|
|
if (category) clearSelectedCategory()
|
|
if (keyword) clearSearchKeyword()
|
|
}
|
|
|
|
return {
|
|
getSuitables,
|
|
getSuitableIds,
|
|
getSuitableDetails,
|
|
getSuitableCommCode,
|
|
toCodeName,
|
|
toSuitableDetail,
|
|
toSuitableDetailIds,
|
|
suitables,
|
|
fetchNextPage,
|
|
hasNextPage,
|
|
isFetchingNextPage,
|
|
isLoading,
|
|
serializeSelectedItems,
|
|
clearSuitableSearch,
|
|
}
|
|
}
|