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, searchCategory, clearSearchCategory, searchKeyword, clearSearchKeyword, selectedItems, clearSelectedItems, } = useSuitableStore() const getSuitables = async ({ pageNumber, category, keyword, }: { pageNumber?: number category?: string keyword?: string }): Promise => { try { const params: Record = { pageNumber: pageNumber || 1, itemPerPage: itemPerPage, } if (category) params.category = category if (keyword) params.keyword = keyword const response = await axiosInstance(null).get('/api/suitable/list', { params }) return response.data } catch (error) { console.error('지붕재 데이터 로드 실패:', error) return [] } } const getSuitableIds = async (): Promise => { try { const params: Record = {} if (searchCategory) params.category = searchCategory if (searchKeyword) params.keyword = searchKeyword const response = await axiosInstance(null).get('/api/suitable/pick', { params }) return response.data } catch (error) { console.error('지붕재 아이디 로드 실패:', error) return [] } } const getSuitableDetails = async (ids: string, detailIds?: string): Promise => { try { const params: Record = { ids: ids } if (detailIds) params.detailIds = detailIds const response = await axiosInstance(null).post('/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[] => { if (!suitableDetailString) return [] 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 => { try { return new Set(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({ queryKey: ['suitables', 'list', searchCategory, searchKeyword], queryFn: async (context) => { const pageParam = context.pageParam as number if (pageParam === 1) clearSuitableStore({ items: true }) return await getSuitables({ pageNumber: pageParam, ...(searchCategory && { category: searchCategory }), ...(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: searchCategory !== '' || searchKeyword !== '', }) const clearSuitableStore = ({ items = false, category = false, keyword = false }: { items?: boolean; category?: boolean; keyword?: boolean }) => { if (items) clearSelectedItems() if (category) clearSearchCategory() if (keyword) clearSearchKeyword() } // TODO: 추후 지붕재 적합성 데이터 CUD 구현 시 ×, -, ー 데이터 관리 필요 const suitableCheckIcon = (value: string): string => { const iconMap: Record = { '×': '/assets/images/sub/compliance_x_icon.svg', '-': '/assets/images/sub/compliance_quest_icon.svg', 'ー': '/assets/images/sub/compliance_quest_icon.svg', default: '/assets/images/sub/compliance_check_icon.svg', } return iconMap[value] || iconMap.default } // TODO: 추후 지붕재 적합성 데이터 CUD 구현 시 ○, ×, -, ー 데이터 관리 필요 const suitableCheckMemo = (value: string): string => { if (value === '○') return '設置可' if (value === '×') return '設置不可' if (value === '-' || value === 'ー') return 'お問い合わせください' return `${value}で設置可` } const serializeSelectedItems = (): { ids: string; detailIds: 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 { ids: ids.join(','), detailIds: detailIds.length > 0 ? detailIds.join(',') : '' } } const getSelectedSuitables = async (): Promise => { const { ids, detailIds } = serializeSelectedItems() return await getSuitableDetails(ids, detailIds) } const downloadSuitablePdf = async (): Promise => { try { const { ids, detailIds } = serializeSelectedItems() const fileTitle = `(${ suitableCommCode.get(SUITABLE_HEAD_CODE.ROOF_MATL_GRP_CD)?.find((category) => category.code === searchCategory)?.codeJp }) 屋根材適合表` const form = document.createElement('form') form.method = 'POST' form.action = '/api/suitable/pdf' form.target = '_blank' const inputIds = document.createElement('input') inputIds.type = 'hidden' inputIds.name = 'ids' inputIds.value = ids const inputDetailIds = document.createElement('input') inputDetailIds.type = 'hidden' inputDetailIds.name = 'detailIds' inputDetailIds.value = detailIds const inputFileTitle = document.createElement('input') inputFileTitle.type = 'hidden' inputFileTitle.name = 'fileTitle' inputFileTitle.value = fileTitle form.appendChild(inputIds) form.appendChild(inputDetailIds) form.appendChild(inputFileTitle) document.body.appendChild(form) form.submit() document.body.removeChild(form) } catch (error) { console.error('지붕재 상세 데이터 pdf 다운로드 실패:', error) } } return { getSuitables, getSuitableIds, getSuitableCommCode, toCodeName, toSuitableDetail, toSuitableDetailIds, suitables, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading, getSelectedSuitables, clearSuitableStore, suitableCheckIcon, suitableCheckMemo, downloadSuitablePdf, } }