diff --git a/apps/as/app/(main)/(with-base-layout)/sewer-bsc-plan/[id]/page.tsx b/apps/as/app/(main)/(with-base-layout)/sewer-bsc-plan/[id]/page.tsx index 17894197e..1b864a7c0 100644 --- a/apps/as/app/(main)/(with-base-layout)/sewer-bsc-plan/[id]/page.tsx +++ b/apps/as/app/(main)/(with-base-layout)/sewer-bsc-plan/[id]/page.tsx @@ -1,17 +1,13 @@ -import Link from "next/link"; +import { SewerBscPlanViewPage } from "@/pages/sewer-bsc-plan"; interface PageProps { params: Promise<{ id: string }>; + searchParams: Promise<{ chgCycl?: string }>; } -export default async function Page({ params }: PageProps) { +export default async function Page({ params, searchParams }: PageProps) { const { id } = await params; - return ( -
- 하수도기본계획 상세({id})는 후속 구현 예정입니다.{" "} - - 수정 화면으로 이동 - -
- ); + const { chgCycl } = await searchParams; + const propChgCycl = chgCycl ? Number(chgCycl) : undefined; + return ; } diff --git a/apps/as/src/entities/elapr/model/elapr-prgrs-stts-interface.ts b/apps/as/src/entities/elapr/model/elapr-prgrs-stts-interface.ts index 7c24ff8eb..61d0f2cdf 100644 --- a/apps/as/src/entities/elapr/model/elapr-prgrs-stts-interface.ts +++ b/apps/as/src/entities/elapr/model/elapr-prgrs-stts-interface.ts @@ -51,7 +51,6 @@ export interface ElaprPrgrsSttsMyDocSearchParams extends ElaprPrgrsSttsSearchDto export interface ElaprProcessRequestDto { atrzPrgrsSttsComCd: string; rjctRsn?: string; - finalApprovalYn?: boolean; } /** 백엔드 ElaprApproverChangeRequestDto */ diff --git a/apps/as/src/entities/sewer-bsc-plan/api/queries.ts b/apps/as/src/entities/sewer-bsc-plan/api/queries.ts index 063e1bd00..a4488a3ed 100644 --- a/apps/as/src/entities/sewer-bsc-plan/api/queries.ts +++ b/apps/as/src/entities/sewer-bsc-plan/api/queries.ts @@ -5,6 +5,8 @@ import { ENDPOINT } from "@/shared/config"; import type { SewerBscPlanApplySaveRequestDto, SewerBscPlanSaveRequestDto, +} from "../model/sewer-bsc-plan-apply-payload-schema"; +import type { SewerBscPlanSearchRequestDto, SewerBscPlanUpdateRequestDto, } from "../model/sewer-bsc-plan-interface"; diff --git a/apps/as/src/entities/sewer-bsc-plan/api/sewer-bsc-plan-service.ts b/apps/as/src/entities/sewer-bsc-plan/api/sewer-bsc-plan-service.ts index 013b1d384..62aced93b 100644 --- a/apps/as/src/entities/sewer-bsc-plan/api/sewer-bsc-plan-service.ts +++ b/apps/as/src/entities/sewer-bsc-plan/api/sewer-bsc-plan-service.ts @@ -4,10 +4,12 @@ import type { PageResponse } from "@/shared/model"; import type { SewerBscPlanApplySaveRequestDto, + SewerBscPlanSaveRequestDto, +} from "../model/sewer-bsc-plan-apply-payload-schema"; +import type { SewerBscPlanApplySaveResponseDto, SewerBscPlanDetResponseDto, SewerBscPlanResponseDto, - SewerBscPlanSaveRequestDto, SewerBscPlanSearchRequestDto, SewerBscPlanService, SewerBscPlanUpdateRequestDto, @@ -75,8 +77,11 @@ async function submitReqSupplement( id: string, chgCycl: number, body: SewerBscPlanApplySaveRequestDto, -): Promise { - const response = await client.post(`${BASE}/${id}/${chgCycl}/reqsupplement`, body); +): Promise { + const response = await client.post( + `${BASE}/${id}/${chgCycl}/reqsupplement`, + body, + ); return response.data; } diff --git a/apps/as/src/entities/sewer-bsc-plan/index.ts b/apps/as/src/entities/sewer-bsc-plan/index.ts index eecf354cd..8d560a60c 100644 --- a/apps/as/src/entities/sewer-bsc-plan/index.ts +++ b/apps/as/src/entities/sewer-bsc-plan/index.ts @@ -13,35 +13,52 @@ export { } from "./api/queries"; export { sewerBscPlanService } from "./api/sewer-bsc-plan-service"; export type { - AtflMngClientResponseDto, CklstResultItem, - CklstRvwRsltTreeDto, EsntlAtchFileItem, - EsntlAtchFileMngTreeResponseDto, SewerBscPlanApplySaveRequestDto, - SewerBscPlanApplySaveResponseDto, SewerBscPlanBizCstItem, + SewerBscPlanDtlSaveRequestDto, + SewerBscPlanFnrsCstItem, + SewerBscPlanOtlnItem, + SewerBscPlanRvwOpnnItem, + SewerBscPlanSaveRequestDto, + SewerBscPlanSplmntDmndItem, + SewerBscPlanTmplntDtlItem, + SewerBscPlanTmplntItem, + SewerBscPlanTmplntTmprStrgItem, +} from "./model/sewer-bsc-plan-apply-payload-schema"; +export { + sewerBscPlanApplySaveSchema, + sewerBscPlanBizCstItemSchema, + sewerBscPlanCklstResultItemSchema, + sewerBscPlanDtlSaveSchema, + sewerBscPlanEsntlAtchFileItemSchema, + sewerBscPlanFnrsCstItemSchema, + sewerBscPlanOtlnItemSchema, + sewerBscPlanRvwOpnnItemSchema, + sewerBscPlanSaveSchema, + sewerBscPlanSplmntDmndItemSchema, + sewerBscPlanTmplntDtlItemSchema, + sewerBscPlanTmplntItemSchema, + sewerBscPlanTmplntTmprStrgItemSchema, +} from "./model/sewer-bsc-plan-apply-payload-schema"; +export type { + AtflMngClientResponseDto, + CklstRvwRsltTreeDto, + EsntlAtchFileMngTreeResponseDto, + SewerBscPlanApplySaveResponseDto, SewerBscPlanBizCstResponseDto, SewerBscPlanDetResponseDto, SewerBscPlanDtlResponseDto, - SewerBscPlanDtlSaveRequestDto, - SewerBscPlanFnrsCstItem, SewerBscPlanFnrsCstResponseDto, - SewerBscPlanOtlnItem, SewerBscPlanOtlnResponseDto, SewerBscPlanResponseDto, - SewerBscPlanRvwOpnnItem, SewerBscPlanRvwOpnnResponseDto, - SewerBscPlanSaveRequestDto, SewerBscPlanSearchRequestDto, SewerBscPlanService, - SewerBscPlanSplmntDmndItem, SewerBscPlanSplmntDmndResponseDto, - SewerBscPlanTmplntDtlItem, SewerBscPlanTmplntDtlResponseDto, - SewerBscPlanTmplntItem, SewerBscPlanTmplntResponseDto, - SewerBscPlanTmplntTmprStrgItem, SewerBscPlanTmplntTmprStrgResponseDto, SewerBscPlanUpdateRequestDto, } from "./model/sewer-bsc-plan-interface"; diff --git a/apps/as/src/entities/sewer-bsc-plan/model/sewer-bsc-plan-apply-payload-schema.ts b/apps/as/src/entities/sewer-bsc-plan/model/sewer-bsc-plan-apply-payload-schema.ts new file mode 100644 index 000000000..0060467b7 --- /dev/null +++ b/apps/as/src/entities/sewer-bsc-plan/model/sewer-bsc-plan-apply-payload-schema.ts @@ -0,0 +1,173 @@ +import { z } from "zod"; + +/** 백엔드 SewerBscPlanSaveRequestDto */ +export const sewerBscPlanSaveSchema = z.object({ + sewerBscPlanDocNo: z.string().optional(), + admdstCd: z.string().optional(), + envoSeComCd: z.string().optional(), + sewerBscPlanSeComCd: z.string().optional(), + sewerBscPlanNm: z.string().optional(), + taskSeComCd: z.string().optional(), + prgrsSttsComCd: z.string().optional(), +}); + +/** 백엔드 SewerBscPlanDtlSaveRequestDto */ +export const sewerBscPlanDtlSaveSchema = z.object({ + sewerBscPlanDocNo: z.string().optional(), + chgCycl: z.number().optional(), + aplcntNm: z.string().optional(), + aplcntMblTelno: z.string().optional(), + aplcntOgdpNm: z.string().optional(), + aplcntEmlAddr: z.string().optional(), + dsgnrNm: z.string().optional(), + dsgnrTelno: z.string().optional(), + dsgnrOgdpNm: z.string().optional(), + dsgnrEmlAddr: z.string().optional(), + planYr: z.string().optional(), + crtrYr: z.string().optional(), + bizOtlnCn: z.string().optional(), + frlvlGoalYr: z.string().optional(), + sclvlGoalYr: z.string().optional(), + thlvlGoalYr: z.string().optional(), + folvlGoalYr: z.string().optional(), + atchFileGroupId: z.string().optional(), +}); + +/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanOtlnItem */ +export const sewerBscPlanOtlnItemSchema = z.object({ + planStpNo: z.number().optional(), + sewerPlanPpltnCnt: z.number().optional(), + sewerPrcsPpltnCnt: z.number().optional(), + sewerPsplyRt: z.number().optional(), +}); + +/** 백엔드 SewerBscPlanApplySaveRequestDto.CklstResultItem */ +export const sewerBscPlanCklstResultItemSchema = z.object({ + cklstRvwSn: z.number().optional(), + cklstArtclSn: z.number().optional(), + cklstSn: z.number().optional(), + rvwStpComCd: z.string(), + selected: z.string().optional(), + picRvwCn: z.string().nullish(), +}); + +/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanFnrsCstItem */ +export const sewerBscPlanFnrsCstItemSchema = z.object({ + planStpNo: z.number().optional(), + gvexpAmt: z.number().optional(), + lcexpAmt: z.number().optional(), + orgprBdchgAmt: z.number().optional(), + etcAmt: z.number().optional(), + sumAmt: z.number().optional(), +}); + +/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanSplmntDmndItem */ +export const sewerBscPlanSplmntDmndItemSchema = z.object({ + splmntDmndSn: z.number().nullish(), + splmntArtclComCd: z.string().optional(), + splmntDmndCn: z.string().optional(), + splmntDmndDt: z.string().optional(), + splmntDmndAtchFileGroupId: z.string().optional(), + splmntCn: z.string().optional(), + splmntPicNm: z.string().optional(), + splmntCmptnDt: z.string().optional(), + splmntAtchFileGroupId: z.string().optional(), + cmptnYn: z.string().optional(), +}); + +/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanRvwOpnnItem */ +export const sewerBscPlanRvwOpnnItemSchema = z.object({ + rvwOpnnSn: z.number().optional(), + opnrSeComCd: z.string().optional(), + opnrNm: z.string().optional(), + rvwRsltCn: z.string().optional(), + rvwRsltAnmlyYn: z.string().optional(), + atchFileGroupId: z.string().optional(), +}); + +/** 백엔드 SewerBscPlanApplySaveRequestDto.EsntlAtchFileItem */ +export const sewerBscPlanEsntlAtchFileItemSchema = z.object({ + esntlAtchFileId: z.string().optional(), + atchFileGroupId: z.string().optional(), +}); + +/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanBizCstItem */ +export const sewerBscPlanBizCstItemSchema = z.object({ + planStpNo: z.number().optional(), + acntgSeCd: z.string().optional(), + cstrnAmt: z.number().optional(), +}); + +/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanTmplntDtlItem */ +export const sewerBscPlanTmplntDtlItemSchema = z.object({ + planStpNo: z.number().optional(), + swtrmtFcltCd: z.string().optional(), + prcsZoneArea: z.number().optional(), + swtrmtPpltnCnt: z.number().optional(), + planSwqty: z.number().optional(), + fcltCpct: z.number().optional(), + sprsysDrtwPplLen: z.number().optional(), + sprsysExlnPplLen: z.number().optional(), + cbsysPplLen: z.number().optional(), + icptgPplLen: z.number().optional(), + drgCnt: z.number().optional(), + drtwRlyPumpCnt: z.number().optional(), + drtwPumpCnt: z.number().optional(), + exlnPumpCnt: z.number().optional(), +}); + +/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanTmplntItem */ +export const sewerBscPlanTmplntItemSchema = z.object({ + swtrmtFcltCd: z.string().optional(), + atchFileGroupId: z.string().optional(), + sewerBscPlanTmplntDtlList: z.array(sewerBscPlanTmplntDtlItemSchema).optional(), +}); + +/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanTmplntTmprStrgItem */ +export const sewerBscPlanTmplntTmprStrgItemSchema = z.object({ + dtStrgDt: z.string().optional(), + swtrmtFcltCd: z.string().optional(), + prcsZoneArea: z.number().optional(), + swtrmtPpltnCnt: z.number().optional(), + planSwqty: z.number().optional(), + fcltCpct: z.number().optional(), + sprsysDrtwPplLen: z.number().optional(), + sprsysExlnPplLen: z.number().optional(), + cbsysPplLen: z.number().optional(), + icptgPplLen: z.number().optional(), + drgCnt: z.number().optional(), + drtwRlyPumpCnt: z.number().optional(), + drtwPumpCnt: z.number().optional(), + exlnPumpCnt: z.number().optional(), +}); + +/** 백엔드 SewerBscPlanApplySaveRequestDto */ +export const sewerBscPlanApplySaveSchema = z.object({ + techReViewSaveCd: z.string().optional(), + rvwStpCd: z.string().optional(), + sewerBscPlan: sewerBscPlanSaveSchema, + sewerBscPlanDtl: sewerBscPlanDtlSaveSchema, + sewerBscPlanOtlnList: z.array(sewerBscPlanOtlnItemSchema).optional(), + cklstResultList: z.array(sewerBscPlanCklstResultItemSchema).optional(), + fnrsCstList: z.array(sewerBscPlanFnrsCstItemSchema).optional(), + splmntDmndList: z.array(sewerBscPlanSplmntDmndItemSchema).optional(), + rvwOpnnList: z.array(sewerBscPlanRvwOpnnItemSchema).optional(), + esntlAtchFileList: z.array(sewerBscPlanEsntlAtchFileItemSchema).optional(), + bizCstList: z.array(sewerBscPlanBizCstItemSchema).optional(), + sewerBscPlanTmplntList: z.array(sewerBscPlanTmplntItemSchema).optional(), + tmplntTmprStrgList: z.array(sewerBscPlanTmplntTmprStrgItemSchema).optional(), +}); + +export type SewerBscPlanSaveRequestDto = z.infer; +export type SewerBscPlanDtlSaveRequestDto = z.infer; +export type SewerBscPlanOtlnItem = z.infer; +export type CklstResultItem = z.infer; +export type SewerBscPlanFnrsCstItem = z.infer; +export type SewerBscPlanSplmntDmndItem = z.infer; +export type SewerBscPlanRvwOpnnItem = z.infer; +export type EsntlAtchFileItem = z.infer; +export type SewerBscPlanBizCstItem = z.infer; +export type SewerBscPlanTmplntDtlItem = z.infer; +export type SewerBscPlanTmplntItem = z.infer; +export type SewerBscPlanTmplntTmprStrgItem = z.infer; +export type SewerBscPlanApplySaveRequestDto = z.infer; diff --git a/apps/as/src/entities/sewer-bsc-plan/model/sewer-bsc-plan-interface.ts b/apps/as/src/entities/sewer-bsc-plan/model/sewer-bsc-plan-interface.ts index cc5f533d8..0e8025278 100644 --- a/apps/as/src/entities/sewer-bsc-plan/model/sewer-bsc-plan-interface.ts +++ b/apps/as/src/entities/sewer-bsc-plan/model/sewer-bsc-plan-interface.ts @@ -1,35 +1,26 @@ import type { AtflMngClientResponseDto, - CklstResultSaveBase, CklstRvwRsltTreeDto, EsntlAtchFileMngTreeResponseDto, - EsntlAtchFileSaveBase, PageableParams, PageResponse, - PbadmsApplySaveHeader, RvwOpnnResponseExtension, RvwOpnnSaveBase, SplmntDmndResponseExtension, SplmntDmndSaveBase, } from "@/shared/model"; +import type { + SewerBscPlanApplySaveRequestDto, + SewerBscPlanSaveRequestDto, +} from "./sewer-bsc-plan-apply-payload-schema"; + export type { AtflMngClientResponseDto, CklstRvwRsltTreeDto, EsntlAtchFileMngTreeResponseDto, } from "@/shared/model"; -/** 백엔드 SewerBscPlanSaveRequestDto */ -export interface SewerBscPlanSaveRequestDto { - sewerBscPlanDocNo?: string; - admdstCd?: string; - envoSeComCd?: string; - sewerBscPlanSeComCd?: string; - sewerBscPlanNm?: string; - taskSeComCd?: string; - prgrsSttsComCd?: string; -} - /** 백엔드 SewerBscPlanUpdateRequestDto */ export interface SewerBscPlanUpdateRequestDto { admdstCd?: string; @@ -72,28 +63,6 @@ export interface SewerBscPlanResponseDto { mdfcnDt?: string; } -/** 백엔드 SewerBscPlanDtlSaveRequestDto */ -export interface SewerBscPlanDtlSaveRequestDto { - sewerBscPlanDocNo?: string; - chgCycl?: number; - aplcntNm?: string; - aplcntMblTelno?: string; - aplcntOgdpNm?: string; - aplcntEmlAddr?: string; - dsgnrNm?: string; - dsgnrTelno?: string; - dsgnrOgdpNm?: string; - dsgnrEmlAddr?: string; - planYr?: string; - crtrYr?: string; - bizOtlnCn?: string; - frlvlGoalYr?: string; - sclvlGoalYr?: string; - thlvlGoalYr?: string; - folvlGoalYr?: string; - atchFileGroupId?: string; -} - /** 백엔드 SewerBscPlanDtlResponseDto */ export interface SewerBscPlanDtlResponseDto { sewerBscPlanDocNo?: string; @@ -210,103 +179,6 @@ export interface SewerBscPlanTmplntTmprStrgResponseDto { exlnPumpCnt?: number; } -/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanOtlnItem */ -export interface SewerBscPlanOtlnItem { - planStpNo?: number; - sewerPlanPpltnCnt?: number; - sewerPrcsPpltnCnt?: number; - sewerPsplyRt?: number; -} - -/** 백엔드 SewerBscPlanApplySaveRequestDto.CklstResultItem */ -export interface CklstResultItem extends CklstResultSaveBase { - selected?: string; -} - -/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanFnrsCstItem */ -export interface SewerBscPlanFnrsCstItem { - planStpNo?: number; - gvexpAmt?: number; - lcexpAmt?: number; - orgprBdchgAmt?: number; - etcAmt?: number; - sumAmt?: number; -} - -/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanSplmntDmndItem */ -export type SewerBscPlanSplmntDmndItem = SplmntDmndSaveBase; - -/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanRvwOpnnItem */ -export type SewerBscPlanRvwOpnnItem = RvwOpnnSaveBase; - -/** 백엔드 SewerBscPlanApplySaveRequestDto.EsntlAtchFileItem */ -export type EsntlAtchFileItem = EsntlAtchFileSaveBase; - -/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanBizCstItem */ -export interface SewerBscPlanBizCstItem { - planStpNo?: number; - acntgSeCd?: string; - cstrnAmt?: number; -} - -/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanTmplntDtlItem */ -export interface SewerBscPlanTmplntDtlItem { - planStpNo?: number; - swtrmtFcltCd?: string; - prcsZoneArea?: number; - swtrmtPpltnCnt?: number; - planSwqty?: number; - fcltCpct?: number; - sprsysDrtwPplLen?: number; - sprsysExlnPplLen?: number; - cbsysPplLen?: number; - icptgPplLen?: number; - drgCnt?: number; - drtwRlyPumpCnt?: number; - drtwPumpCnt?: number; - exlnPumpCnt?: number; -} - -/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanTmplntItem */ -export interface SewerBscPlanTmplntItem { - swtrmtFcltCd?: string; - atchFileGroupId?: string; - sewerBscPlanTmplntDtlList?: SewerBscPlanTmplntDtlItem[]; -} - -/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanTmplntTmprStrgItem */ -export interface SewerBscPlanTmplntTmprStrgItem { - dtStrgDt?: string; - swtrmtFcltCd?: string; - prcsZoneArea?: number; - swtrmtPpltnCnt?: number; - planSwqty?: number; - fcltCpct?: number; - sprsysDrtwPplLen?: number; - sprsysExlnPplLen?: number; - cbsysPplLen?: number; - icptgPplLen?: number; - drgCnt?: number; - drtwRlyPumpCnt?: number; - drtwPumpCnt?: number; - exlnPumpCnt?: number; -} - -/** 백엔드 SewerBscPlanApplySaveRequestDto */ -export interface SewerBscPlanApplySaveRequestDto extends PbadmsApplySaveHeader { - sewerBscPlan: SewerBscPlanSaveRequestDto; - sewerBscPlanDtl: SewerBscPlanDtlSaveRequestDto; - sewerBscPlanOtlnList?: SewerBscPlanOtlnItem[]; - cklstResultList?: CklstResultItem[]; - fnrsCstList?: SewerBscPlanFnrsCstItem[]; - splmntDmndList?: SewerBscPlanSplmntDmndItem[]; - rvwOpnnList?: SewerBscPlanRvwOpnnItem[]; - esntlAtchFileList?: EsntlAtchFileItem[]; - bizCstList?: SewerBscPlanBizCstItem[]; - sewerBscPlanTmplntList?: SewerBscPlanTmplntItem[]; - tmplntTmprStrgList?: SewerBscPlanTmplntTmprStrgItem[]; -} - /** 백엔드 SewerBscPlanApplySaveResponseDto */ export interface SewerBscPlanApplySaveResponseDto { sewerBscPlanDocNo: string; @@ -346,6 +218,6 @@ export interface SewerBscPlanService { id: string, chgCycl: number, body: SewerBscPlanApplySaveRequestDto, - ): Promise; + ): Promise; techReview(id: string, body: SewerBscPlanApplySaveRequestDto): Promise; } diff --git a/apps/as/src/pages/design-cnstn/ui/design-form-page.tsx b/apps/as/src/pages/design-cnstn/ui/design-form-page.tsx index 63d4eda75..b9bc230d9 100644 --- a/apps/as/src/pages/design-cnstn/ui/design-form-page.tsx +++ b/apps/as/src/pages/design-cnstn/ui/design-form-page.tsx @@ -15,10 +15,12 @@ import { type DesignCnstnMngDetResponseDto, designCnstnMngService, } from "@/entities/design-cnstn"; +import { useEsntlAtchFileMngTree } from "@/entities/esntl"; import { AttachmentsFormSection, BusinessScaleFormSection, ContactInfoFormSection, + isFormEsntlAtchComplete, PrivacyConsentSection, } from "@/widgets/pbadms-sprt"; import { Button } from "@common/components"; @@ -53,6 +55,8 @@ function DesignFormPage({ id, mode, initialData, createDefaults }: DesignFormPag const [isSubmitting, setIsSubmitting] = useState(false); const isEditMode = mode === "edit"; + const { data: essentialFiles = [] } = useEsntlAtchFileMngTree({ docSeComCd: "CNFM" }); + const form = useForm({ resolver: zodResolver(designCnstnRegistSchema), mode: "onChange", @@ -113,6 +117,11 @@ function DesignFormPage({ id, mode, initialData, createDefaults }: DesignFormPag async function onApply(data: DesignCnstnRegistFormData) { if (isSubmitting) return; + if (!isFormEsntlAtchComplete(essentialFiles, data.esntlAtchFileList)) { + alert("필수 첨부파일을 모두 등록해야 신청이 가능합니다."); + return; + } + try { setIsSubmitting(true); const designCnstnDocNo = await submitForm(data, "CT"); diff --git a/apps/as/src/pages/design-cnstn/ui/sections/attachments-section.tsx b/apps/as/src/pages/design-cnstn/ui/sections/attachments-section.tsx index 082881231..d176631be 100644 --- a/apps/as/src/pages/design-cnstn/ui/sections/attachments-section.tsx +++ b/apps/as/src/pages/design-cnstn/ui/sections/attachments-section.tsx @@ -62,49 +62,51 @@ function AttachmentsSection({ esntlFileList, etcFileList }: AttachmentsSectionPr )} - -
- - - - 파일명 - 크기 - - - - {etcFileList.length === 0 ? ( + {etcFileList.length > 0 && ( + +
+
+ - - 등록된 기타첨부파일이 없습니다. - + 파일명 + 크기 - ) : ( - etcFileList.map((file) => ( - - - {file.atflCd ? ( - downloadAttachment(file.atflCd)} - target="_blank" - rel="noreferrer" - > - {file.orgnlFileNm || file.physFileNm || file.atflId} - - ) : ( - {file.orgnlFileNm || file.physFileNm || file.atflId} - )} - - - {formatFileSize(file.atflFlieSz)} + + + {etcFileList.length === 0 ? ( + + + 등록된 기타첨부파일이 없습니다. - )) - )} - -
-
-
+ ) : ( + etcFileList.map((file) => ( + + + {file.atflCd ? ( + downloadAttachment(file.atflCd)} + target="_blank" + rel="noreferrer" + > + {file.orgnlFileNm || file.physFileNm || file.atflId} + + ) : ( + {file.orgnlFileNm || file.physFileNm || file.atflId} + )} + + + {formatFileSize(file.atflFlieSz)} + + + )) + )} + + + + + )} ); } diff --git a/apps/as/src/pages/design-cnstn/ui/sections/tech-review-opinion-section.tsx b/apps/as/src/pages/design-cnstn/ui/sections/tech-review-opinion-section.tsx index 9c6985ffb..773110fca 100644 --- a/apps/as/src/pages/design-cnstn/ui/sections/tech-review-opinion-section.tsx +++ b/apps/as/src/pages/design-cnstn/ui/sections/tech-review-opinion-section.tsx @@ -2,8 +2,11 @@ import { forwardRef, useEffect, useImperativeHandle, useState } from "react"; +import { Paperclip } from "lucide-react"; + import { PROXY_HOST } from "@/shared/config"; import { dayjs, getDefaultFileKey, useTus } from "@/shared/lib"; +import { TextShimmer } from "@/shared/ui"; import { Field, FieldLabel, FieldSet } from "@/shared/ui/field"; import { attachService } from "@/entities/attach"; import type { DesignCnstnRvwOpnnResponseDto } from "@/entities/design-cnstn"; @@ -71,12 +74,10 @@ function hasFormContent(formData: ReviewOpinionFormData) { const TechReviewOpinionSection = forwardRef< TechReviewOpinionSectionHandle, TechReviewOpinionSectionProps ->(function TechReviewOpinionSection({ - rvwList, - editableReviewStep, - atrzSeComCdList = [], - isAtrzLoading = false, -}, ref) { +>(function TechReviewOpinionSection( + { rvwList, editableReviewStep, atrzSeComCdList = [], isAtrzLoading = false }, + ref, +) { const canWriteOpinion = !isAtrzLoading && atrzSeComCdList.includes("ATRZ02"); const [formData, setFormData] = useState({ ...EMPTY_FORM_DATA, @@ -240,7 +241,9 @@ const TechReviewOpinionSection = forwardRef< {uploadedFile ? (
- {uploadedFile.fileName} + + {uploadedFile.fileName} + diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/components/floating-action-buttons.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/components/floating-action-buttons.tsx index b4461ab1b..d776aed53 100644 --- a/apps/as/src/pages/fnrs-cnsltn/ui/components/floating-action-buttons.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/ui/components/floating-action-buttons.tsx @@ -498,6 +498,7 @@ function FloatingActionButtons({ /> setActiveDialog(null)} isSubmitting={isProcessing} diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-form-page.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-form-page.tsx index e85efd562..5a4222553 100644 --- a/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-form-page.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-form-page.tsx @@ -10,6 +10,7 @@ import { useQueryClient } from "@tanstack/react-query"; import { useAlertStore, useUserStore } from "@/shared/lib"; import { useAcntgSeMngTree } from "@/entities/acntg"; +import { useEsntlAtchFileMngTree } from "@/entities/esntl"; import { type FnrsCnsltnApplySaveRequestDto, fnrsCnsltnMngBaseKey, @@ -27,6 +28,7 @@ import { ContactInfoFormSection, FnrsSharFormSection, isFormChecklistComplete, + isFormEsntlAtchComplete, PrivacyConsentSection, recalculateFnrsSharTotals, SplmntDmndFormSection, @@ -67,6 +69,7 @@ function FnrsFormPage({ id, mode, initialData, createDefaults }: FnrsFormPagePro const { data: masterSharTree = [] } = useFnrsSharSeMngTree(); const { data: acntgTree = [] } = useAcntgSeMngTree(); + const { data: essentialFiles = [] } = useEsntlAtchFileMngTree({ docSeComCd: "FNRS" }); const sharTree = isEditMode && initialData?.fnrsSharList?.length ? initialData.fnrsSharList : masterSharTree; const sharItems = useMemo(() => buildFnrsSharItems(sharTree), [sharTree]); @@ -210,6 +213,11 @@ function FnrsFormPage({ id, mode, initialData, createDefaults }: FnrsFormPagePro return; } + if (!isFormEsntlAtchComplete(essentialFiles, data.esntlAtchFileList)) { + alert("필수 첨부파일을 모두 등록해야 신청이 가능합니다."); + return; + } + try { setIsSubmitting(true); const fnrsCnsltnDocNo = await submitForm(data, "ST"); diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/sections/attachments-section.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/sections/attachments-section.tsx index 3dbbdf1fd..0ac529c18 100644 --- a/apps/as/src/pages/fnrs-cnsltn/ui/sections/attachments-section.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/ui/sections/attachments-section.tsx @@ -19,98 +19,104 @@ function AttachmentsSection({ esntlFileList, etcFileList }: AttachmentsSectionPr return ( <> - -
- - - - 필수 자료명 - 파일명 - 크기 - - - - {esntlFileList.length === 0 ? ( + {esntlFileList.length > 0 && ( + +
+
+ - - 조회된 필수 첨부파일 항목이 없습니다. - + 필수 자료명 + 파일명 + 크기 - ) : ( - esntlFileList.map((file) => ( - - - {file.esntlAtchFileNm} - {file.esntlAtchYn === "Y" ? ( - * - ) : null} + + + {esntlFileList.length === 0 ? ( + + + 조회된 필수 첨부파일 항목이 없습니다. - - {file.atflCd ? ( - downloadAttachment(file.atflCd ?? "")} - target="_blank" - rel="noreferrer" - > - {file.orgnlFileNm || "다운로드"} - - ) : ( - 첨부없음 - )} - - {formatFileSize(file.atflFlieSz)} - )) - )} - -
-
-
+ ) : ( + esntlFileList.map((file) => ( + + + {file.esntlAtchFileNm} + {file.esntlAtchYn === "Y" ? ( + * + ) : null} + + + {file.atflCd ? ( + downloadAttachment(file.atflCd ?? "")} + target="_blank" + rel="noreferrer" + > + {file.orgnlFileNm || "다운로드"} + + ) : ( + 첨부없음 + )} + + + {formatFileSize(file.atflFlieSz)} + + + )) + )} + + +
+ + )} - -
- - - - 파일명 - 크기 - - - - {etcFileList.length === 0 ? ( + {etcFileList.length > 0 && ( + +
+
+ - - 등록된 기타첨부파일이 없습니다. - + 파일명 + 크기 - ) : ( - etcFileList.map((file) => ( - - - {file.atflCd ? ( - downloadAttachment(file.atflCd)} - target="_blank" - rel="noreferrer" - > - {file.orgnlFileNm || file.physFileNm || file.atflId} - - ) : ( - {file.orgnlFileNm || file.physFileNm || file.atflId} - )} - - - {formatFileSize(file.atflFlieSz)} + + + {etcFileList.length === 0 ? ( + + + 등록된 기타첨부파일이 없습니다. - )) - )} - -
-
-
+ ) : ( + etcFileList.map((file) => ( + + + {file.atflCd ? ( + downloadAttachment(file.atflCd)} + target="_blank" + rel="noreferrer" + > + {file.orgnlFileNm || file.physFileNm || file.atflId} + + ) : ( + {file.orgnlFileNm || file.physFileNm || file.atflId} + )} + + + {formatFileSize(file.atflFlieSz)} + + + )) + )} + + + + + )} ); } diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/sections/checklist-section.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/sections/checklist-section.tsx index 80671876a..09aa48052 100644 --- a/apps/as/src/pages/fnrs-cnsltn/ui/sections/checklist-section.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/ui/sections/checklist-section.tsx @@ -71,6 +71,10 @@ function ChecklistSection({ const { total, completed, percent } = progress; + if (cklstResultList.length === 0) { + return null; + } + return (
diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/sections/tech-review-opinion-section.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/sections/tech-review-opinion-section.tsx index bc7a51af6..f8d416af1 100644 --- a/apps/as/src/pages/fnrs-cnsltn/ui/sections/tech-review-opinion-section.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/ui/sections/tech-review-opinion-section.tsx @@ -2,8 +2,11 @@ import { forwardRef, useEffect, useImperativeHandle, useState } from "react"; +import { Paperclip } from "lucide-react"; + import { PROXY_HOST } from "@/shared/config"; import { dayjs, getDefaultFileKey, useTus } from "@/shared/lib"; +import { TextShimmer } from "@/shared/ui"; import { Field, FieldLabel, FieldSet } from "@/shared/ui/field"; import { attachService } from "@/entities/attach"; import type { FnrsCnsltnRvwOpnnResponseDto } from "@/entities/fnrs-cnsltn"; @@ -71,12 +74,10 @@ function hasFormContent(formData: ReviewOpinionFormData) { const TechReviewOpinionSection = forwardRef< TechReviewOpinionSectionHandle, TechReviewOpinionSectionProps ->(function TechReviewOpinionSection({ - rvwList, - editableReviewStep, - atrzSeComCdList = [], - isAtrzLoading = false, -}, ref) { +>(function TechReviewOpinionSection( + { rvwList, editableReviewStep, atrzSeComCdList = [], isAtrzLoading = false }, + ref, +) { const canWriteKecoOpinion = !isAtrzLoading && atrzSeComCdList.includes("ATRZ02"); const [formData, setFormData] = useState({ ...EMPTY_FORM_DATA, @@ -247,7 +248,9 @@ const TechReviewOpinionSection = forwardRef< {uploadedFile ? (
- {uploadedFile.fileName} + + {uploadedFile.fileName} + diff --git a/apps/as/src/pages/instl-sncn/ui/components/floating-action-buttons.tsx b/apps/as/src/pages/instl-sncn/ui/components/floating-action-buttons.tsx index e3c0d8119..a7610e355 100644 --- a/apps/as/src/pages/instl-sncn/ui/components/floating-action-buttons.tsx +++ b/apps/as/src/pages/instl-sncn/ui/components/floating-action-buttons.tsx @@ -511,6 +511,7 @@ function FloatingActionButtons({ /> setActiveDialog(null)} isSubmitting={isProcessing} diff --git a/apps/as/src/pages/instl-sncn/ui/instl-form-page.tsx b/apps/as/src/pages/instl-sncn/ui/instl-form-page.tsx index 766712e35..bc248e3b2 100644 --- a/apps/as/src/pages/instl-sncn/ui/instl-form-page.tsx +++ b/apps/as/src/pages/instl-sncn/ui/instl-form-page.tsx @@ -9,6 +9,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { useQueryClient } from "@tanstack/react-query"; import { useAlertStore, useUserStore } from "@/shared/lib"; +import { useEsntlAtchFileMngTree } from "@/entities/esntl"; import { type InstlSncnApplySaveRequestDto, instlSncnKeys, @@ -22,6 +23,7 @@ import { ChecklistFormSection, ContactInfoFormSection, isFormChecklistComplete, + isFormEsntlAtchComplete, PrivacyConsentSection, SplmntDmndFormSection, } from "@/widgets/pbadms-sprt"; @@ -57,6 +59,8 @@ function InstlFormPage({ id, mode, initialData, createDefaults }: InstlFormPageP const isEditMode = mode === "edit"; const isSplmntPrgrsStts = initialData?.detDto.prgrsSttsComCd === "SL"; + const { data: essentialFiles = [] } = useEsntlAtchFileMngTree({ docSeComCd: "INSTL" }); + const form = useForm({ resolver: zodResolver(instlSncnRegistSchema), mode: "onChange", @@ -172,6 +176,11 @@ function InstlFormPage({ id, mode, initialData, createDefaults }: InstlFormPageP return; } + if (!isFormEsntlAtchComplete(essentialFiles, data.esntlAtchFileList)) { + alert("필수 첨부파일을 모두 등록해야 신청이 가능합니다."); + return; + } + try { setIsSubmitting(true); const instlSncnDocNo = await submitForm(data, "ST"); diff --git a/apps/as/src/pages/instl-sncn/ui/sections/attachments-section.tsx b/apps/as/src/pages/instl-sncn/ui/sections/attachments-section.tsx index d518e80dc..5cd7fec89 100644 --- a/apps/as/src/pages/instl-sncn/ui/sections/attachments-section.tsx +++ b/apps/as/src/pages/instl-sncn/ui/sections/attachments-section.tsx @@ -19,98 +19,104 @@ function AttachmentsSection({ esntlFileList, etcFileList }: AttachmentsSectionPr return ( <> - -
- - - - 필수 자료명 - 파일명 - 크기 - - - - {esntlFileList.length === 0 ? ( + {esntlFileList.length > 0 && ( + +
+
+ - - 조회된 필수 첨부파일 항목이 없습니다. - + 필수 자료명 + 파일명 + 크기 - ) : ( - esntlFileList.map((file) => ( - - - {file.esntlAtchFileNm} - {file.esntlAtchYn === "Y" ? ( - * - ) : null} + + + {esntlFileList.length === 0 ? ( + + + 조회된 필수 첨부파일 항목이 없습니다. - - {file.atflCd ? ( - downloadAttachment(file.atflCd ?? "")} - target="_blank" - rel="noreferrer" - > - {file.orgnlFileNm || "다운로드"} - - ) : ( - 첨부없음 - )} - - {formatFileSize(file.atflFlieSz)} - )) - )} - -
-
-
+ ) : ( + esntlFileList.map((file) => ( + + + {file.esntlAtchFileNm} + {file.esntlAtchYn === "Y" ? ( + * + ) : null} + + + {file.atflCd ? ( + downloadAttachment(file.atflCd ?? "")} + target="_blank" + rel="noreferrer" + > + {file.orgnlFileNm || "다운로드"} + + ) : ( + 첨부없음 + )} + + + {formatFileSize(file.atflFlieSz)} + + + )) + )} + + +
+ + )} - -
- - - - 파일명 - 크기 - - - - {etcFileList.length === 0 ? ( + {etcFileList.length > 0 && ( + +
+
+ - - 등록된 기타첨부파일이 없습니다. - + 파일명 + 크기 - ) : ( - etcFileList.map((file) => ( - - - {file.atflCd ? ( - downloadAttachment(file.atflCd)} - target="_blank" - rel="noreferrer" - > - {file.orgnlFileNm || file.physFileNm || file.atflId} - - ) : ( - {file.orgnlFileNm || file.physFileNm || file.atflId} - )} - - - {formatFileSize(file.atflFlieSz)} + + + {etcFileList.length === 0 ? ( + + + 등록된 기타첨부파일이 없습니다. - )) - )} - -
-
-
+ ) : ( + etcFileList.map((file) => ( + + + {file.atflCd ? ( + downloadAttachment(file.atflCd)} + target="_blank" + rel="noreferrer" + > + {file.orgnlFileNm || file.physFileNm || file.atflId} + + ) : ( + {file.orgnlFileNm || file.physFileNm || file.atflId} + )} + + + {formatFileSize(file.atflFlieSz)} + + + )) + )} + + +
+
+ )} ); } diff --git a/apps/as/src/pages/instl-sncn/ui/sections/checklist-section.tsx b/apps/as/src/pages/instl-sncn/ui/sections/checklist-section.tsx index 0846d2b3e..2f370a5d7 100644 --- a/apps/as/src/pages/instl-sncn/ui/sections/checklist-section.tsx +++ b/apps/as/src/pages/instl-sncn/ui/sections/checklist-section.tsx @@ -70,6 +70,10 @@ function ChecklistSection({ const { total, completed, percent } = progress; + if (cklstResultList.length === 0) { + return null; + } + return (
diff --git a/apps/as/src/pages/instl-sncn/ui/sections/tech-review-opinion-section.tsx b/apps/as/src/pages/instl-sncn/ui/sections/tech-review-opinion-section.tsx index 2227492ed..62efef962 100644 --- a/apps/as/src/pages/instl-sncn/ui/sections/tech-review-opinion-section.tsx +++ b/apps/as/src/pages/instl-sncn/ui/sections/tech-review-opinion-section.tsx @@ -2,8 +2,11 @@ import { forwardRef, useEffect, useImperativeHandle, useState } from "react"; +import { Paperclip } from "lucide-react"; + import { PROXY_HOST } from "@/shared/config"; import { dayjs, getDefaultFileKey, useTus } from "@/shared/lib"; +import { TextShimmer } from "@/shared/ui"; import { Field, FieldLabel, FieldSet } from "@/shared/ui/field"; import { attachService } from "@/entities/attach"; import type { InstlSncnRvwOpnnResponseDto, ReviewStepCode } from "@/entities/instl-sncn"; @@ -67,12 +70,10 @@ function hasFormContent(formData: ReviewOpinionFormData) { const TechReviewOpinionSection = forwardRef< TechReviewOpinionSectionHandle, TechReviewOpinionSectionProps ->(function TechReviewOpinionSection({ - rvwList, - editableReviewStep, - atrzSeComCdList = [], - isAtrzLoading = false, -}, ref) { +>(function TechReviewOpinionSection( + { rvwList, editableReviewStep, atrzSeComCdList = [], isAtrzLoading = false }, + ref, +) { const canWriteKecoOpinion = !isAtrzLoading && atrzSeComCdList.includes("ATRZ02"); const [formData, setFormData] = useState({ ...EMPTY_FORM_DATA, @@ -240,7 +241,9 @@ const TechReviewOpinionSection = forwardRef< {uploadedFile ? (
- {uploadedFile.fileName} + + {uploadedFile.fileName} +