158 lines
6.0 KiB
TypeScript
158 lines
6.0 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { Controller, useFormContext } from "react-hook-form";
|
|
|
|
import { NON_NEGATIVE_INPUT_PROPS } from "@/shared/lib";
|
|
import { SectionCollapsible } from "@/shared/ui";
|
|
import { Field, FieldError, FieldGroup } from "@/shared/ui/field";
|
|
import { findCodeLabel, useCodeList } from "@/entities/code";
|
|
import { type BnsApplyData, BnsPickerDialog } from "@/widgets/bns-picker";
|
|
import { Input, Table, TableCell, TableHead, TableHeader, TableRow } from "@common/components";
|
|
|
|
import type { DesignCnstnRegistFormData } from "../../lib/design-cnstn-regist-schema";
|
|
|
|
function BasicInfoFormSection() {
|
|
const { control, watch, setValue } = useFormContext<DesignCnstnRegistFormData>();
|
|
const [isPickerOpen, setIsPickerOpen] = useState(false);
|
|
const taskSeComCd = watch("designCnstnMng.taskSeComCd");
|
|
const localGovLabel = [watch("designCnstnMng.sido"), watch("designCnstnMng.gugun")]
|
|
.filter(Boolean)
|
|
.join(" ");
|
|
const { data: taskOptions } = useCodeList("CNFM");
|
|
|
|
function handleBnsSelect(data: BnsApplyData) {
|
|
setValue("designCnstnMng.bizNm", data.bizNm);
|
|
setValue("designCnstnMng.bizBgngYr", data.bizBgngYr);
|
|
setValue("designCnstnMng.bizEndYr", data.bizEndYr);
|
|
setValue("designCnstnMng.bizCn", data.bizCn);
|
|
}
|
|
|
|
const taskSeComCdLabel =
|
|
taskSeComCd
|
|
.map((code) => findCodeLabel(taskOptions, code))
|
|
.filter(Boolean)
|
|
.join(", ") || "-";
|
|
|
|
return (
|
|
<SectionCollapsible title="기본 정보">
|
|
<Table caption="사업 기본 정보 입력" variant="secondary">
|
|
<colgroup>
|
|
<col width="15%" />
|
|
<col width="35%" />
|
|
<col width="15%" />
|
|
<col width="35%" />
|
|
</colgroup>
|
|
<TableHeader>
|
|
<TableRow>
|
|
<TableHead scope="row" className="w-[20rem]" data-required>
|
|
사업명
|
|
</TableHead>
|
|
<TableCell colSpan={3}>
|
|
<Controller
|
|
name="designCnstnMng.bizNm"
|
|
control={control}
|
|
render={({ field, fieldState }) => (
|
|
<Field data-invalid={fieldState.invalid}>
|
|
<div className="flex gap-2">
|
|
<Input
|
|
{...field}
|
|
id={field.name}
|
|
placeholder="사업명 입력"
|
|
aria-invalid={fieldState.invalid}
|
|
className="w-[40rem]"
|
|
/>
|
|
{/* <Button type="button" onClick={() => setIsPickerOpen(true)}>
|
|
사업찾기
|
|
</Button> */}
|
|
</div>
|
|
<FieldError errors={[fieldState.error]} />
|
|
</Field>
|
|
)}
|
|
/>
|
|
</TableCell>
|
|
</TableRow>
|
|
<TableRow>
|
|
<TableHead scope="row" data-required>사업기간</TableHead>
|
|
<TableCell colSpan={3}>
|
|
<FieldGroup className="flex-row items-center gap-2">
|
|
<Controller
|
|
name="designCnstnMng.bizBgngYr"
|
|
control={control}
|
|
render={({ field, fieldState }) => (
|
|
<Field data-invalid={fieldState.invalid} className="w-auto !gap-1">
|
|
<Input
|
|
{...field}
|
|
{...NON_NEGATIVE_INPUT_PROPS}
|
|
type="number"
|
|
id={field.name}
|
|
placeholder="시작연도"
|
|
className="max-w-[12rem]"
|
|
aria-invalid={fieldState.invalid}
|
|
/>
|
|
<FieldError errors={[fieldState.error]} />
|
|
</Field>
|
|
)}
|
|
/>
|
|
<span>~</span>
|
|
<Controller
|
|
name="designCnstnMng.bizEndYr"
|
|
control={control}
|
|
render={({ field, fieldState }) => (
|
|
<Field data-invalid={fieldState.invalid} className="w-auto !gap-1">
|
|
<Input
|
|
{...field}
|
|
{...NON_NEGATIVE_INPUT_PROPS}
|
|
type="number"
|
|
id={field.name}
|
|
placeholder="종료연도"
|
|
className="max-w-[12rem]"
|
|
aria-invalid={fieldState.invalid}
|
|
/>
|
|
<FieldError errors={[fieldState.error]} />
|
|
</Field>
|
|
)}
|
|
/>
|
|
</FieldGroup>
|
|
</TableCell>
|
|
</TableRow>
|
|
<TableRow>
|
|
<TableHead scope="row" data-required>사업내용</TableHead>
|
|
<TableCell colSpan={3}>
|
|
<Controller
|
|
name="designCnstnMng.bizCn"
|
|
control={control}
|
|
render={({ field, fieldState }) => (
|
|
<Field data-invalid={fieldState.invalid}>
|
|
<Input
|
|
{...field}
|
|
id={field.name}
|
|
placeholder="사업내용 입력"
|
|
aria-invalid={fieldState.invalid}
|
|
/>
|
|
<FieldError errors={[fieldState.error]} />
|
|
</Field>
|
|
)}
|
|
/>
|
|
</TableCell>
|
|
</TableRow>
|
|
<TableRow>
|
|
<TableHead scope="row" data-required>구분</TableHead>
|
|
<TableCell>{taskSeComCdLabel}</TableCell>
|
|
<TableHead scope="row">신청 지자체</TableHead>
|
|
<TableCell>{localGovLabel}</TableCell>
|
|
</TableRow>
|
|
</TableHeader>
|
|
</Table>
|
|
|
|
<BnsPickerDialog
|
|
open={isPickerOpen}
|
|
onClose={() => setIsPickerOpen(false)}
|
|
onSelect={handleBnsSelect}
|
|
/>
|
|
</SectionCollapsible>
|
|
);
|
|
}
|
|
|
|
export { BasicInfoFormSection };
|