354 lines
14 KiB
TypeScript
354 lines
14 KiB
TypeScript
'use client'
|
|
|
|
import { useSurveySaleTabState } from '@/store/surveySaleTabState'
|
|
|
|
import { useServey } from '@/hooks/useSurvey'
|
|
import { SurveyDetailRequest } from '@/types/Survey'
|
|
import { useRouter, useSearchParams } from 'next/navigation'
|
|
import { useEffect, useState } from 'react'
|
|
import MultiCheckEtc from './etcProcess/MultiCheckEtc'
|
|
import SelectBoxEtc from './etcProcess/SelectBoxEtc'
|
|
import RadioEtc from './etcProcess/RadioEtc'
|
|
|
|
const defaultDetailInfoForm: SurveyDetailRequest = {
|
|
CONTRACT_CAPACITY: null,
|
|
RETAIL_COMPANY: null,
|
|
SUPPLEMENTARY_FACILITIES: null,
|
|
SUPPLEMENTARY_FACILITIES_ETC: null,
|
|
INSTALLATION_SYSTEM: null,
|
|
INSTALLATION_SYSTEM_ETC: null,
|
|
CONSTRUCTION_YEAR: null,
|
|
CONSTRUCTION_YEAR_ETC: null,
|
|
ROOF_MATERIAL: null,
|
|
ROOF_MATERIAL_ETC: null,
|
|
ROOF_SHAPE: null,
|
|
ROOF_SHAPE_ETC: null,
|
|
ROOF_SLOPE: null,
|
|
HOUSE_STRUCTURE: '1',
|
|
HOUSE_STRUCTURE_ETC: null,
|
|
RAFTER_MATERIAL: '1',
|
|
RAFTER_MATERIAL_ETC: null,
|
|
RAFTER_SIZE: null,
|
|
RAFTER_SIZE_ETC: null,
|
|
RAFTER_PITCH: null,
|
|
RAFTER_PITCH_ETC: null,
|
|
RAFTER_DIRECTION: '1',
|
|
OPEN_FIELD_PLATE_KIND: null,
|
|
OPEN_FIELD_PLATE_KIND_ETC: null,
|
|
OPEN_FIELD_PLATE_THICKNESS: null,
|
|
LEAK_TRACE: false,
|
|
WATERPROOF_MATERIAL: null,
|
|
WATERPROOF_MATERIAL_ETC: null,
|
|
INSULATION_PRESENCE: '1',
|
|
INSULATION_PRESENCE_ETC: null,
|
|
STRUCTURE_ORDER: null,
|
|
STRUCTURE_ORDER_ETC: null,
|
|
INSTALLATION_AVAILABILITY: null,
|
|
INSTALLATION_AVAILABILITY_ETC: null,
|
|
MEMO: null,
|
|
}
|
|
|
|
export default function RoofInfoForm() {
|
|
const { setRoofInfoSelected } = useSurveySaleTabState()
|
|
|
|
useEffect(() => {
|
|
setRoofInfoSelected()
|
|
}, [])
|
|
|
|
const router = useRouter()
|
|
const searchParams = useSearchParams()
|
|
const id = searchParams.get('id')
|
|
|
|
const { surveyDetail, createSurveyDetail, validateSurveyDetail } = useServey(Number(id))
|
|
|
|
const [detailInfoData, setDetailInfoData] = useState<SurveyDetailRequest>(defaultDetailInfoForm)
|
|
|
|
useEffect(() => {
|
|
if (surveyDetail?.DETAIL_INFO) {
|
|
const { ID, UPT_DT, REG_DT, BASIC_INFO_ID, ...rest } = surveyDetail.DETAIL_INFO
|
|
setDetailInfoData(rest)
|
|
}
|
|
}, [surveyDetail])
|
|
|
|
const handleNumberInput = (key: keyof SurveyDetailRequest, value: number | string) => {
|
|
if (key === 'ROOF_SLOPE' || key === 'OPEN_FIELD_PLATE_THICKNESS') {
|
|
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
|
|
}
|
|
}
|
|
setDetailInfoData({ ...detailInfoData, [key]: value.toString() })
|
|
} else {
|
|
setDetailInfoData({ ...detailInfoData, [key]: value.toString() })
|
|
}
|
|
}
|
|
|
|
const handleTextInput = (key: keyof SurveyDetailRequest, value: string) => {
|
|
setDetailInfoData({ ...detailInfoData, [key]: value || null })
|
|
}
|
|
|
|
const handleBooleanInput = (key: keyof SurveyDetailRequest, value: boolean) => {
|
|
setDetailInfoData({ ...detailInfoData, [key]: value })
|
|
}
|
|
|
|
const handleUnitInput = (value: string) => {
|
|
const numericValue = detailInfoData.CONTRACT_CAPACITY?.replace(/[^0-9.]/g, '') || ''
|
|
setDetailInfoData({
|
|
...detailInfoData,
|
|
CONTRACT_CAPACITY: numericValue ? `${numericValue} ${value}` : value,
|
|
})
|
|
}
|
|
|
|
const handleSave = async () => {
|
|
console.log(detailInfoData)
|
|
if (id) {
|
|
const emptyField = validateSurveyDetail(detailInfoData)
|
|
if (emptyField.trim() === '') {
|
|
const updatedBasicInfoData = {
|
|
DETAIL_INFO: detailInfoData,
|
|
}
|
|
try {
|
|
createSurveyDetail({
|
|
surveyId: Number(id),
|
|
surveyDetail: updatedBasicInfoData,
|
|
})
|
|
alert('調査物件を保存しました。')
|
|
} catch (error) {
|
|
alert(error)
|
|
throw new Error('failed to create survey detail: ' + error)
|
|
}
|
|
router.push(`/survey-sale`)
|
|
} else {
|
|
alert(emptyField + ' は必須項目です。')
|
|
focusOnInput(emptyField)
|
|
}
|
|
} else {
|
|
alert('基本情報を作成した後、屋根情報を作成することができます。')
|
|
}
|
|
}
|
|
const focusOnInput = (field: string) => {
|
|
const input = document.getElementById(field)
|
|
if (input) {
|
|
input.focus()
|
|
}
|
|
}
|
|
return (
|
|
<>
|
|
<div className="sale-frame">
|
|
<div className="sale-roof-title">電気関係</div>
|
|
<div className="data-form-wrap">
|
|
<div className="data-input-form-bx">
|
|
{/* 전기계약 용량 - contract_capacity */}
|
|
<div className="data-input-form-tit">電気契約容量</div>
|
|
<div className="data-input mb5">
|
|
<input
|
|
type="number"
|
|
inputMode="decimal"
|
|
className="input-frame"
|
|
value={detailInfoData.CONTRACT_CAPACITY?.split(' ')[0] ?? ''}
|
|
onChange={(e) => handleNumberInput('CONTRACT_CAPACITY', e.target.value)}
|
|
/>
|
|
</div>
|
|
<div className="data-input">
|
|
<select
|
|
className="select-form"
|
|
name="CONTRACT_CAPACITY_UNIT"
|
|
id="CONTRACT_CAPACITY_UNIT"
|
|
onChange={(e) => handleUnitInput(e.target.value)}
|
|
value={detailInfoData.CONTRACT_CAPACITY?.split(' ')[1] ?? ''}
|
|
>
|
|
<option value="" hidden>
|
|
選択してください
|
|
</option>
|
|
<option value="kVA">kVA</option>
|
|
<option value="A">A</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
{/* 전기 소매 회사 - retail_company */}
|
|
<div className="data-input-form-bx">
|
|
<div className="data-input-form-tit">電気小売会社</div>
|
|
<input
|
|
type="text"
|
|
className="input-frame"
|
|
value={detailInfoData.RETAIL_COMPANY ?? ''}
|
|
onChange={(e) => handleTextInput('RETAIL_COMPANY', e.target.value)}
|
|
/>
|
|
</div>
|
|
{/* 전기 부대 설비 - supplementary_facilities */}
|
|
<div className="data-input-form-bx">
|
|
<MultiCheckEtc column={'SUPPLEMENTARY_FACILITIES'} setDetailInfoData={setDetailInfoData} detailInfoData={detailInfoData} />
|
|
</div>
|
|
{/* 설치 희망 시스템 - installation_system */}
|
|
<SelectBoxEtc column={'INSTALLATION_SYSTEM'} setDetailInfoData={setDetailInfoData} detailInfoData={detailInfoData} />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="sale-frame">
|
|
<div className="sale-roof-title">屋根関係</div>
|
|
<div className="data-form-wrap">
|
|
{/* 건축 연수 - construction_year */}
|
|
<SelectBoxEtc column={'CONSTRUCTION_YEAR'} setDetailInfoData={setDetailInfoData} detailInfoData={detailInfoData} />
|
|
{/* 지붕재 - roof_material */}
|
|
<div className="data-input-form-bx">
|
|
<MultiCheckEtc column={'ROOF_MATERIAL'} setDetailInfoData={setDetailInfoData} detailInfoData={detailInfoData} />
|
|
</div>
|
|
{/* 지붕 모양 - roof_shape */}
|
|
<SelectBoxEtc column={'ROOF_SHAPE'} setDetailInfoData={setDetailInfoData} detailInfoData={detailInfoData} />
|
|
{/* 지붕 경사도 - roof_slope */}
|
|
<div className="data-input-form-bx">
|
|
<div className="data-input-form-tit">屋根の斜面</div>
|
|
<div className="data-input flex">
|
|
<input
|
|
type="number"
|
|
step={0.1}
|
|
inputMode="decimal"
|
|
className="input-frame"
|
|
value={detailInfoData.ROOF_SLOPE ?? ''}
|
|
onChange={(e) => handleNumberInput('ROOF_SLOPE', e.target.value)}
|
|
/>
|
|
<span>寸</span>
|
|
</div>
|
|
</div>
|
|
{/* 주택 구조 - house_structure */}
|
|
<RadioEtc column={'HOUSE_STRUCTURE'} setDetailInfoData={setDetailInfoData} detailInfoData={detailInfoData} />
|
|
{/* 서까래 재질 - rafter_material */}
|
|
<RadioEtc column={'RAFTER_MATERIAL'} setDetailInfoData={setDetailInfoData} detailInfoData={detailInfoData} />
|
|
{/* 서까래 크기 - rafter_size */}
|
|
<SelectBoxEtc column={'RAFTER_SIZE'} setDetailInfoData={setDetailInfoData} detailInfoData={detailInfoData} />
|
|
{/* 서까래 피치 - rafter_pitch */}
|
|
<SelectBoxEtc column={'RAFTER_PITCH'} setDetailInfoData={setDetailInfoData} detailInfoData={detailInfoData} />
|
|
{/* 서까래 방향 - rafter_direction */}
|
|
<div className="data-input-form-bx">
|
|
<div className="data-input-form-tit red-f">垂木の方向</div>
|
|
<div className="data-check-wrap mb0" id="rafter_direction">
|
|
<div className="radio-form-box">
|
|
<input
|
|
type="radio"
|
|
name="RAFTER_DIRECTION"
|
|
id="RAFTER_DIRECTION_1"
|
|
value={1}
|
|
onChange={(e) => handleNumberInput('RAFTER_DIRECTION', Number(e.target.value))}
|
|
checked={detailInfoData.RAFTER_DIRECTION === '1'}
|
|
/>
|
|
<label htmlFor="RAFTER_DIRECTION_1">垂直垂木</label>
|
|
</div>
|
|
<div className="radio-form-box">
|
|
<input
|
|
type="radio"
|
|
name="RAFTER_DIRECTION"
|
|
id="RAFTER_DIRECTION_2"
|
|
value={2}
|
|
onChange={(e) => handleNumberInput('RAFTER_DIRECTION', Number(e.target.value))}
|
|
checked={detailInfoData.RAFTER_DIRECTION === '2'}
|
|
/>
|
|
<label htmlFor="RAFTER_DIRECTION_2">水平垂木</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{/* 노지판 종류 - open_field_plate_kind */}
|
|
<SelectBoxEtc column={'OPEN_FIELD_PLATE_KIND'} setDetailInfoData={setDetailInfoData} detailInfoData={detailInfoData} />
|
|
{/* 노지판 두께 - open_field_plate_thickness */}
|
|
<div className="data-input-form-bx">
|
|
<div className="data-input-form-tit">
|
|
路地板厚<span>※小幅板を選択した場合, 厚さ. 小幅板間の間隔寸法を記載</span>
|
|
</div>
|
|
<div className="data-input flex">
|
|
<input
|
|
type="number"
|
|
step={0.1}
|
|
inputMode="decimal"
|
|
className="input-frame"
|
|
value={detailInfoData.OPEN_FIELD_PLATE_THICKNESS ?? ''}
|
|
onChange={(e) => handleNumberInput('OPEN_FIELD_PLATE_THICKNESS', e.target.value)}
|
|
/>
|
|
<span>mm</span>
|
|
</div>
|
|
</div>
|
|
{/* 누수 흔적 - leak_trace */}
|
|
<div className="data-input-form-bx">
|
|
<div className="data-input-form-tit ">水漏れの痕跡</div>
|
|
<div className="data-check-wrap mb0">
|
|
<div className="radio-form-box">
|
|
<input
|
|
type="radio"
|
|
name="LEAK_TRACE"
|
|
id="LEAK_TRACE_1"
|
|
checked={detailInfoData.LEAK_TRACE === true}
|
|
onChange={(e) => handleBooleanInput('LEAK_TRACE', true)}
|
|
/>
|
|
<label htmlFor="LEAK_TRACE_1">あり</label>
|
|
</div>
|
|
<div className="radio-form-box">
|
|
<input
|
|
type="radio"
|
|
name="LEAK_TRACE"
|
|
id="LEAK_TRACE_2"
|
|
checked={detailInfoData.LEAK_TRACE === false}
|
|
onChange={(e) => handleBooleanInput('LEAK_TRACE', false)}
|
|
/>
|
|
<label htmlFor="LEAK_TRACE_2">なし</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{/* 방수재 종류 - waterproof_material */}
|
|
<RadioEtc column={'WATERPROOF_MATERIAL'} setDetailInfoData={setDetailInfoData} detailInfoData={detailInfoData} />
|
|
{/* 단열재 유무 - insulation_presence */}
|
|
<RadioEtc column={'INSULATION_PRESENCE'} setDetailInfoData={setDetailInfoData} detailInfoData={detailInfoData} />
|
|
{/* 노지판 종류 - open_field_plate_kind */}
|
|
<SelectBoxEtc column={'STRUCTURE_ORDER'} setDetailInfoData={setDetailInfoData} detailInfoData={detailInfoData} />
|
|
{/* 설치 가능 여부 - installation_availability */}
|
|
<SelectBoxEtc column={'INSTALLATION_AVAILABILITY'} setDetailInfoData={setDetailInfoData} detailInfoData={detailInfoData} />
|
|
{/* 메모 - memo */}
|
|
<div className="data-input-form-bx">
|
|
<div className="data-input-form-tit">メモ</div>
|
|
<div className="data-input mb5">
|
|
<select className="select-form" name="" id="">
|
|
<option value="">確認済み</option>
|
|
<option value="">確認済み</option>
|
|
<option value="">確認済み</option>
|
|
<option value="">確認済み</option>
|
|
<option value="">確認済み</option>
|
|
</select>
|
|
</div>
|
|
<div className="data-input">
|
|
<textarea
|
|
className="textarea-form"
|
|
name="MEMO"
|
|
id="MEMO"
|
|
value={detailInfoData.MEMO ?? ''}
|
|
onChange={(e) => handleTextInput('MEMO', e.target.value)}
|
|
placeholder="例: 漏れの兆候があるため、正確な点検が必要です."
|
|
></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="btn-flex-wrap">
|
|
<div className="btn-bx">
|
|
<button className="btn-frame n-blue icon" onClick={handleSave}>
|
|
一時保存<i className="btn-arr"></i>
|
|
</button>
|
|
</div>
|
|
<div className="btn-bx">
|
|
<button className="btn-frame red icon" onClick={handleSave}>
|
|
保存<i className="btn-arr"></i>
|
|
</button>
|
|
</div>
|
|
<div className="btn-bx">
|
|
<button className="btn-frame n-blue icon" onClick={() => router.push('/survey-sale')}>
|
|
リスト<i className="btn-arr"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
)
|
|
}
|