- 조사 매물 생성, 수정 시 각 컬럼 필수값 validation 추가 - 조사 매물 수정 페이지에서 기타 옵션 선택 시 값 초기화 되도록 구현
256 lines
6.2 KiB
TypeScript
256 lines
6.2 KiB
TypeScript
import type { SurveyDetailRequest } from '@/types/Survey'
|
||
import { useEffect, useState } from 'react'
|
||
|
||
type SelectBoxKeys =
|
||
| 'installation_system'
|
||
| 'construction_year'
|
||
| 'roof_shape'
|
||
| 'rafter_pitch'
|
||
| 'rafter_size'
|
||
| 'open_field_plate_kind'
|
||
| 'structure_order'
|
||
| 'installation_availability'
|
||
|
||
const font: Record<SelectBoxKeys, string> = {
|
||
installation_system: 'data-input-form-tit red-f',
|
||
construction_year: 'data-input-form-tit red-f',
|
||
roof_shape: 'data-input-form-tit',
|
||
rafter_pitch: 'data-input-form-tit red-f',
|
||
rafter_size: 'data-input-form-tit red-f',
|
||
open_field_plate_kind: 'data-input-form-tit',
|
||
structure_order: 'data-input-form-tit red-f',
|
||
installation_availability: 'data-input-form-tit',
|
||
}
|
||
|
||
const translateJapanese: Record<SelectBoxKeys, string> = {
|
||
installation_system: '設置希望システム',
|
||
construction_year: '建築年数',
|
||
roof_shape: '屋根の形状',
|
||
rafter_pitch: '垂木傾斜',
|
||
rafter_size: '垂木サイズ',
|
||
open_field_plate_kind: '路地板の種類',
|
||
structure_order: '屋根構造の順序',
|
||
installation_availability: '屋根製品名 設置可否確認',
|
||
}
|
||
|
||
const selectBoxOptions: Record<SelectBoxKeys, { id: number; name: string }[]> = {
|
||
installation_system: [
|
||
{
|
||
id: 1,
|
||
name: '太陽光発電', //태양광발전
|
||
},
|
||
{
|
||
id: 2,
|
||
name: 'ハイブリッド蓄電システム', //하이브리드축전지시스템
|
||
},
|
||
{
|
||
id: 3,
|
||
name: '蓄電池システム', //축전지시스템
|
||
},
|
||
],
|
||
construction_year: [
|
||
{
|
||
id: 1,
|
||
name: '新築', //신축
|
||
},
|
||
{
|
||
id: 2,
|
||
name: '既築', //기존
|
||
},
|
||
],
|
||
roof_shape: [
|
||
{
|
||
id: 1,
|
||
name: '切妻', //박공지붕
|
||
},
|
||
{
|
||
id: 2,
|
||
name: '寄棟', //기동
|
||
},
|
||
{
|
||
id: 3,
|
||
name: '片流れ', //한쪽흐름
|
||
},
|
||
],
|
||
rafter_size: [
|
||
{
|
||
id: 1,
|
||
name: '幅35mm以上×高さ48mm以上',
|
||
},
|
||
{
|
||
id: 2,
|
||
name: '幅36mm以上×高さ46mm以上',
|
||
},
|
||
{
|
||
id: 3,
|
||
name: '幅37mm以上×高さ43mm以上',
|
||
},
|
||
{
|
||
id: 4,
|
||
name: '幅38mm以上×高さ40mm以上',
|
||
},
|
||
],
|
||
rafter_pitch: [
|
||
{
|
||
id: 1,
|
||
name: '(455mm以下',
|
||
},
|
||
{
|
||
id: 2,
|
||
name: '500mm以下',
|
||
},
|
||
{
|
||
id: 3,
|
||
name: '606mm以下',
|
||
},
|
||
],
|
||
open_field_plate_kind: [
|
||
{
|
||
id: 1,
|
||
name: '構造用合板', //구조용합판
|
||
},
|
||
{
|
||
id: 2,
|
||
name: 'OSB', //OSB
|
||
},
|
||
{
|
||
id: 3,
|
||
name: 'パーティクルボード', //파티클보드
|
||
},
|
||
{
|
||
id: 4,
|
||
name: '小幅板', //소판
|
||
},
|
||
],
|
||
structure_order: [
|
||
{
|
||
id: 1,
|
||
name: '屋根材', //지붕재
|
||
},
|
||
{
|
||
id: 2,
|
||
name: '防水材', //방수재
|
||
},
|
||
{
|
||
id: 3,
|
||
name: '屋根の基礎', //지붕의기초
|
||
},
|
||
{
|
||
id: 4,
|
||
name: '垂木', //서까래
|
||
},
|
||
],
|
||
installation_availability: [
|
||
{
|
||
id: 1,
|
||
name: '確認済み', //확인완료
|
||
},
|
||
{
|
||
id: 2,
|
||
name: '未確認', //미확인
|
||
},
|
||
],
|
||
}
|
||
|
||
export default function SelectBoxForm({
|
||
column,
|
||
setDetailInfoData,
|
||
detailInfoData,
|
||
}: {
|
||
column: SelectBoxKeys
|
||
setDetailInfoData: (data: any) => void
|
||
detailInfoData: SurveyDetailRequest
|
||
}) {
|
||
const [isEtcSelected, setIsEtcSelected] = useState(false)
|
||
const [etcValue, setEtcValue] = useState('')
|
||
|
||
useEffect(() => {
|
||
if (detailInfoData[`${column}_etc` as keyof SurveyDetailRequest]) {
|
||
setIsEtcSelected(true)
|
||
setEtcValue(detailInfoData[`${column}_etc` as keyof SurveyDetailRequest] as string)
|
||
}
|
||
}, [detailInfoData])
|
||
|
||
const handleSelectChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||
const value = e.target.value
|
||
if (column === 'installation_availability' || column === 'construction_year') {
|
||
setIsEtcSelected(value === '2') // 건축 연수 & 설치 가능 여부 컬럼 2번 선택 시 input 활성화
|
||
setDetailInfoData({
|
||
...detailInfoData,
|
||
[column]: Number(value),
|
||
})
|
||
} else if (value === 'etc') {
|
||
setIsEtcSelected(true) // 기타 선택 시 input 활성화
|
||
setDetailInfoData({
|
||
...detailInfoData,
|
||
[column]: null,
|
||
})
|
||
} else {
|
||
setIsEtcSelected(false) // 기타 선택 해제 시 input 비활성화
|
||
setEtcValue('')
|
||
setDetailInfoData({
|
||
...detailInfoData,
|
||
[`${column}_etc`]: null,
|
||
[column]: Number(value),
|
||
})
|
||
}
|
||
}
|
||
|
||
const handleEtcInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||
const value = e.target.value
|
||
setEtcValue(value)
|
||
setDetailInfoData({
|
||
...detailInfoData,
|
||
[`${column}_etc`]: value,
|
||
})
|
||
}
|
||
|
||
return (
|
||
<>
|
||
<div className="data-input-form-bx">
|
||
<div className={font[column]}>{translateJapanese[column]}</div>
|
||
<div className="data-input mb5">
|
||
<select
|
||
className="select-form"
|
||
name={column}
|
||
id={column}
|
||
onChange={handleSelectChange}
|
||
value={
|
||
detailInfoData[column]
|
||
? detailInfoData[column]
|
||
: detailInfoData[`${column}_etc`]
|
||
? 'etc'
|
||
: ''
|
||
}
|
||
>
|
||
<option value="" hidden>
|
||
선택해주세요
|
||
</option>
|
||
{selectBoxOptions[column].map((option) => (
|
||
<option key={option.id} value={option.id}>
|
||
{option.name}
|
||
</option>
|
||
))}
|
||
{column !== 'installation_availability' && column !== 'construction_year' && <option value="etc">その他 (直接入力)</option>}
|
||
</select>
|
||
</div>
|
||
<div className="data-input">
|
||
<input
|
||
type="text"
|
||
className="input-frame"
|
||
value={etcValue ?? ''}
|
||
onChange={handleEtcInputChange}
|
||
disabled={
|
||
column === 'installation_availability'
|
||
? !Boolean(detailInfoData[column])
|
||
: column === 'construction_year'
|
||
? detailInfoData[column] !== 2 // 既築(2)가 아닐 때 비활성화
|
||
: !isEtcSelected
|
||
}
|
||
/>
|
||
</div>
|
||
</div>
|
||
</>
|
||
)
|
||
}
|