onsitesurvey/src/hooks/useSurvey.ts

243 lines
7.6 KiB
TypeScript

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'
const requiredFields = [
{
field: 'INSTALLATION_SYSTEM',
name: '設置希望システム',
},
{
field: 'CONSTRUCTION_YEAR',
name: '建築年数',
},
{
field: 'RAFTER_SIZE',
name: '垂木サイズ',
},
{
field: 'RAFTER_PITCH',
name: '垂木傾斜',
},
{
field: 'WATERPROOF_MATERIAL',
name: '防水材',
},
{
field: 'INSULATION_PRESENCE',
name: '断熱材有無',
},
{
field: 'STRUCTURE_ORDER',
name: '屋根構造の順序',
},
]
interface ZipCodeResponse {
status: number
message: string | null
results: ZipCode[] | null
}
type ZipCode = {
zipcode: string
prefcode: string
address1: string
address2: string
address3: string
kana1: string
kana2: string
kana3: string
}
export function useServey(id?: number): {
surveyList: SurveyBasicInfo[] | []
surveyDetail: SurveyBasicInfo | null
surveyListCount: number
isLoadingSurveyList: boolean
isLoadingSurveyDetail: boolean
isCreatingSurvey: boolean
isUpdatingSurvey: boolean
isDeletingSurvey: boolean
createSurvey: (survey: SurveyRegistRequest) => Promise<number>
createSurveyDetail: (params: { surveyId: number; surveyDetail: SurveyDetailCoverRequest }) => void
updateSurvey: (survey: SurveyRegistRequest) => void
deleteSurvey: () => Promise<boolean>
submitSurvey: () => void
validateSurveyDetail: (surveyDetail: SurveyDetailRequest) => string
getZipCode: (zipCode: string) => Promise<ZipCode[] | null>
} {
const queryClient = useQueryClient()
const { keyword, searchOption, isMySurvey, sort, offset } = useSurveyFilterStore()
const { session } = useSessionStore()
const { data: surveyList, isLoading: isLoadingSurveyList } = useQuery({
queryKey: ['survey', 'list', keyword, searchOption, isMySurvey, sort, offset, session?.storeNm, session?.builderNo, session?.role],
queryFn: async () => {
const resp = await axiosInstance(null).get<SurveyBasicInfo[]>('/api/survey-sales', {
params: {
keyword,
searchOption,
isMySurvey,
sort,
offset,
store: session?.storeNm,
builderNo: session?.builderNo,
role: session?.role,
},
})
return resp.data
},
})
const { data: surveyDetail, isLoading: isLoadingSurveyDetail } = useQuery({
queryKey: ['survey', id],
queryFn: async () => {
if (id === undefined) throw new Error('id is required')
if (id === null) return null
const resp = await axiosInstance(null).get<SurveyBasicInfo>(`/api/survey-sales/${id}`)
return resp.data
},
enabled: id !== undefined,
})
const { data: surveyListCount } = useQuery({
queryKey: ['survey', 'list', keyword, searchOption, isMySurvey, sort, session?.builderNo, session?.storeNm, session?.role],
queryFn: async () => {
const resp = await axiosInstance(null).get<number>('/api/survey-sales', {
params: {
keyword,
searchOption,
isMySurvey,
sort,
builderNo: session?.builderNo,
store: session?.storeNm,
role: session?.role,
},
})
return resp.data
},
})
const { mutateAsync: createSurvey, isPending: isCreatingSurvey } = useMutation({
mutationFn: async (survey: SurveyRegistRequest) => {
const resp = await axiosInstance(null).post<SurveyBasicInfo>('/api/survey-sales', survey)
return resp.data.ID ?? 0
},
onSuccess: (data) => {
queryClient.invalidateQueries({ queryKey: ['survey', 'list'] })
queryClient.invalidateQueries({ queryKey: ['survey', id] })
return data
},
})
const { mutate: updateSurvey, isPending: isUpdatingSurvey } = useMutation({
mutationFn: async (survey: SurveyRegistRequest) => {
if (id === undefined) throw new Error('id is required')
const resp = await axiosInstance(null).put<SurveyRegistRequest>(`/api/survey-sales/${id}`, survey)
return resp.data
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['survey', id] })
queryClient.invalidateQueries({ queryKey: ['survey', 'list'] })
},
})
const { mutateAsync: deleteSurvey, isPending: isDeletingSurvey } = useMutation({
mutationFn: async () => {
if (id === null) throw new Error('id is required')
const resp = await axiosInstance(null).delete<boolean>(`/api/survey-sales/${id}`)
return resp.data
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['survey', 'list'] })
queryClient.invalidateQueries({ queryKey: ['survey', id] })
},
})
const { mutateAsync: createSurveyDetail } = useMutation({
mutationFn: async ({ surveyId, surveyDetail }: { surveyId: number; surveyDetail: SurveyDetailCoverRequest }) => {
const resp = await axiosInstance(null).patch<SurveyDetailInfo>(`/api/survey-sales/${surveyId}`, surveyDetail)
return resp.data
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['survey', 'list'] })
queryClient.invalidateQueries({ queryKey: ['survey', id] })
},
})
const { mutateAsync: submitSurvey } = useMutation({
mutationFn: async () => {
if (id === undefined) throw new Error('id is required')
const resp = await axiosInstance(null).patch<boolean>(`/api/survey-sales/${id}`, {
submit: true,
})
return resp.data
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['survey', 'list'] })
queryClient.invalidateQueries({ queryKey: ['survey', id] })
},
})
const validateSurveyDetail = (surveyDetail: SurveyDetailRequest) => {
const etcFields = ['INSTALLATION_SYSTEM', 'CONSTRUCTION_YEAR', 'RAFTER_SIZE', 'RAFTER_PITCH', 'WATERPROOF_MATERIAL', 'STRUCTURE_ORDER'] as const
const emptyField = requiredFields.find((field) => {
if (etcFields.includes(field.field as (typeof etcFields)[number])) {
return (
surveyDetail[field.field as keyof SurveyDetailRequest] === null && surveyDetail[`${field.field}_ETC` as keyof SurveyDetailRequest] === ''
)
} else {
return surveyDetail[field.field as keyof SurveyDetailRequest] === null
}
})
const contractCapacity = surveyDetail.CONTRACT_CAPACITY
if (contractCapacity && contractCapacity.trim() !== '' && contractCapacity.split(' ')?.length === 1) {
return 'CONTRACT_CAPACITY_UNIT'
}
return emptyField?.name || ''
}
const getZipCode = async (zipCode: string): Promise<ZipCode[] | null> => {
try {
const { data } = await axiosInstance(null).get<ZipCodeResponse>(
`https://zipcloud.ibsnet.co.jp/api/search?${queryStringFormatter({ zipcode: zipCode.trim() })}`,
)
return data.results
} catch (e) {
console.error('Failed to fetch zipcode data:', e)
throw new Error('Failed to fetch zipcode data')
}
}
return {
surveyList: surveyList || [],
surveyDetail: surveyDetail || null,
surveyListCount: surveyListCount || 0,
isLoadingSurveyList,
isLoadingSurveyDetail,
isCreatingSurvey,
isUpdatingSurvey,
isDeletingSurvey,
createSurvey,
updateSurvey,
deleteSurvey,
createSurveyDetail,
submitSurvey,
validateSurveyDetail,
getZipCode,
}
}