import { useState } from 'react' import type { Mode, SurveyDetailInfo, SurveyDetailRequest } from '@/types/Survey' type RadioEtcKeys = 'houseStructure' | 'rafterMaterial' | 'waterproofMaterial' | 'insulationPresence' | 'rafterDirection' | 'leakTrace' type SelectBoxKeys = | 'installationSystem' | 'constructionYear' | 'roofShape' | 'rafterPitch' | 'rafterSize' | 'openFieldPlateKind' | 'structureOrder' | 'installationAvailability' export const supplementaryFacilities = [ { id: 1, name: 'エコキュート' }, //에코큐트 { id: 2, name: 'エネパーム' }, //에네팜 { id: 3, name: '蓄電池システム' }, //축전지시스템 { id: 4, name: '太陽光発電' }, //태양광발전 ] export const roofMaterial = [ { id: 1, name: 'スレート' }, //슬레이트 { id: 2, name: 'アスファルトシングル' }, //아스팔트 싱글 { id: 3, name: '瓦' }, //기와 { id: 4, name: '金属屋根' }, //금속지붕 ] export const selectBoxOptions: Record = { installationSystem: [ { id: 1, name: '太陽光発電', //태양광발전 }, { id: 2, name: 'ハイブリッド蓄電システム', //하이브리드축전지시스템 }, { id: 3, name: '蓄電池システム', //축전지시스템 }, ], constructionYear: [ { id: 1, name: '新築', //신축 }, { id: 2, name: '既築', //기존 }, ], roofShape: [ { id: 1, name: '切妻', //박공지붕 }, { id: 2, name: '寄棟', //기동 }, { id: 3, name: '片流れ', //한쪽흐름 }, ], rafterSize: [ { id: 1, name: '幅35mm以上×高さ48mm以上', }, { id: 2, name: '幅36mm以上×高さ46mm以上', }, { id: 3, name: '幅37mm以上×高さ43mm以上', }, { id: 4, name: '幅38mm以上×高さ40mm以上', }, ], rafterPitch: [ { id: 1, name: '455mm以下', }, { id: 2, name: '500mm以下', }, { id: 3, name: '606mm以下', }, ], openFieldPlateKind: [ { id: 1, name: '構造用合板', //구조용합판 }, { id: 2, name: 'OSB', //OSB }, { id: 3, name: 'パーティクルボード', //파티클보드 }, { id: 4, name: '小幅板', //소판 }, ], structureOrder: [ { id: 1, name: '屋根材', //지붕재 }, { id: 2, name: '防水材', //방수재 }, { id: 3, name: '屋根の基礎', //지붕의기초 }, { id: 4, name: '垂木', //서까래 }, ], installationAvailability: [ { id: 1, name: '確認済み', //확인완료 }, { id: 2, name: '未確認', //미확인 }, ], } export const radioEtcData: Record = { houseStructure: [ { id: 1, label: '木製', }, ], rafterMaterial: [ { id: 1, label: '木製', }, { id: 2, label: '強制', }, ], waterproofMaterial: [ { id: 1, label: 'アスファルト屋根940(22kg以上)', }, ], insulationPresence: [ { id: 1, label: 'なし', }, { id: 2, label: 'あり', }, ], rafterDirection: [ { id: 1, label: '垂直垂木', }, { id: 2, label: '水平垂木', }, ], leakTrace: [ { id: 1, label: 'あり', }, { id: 2, label: 'なし', }, ], } const makeNumArr = (value: string) => { return value .split(',') .map((v) => v.trim()) .filter((v) => v.length > 0) } export default function RoofForm(props: { roofInfo: SurveyDetailRequest | SurveyDetailInfo setRoofInfo: (roofInfo: SurveyDetailRequest) => void mode: Mode }) { const { roofInfo, setRoofInfo, mode } = props const [isFlip, setIsFlip] = useState(true) const handleNumberInput = (key: keyof SurveyDetailRequest, value: number | string) => { if (key === 'roofSlope' || key === 'openFieldPlateThickness') { const stringValue = value.toString() if (stringValue.length > 5) { alert('保存できるサイズを超えました。') return } if (stringValue.includes('.')) { const decimalPlaces = stringValue.split('.')[1].length if (decimalPlaces > 1) { alert('小数点以下1桁までしか許されません。') return } } } if (key === 'contractCapacity') { const remainValue = roofInfo.contractCapacity?.split(' ')[1] ?? roofInfo.contractCapacity if (Number.isNaN(Number(remainValue))) { setRoofInfo({ ...roofInfo, [key]: value + ' ' + remainValue }) return } setRoofInfo({ ...roofInfo, [key]: value.toString() }) } setRoofInfo({ ...roofInfo, [key]: value.toString() }) } const handleUnitInput = (value: string) => { const numericValue = roofInfo.contractCapacity?.replace(/[^0-9.]/g, '') || '' setRoofInfo({ ...roofInfo, contractCapacity: numericValue ? `${numericValue} ${value}` : '0 ' + value, }) } return (
setIsFlip(!isFlip)}>
電気 / 屋根情報
{/* 전기 관계 */}
電気関係
{/* 전기 계약 용량 */}
電気契約容量
{mode === 'READ' && } {mode !== 'READ' && (
handleNumberInput('contractCapacity', e.target.value)} />
)}
{/* 전기 소매 회사사 */}
電気小売会社
setRoofInfo({ ...roofInfo, retailCompany: e.target.value })} />
{/* 전기 부대 설비 */}
電気袋設備※複数選択可能
設置希望システム
{/* 지붕 관계 */}
屋根関係
{/* 건축 연수 */}
建築研修
{/* 지붕재 */}
屋根材※最大2個まで選択可能
{/* 지붕 모양 */}
屋根の形状
{/* 지붕 경사도도 */}
屋根の斜面
handleNumberInput('roofSlope', e.target.value)} />
{/* 주택구조조 */}
住宅構造
{/* 서까래 재질 */}
垂木材質
{/* 서까래 크기 */}
垂木サイズ
{/* 서까래 피치 */}
垂木サイズ
{/* 서까래 방향 */}
垂木の方向
{/* 노지판 종류류 */}
路地板の種類
{/* 노지판 두께 */}
路地板厚※小幅板を選択した場合, 厚さ. 小幅板間の間隔寸法を記載
handleNumberInput('openFieldPlateThickness', e.target.value)} /> mm
{/* 누수 흔적 */}
水漏れの痕跡
{/* 방수재 종류 */}
防水材の種類
{/* 단열재 유무 */}
断熱材の有無
{/* 지붕 구조의 순서 */}
屋根構造の順序
{/* 지붕 제품명 설치 가능 여부 확인 */}
屋根製品名 設置可否確認
{/* 메모 */}
メモ
) } const SelectedBox = ({ mode, column, detailInfoData, setRoofInfo, }: { mode: Mode column: string detailInfoData: SurveyDetailInfo setRoofInfo: (roofInfo: SurveyDetailRequest) => void }) => { const selectedId = detailInfoData?.[column as keyof SurveyDetailInfo] const etcValue = detailInfoData?.[`${column}Etc` as keyof SurveyDetailInfo] const [isEtcSelected, setIsEtcSelected] = useState(Boolean(etcValue)) const isSpecialCase = column === 'constructionYear' || column === 'installationAvailability' const showEtcOption = !isSpecialCase const handleSelectChange = (e: React.ChangeEvent) => { const value = e.target.value const isEtc = value === 'etc' const isSpecialEtc = isSpecialCase && value === '2' const updatedData = { ...detailInfoData, [column]: isEtc ? null : value, [`${column}Etc`]: isEtc ? '' : null, } if (isSpecialEtc) { updatedData[column] = value } setIsEtcSelected(isEtc || isSpecialEtc) setRoofInfo(updatedData) } const handleEtcInputChange = (e: React.ChangeEvent) => { setRoofInfo({ ...detailInfoData, [`${column}Etc`]: e.target.value }) } const isInputDisabled = () => { if (mode === 'READ') return true if (column === 'installationAvailability') return false if (column === 'constructionYear') { return detailInfoData.constructionYear === '1' || detailInfoData.constructionYear === null } return !isEtcSelected && !etcValue } return ( <>
{column === 'constructionYear' && }
) } const RadioSelected = ({ mode, column, detailInfoData, setRoofInfo, }: { mode: Mode column: string detailInfoData: SurveyDetailInfo setRoofInfo: (roofInfo: SurveyDetailRequest) => void }) => { const etcValue = detailInfoData?.[`${column}Etc` as keyof SurveyDetailInfo] const [etcChecked, setEtcChecked] = useState(Boolean(etcValue)) const selectedId = column === 'leakTrace' ? Number(detailInfoData?.[column as keyof SurveyDetailInfo]) || 2 : detailInfoData?.[column as keyof SurveyDetailInfo] const isSpecialColumn = column === 'rafterDirection' || column === 'leakTrace' || column === 'insulationPresence' const showEtcOption = !isSpecialColumn const handleRadioChange = (e: React.ChangeEvent) => { const value = e.target.value if (column === 'leakTrace') { setRoofInfo({ ...detailInfoData, leakTrace: value === '1' }) return } if (value === 'etc') { setEtcChecked(true) setRoofInfo({ ...detailInfoData, [column]: null, [`${column}Etc`]: '' }) return } const isInsulationPresence = column === 'insulationPresence' const isRafterDirection = column === 'rafterDirection' setEtcChecked(isInsulationPresence && value === '2') setRoofInfo({ ...detailInfoData, [column]: value, [`${column}Etc`]: isRafterDirection ? detailInfoData[`${column}Etc` as keyof SurveyDetailInfo] : null, }) } const handleEtcInputChange = (e: React.ChangeEvent) => { setRoofInfo({ ...detailInfoData, [`${column}Etc`]: e.target.value }) } const isInputDisabled = () => { if (mode === 'READ') return true if (column === 'insulationPresence') { return detailInfoData.insulationPresence !== '2' } return !etcChecked && !etcValue } return ( <> {radioEtcData[column as keyof typeof radioEtcData].map((item) => (
))} {showEtcOption && (
)} {(showEtcOption || column === 'insulationPresence') && (
)} ) } const MultiCheck = ({ mode, column, roofInfo, setRoofInfo, }: { mode: Mode column: string roofInfo: SurveyDetailInfo setRoofInfo: (roofInfo: SurveyDetailRequest) => void }) => { const multiCheckData = column === 'supplementaryFacilities' ? supplementaryFacilities : roofMaterial const etcValue = roofInfo?.[`${column}Etc` as keyof SurveyDetailInfo] const [isOtherCheck, setIsOtherCheck] = useState(Boolean(etcValue)) const isRoofMaterial = column === 'roofMaterial' const selectedValues = makeNumArr(String(roofInfo[column as keyof SurveyDetailInfo] ?? '')) const handleCheckbox = (id: number) => { const isOtherSelected = Boolean(etcValue) let newValue: string[] if (selectedValues.includes(String(id))) { newValue = selectedValues.filter((v) => v !== String(id)) } else { if (isRoofMaterial) { const totalSelected = selectedValues.length + (isOtherSelected ? 1 : 0) if (totalSelected >= 2) { alert('屋根材は最大2個まで選択できます。') return } } newValue = [...selectedValues, String(id)] } setRoofInfo({ ...roofInfo, [column]: newValue.join(',') }) } const handleOtherCheckbox = () => { if (isRoofMaterial) { const currentSelected = selectedValues.length if (!isOtherCheck && currentSelected >= 2) { alert('屋根材は最大2個まで選択できます。') return } } const newIsOtherCheck = !isOtherCheck setIsOtherCheck(newIsOtherCheck) // 기타 선택 해제 시 값도 null로 설정 setRoofInfo({ ...roofInfo, [`${column}Etc`]: newIsOtherCheck ? '' : null, }) } const handleOtherInputChange = (e: React.ChangeEvent) => { setRoofInfo({ ...roofInfo, [`${column}Etc`]: e.target.value }) } const isInputDisabled = () => { return mode === 'READ' || (!isOtherCheck && !etcValue) } return ( <>
{multiCheckData.map((item) => (
handleCheckbox(item.id)} />
))}
) }