From 07a625e03b071660680ea0af0063e2ccfe37b62a Mon Sep 17 00:00:00 2001 From: bicochan Date: Fri, 7 Aug 2026 15:34:26 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[as]=20rename:=20SectionCollapsible=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20shared=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../elapr/ui/elapr-doc-prgrs-status.tsx | 41 ++++++---- .../design-cnstn/ui/design-view-page.tsx | 5 +- .../ui/sections/attachments-section.tsx | 2 +- .../ui/sections/basic-info-form-section.tsx | 2 +- .../ui/sections/basic-info-section.tsx | 2 +- .../ui/sections/business-scale-section.tsx | 3 +- .../ui/sections/contact-info-section.tsx | 2 +- .../sections/tech-review-opinion-section.tsx | 2 +- .../pages/fnrs-cnsltn/ui/fnrs-view-page.tsx | 6 +- .../ui/sections/attachments-section.tsx | 2 +- .../ui/sections/basic-info-form-section.tsx | 2 +- .../ui/sections/basic-info-section.tsx | 2 +- .../ui/sections/business-cost-section.tsx | 2 +- .../ui/sections/business-scale-section.tsx | 2 +- .../ui/sections/checklist-section.tsx | 2 +- .../ui/sections/contact-info-section.tsx | 2 +- .../ui/sections/fnrs-shar-section.tsx | 3 +- .../sections/tech-review-opinion-section.tsx | 2 +- .../pages/instl-sncn/ui/instl-view-page.tsx | 6 +- .../ui/sections/attachments-section.tsx | 2 +- .../ui/sections/basic-info-form-section.tsx | 2 +- .../ui/sections/basic-info-section.tsx | 2 +- .../ui/sections/business-cost-section.tsx | 2 +- .../ui/sections/business-scale-section.tsx | 2 +- .../ui/sections/checklist-section.tsx | 2 +- .../ui/sections/contact-info-section.tsx | 2 +- .../sections/tech-review-opinion-section.tsx | 2 +- .../ui/previous-plan-lookup-dialog.tsx | 2 +- .../ui/sections/attachments-section.tsx | 2 +- .../ui/sections/basic-info-form-section.tsx | 2 +- .../ui/sections/basic-info-section.tsx | 2 +- .../sections/biz-cst-matrix-form-section.tsx | 3 +- .../ui/sections/biz-cst-matrix-section.tsx | 3 +- .../ui/sections/checklist-section.tsx | 2 +- .../ui/sections/contact-info-section.tsx | 2 +- .../ui/sections/fnrs-cst-form-section.tsx | 3 +- .../ui/sections/fnrs-cst-section.tsx | 3 +- .../ui/sections/outline-form-section.tsx | 2 +- .../ui/sections/outline-section.tsx | 3 +- .../sections/tech-review-opinion-section.tsx | 2 +- .../ui/sections/tmplnt-form-section.tsx | 2 +- .../ui/sections/tmplnt-section.tsx | 3 +- .../ui/sewer-bsc-plan-view-page.tsx | 6 +- apps/as/src/shared/ui/index.ts | 1 + .../ui/section-collapsible.tsx | 74 +++++++++---------- .../bns-picker/ui/bns-picker-dialog.tsx | 2 +- apps/as/src/widgets/cnfm/ui/attachments.tsx | 1 + apps/as/src/widgets/pbadms-sprt/index.ts | 1 - .../ui/attachments-form-section.tsx | 5 +- .../ui/business-cost-form-section.tsx | 5 +- .../ui/business-scale-form-section.tsx | 5 +- .../pbadms-sprt/ui/checklist-form-section.tsx | 5 +- .../ui/contact-info-form-section.tsx | 2 +- .../pbadms-sprt/ui/fnrs-shar-form-section.tsx | 2 +- .../ui/privacy-consent-section.tsx | 5 +- .../ui/splmnt-dmnd-form-section.tsx | 3 +- .../ui/supplement-demand-section.tsx | 3 +- 57 files changed, 133 insertions(+), 129 deletions(-) rename apps/as/src/{widgets/pbadms-sprt => shared}/ui/section-collapsible.tsx (96%) diff --git a/apps/as/src/entities/elapr/ui/elapr-doc-prgrs-status.tsx b/apps/as/src/entities/elapr/ui/elapr-doc-prgrs-status.tsx index 731e39a07..77ec13b78 100644 --- a/apps/as/src/entities/elapr/ui/elapr-doc-prgrs-status.tsx +++ b/apps/as/src/entities/elapr/ui/elapr-doc-prgrs-status.tsx @@ -4,7 +4,9 @@ import { Fragment } from "react"; import { ChevronRight } from "lucide-react"; +import { useUserStore } from "@/shared/lib"; import type { ElaprDocPrgrsClientResponseDto } from "@/shared/model"; +import { SectionCollapsible } from "@/shared/ui"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/shared/ui/tooltip"; import { cn, Skeleton } from "@common/components"; @@ -61,16 +63,23 @@ function ElaprDocPrgrsStep({ item }: { item: ElaprDocPrgrsClientResponseDto }) { } function ElaprDocPrgrsStatus({ elaprDocNo }: ElaprDocPrgrsStatusProps) { + const userInfo = useUserStore((state) => state.userInfo); const { data, isLoading } = useElaprDocPrgrsByDocNo(elaprDocNo); const steps = sortByAtrzSeqNo(data ?? []); + if (userInfo?.dtlInstCd !== "ROLE_USER01") { + return null; + } + if (isLoading) { return ( -
- - - -
+ +
+ + + +
+
); } @@ -79,16 +88,18 @@ function ElaprDocPrgrsStatus({ elaprDocNo }: ElaprDocPrgrsStatusProps) { } return ( -
- {steps.map((item, index) => ( - -
- {index > 0 && } -
- -
- ))} -
+ +
+ {steps.map((item, index) => ( + +
+ {index > 0 && } +
+ +
+ ))} +
+
); } diff --git a/apps/as/src/pages/design-cnstn/ui/design-view-page.tsx b/apps/as/src/pages/design-cnstn/ui/design-view-page.tsx index aefd42317..c900ab530 100644 --- a/apps/as/src/pages/design-cnstn/ui/design-view-page.tsx +++ b/apps/as/src/pages/design-cnstn/ui/design-view-page.tsx @@ -6,7 +6,6 @@ import { useUserStore } from "@/shared/lib"; import { useDesignCnstnMng } from "@/entities/design-cnstn"; import { ElaprDocPrgrsStatus } from "@/entities/elapr"; import { useRvwMnpwMngLoginUserList } from "@/entities/rvw-mnpw"; -import { SectionCollapsible } from "@/widgets/pbadms-sprt"; import { Skeleton } from "@common/components"; import { needsRoleUser01AtrzResolve } from "../lib/button-config"; @@ -80,9 +79,7 @@ function DesignViewPage({ id }: DesignViewPageProps) {
- - - + - - - + 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 0ac529c18..b55b87c47 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 @@ -1,12 +1,12 @@ "use client"; import { formatFileSize } from "@/shared/lib/file-utils"; +import { SectionCollapsible } from "@/shared/ui"; import { useDownloadAttachmentByAtflCd } from "@/entities/attach"; import type { AtflMngClientResponseDto, EsntlAtchFileMngTreeResponseDto, } from "@/entities/fnrs-cnsltn"; -import { SectionCollapsible } from "@/widgets/pbadms-sprt"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@common/components"; interface AttachmentsSectionProps { diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/sections/basic-info-form-section.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/sections/basic-info-form-section.tsx index 751312ac6..759b1f0df 100644 --- a/apps/as/src/pages/fnrs-cnsltn/ui/sections/basic-info-form-section.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/ui/sections/basic-info-form-section.tsx @@ -3,10 +3,10 @@ import { useState } from "react"; import { Controller, useFormContext } from "react-hook-form"; +import { SectionCollapsible } from "@/shared/ui"; import { Field, FieldError, FieldGroup, FieldLabel, FieldSet } from "@/shared/ui/field"; import { findCodeLabel, useCodeList } from "@/entities/code"; import { type BnsApplyData, BnsPickerDialog } from "@/widgets/bns-picker"; -import { SectionCollapsible } from "@/widgets/pbadms-sprt"; import { Button, Checkbox, diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/sections/basic-info-section.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/sections/basic-info-section.tsx index 939af68fd..48f14eceb 100644 --- a/apps/as/src/pages/fnrs-cnsltn/ui/sections/basic-info-section.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/ui/sections/basic-info-section.tsx @@ -1,7 +1,7 @@ "use client"; +import { SectionCollapsible } from "@/shared/ui"; import type { FnrsCnsltnMngResponseDto } from "@/entities/fnrs-cnsltn"; -import { SectionCollapsible } from "@/widgets/pbadms-sprt"; import { Table, TableCell, TableHead, TableHeader, TableRow } from "@common/components"; interface BasicInfoSectionProps { diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/sections/business-cost-section.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/sections/business-cost-section.tsx index 285fe8bed..d880811b6 100644 --- a/apps/as/src/pages/fnrs-cnsltn/ui/sections/business-cost-section.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/ui/sections/business-cost-section.tsx @@ -2,9 +2,9 @@ import { useMemo } from "react"; +import { SectionCollapsible } from "@/shared/ui"; import type { BizCstTreeDto } from "@/entities/fnrs-cnsltn"; import { calcDiffPercent, fmtNumber, indentPx } from "@/widgets/pbadms-sprt"; -import { SectionCollapsible } from "@/widgets/pbadms-sprt"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@common/components"; import { sortBizCstListByTreePath } from "../../lib/business-cost-utils"; diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/sections/business-scale-section.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/sections/business-scale-section.tsx index f8849cf8f..c1f5a28af 100644 --- a/apps/as/src/pages/fnrs-cnsltn/ui/sections/business-scale-section.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/ui/sections/business-scale-section.tsx @@ -1,8 +1,8 @@ "use client"; +import { SectionCollapsible } from "@/shared/ui"; import type { BizSclTreeDto } from "@/entities/fnrs-cnsltn"; import { fmtNumber, indentPx } from "@/widgets/pbadms-sprt"; -import { SectionCollapsible } from "@/widgets/pbadms-sprt"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@common/components"; interface BusinessScaleSectionProps { 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 09aa48052..e50f5a6b8 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 @@ -2,8 +2,8 @@ import { type Dispatch, type SetStateAction, useEffect, useMemo, useState } from "react"; +import { SectionCollapsible } from "@/shared/ui"; import type { CklstRvwRsltTreeDto } from "@/entities/fnrs-cnsltn"; -import { SectionCollapsible } from "@/widgets/pbadms-sprt"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@common/components"; import { diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/sections/contact-info-section.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/sections/contact-info-section.tsx index 7443460e8..f5273fb33 100644 --- a/apps/as/src/pages/fnrs-cnsltn/ui/sections/contact-info-section.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/ui/sections/contact-info-section.tsx @@ -1,7 +1,7 @@ "use client"; +import { SectionCollapsible } from "@/shared/ui"; import type { FnrsCnsltnMngResponseDto } from "@/entities/fnrs-cnsltn"; -import { SectionCollapsible } from "@/widgets/pbadms-sprt"; import { Table, TableCell, TableHead, TableHeader, TableRow } from "@common/components"; interface ContactInfoSectionProps { diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/sections/fnrs-shar-section.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/sections/fnrs-shar-section.tsx index 198261c41..ad83c53e4 100644 --- a/apps/as/src/pages/fnrs-cnsltn/ui/sections/fnrs-shar-section.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/ui/sections/fnrs-shar-section.tsx @@ -2,8 +2,9 @@ import { useMemo } from "react"; +import { SectionCollapsible } from "@/shared/ui"; import type { FnrsSharBizCstTreeDto } from "@/entities/fnrs-shar-se"; -import { fmtNumber, indentPx, SectionCollapsible } from "@/widgets/pbadms-sprt"; +import { fmtNumber, indentPx } from "@/widgets/pbadms-sprt"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@common/components"; interface FnrsSharSectionProps { 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 f8d416af1..bdbd4e622 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 @@ -7,10 +7,10 @@ import { Paperclip } from "lucide-react"; import { PROXY_HOST } from "@/shared/config"; import { dayjs, getDefaultFileKey, useTus } from "@/shared/lib"; import { TextShimmer } from "@/shared/ui"; +import { SectionCollapsible } from "@/shared/ui"; import { Field, FieldLabel, FieldSet } from "@/shared/ui/field"; import { attachService } from "@/entities/attach"; import type { FnrsCnsltnRvwOpnnResponseDto } from "@/entities/fnrs-cnsltn"; -import { SectionCollapsible } from "@/widgets/pbadms-sprt"; import { Button, RadioGroup, diff --git a/apps/as/src/pages/instl-sncn/ui/instl-view-page.tsx b/apps/as/src/pages/instl-sncn/ui/instl-view-page.tsx index 094072f1a..88677bbf3 100644 --- a/apps/as/src/pages/instl-sncn/ui/instl-view-page.tsx +++ b/apps/as/src/pages/instl-sncn/ui/instl-view-page.tsx @@ -6,7 +6,7 @@ import { useUserStore } from "@/shared/lib"; import { ElaprDocPrgrsStatus } from "@/entities/elapr"; import { useInstlSncnDetail } from "@/entities/instl-sncn"; import { useRvwMnpwMngLoginUserList } from "@/entities/rvw-mnpw"; -import { SectionCollapsible, SupplementDemandSection } from "@/widgets/pbadms-sprt"; +import { SupplementDemandSection } from "@/widgets/pbadms-sprt"; import { Skeleton } from "@common/components"; import { needsRoleUser01AtrzResolve } from "../lib/button-config"; @@ -90,9 +90,7 @@ function InstlViewPage({ id }: InstlViewPageProps) {
- - - + - - - + diff --git a/apps/as/src/shared/ui/index.ts b/apps/as/src/shared/ui/index.ts index 926342b84..577618146 100644 --- a/apps/as/src/shared/ui/index.ts +++ b/apps/as/src/shared/ui/index.ts @@ -1,4 +1,5 @@ export { NoData } from "./no-data"; export { PageLayout } from "./page-layout"; +export { SectionCollapsible } from "./section-collapsible"; export type { TextShimmerProps } from "./text-shimmer"; export { TEXT_SHIMMER_CLASS, TextShimmer } from "./text-shimmer"; diff --git a/apps/as/src/widgets/pbadms-sprt/ui/section-collapsible.tsx b/apps/as/src/shared/ui/section-collapsible.tsx similarity index 96% rename from apps/as/src/widgets/pbadms-sprt/ui/section-collapsible.tsx rename to apps/as/src/shared/ui/section-collapsible.tsx index 2410ff325..2d9d6f27e 100644 --- a/apps/as/src/widgets/pbadms-sprt/ui/section-collapsible.tsx +++ b/apps/as/src/shared/ui/section-collapsible.tsx @@ -1,37 +1,37 @@ -"use client"; - -import type { ReactNode } from "react"; - -import { ChevronDown } from "lucide-react"; - -import { cn, Collapsible, CollapsibleContent, CollapsibleTrigger } from "@common/components"; - -interface SectionCollapsibleProps { - title: ReactNode; - defaultOpen?: boolean; - children: ReactNode; -} - -function SectionCollapsible({ title, defaultOpen = true, children }: SectionCollapsibleProps) { - return ( - - - - - {children} - - ); -} - -export { SectionCollapsible }; +"use client"; + +import type { ReactNode } from "react"; + +import { ChevronDown } from "lucide-react"; + +import { cn, Collapsible, CollapsibleContent, CollapsibleTrigger } from "@common/components"; + +interface SectionCollapsibleProps { + title: ReactNode; + defaultOpen?: boolean; + children: ReactNode; +} + +function SectionCollapsible({ title, defaultOpen = true, children }: SectionCollapsibleProps) { + return ( + + + + + {children} + + ); +} + +export { SectionCollapsible }; diff --git a/apps/as/src/widgets/bns-picker/ui/bns-picker-dialog.tsx b/apps/as/src/widgets/bns-picker/ui/bns-picker-dialog.tsx index a259c8aca..4153aec1a 100644 --- a/apps/as/src/widgets/bns-picker/ui/bns-picker-dialog.tsx +++ b/apps/as/src/widgets/bns-picker/ui/bns-picker-dialog.tsx @@ -12,12 +12,12 @@ import { import { useDataTable } from "@/shared/lib"; import type { PageResponse } from "@/shared/model"; +import { SectionCollapsible } from "@/shared/ui"; import { NoData } from "@/shared/ui/no-data"; import type { CmCdAdstDstrComboResponseDto } from "@/entities/adstdstr"; import { useFindGugunCombo, useFindSidoCombo } from "@/entities/adstdstr"; import type { BnsDetailResponseDto, BnsListResponseDto, BnsSearchDto } from "@/entities/bns-if"; import { buildBnsSearchDto, useBnsDetail, useBnsList } from "@/entities/bns-if"; -import { SectionCollapsible } from "@/widgets/pbadms-sprt"; import { Button, Dialog, diff --git a/apps/as/src/widgets/cnfm/ui/attachments.tsx b/apps/as/src/widgets/cnfm/ui/attachments.tsx index dcd68209e..4a585d231 100644 --- a/apps/as/src/widgets/cnfm/ui/attachments.tsx +++ b/apps/as/src/widgets/cnfm/ui/attachments.tsx @@ -1,4 +1,5 @@ import React from "react"; + import { formatFileSize } from "@/shared/lib/file-utils"; type EtcFile = { diff --git a/apps/as/src/widgets/pbadms-sprt/index.ts b/apps/as/src/widgets/pbadms-sprt/index.ts index 8f2c44b95..5b759af65 100644 --- a/apps/as/src/widgets/pbadms-sprt/index.ts +++ b/apps/as/src/widgets/pbadms-sprt/index.ts @@ -39,7 +39,6 @@ export { type PbadmsTaskApplySelection, } from "./ui/pbadms-task-apply-dialog"; export { PrivacyConsentSection } from "./ui/privacy-consent-section"; -export { SectionCollapsible } from "./ui/section-collapsible"; export { SplmntDmndDialog, type SplmntDmndDialogConfirmItem, diff --git a/apps/as/src/widgets/pbadms-sprt/ui/attachments-form-section.tsx b/apps/as/src/widgets/pbadms-sprt/ui/attachments-form-section.tsx index 03d812211..b4bce6b8a 100644 --- a/apps/as/src/widgets/pbadms-sprt/ui/attachments-form-section.tsx +++ b/apps/as/src/widgets/pbadms-sprt/ui/attachments-form-section.tsx @@ -9,6 +9,7 @@ import { ENDPOINT } from "@/shared/config"; import { useTus } from "@/shared/lib"; import type { AtflMngClientResponseDto, EsntlAtchFileMngTreeResponseDto } from "@/shared/model"; import { TextShimmer } from "@/shared/ui"; +import { SectionCollapsible } from "@/shared/ui"; import { attachService } from "@/entities/attach"; import { useEsntlAtchFileMngTree } from "@/entities/esntl"; import { @@ -29,9 +30,7 @@ import { type FieldPrefix, isEtcFileKey, toFileAccept, -} from "../lib/attachments-form-utils"; - -import { SectionCollapsible } from "./section-collapsible"; +} from "../lib/attachments-form-utils"; interface AttachmentsFormData { esntlAtchFileList: Array<{ diff --git a/apps/as/src/widgets/pbadms-sprt/ui/business-cost-form-section.tsx b/apps/as/src/widgets/pbadms-sprt/ui/business-cost-form-section.tsx index 51d7a82a1..969a4613b 100644 --- a/apps/as/src/widgets/pbadms-sprt/ui/business-cost-form-section.tsx +++ b/apps/as/src/widgets/pbadms-sprt/ui/business-cost-form-section.tsx @@ -3,6 +3,7 @@ import { useEffect, useMemo } from "react"; import { Controller, useFormContext, useWatch } from "react-hook-form"; +import { SectionCollapsible } from "@/shared/ui"; import { Field } from "@/shared/ui/field"; import { useAcntgSeMngTree } from "@/entities/acntg"; import { @@ -17,9 +18,7 @@ import { } from "@common/components"; import { buildAcntgCostItems, recalculateBizCstTotals } from "../lib/business-cost-form-utils"; -import { calcDiffPercent } from "../lib/format-utils"; - -import { SectionCollapsible } from "./section-collapsible"; +import { calcDiffPercent } from "../lib/format-utils"; interface BusinessCostFormData { bizCstList: Array<{ diff --git a/apps/as/src/widgets/pbadms-sprt/ui/business-scale-form-section.tsx b/apps/as/src/widgets/pbadms-sprt/ui/business-scale-form-section.tsx index 63698dd08..2bee5e104 100644 --- a/apps/as/src/widgets/pbadms-sprt/ui/business-scale-form-section.tsx +++ b/apps/as/src/widgets/pbadms-sprt/ui/business-scale-form-section.tsx @@ -3,6 +3,7 @@ import { useEffect, useMemo } from "react"; import { Controller, useFormContext, useWatch } from "react-hook-form"; +import { SectionCollapsible } from "@/shared/ui"; import { Field } from "@/shared/ui/field"; import { useCnstpSeMngTree } from "@/entities/cnstp"; import { @@ -16,9 +17,7 @@ import { TableRow, } from "@common/components"; -import { buildCnstpScaleItems, recalculateBzScaleTotals } from "../lib/business-scale-form-utils"; - -import { SectionCollapsible } from "./section-collapsible"; +import { buildCnstpScaleItems, recalculateBzScaleTotals } from "../lib/business-scale-form-utils"; interface BusinessScaleFormData { bzScaleList: Array<{ diff --git a/apps/as/src/widgets/pbadms-sprt/ui/checklist-form-section.tsx b/apps/as/src/widgets/pbadms-sprt/ui/checklist-form-section.tsx index 36fb793ae..4b9866877 100644 --- a/apps/as/src/widgets/pbadms-sprt/ui/checklist-form-section.tsx +++ b/apps/as/src/widgets/pbadms-sprt/ui/checklist-form-section.tsx @@ -5,6 +5,7 @@ import { Controller, useFormContext, useWatch } from "react-hook-form"; import { useQuery } from "@tanstack/react-query"; +import { SectionCollapsible } from "@/shared/ui"; import { Field, FieldLabel } from "@/shared/ui/field"; import { cklstMngService, type CklstTreeNode } from "@/entities/cklst"; import { useCodeList } from "@/entities/code"; @@ -29,9 +30,7 @@ import { buildChecklistTabs, normalizeTaskSeComCdArray, syncCklstResultListFromTree, -} from "../lib/checklist-form-utils"; - -import { SectionCollapsible } from "./section-collapsible"; +} from "../lib/checklist-form-utils"; type FieldPrefix = "fnrsCnsltnMng" | "instlSncnMng" | "designCnstnMng" | "sewerBscPlan"; diff --git a/apps/as/src/widgets/pbadms-sprt/ui/contact-info-form-section.tsx b/apps/as/src/widgets/pbadms-sprt/ui/contact-info-form-section.tsx index c3dc02fcc..0f5b659a0 100644 --- a/apps/as/src/widgets/pbadms-sprt/ui/contact-info-form-section.tsx +++ b/apps/as/src/widgets/pbadms-sprt/ui/contact-info-form-section.tsx @@ -3,8 +3,8 @@ import { Controller, useFormContext } from "react-hook-form"; import { useUserStore } from "@/shared/lib"; +import { SectionCollapsible } from "@/shared/ui"; import { Field, FieldError } from "@/shared/ui/field"; -import { SectionCollapsible } from "@/widgets/pbadms-sprt"; import { Input, Table, TableCell, TableHead, TableHeader, TableRow } from "@common/components"; type FieldPrefix = diff --git a/apps/as/src/widgets/pbadms-sprt/ui/fnrs-shar-form-section.tsx b/apps/as/src/widgets/pbadms-sprt/ui/fnrs-shar-form-section.tsx index 5365db9c9..0ab921ef9 100644 --- a/apps/as/src/widgets/pbadms-sprt/ui/fnrs-shar-form-section.tsx +++ b/apps/as/src/widgets/pbadms-sprt/ui/fnrs-shar-form-section.tsx @@ -5,6 +5,7 @@ import { Controller, useFormContext, useWatch } from "react-hook-form"; import { getDefaultFileKey, useTus } from "@/shared/lib"; import { TextShimmer } from "@/shared/ui"; +import { SectionCollapsible } from "@/shared/ui"; import { Field } from "@/shared/ui/field"; import { useAcntgSeMngTree } from "@/entities/acntg"; import type { AtflMngClientResponseDto } from "@/entities/fnrs-cnsltn"; @@ -34,7 +35,6 @@ import { import { calcDiffPercent } from "../lib/format-utils"; import { BizCstTotalDisplayTable } from "./biz-cst-total-display-table"; -import { SectionCollapsible } from "./section-collapsible"; const SHAR_FILE_KEY_PREFIX = "fnrs-shar::"; diff --git a/apps/as/src/widgets/pbadms-sprt/ui/privacy-consent-section.tsx b/apps/as/src/widgets/pbadms-sprt/ui/privacy-consent-section.tsx index d51d9aeef..eefd96163 100644 --- a/apps/as/src/widgets/pbadms-sprt/ui/privacy-consent-section.tsx +++ b/apps/as/src/widgets/pbadms-sprt/ui/privacy-consent-section.tsx @@ -2,6 +2,7 @@ import { Controller, useFormContext } from "react-hook-form"; +import { SectionCollapsible } from "@/shared/ui"; import { Field, FieldError, FieldLabel, FieldSet } from "@/shared/ui/field"; import { RadioGroup, @@ -11,9 +12,7 @@ import { TableHead, TableHeader, TableRow, -} from "@common/components"; - -import { SectionCollapsible } from "./section-collapsible"; +} from "@common/components"; interface PrivacyConsentFormData { privacyConsent: "Y" | "N"; diff --git a/apps/as/src/widgets/pbadms-sprt/ui/splmnt-dmnd-form-section.tsx b/apps/as/src/widgets/pbadms-sprt/ui/splmnt-dmnd-form-section.tsx index 6a8d94670..a8efff36d 100644 --- a/apps/as/src/widgets/pbadms-sprt/ui/splmnt-dmnd-form-section.tsx +++ b/apps/as/src/widgets/pbadms-sprt/ui/splmnt-dmnd-form-section.tsx @@ -7,6 +7,7 @@ import { Paperclip } from "lucide-react"; import { dayjs, getDefaultFileKey, useTus } from "@/shared/lib"; import { TextShimmer } from "@/shared/ui"; +import { SectionCollapsible } from "@/shared/ui"; import { attachService, useDownloadAttachmentByAtflCd } from "@/entities/attach"; import { Badge, @@ -20,8 +21,6 @@ import { Textarea, } from "@common/components"; -import { SectionCollapsible } from "./section-collapsible"; - const SPLMNT_CMPTN_FILE_KEY_PREFIX = "splmnt-cmptn::"; interface UploadedSplmntFile { diff --git a/apps/as/src/widgets/pbadms-sprt/ui/supplement-demand-section.tsx b/apps/as/src/widgets/pbadms-sprt/ui/supplement-demand-section.tsx index 8c7d6a8c7..1da222fdf 100644 --- a/apps/as/src/widgets/pbadms-sprt/ui/supplement-demand-section.tsx +++ b/apps/as/src/widgets/pbadms-sprt/ui/supplement-demand-section.tsx @@ -4,6 +4,7 @@ import { Paperclip } from "lucide-react"; import { dayjs } from "@/shared/lib"; import type { SplmntDmndResponseExtension, SplmntDmndSaveBase } from "@/shared/model"; +import { SectionCollapsible } from "@/shared/ui"; import { useDownloadAttachmentByAtflCd } from "@/entities/attach"; import { Badge, @@ -15,8 +16,6 @@ import { TableRow, } from "@common/components"; -import { SectionCollapsible } from "./section-collapsible"; - type SplmntDmndItem = SplmntDmndSaveBase & SplmntDmndResponseExtension; interface SupplementDemandSectionProps { From 0459c0b23157be5fe8a6148524b21da44db20259 Mon Sep 17 00:00:00 2001 From: bicochan Date: Fri, 7 Aug 2026 17:01:00 +0900 Subject: [PATCH 2/4] =?UTF-8?q?[as]=20feat:=20=ED=96=89=EC=A0=95=EC=A7=80?= =?UTF-8?q?=EC=9B=90=20=EC=97=85=EB=AC=B4=EB=B3=84=20=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=EB=82=B4=20=EC=A7=84=ED=96=89=EC=83=81=ED=99=A9=20ui=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/fnrs-cnsltn-interface.ts | 1 + .../instl-sncn/model/instl-sncn-interface.ts | 2 + .../model/sewer-bsc-plan-interface.ts | 1 + .../src/pages/design-cnstn/model/columns.tsx | 60 +++++---------- .../src/pages/fnrs-cnsltn/model/columns.tsx | 77 +++++++++++-------- .../as/src/pages/instl-sncn/model/columns.tsx | 69 ++++++++++------- .../pages/sewer-bsc-plan/model/columns.tsx | 76 +++++++++--------- 7 files changed, 145 insertions(+), 141 deletions(-) diff --git a/apps/as/src/entities/fnrs-cnsltn/model/fnrs-cnsltn-interface.ts b/apps/as/src/entities/fnrs-cnsltn/model/fnrs-cnsltn-interface.ts index d0a43a71b..44045341d 100644 --- a/apps/as/src/entities/fnrs-cnsltn/model/fnrs-cnsltn-interface.ts +++ b/apps/as/src/entities/fnrs-cnsltn/model/fnrs-cnsltn-interface.ts @@ -92,6 +92,7 @@ interface FnrsCnsltnMngResponseExtension { mdfcnDt?: string; sido?: string; gugun?: string; + techRplyHstryYn?: "Y" | "N"; } /** 백엔드 FnrsCnsltnMngResponseDto */ diff --git a/apps/as/src/entities/instl-sncn/model/instl-sncn-interface.ts b/apps/as/src/entities/instl-sncn/model/instl-sncn-interface.ts index 4bbd7ae24..a5e4ce791 100644 --- a/apps/as/src/entities/instl-sncn/model/instl-sncn-interface.ts +++ b/apps/as/src/entities/instl-sncn/model/instl-sncn-interface.ts @@ -148,6 +148,8 @@ export interface InstlSncnMngResponseDto extends InstlSncnMngSaveRequestDto { taskSeCdNm: string; /** 진행상태공통코드명 */ prgrsSttsCdNm: string; + /** 기술검토회신이력여부 */ + techRplyHstryYn: "Y" | "N"; /** 재이용시설구분공통코드명 */ rtlztnFcltSeComNm: string; /** 재이용용도구분공통코드명 */ 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 0e8025278..a6833bec0 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 @@ -61,6 +61,7 @@ export interface SewerBscPlanResponseDto { rgtr?: string; rgtrNm?: string; mdfcnDt?: string; + techRplyHstryYn?: "Y" | "N"; } /** 백엔드 SewerBscPlanDtlResponseDto */ diff --git a/apps/as/src/pages/design-cnstn/model/columns.tsx b/apps/as/src/pages/design-cnstn/model/columns.tsx index 6cfdb7f70..c74345041 100644 --- a/apps/as/src/pages/design-cnstn/model/columns.tsx +++ b/apps/as/src/pages/design-cnstn/model/columns.tsx @@ -11,62 +11,48 @@ import { Badge } from "@common/components"; const columnHelper = createColumnHelper(); const MAIN_STEP_LABELS = { - save: "저장", - apply: "신청완료", - review: "설계자문 검토", - reply: "설계검토 회신", + apply: "설계자문 신청", + techReview: "기술검토", + reply: "검토결과 회신", } as const; -const REVIEW_STATUS_CODES = new Set(["CS", "CR"]); - -type BadgeState = "completed" | "current" | "pending" | "action"; +type BadgeState = "completed" | "current" | "pending"; interface ProgressBadge { label: string; state: BadgeState; } -function buildProgressBadges(prgrsSttsComCd: string, prgrsSttsCdNm: string): ProgressBadge[] { - const reviewLabel = prgrsSttsCdNm || MAIN_STEP_LABELS.review; - const replyLabel = prgrsSttsCdNm || MAIN_STEP_LABELS.reply; - +function buildProgressBadges(prgrsSttsComCd: string): ProgressBadge[] { if (prgrsSttsComCd === "CV") { return [ - { label: MAIN_STEP_LABELS.save, state: "current" }, { label: MAIN_STEP_LABELS.apply, state: "pending" }, - { label: MAIN_STEP_LABELS.review, state: "pending" }, + { label: MAIN_STEP_LABELS.techReview, state: "pending" }, { label: MAIN_STEP_LABELS.reply, state: "pending" }, ]; } - if (prgrsSttsComCd === "CT") { + if (prgrsSttsComCd === "ER" || prgrsSttsComCd === "CS" || prgrsSttsComCd === "SL") { return [ - { label: MAIN_STEP_LABELS.save, state: "completed" }, - { label: MAIN_STEP_LABELS.apply, state: "current" }, - { label: MAIN_STEP_LABELS.review, state: "pending" }, - { label: MAIN_STEP_LABELS.reply, state: "pending" }, - ]; - } - - if (REVIEW_STATUS_CODES.has(prgrsSttsComCd)) { - return [ - { label: MAIN_STEP_LABELS.save, state: "completed" }, { label: MAIN_STEP_LABELS.apply, state: "completed" }, - { label: reviewLabel, state: "action" }, + { label: MAIN_STEP_LABELS.techReview, state: "current" }, { label: MAIN_STEP_LABELS.reply, state: "pending" }, ]; } - if (prgrsSttsComCd === "CP" || prgrsSttsComCd === "EP") { + if (prgrsSttsComCd === "CP") { return [ - { label: MAIN_STEP_LABELS.save, state: "completed" }, { label: MAIN_STEP_LABELS.apply, state: "completed" }, - { label: MAIN_STEP_LABELS.review, state: "completed" }, - { label: replyLabel, state: "action" }, + { label: MAIN_STEP_LABELS.techReview, state: "completed" }, + { label: MAIN_STEP_LABELS.reply, state: "completed" }, ]; } - return [{ label: prgrsSttsCdNm || prgrsSttsComCd || "-", state: "current" }]; + return [ + { label: MAIN_STEP_LABELS.apply, state: "pending" }, + { label: MAIN_STEP_LABELS.techReview, state: "pending" }, + { label: MAIN_STEP_LABELS.reply, state: "pending" }, + ]; } function getBadgeColor(state: BadgeState) { @@ -77,8 +63,6 @@ function getBadgeColor(state: BadgeState) { return "blue"; case "pending": return "lightGray"; - case "action": - return "orange"; } } @@ -88,11 +72,10 @@ function formatOptional(value: string | undefined) { interface ProgressStepBadgeProps { prgrsSttsComCd: string; - prgrsSttsCdNm: string; } -function ProgressStepBadge({ prgrsSttsComCd, prgrsSttsCdNm }: ProgressStepBadgeProps) { - const badges = buildProgressBadges(prgrsSttsComCd, prgrsSttsCdNm); +function ProgressStepBadge({ prgrsSttsComCd }: ProgressStepBadgeProps) { + const badges = buildProgressBadges(prgrsSttsComCd); return (
@@ -142,12 +125,7 @@ export function createDesignCnstnColumns() { id: "progress", header: "진행상황", meta: { align: "center" }, - cell: ({ row }) => ( - - ), + cell: ({ row }) => , }), columnHelper.accessor("regDt", { header: "신청일", diff --git a/apps/as/src/pages/fnrs-cnsltn/model/columns.tsx b/apps/as/src/pages/fnrs-cnsltn/model/columns.tsx index ba660c342..a29e2096c 100644 --- a/apps/as/src/pages/fnrs-cnsltn/model/columns.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/model/columns.tsx @@ -11,29 +11,24 @@ import { Badge } from "@common/components"; const columnHelper = createColumnHelper(); const MAIN_STEP_LABELS = { - save: "저장", - apply: "신청완료", + apply: "재원협의 신청", + envoReview: "환경청 검토", techReview: "기술검토", reply: "검토결과 회신", } as const; -const TECH_REVIEW_STATUS_CODES = new Set(["LE", "ER", "EE", "TE", "TS", "TR", "TP"]); - -type BadgeState = "completed" | "current" | "pending" | "action"; +type BadgeState = "completed" | "current" | "pending"; interface ProgressBadge { label: string; state: BadgeState; } -function buildProgressBadges(prgrsSttsComCd: string, prgrsSttsCdNm: string): ProgressBadge[] { - const techReviewLabel = prgrsSttsCdNm || MAIN_STEP_LABELS.techReview; - const replyLabel = prgrsSttsCdNm || MAIN_STEP_LABELS.reply; - +function buildProgressBadges(prgrsSttsComCd: string, techRplyHstryYn: "Y" | "N"): ProgressBadge[] { if (prgrsSttsComCd === "SV") { return [ - { label: MAIN_STEP_LABELS.save, state: "current" }, { label: MAIN_STEP_LABELS.apply, state: "pending" }, + { label: MAIN_STEP_LABELS.envoReview, state: "pending" }, { label: MAIN_STEP_LABELS.techReview, state: "pending" }, { label: MAIN_STEP_LABELS.reply, state: "pending" }, ]; @@ -41,41 +36,61 @@ function buildProgressBadges(prgrsSttsComCd: string, prgrsSttsCdNm: string): Pro if (prgrsSttsComCd === "ST") { return [ - { label: MAIN_STEP_LABELS.save, state: "completed" }, { label: MAIN_STEP_LABELS.apply, state: "current" }, + { label: MAIN_STEP_LABELS.envoReview, state: "pending" }, { label: MAIN_STEP_LABELS.techReview, state: "pending" }, { label: MAIN_STEP_LABELS.reply, state: "pending" }, ]; } - if (TECH_REVIEW_STATUS_CODES.has(prgrsSttsComCd)) { + if (prgrsSttsComCd === "LE") { return [ - { label: MAIN_STEP_LABELS.save, state: "completed" }, { label: MAIN_STEP_LABELS.apply, state: "completed" }, - { label: techReviewLabel, state: "action" }, + { label: MAIN_STEP_LABELS.envoReview, state: "current" }, + { label: MAIN_STEP_LABELS.techReview, state: "pending" }, { label: MAIN_STEP_LABELS.reply, state: "pending" }, ]; } + if (prgrsSttsComCd === "ER" || prgrsSttsComCd === "TE" || prgrsSttsComCd === "SL") { + return [ + { label: MAIN_STEP_LABELS.apply, state: "completed" }, + { label: MAIN_STEP_LABELS.envoReview, state: "completed" }, + { label: MAIN_STEP_LABELS.techReview, state: "current" }, + { label: MAIN_STEP_LABELS.reply, state: "pending" }, + ]; + } + + if (prgrsSttsComCd === "TP") { + return [ + { label: MAIN_STEP_LABELS.apply, state: "completed" }, + { label: MAIN_STEP_LABELS.envoReview, state: "completed" }, + { + label: MAIN_STEP_LABELS.techReview, + state: techRplyHstryYn === "Y" ? "completed" : "pending", + }, + { label: MAIN_STEP_LABELS.reply, state: "current" }, + ]; + } + if (prgrsSttsComCd === "EP") { return [ - { label: MAIN_STEP_LABELS.save, state: "completed" }, { label: MAIN_STEP_LABELS.apply, state: "completed" }, - { label: MAIN_STEP_LABELS.techReview, state: "completed" }, - { label: replyLabel, state: "action" }, - ]; - } - - if (prgrsSttsComCd === "TA" || prgrsSttsComCd === "TB") { - return [ - { label: MAIN_STEP_LABELS.save, state: "completed" }, - { label: MAIN_STEP_LABELS.apply, state: "completed" }, - { label: MAIN_STEP_LABELS.techReview, state: "completed" }, + { label: MAIN_STEP_LABELS.envoReview, state: "completed" }, + { + label: MAIN_STEP_LABELS.techReview, + state: techRplyHstryYn === "Y" ? "completed" : "pending", + }, { label: MAIN_STEP_LABELS.reply, state: "completed" }, ]; } - return [{ label: prgrsSttsCdNm || prgrsSttsComCd || "-", state: "current" }]; + return [ + { label: MAIN_STEP_LABELS.apply, state: "pending" }, + { label: MAIN_STEP_LABELS.envoReview, state: "pending" }, + { label: MAIN_STEP_LABELS.techReview, state: "pending" }, + { label: MAIN_STEP_LABELS.reply, state: "pending" }, + ]; } function getBadgeColor(state: BadgeState) { @@ -86,8 +101,6 @@ function getBadgeColor(state: BadgeState) { return "blue"; case "pending": return "lightGray"; - case "action": - return "orange"; } } @@ -97,11 +110,11 @@ function formatOptional(value: string | undefined) { interface ProgressStepBadgeProps { prgrsSttsComCd: string; - prgrsSttsCdNm: string; + techRplyHstryYn: "Y" | "N"; } -function ProgressStepBadge({ prgrsSttsComCd, prgrsSttsCdNm }: ProgressStepBadgeProps) { - const badges = buildProgressBadges(prgrsSttsComCd, prgrsSttsCdNm); +function ProgressStepBadge({ prgrsSttsComCd, techRplyHstryYn }: ProgressStepBadgeProps) { + const badges = buildProgressBadges(prgrsSttsComCd, techRplyHstryYn); return (
@@ -154,7 +167,7 @@ export function createFnrsCnsltnColumns() { cell: ({ row }) => ( ), }), diff --git a/apps/as/src/pages/instl-sncn/model/columns.tsx b/apps/as/src/pages/instl-sncn/model/columns.tsx index 772e20df0..ee9ddb055 100644 --- a/apps/as/src/pages/instl-sncn/model/columns.tsx +++ b/apps/as/src/pages/instl-sncn/model/columns.tsx @@ -11,29 +11,24 @@ import { Badge } from "@common/components"; const columnHelper = createColumnHelper(); const MAIN_STEP_LABELS = { - save: "저장", - apply: "신청완료", + apply: "설치인가 신청", + envoReview: "환경청 검토", techReview: "기술검토", reply: "검토결과 회신", } as const; -const TECH_REVIEW_STATUS_CODES = new Set(["LE", "ER", "EE", "TE", "TS", "TR", "TP"]); - -type BadgeState = "completed" | "current" | "pending" | "action"; +type BadgeState = "completed" | "current" | "pending"; interface ProgressBadge { label: string; state: BadgeState; } -function buildProgressBadges(prgrsSttsComCd: string, prgrsSttsCdNm: string): ProgressBadge[] { - const techReviewLabel = prgrsSttsCdNm || MAIN_STEP_LABELS.techReview; - const replyLabel = prgrsSttsCdNm || MAIN_STEP_LABELS.reply; - +function buildProgressBadges(prgrsSttsComCd: string, techRplyHstryYn: "Y" | "N"): ProgressBadge[] { if (prgrsSttsComCd === "SV") { return [ - { label: MAIN_STEP_LABELS.save, state: "current" }, { label: MAIN_STEP_LABELS.apply, state: "pending" }, + { label: MAIN_STEP_LABELS.envoReview, state: "pending" }, { label: MAIN_STEP_LABELS.techReview, state: "pending" }, { label: MAIN_STEP_LABELS.reply, state: "pending" }, ]; @@ -41,41 +36,61 @@ function buildProgressBadges(prgrsSttsComCd: string, prgrsSttsCdNm: string): Pro if (prgrsSttsComCd === "ST") { return [ - { label: MAIN_STEP_LABELS.save, state: "completed" }, { label: MAIN_STEP_LABELS.apply, state: "current" }, + { label: MAIN_STEP_LABELS.envoReview, state: "pending" }, { label: MAIN_STEP_LABELS.techReview, state: "pending" }, { label: MAIN_STEP_LABELS.reply, state: "pending" }, ]; } - if (TECH_REVIEW_STATUS_CODES.has(prgrsSttsComCd)) { + if (prgrsSttsComCd === "LE") { return [ - { label: MAIN_STEP_LABELS.save, state: "completed" }, { label: MAIN_STEP_LABELS.apply, state: "completed" }, - { label: techReviewLabel, state: "action" }, + { label: MAIN_STEP_LABELS.envoReview, state: "current" }, + { label: MAIN_STEP_LABELS.techReview, state: "pending" }, { label: MAIN_STEP_LABELS.reply, state: "pending" }, ]; } - if (prgrsSttsComCd === "EP") { + if (prgrsSttsComCd === "ER" || prgrsSttsComCd === "TE" || prgrsSttsComCd === "SL") { return [ - { label: MAIN_STEP_LABELS.save, state: "completed" }, { label: MAIN_STEP_LABELS.apply, state: "completed" }, - { label: MAIN_STEP_LABELS.techReview, state: "completed" }, - { label: replyLabel, state: "action" }, + { label: MAIN_STEP_LABELS.envoReview, state: "completed" }, + { label: MAIN_STEP_LABELS.techReview, state: "current" }, + { label: MAIN_STEP_LABELS.reply, state: "pending" }, ]; } - if (prgrsSttsComCd === "TA" || prgrsSttsComCd === "TB") { + if (prgrsSttsComCd === "TP" || prgrsSttsComCd === "EP") { return [ - { label: MAIN_STEP_LABELS.save, state: "completed" }, { label: MAIN_STEP_LABELS.apply, state: "completed" }, - { label: MAIN_STEP_LABELS.techReview, state: "completed" }, + { label: MAIN_STEP_LABELS.envoReview, state: "completed" }, + { + label: MAIN_STEP_LABELS.techReview, + state: techRplyHstryYn === "Y" ? "completed" : "pending", + }, + { label: MAIN_STEP_LABELS.reply, state: "current" }, + ]; + } + + if (prgrsSttsComCd === "TA") { + return [ + { label: MAIN_STEP_LABELS.apply, state: "completed" }, + { label: MAIN_STEP_LABELS.envoReview, state: "completed" }, + { + label: MAIN_STEP_LABELS.techReview, + state: techRplyHstryYn === "Y" ? "completed" : "pending", + }, { label: MAIN_STEP_LABELS.reply, state: "completed" }, ]; } - return [{ label: prgrsSttsCdNm || prgrsSttsComCd || "-", state: "current" }]; + return [ + { label: MAIN_STEP_LABELS.apply, state: "pending" }, + { label: MAIN_STEP_LABELS.envoReview, state: "pending" }, + { label: MAIN_STEP_LABELS.techReview, state: "pending" }, + { label: MAIN_STEP_LABELS.reply, state: "pending" }, + ]; } function getBadgeColor(state: BadgeState) { @@ -86,8 +101,6 @@ function getBadgeColor(state: BadgeState) { return "blue"; case "pending": return "lightGray"; - case "action": - return "orange"; } } @@ -97,11 +110,11 @@ function formatOptional(value: string | undefined) { interface ProgressStepBadgeProps { prgrsSttsComCd: string; - prgrsSttsCdNm: string; + techRplyHstryYn: "Y" | "N"; } -function ProgressStepBadge({ prgrsSttsComCd, prgrsSttsCdNm }: ProgressStepBadgeProps) { - const badges = buildProgressBadges(prgrsSttsComCd, prgrsSttsCdNm); +function ProgressStepBadge({ prgrsSttsComCd, techRplyHstryYn }: ProgressStepBadgeProps) { + const badges = buildProgressBadges(prgrsSttsComCd, techRplyHstryYn); return (
@@ -154,7 +167,7 @@ export function createInstlSncnColumns() { cell: ({ row }) => ( ), }), diff --git a/apps/as/src/pages/sewer-bsc-plan/model/columns.tsx b/apps/as/src/pages/sewer-bsc-plan/model/columns.tsx index ec387c8cb..9ad252381 100644 --- a/apps/as/src/pages/sewer-bsc-plan/model/columns.tsx +++ b/apps/as/src/pages/sewer-bsc-plan/model/columns.tsx @@ -11,30 +11,22 @@ import { Badge } from "@common/components"; const columnHelper = createColumnHelper(); const MAIN_STEP_LABELS = { - save: "저장", - apply: "신청완료", + apply: "기본계획 신청", envoReview: "환경청 검토", techReview: "기술검토", reply: "검토결과 회신", - supplement: "보완요청", } as const; -const TECH_REVIEW_STATUS_CODES = new Set(["ER", "TE", "TP"]); - -type BadgeState = "completed" | "current" | "pending" | "action"; +type BadgeState = "completed" | "current" | "pending"; interface ProgressBadge { label: string; state: BadgeState; } -function buildProgressBadges(prgrsSttsComCd: string, prgrsSttsCdNm: string): ProgressBadge[] { - const techReviewLabel = prgrsSttsCdNm || MAIN_STEP_LABELS.techReview; - const replyLabel = prgrsSttsCdNm || MAIN_STEP_LABELS.reply; - +function buildProgressBadges(prgrsSttsComCd: string, techRplyHstryYn: "Y" | "N"): ProgressBadge[] { if (prgrsSttsComCd === "SV") { return [ - { label: MAIN_STEP_LABELS.save, state: "current" }, { label: MAIN_STEP_LABELS.apply, state: "pending" }, { label: MAIN_STEP_LABELS.envoReview, state: "pending" }, { label: MAIN_STEP_LABELS.techReview, state: "pending" }, @@ -42,57 +34,63 @@ function buildProgressBadges(prgrsSttsComCd: string, prgrsSttsCdNm: string): Pro ]; } + if (prgrsSttsComCd === "ST") { + return [ + { label: MAIN_STEP_LABELS.apply, state: "current" }, + { label: MAIN_STEP_LABELS.envoReview, state: "pending" }, + { label: MAIN_STEP_LABELS.techReview, state: "pending" }, + { label: MAIN_STEP_LABELS.reply, state: "pending" }, + ]; + } + if (prgrsSttsComCd === "LE") { return [ - { label: MAIN_STEP_LABELS.save, state: "completed" }, { label: MAIN_STEP_LABELS.apply, state: "completed" }, - { label: MAIN_STEP_LABELS.envoReview, state: "action" }, + { label: MAIN_STEP_LABELS.envoReview, state: "current" }, { label: MAIN_STEP_LABELS.techReview, state: "pending" }, { label: MAIN_STEP_LABELS.reply, state: "pending" }, ]; } - if (prgrsSttsComCd === "SL") { + if (prgrsSttsComCd === "ER" || prgrsSttsComCd === "TE" || prgrsSttsComCd === "SL") { return [ - { label: MAIN_STEP_LABELS.save, state: "completed" }, { label: MAIN_STEP_LABELS.apply, state: "completed" }, { label: MAIN_STEP_LABELS.envoReview, state: "completed" }, - { label: MAIN_STEP_LABELS.supplement, state: "action" }, + { label: MAIN_STEP_LABELS.techReview, state: "current" }, { label: MAIN_STEP_LABELS.reply, state: "pending" }, ]; } - if (TECH_REVIEW_STATUS_CODES.has(prgrsSttsComCd)) { + if (prgrsSttsComCd === "TP") { return [ - { label: MAIN_STEP_LABELS.save, state: "completed" }, { label: MAIN_STEP_LABELS.apply, state: "completed" }, { label: MAIN_STEP_LABELS.envoReview, state: "completed" }, - { label: techReviewLabel, state: "action" }, - { label: MAIN_STEP_LABELS.reply, state: "pending" }, - ]; - } - - if (prgrsSttsComCd === "TA") { - return [ - { label: MAIN_STEP_LABELS.save, state: "completed" }, - { label: MAIN_STEP_LABELS.apply, state: "completed" }, - { label: MAIN_STEP_LABELS.envoReview, state: "completed" }, - { label: MAIN_STEP_LABELS.techReview, state: "completed" }, - { label: MAIN_STEP_LABELS.reply, state: "completed" }, + { + label: MAIN_STEP_LABELS.techReview, + state: techRplyHstryYn === "Y" ? "completed" : "pending", + }, + { label: MAIN_STEP_LABELS.reply, state: "current" }, ]; } if (prgrsSttsComCd === "EP") { return [ - { label: MAIN_STEP_LABELS.save, state: "completed" }, { label: MAIN_STEP_LABELS.apply, state: "completed" }, { label: MAIN_STEP_LABELS.envoReview, state: "completed" }, - { label: MAIN_STEP_LABELS.techReview, state: "completed" }, - { label: replyLabel, state: "completed" }, + { + label: MAIN_STEP_LABELS.techReview, + state: techRplyHstryYn === "Y" ? "completed" : "pending", + }, + { label: MAIN_STEP_LABELS.reply, state: "completed" }, ]; } - return [{ label: prgrsSttsCdNm || prgrsSttsComCd || "-", state: "current" }]; + return [ + { label: MAIN_STEP_LABELS.apply, state: "pending" }, + { label: MAIN_STEP_LABELS.envoReview, state: "pending" }, + { label: MAIN_STEP_LABELS.techReview, state: "pending" }, + { label: MAIN_STEP_LABELS.reply, state: "pending" }, + ]; } function getBadgeColor(state: BadgeState) { @@ -103,8 +101,6 @@ function getBadgeColor(state: BadgeState) { return "blue"; case "pending": return "lightGray"; - case "action": - return "orange"; } } @@ -114,11 +110,11 @@ function formatOptional(value: string | undefined) { interface ProgressStepBadgeProps { prgrsSttsComCd: string; - prgrsSttsCdNm: string; + techRplyHstryYn: "Y" | "N"; } -function ProgressStepBadge({ prgrsSttsComCd, prgrsSttsCdNm }: ProgressStepBadgeProps) { - const badges = buildProgressBadges(prgrsSttsComCd, prgrsSttsCdNm); +function ProgressStepBadge({ prgrsSttsComCd, techRplyHstryYn }: ProgressStepBadgeProps) { + const badges = buildProgressBadges(prgrsSttsComCd, techRplyHstryYn); return (
@@ -177,7 +173,7 @@ export function createSewerBscPlanColumns() { cell: ({ row }) => ( ), }), From dbda77a75b0fefbc828551fe94523d293f5a9310 Mon Sep 17 00:00:00 2001 From: bicochan Date: Mon, 10 Aug 2026 15:27:53 +0900 Subject: [PATCH 3/4] =?UTF-8?q?[as]=20feat:=20=EA=B2=B0=EC=9E=AC=ED=98=84?= =?UTF-8?q?=ED=99=A9=20ui=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/entities/elapr/lib/approval-utils.ts | 40 +++++++++++++++---- .../elapr/ui/elapr-doc-prgrs-status.tsx | 31 ++++++++------ .../as/src/pages/instl-sncn/model/columns.tsx | 2 +- 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/apps/as/src/entities/elapr/lib/approval-utils.ts b/apps/as/src/entities/elapr/lib/approval-utils.ts index 00d7d7b2a..831c06949 100644 --- a/apps/as/src/entities/elapr/lib/approval-utils.ts +++ b/apps/as/src/entities/elapr/lib/approval-utils.ts @@ -6,11 +6,26 @@ export interface ApproverStatusConfig { } export const APPROVER_STATUS_MAP: Record = { - ATRZ_PRGRS_001: { label: "대기", badgeClass: "bg-gray-100 text-gray-700" }, - ATRZ_PRGRS_002: { label: "요청", badgeClass: "bg-yellow-100 text-yellow-700" }, - ATRZ_PRGRS_003: { label: "승인", badgeClass: "bg-green-100 text-green-700" }, - ATRZ_PRGRS_004: { label: "반려", badgeClass: "bg-red-100 text-red-700" }, - ATRZ_PRGRS_999: { label: "결재안함", badgeClass: "bg-blue-100 text-blue-700" }, + ATRZ_PRGRS_001: { + label: "대기", + badgeClass: "bg-gray-100 text-gray-700", + }, + ATRZ_PRGRS_002: { + label: "결재요청", + badgeClass: "bg-yellow-100 text-yellow-700", + }, + ATRZ_PRGRS_003: { + label: "결재승인", + badgeClass: "bg-green-100 text-green-700", + }, + ATRZ_PRGRS_004: { + label: "반려", + badgeClass: "bg-red-100 text-red-700", + }, + ATRZ_PRGRS_999: { + label: "결재안함", + badgeClass: "bg-blue-100 text-blue-700", + }, }; export function sortByAtrzSeqNo( @@ -19,10 +34,19 @@ export function sortByAtrzSeqNo( return list.slice().sort((a, b) => Number(a.atrzSeqNo ?? 0) - Number(b.atrzSeqNo ?? 0)); } -export function getApproverStatus(status: string | undefined): ApproverStatusConfig { +export function getApproverStatus( + atrzPrgrsSttsComCd?: string, + atrzSeComCd?: string, +): ApproverStatusConfig { + if (atrzPrgrsSttsComCd === "ATRZ_PRGRS_003" && atrzSeComCd === "ATRZ01") + return { + label: "기술검토 접수", + badgeClass: "bg-green-100 text-green-700", + }; + return ( - APPROVER_STATUS_MAP[status ?? ""] ?? { - label: status || "-", + APPROVER_STATUS_MAP[atrzPrgrsSttsComCd ?? ""] ?? { + label: "-", badgeClass: "bg-gray-100 text-gray-700", } ); diff --git a/apps/as/src/entities/elapr/ui/elapr-doc-prgrs-status.tsx b/apps/as/src/entities/elapr/ui/elapr-doc-prgrs-status.tsx index 77ec13b78..4be4cf0c3 100644 --- a/apps/as/src/entities/elapr/ui/elapr-doc-prgrs-status.tsx +++ b/apps/as/src/entities/elapr/ui/elapr-doc-prgrs-status.tsx @@ -4,7 +4,7 @@ import { Fragment } from "react"; import { ChevronRight } from "lucide-react"; -import { useUserStore } from "@/shared/lib"; +import { dayjs, useUserStore } from "@/shared/lib"; import type { ElaprDocPrgrsClientResponseDto } from "@/shared/model"; import { SectionCollapsible } from "@/shared/ui"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/shared/ui/tooltip"; @@ -20,7 +20,7 @@ interface ElaprDocPrgrsStatusProps { } function ElaprDocPrgrsStep({ item }: { item: ElaprDocPrgrsClientResponseDto }) { - const status = getApproverStatus(item.atrzPrgrsSttsComCd); + const status = getApproverStatus(item.atrzPrgrsSttsComCd, item.atrzSeComCd); const isRejected = item.atrzPrgrsSttsComCd === REJECT_STATUS_CD; const rjctRsn = item.rjctRsn?.trim(); const metaParts = [item.ognzNm, item.jbpsSeNm].filter(Boolean); @@ -28,7 +28,7 @@ function ElaprDocPrgrsStep({ item }: { item: ElaprDocPrgrsClientResponseDto }) { const statusBadge = ( +
{isRejected && rjctRsn ? ( {statusBadge} @@ -51,11 +51,16 @@ function ElaprDocPrgrsStep({ item }: { item: ElaprDocPrgrsClientResponseDto }) { )}
- [{item.atrzSeComNm || "-"}] - {item.aprvrNm || item.aprvrUuid || "-"} +

+ [{item.atrzSeComNm || "-"}]{" "} + {item.aprvrNm || item.aprvrUuid || "-"} +

{metaParts.length > 0 && ( - {metaParts.join(" · ")} + {metaParts.join(" · ")} + )} + {item.atrzDt && ( + {dayjs(item.atrzDt).format("YYYY-MM-DD")} )}
@@ -84,17 +89,19 @@ function ElaprDocPrgrsStatus({ elaprDocNo }: ElaprDocPrgrsStatusProps) { } if (steps.length === 0) { - return
결재 정보가 없습니다.
; + return null; } return ( -
+
{steps.map((item, index) => ( -
- {index > 0 && } -
+ {index > 0 && ( +
+ {} +
+ )}
))} diff --git a/apps/as/src/pages/instl-sncn/model/columns.tsx b/apps/as/src/pages/instl-sncn/model/columns.tsx index ee9ddb055..cca857fd9 100644 --- a/apps/as/src/pages/instl-sncn/model/columns.tsx +++ b/apps/as/src/pages/instl-sncn/model/columns.tsx @@ -73,7 +73,7 @@ function buildProgressBadges(prgrsSttsComCd: string, techRplyHstryYn: "Y" | "N") ]; } - if (prgrsSttsComCd === "TA") { + if (prgrsSttsComCd === "TA" || prgrsSttsComCd === "TB") { return [ { label: MAIN_STEP_LABELS.apply, state: "completed" }, { label: MAIN_STEP_LABELS.envoReview, state: "completed" }, From d79e0e585a3ae0a54a9d6d3cf66c387c797a9a94 Mon Sep 17 00:00:00 2001 From: bicochan Date: Mon, 10 Aug 2026 17:57:39 +0900 Subject: [PATCH 4/4] =?UTF-8?q?[as]=20feat:=20=ED=96=89=EC=A0=95=EC=A7=80?= =?UTF-8?q?=EC=9B=90=20=EC=97=85=EB=AC=B4=EB=B3=84=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=82=B4=20=EC=A7=84=ED=96=89?= =?UTF-8?q?=EC=83=81=ED=83=9C=20=EC=84=B9=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../elapr/ui/elapr-approval-dialog.tsx | 4 +- .../elapr/ui/sortable-prgrs-stts-row.tsx | 4 +- .../model/sewer-bsc-plan-interface.ts | 2 + .../src/pages/design-cnstn/model/columns.tsx | 6 ++ .../design-cnstn/ui/design-form-page.tsx | 9 ++ .../design-cnstn/ui/design-view-page.tsx | 20 +++-- .../src/pages/fnrs-cnsltn/model/columns.tsx | 9 ++ .../pages/fnrs-cnsltn/ui/fnrs-form-page.tsx | 9 ++ .../pages/fnrs-cnsltn/ui/fnrs-view-page.tsx | 29 +++--- .../as/src/pages/instl-sncn/model/columns.tsx | 10 +++ .../pages/instl-sncn/ui/instl-form-page.tsx | 9 ++ .../pages/instl-sncn/ui/instl-view-page.tsx | 9 +- .../pages/sewer-bsc-plan/model/columns.tsx | 8 ++ .../ui/sewer-bsc-plan-form-page.tsx | 9 ++ .../ui/sewer-bsc-plan-view-page.tsx | 33 ++++--- apps/as/src/shared/model/index.ts | 1 + apps/as/src/shared/model/pbadms-sprt.ts | 17 ++++ apps/as/src/widgets/pbadms-sprt/index.ts | 1 + .../pbadms-sprt/lib/progress-status-utils.ts | 59 +++++++++++++ .../ui/progress-status-section.tsx | 88 +++++++++++++++++++ 20 files changed, 304 insertions(+), 32 deletions(-) create mode 100644 apps/as/src/widgets/pbadms-sprt/lib/progress-status-utils.ts create mode 100644 apps/as/src/widgets/pbadms-sprt/ui/progress-status-section.tsx diff --git a/apps/as/src/entities/elapr/ui/elapr-approval-dialog.tsx b/apps/as/src/entities/elapr/ui/elapr-approval-dialog.tsx index c4cb3956d..ad9abfa3e 100644 --- a/apps/as/src/entities/elapr/ui/elapr-approval-dialog.tsx +++ b/apps/as/src/entities/elapr/ui/elapr-approval-dialog.tsx @@ -314,8 +314,8 @@ function ElaprApprovalDialog({ - - + + diff --git a/apps/as/src/entities/elapr/ui/sortable-prgrs-stts-row.tsx b/apps/as/src/entities/elapr/ui/sortable-prgrs-stts-row.tsx index 601d272f2..3c2bb457a 100644 --- a/apps/as/src/entities/elapr/ui/sortable-prgrs-stts-row.tsx +++ b/apps/as/src/entities/elapr/ui/sortable-prgrs-stts-row.tsx @@ -73,14 +73,14 @@ function SortablePrgrsSttsRow({ const isDcarbable = isPrgrsSttsRowDcarbable(row); const rowDisabled = isLocked && !isEditing; const atrzSeLabel = row.atrzSeComNm || findCodeLabel(atrzSeCodes, row.atrzSeComCd); - const status = getApproverStatus(row.atrzPrgrsSttsComCd); + const status = getApproverStatus(row.atrzPrgrsSttsComCd, row.atrzSeComCd); const isRejectedRow = row.atrzPrgrsSttsComCd === "ATRZ_PRGRS_004"; const rjctRsn = row.rjctRsn?.trim(); const statusBadge = (
+ {initialData?.detDto?.designCnstnDocNo && ( + + )} diff --git a/apps/as/src/pages/design-cnstn/ui/design-view-page.tsx b/apps/as/src/pages/design-cnstn/ui/design-view-page.tsx index c900ab530..cc4315025 100644 --- a/apps/as/src/pages/design-cnstn/ui/design-view-page.tsx +++ b/apps/as/src/pages/design-cnstn/ui/design-view-page.tsx @@ -6,10 +6,12 @@ import { useUserStore } from "@/shared/lib"; import { useDesignCnstnMng } from "@/entities/design-cnstn"; import { ElaprDocPrgrsStatus } from "@/entities/elapr"; import { useRvwMnpwMngLoginUserList } from "@/entities/rvw-mnpw"; +import { ProgressStatusSection } from "@/widgets/pbadms-sprt"; import { Skeleton } from "@common/components"; import { needsRoleUser01AtrzResolve } from "../lib/button-config"; import { getEditableReviewStep } from "../lib/review-step-utils"; +import { PROGRESS_STATUS_COLUMNS } from "../model/columns"; import { FloatingActionButtons } from "./components/floating-action-buttons"; import { AttachmentsSection } from "./sections/attachments-section"; @@ -64,11 +66,14 @@ function DesignViewPage({ id }: DesignViewPageProps) { return
상세 정보를 찾을 수 없습니다.
; } - const detDto = data.detDto; - const bizSclList = data.bizSclList ?? []; - const esntlFileList = data.esntlFileList ?? []; - const etcFileList = data.etcFileList ?? []; - const rvwList = data.rvwList ?? []; + const { + detDto, + bizSclList = [], + esntlFileList = [], + etcFileList = [], + rvwList = [], + sttsChgHstryList = [], + } = data; const editableReviewStep = getEditableReviewStep( userInfo?.dtlInstCd, @@ -77,6 +82,11 @@ function DesignViewPage({ id }: DesignViewPageProps) { return (
+ diff --git a/apps/as/src/pages/fnrs-cnsltn/model/columns.tsx b/apps/as/src/pages/fnrs-cnsltn/model/columns.tsx index a29e2096c..fff55d21a 100644 --- a/apps/as/src/pages/fnrs-cnsltn/model/columns.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/model/columns.tsx @@ -17,6 +17,15 @@ const MAIN_STEP_LABELS = { reply: "검토결과 회신", } as const; +export const PROGRESS_STATUS_COLUMNS = [ + { label: "재원협의 신청 (시군)", sttsComCd: "ST" }, + { label: "재원협의 신청 (시도)", sttsComCd: "LE" }, + { label: "환경청 검토", sttsComCd: "ER" }, + { label: "기술검토", sttsComCd: "TE" }, + { label: "기술검토 회신", sttsComCd: "TP" }, + { label: "환경청 검토 결과 회신", sttsComCd: "EP" }, +]; + type BadgeState = "completed" | "current" | "pending"; interface ProgressBadge { 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 5a4222553..e189e28f6 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 @@ -30,6 +30,7 @@ import { isFormChecklistComplete, isFormEsntlAtchComplete, PrivacyConsentSection, + ProgressStatusSection, recalculateFnrsSharTotals, SplmntDmndFormSection, toFnrsSharSaveList, @@ -43,6 +44,7 @@ import { formatTaskSeComCdForApi, } from "../lib/fnrs-cnsltn-regist-schema"; import { getCreateDefaultValues, mapDetailToFormData } from "../lib/form-data-mapper"; +import { PROGRESS_STATUS_COLUMNS } from "../model/columns"; import { BasicInfoFormSection } from "./sections/basic-info-form-section"; interface FnrsFormPageProps { @@ -270,6 +272,13 @@ function FnrsFormPage({ id, mode, initialData, createDefaults }: FnrsFormPagePro return ( + {initialData?.detDto?.fnrsCnsltnDocNo && ( + + )} diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-view-page.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-view-page.tsx index 650383f9f..6fa957d44 100644 --- a/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-view-page.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-view-page.tsx @@ -6,12 +6,13 @@ import { useUserStore } from "@/shared/lib"; import { ElaprDocPrgrsStatus } from "@/entities/elapr"; import { useFnrsCnsltnMng } from "@/entities/fnrs-cnsltn"; import { useRvwMnpwMngLoginUserList } from "@/entities/rvw-mnpw"; -import { SupplementDemandSection } from "@/widgets/pbadms-sprt"; +import { ProgressStatusSection, SupplementDemandSection } from "@/widgets/pbadms-sprt"; import { Skeleton } from "@common/components"; import { needsRoleUser01AtrzResolve } from "../lib/button-config"; import { getEditableReviewStep } from "../lib/review-step-utils"; import { EMPTY_CKLST_RESULT_LIST, useChecklistFormState } from "../lib/use-checklist-form-state"; +import { PROGRESS_STATUS_COLUMNS } from "../model/columns"; import { FloatingActionButtons } from "./components/floating-action-buttons"; import { AttachmentsSection } from "./sections/attachments-section"; @@ -71,15 +72,18 @@ function FnrsViewPage({ id }: FnrsViewPageProps) { return
상세 정보를 찾을 수 없습니다.
; } - const detDto = data.detDto; - const bizSclList = data.bizSclList ?? []; - const bizCstList = data.bizCstList ?? []; - const cklstResultList = data.cklstResultList ?? []; - const esntlFileList = data.esntlFileList ?? []; - const etcFileList = data.etcFileList ?? []; - const rvwList = data.rvwList ?? []; - const splmntDmndList = data.splmntDmndList ?? []; - const fnrsSharList = data.fnrsSharList ?? []; + const { + detDto, + bizSclList = [], + bizCstList = [], + cklstResultList = [], + esntlFileList = [], + etcFileList = [], + rvwList = [], + splmntDmndList = [], + fnrsSharList = [], + sttsChgHstryList = [], + } = data; const editableReviewStep = getEditableReviewStep( userInfo?.dtlInstCd, @@ -88,6 +92,11 @@ function FnrsViewPage({ id }: FnrsViewPageProps) { return (
+ diff --git a/apps/as/src/pages/instl-sncn/model/columns.tsx b/apps/as/src/pages/instl-sncn/model/columns.tsx index cca857fd9..2dcca5c58 100644 --- a/apps/as/src/pages/instl-sncn/model/columns.tsx +++ b/apps/as/src/pages/instl-sncn/model/columns.tsx @@ -17,6 +17,16 @@ const MAIN_STEP_LABELS = { reply: "검토결과 회신", } as const; +export const PROGRESS_STATUS_COLUMNS = [ + { label: "설치인가 신청 (시군)", sttsComCd: "ST" }, + { label: "설치인가 신청 (시도)", sttsComCd: "LE" }, + { label: "환경청 검토", sttsComCd: "ER" }, + { label: "기술검토", sttsComCd: "TE" }, + { label: "기술검토 회신", sttsComCd: "TP" }, + { label: "검토결과 회신", sttsComCd: "EP" }, + { label: "설치인가 승인", sttsComCd: "TA" }, +]; + type BadgeState = "completed" | "current" | "pending"; interface ProgressBadge { 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 bc248e3b2..c2bd574b9 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 @@ -25,6 +25,7 @@ import { isFormChecklistComplete, isFormEsntlAtchComplete, PrivacyConsentSection, + ProgressStatusSection, SplmntDmndFormSection, } from "@/widgets/pbadms-sprt"; import { Button } from "@common/components"; @@ -35,6 +36,7 @@ import { type InstlSncnRegistFormData, instlSncnRegistSchema, } from "../lib/instl-sncn-regist-schema"; +import { PROGRESS_STATUS_COLUMNS } from "../model/columns"; import { BasicInfoFormSection } from "./sections/basic-info-form-section"; interface InstlFormPageProps { @@ -228,6 +230,13 @@ function InstlFormPage({ id, mode, initialData, createDefaults }: InstlFormPageP return ( + {initialData?.detDto.instlSncnDocNo && ( + + )} diff --git a/apps/as/src/pages/instl-sncn/ui/instl-view-page.tsx b/apps/as/src/pages/instl-sncn/ui/instl-view-page.tsx index 88677bbf3..d8f637f59 100644 --- a/apps/as/src/pages/instl-sncn/ui/instl-view-page.tsx +++ b/apps/as/src/pages/instl-sncn/ui/instl-view-page.tsx @@ -6,12 +6,13 @@ import { useUserStore } from "@/shared/lib"; import { ElaprDocPrgrsStatus } from "@/entities/elapr"; import { useInstlSncnDetail } from "@/entities/instl-sncn"; import { useRvwMnpwMngLoginUserList } from "@/entities/rvw-mnpw"; -import { SupplementDemandSection } from "@/widgets/pbadms-sprt"; +import { ProgressStatusSection, SupplementDemandSection } from "@/widgets/pbadms-sprt"; import { Skeleton } from "@common/components"; import { needsRoleUser01AtrzResolve } from "../lib/button-config"; import { getEditableReviewStep } from "../lib/review-step-utils"; import { EMPTY_CKLST_RESULT_LIST, useChecklistFormState } from "../lib/use-checklist-form-state"; +import { PROGRESS_STATUS_COLUMNS } from "../model/columns"; import { FloatingActionButtons } from "./components/floating-action-buttons"; import { AttachmentsSection } from "./sections/attachments-section"; @@ -79,6 +80,7 @@ function InstlViewPage({ id }: InstlViewPageProps) { etcFileList, rvwList = [], splmntDmndList = [], + sttsChgHstryList = [], } = data; const editableReviewStep = getEditableReviewStep( @@ -88,6 +90,11 @@ function InstlViewPage({ id }: InstlViewPageProps) { return (
+ diff --git a/apps/as/src/pages/sewer-bsc-plan/model/columns.tsx b/apps/as/src/pages/sewer-bsc-plan/model/columns.tsx index 9ad252381..4dc1af0c6 100644 --- a/apps/as/src/pages/sewer-bsc-plan/model/columns.tsx +++ b/apps/as/src/pages/sewer-bsc-plan/model/columns.tsx @@ -17,6 +17,14 @@ const MAIN_STEP_LABELS = { reply: "검토결과 회신", } as const; +export const PROGRESS_STATUS_COLUMNS = [ + { label: "기본계획 신청 (시군)", sttsComCd: "LE" }, + { label: "환경청 검토", sttsComCd: "ER" }, + { label: "기술검토", sttsComCd: "TE" }, + { label: "기술검토 회신", sttsComCd: "TP" }, + { label: "횐경청 검토 결과 회신", sttsComCd: "EP" }, +]; + type BadgeState = "completed" | "current" | "pending"; interface ProgressBadge { diff --git a/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-form-page.tsx b/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-form-page.tsx index 03c605ebe..ca8f2c9d0 100644 --- a/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-form-page.tsx +++ b/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-form-page.tsx @@ -25,6 +25,7 @@ import { isFormChecklistComplete, isFormEsntlAtchComplete, PrivacyConsentSection, + ProgressStatusSection, SplmntDmndFormSection, } from "@/widgets/pbadms-sprt"; import { Button } from "@common/components"; @@ -39,6 +40,7 @@ import { type SewerBscPlanRegistFormData, sewerBscPlanRegistSchema, } from "../lib/sewer-bsc-plan-regist-schema"; +import { PROGRESS_STATUS_COLUMNS } from "../model/columns"; import { BasicInfoFormSection } from "./sections/basic-info-form-section"; import { BizCstMatrixFormSection } from "./sections/biz-cst-matrix-form-section"; @@ -242,6 +244,13 @@ function SewerBscPlanFormPage({ return ( + {initialData?.detDto?.sewerBscPlanDocNo && ( + + )} diff --git a/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-view-page.tsx b/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-view-page.tsx index 9fd161733..e04483925 100644 --- a/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-view-page.tsx +++ b/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-view-page.tsx @@ -6,12 +6,13 @@ import { useUserStore } from "@/shared/lib"; import { ElaprDocPrgrsStatus } from "@/entities/elapr"; import { useRvwMnpwMngLoginUserList } from "@/entities/rvw-mnpw"; import { useSewerBscPlanDetails } from "@/entities/sewer-bsc-plan"; -import { SupplementDemandSection } from "@/widgets/pbadms-sprt"; +import { ProgressStatusSection, SupplementDemandSection } from "@/widgets/pbadms-sprt"; import { Skeleton } from "@common/components"; import { needsRoleUser01AtrzResolve } from "../lib/button-config"; import { getEditableReviewStep } from "../lib/review-step-utils"; import { EMPTY_CKLST_RESULT_LIST, useChecklistFormState } from "../lib/use-checklist-form-state"; +import { PROGRESS_STATUS_COLUMNS } from "../model/columns"; import { FloatingActionButtons } from "./components/floating-action-buttons"; import { AttachmentsSection } from "./sections/attachments-section"; @@ -74,17 +75,20 @@ function SewerBscPlanViewPage({ id, propChgCycl }: SewerBscPlanViewPageProps) { return
상세 정보를 찾을 수 없습니다.
; } - const detDto = data.detDto; - const activeDtlDto = data.activeDtlDto; - const otlnList = data.otlnList ?? []; - const bizCstList = data.bizCstList ?? []; - const fnrsCstList = data.fnrsCstList ?? []; - const tmplntList = data.tmplntList ?? []; - const cklstResultRows = data.cklstResultRows ?? []; - const esntlFileList = data.esntlFileList ?? []; - const etcFileList = data.etcFileList ?? []; - const rvwOpnnList = data.rvwOpnnList ?? []; - const splmntDmndList = data.splmntDmndList ?? []; + const { + detDto, + activeDtlDto, + otlnList = [], + bizCstList = [], + fnrsCstList = [], + tmplntList = [], + cklstResultRows = [], + esntlFileList = [], + etcFileList = [], + rvwOpnnList = [], + splmntDmndList = [], + sttsChgHstryList = [], + } = data; const editableReviewStep = getEditableReviewStep( userInfo?.dtlInstCd, @@ -93,6 +97,11 @@ function SewerBscPlanViewPage({ id, propChgCycl }: SewerBscPlanViewPageProps) { return (
+ diff --git a/apps/as/src/shared/model/index.ts b/apps/as/src/shared/model/index.ts index bdf339145..75c66834d 100644 --- a/apps/as/src/shared/model/index.ts +++ b/apps/as/src/shared/model/index.ts @@ -38,6 +38,7 @@ export type { CklstResultSaveBase, CklstRvwRsltTreeDto, DocPrgrsUpdateRequestDto, + DocSttsChgHstryResponseDto, ElaprDocPrgrsClientResponseDto, EsntlAtchFileMngTreeResponseDto, EsntlAtchFileSaveBase, diff --git a/apps/as/src/shared/model/pbadms-sprt.ts b/apps/as/src/shared/model/pbadms-sprt.ts index 67b0b831e..272e6d110 100644 --- a/apps/as/src/shared/model/pbadms-sprt.ts +++ b/apps/as/src/shared/model/pbadms-sprt.ts @@ -155,6 +155,22 @@ export interface ElaprDocPrgrsClientResponseDto { dcarbYn?: string; } +/** 문서 상태 변경 이력 응답 DTO */ +export interface DocSttsChgHstryResponseDto { + chgHstrySn: number; + docSeComCd: string; + docSeComNm: string; + docNo: string; + chgBfrSttsComCd: string; + chgBfrSttsComNm: string; + chgAftrSttsComCd: string; + chgAftrSttsComNm: string; + rmrk: string; + rgtrUuid: string; + rgtrNm: string; + regDt: string; +} + /** 사업규모 저장 공통 필드 */ export interface BzScaleSaveBase { cnstpSeCd?: string; @@ -244,4 +260,5 @@ export interface PbadmsMngDetResponseBase item.chgAftrSttsComCd === sttsComCd) + .map((item) => ({ + rgtrNm: item.rgtrNm, + regDt: item.regDt, + })); +} + +function findTechReviewProgressItem( + elaprDocPrgrsList: ElaprDocPrgrsClientResponseDto[], +): ProgressStatusItem[] { + return elaprDocPrgrsList + .filter( + (item) => + item.atrzSeComCd === TECH_REVIEW_ATRZ_SE_COM_CD && + item.atrzPrgrsSttsComCd === TECH_REVIEW_ATRZ_PRGRS_STTS_COM_CD, + ) + .map((item) => ({ + rgtrNm: item.aprvrNm ?? "", + regDt: item.atrzDt ?? "", + })); +} + +function resolveProgressStatusItem( + sttsComCd: string, + sttsChgHstryList: DocSttsChgHstryResponseDto[], + elaprDocPrgrsList: ElaprDocPrgrsClientResponseDto[], +): ProgressStatusItem[] { + if (sttsComCd === TECH_REVIEW_STTS_COM_CD) { + return findTechReviewProgressItem(elaprDocPrgrsList); + } + + return findProgressStatusItem(sttsChgHstryList, sttsComCd); +} + +export { + findProgressStatusItem, + findTechReviewProgressItem, + resolveProgressStatusItem, + TECH_REVIEW_STTS_COM_CD, +}; diff --git a/apps/as/src/widgets/pbadms-sprt/ui/progress-status-section.tsx b/apps/as/src/widgets/pbadms-sprt/ui/progress-status-section.tsx new file mode 100644 index 000000000..4ce4d8a0a --- /dev/null +++ b/apps/as/src/widgets/pbadms-sprt/ui/progress-status-section.tsx @@ -0,0 +1,88 @@ +"use client"; + +import dayjs from "dayjs"; + +import { DocSttsChgHstryResponseDto } from "@/shared/model/pbadms-sprt"; +import { SectionCollapsible } from "@/shared/ui"; +import { useElaprDocPrgrsByDocNo } from "@/entities/elapr"; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@common/components"; + +import { resolveProgressStatusItem } from "../lib/progress-status-utils"; + +interface ProgressStatusColumn { + label: string; + sttsComCd: string; +} + +interface ProgressStatusItem { + rgtrNm: string; + regDt: string; +} + +interface ProgressStatusSectionProps { + columns: ProgressStatusColumn[]; + sttsChgHstryList: DocSttsChgHstryResponseDto[]; + elaprDocNo: string; +} + +interface ProgressStatusCellProps { + items: ProgressStatusItem[]; +} + +function ProgressStatusCell({ items }: ProgressStatusCellProps) { + if (items.length === 0) return "-"; + + return ( +
+ {items.map((item, index) => ( +
+ {item.rgtrNm || "-"} + {item.regDt && ( +

+ {dayjs(item.regDt).format("YYYY-MM-DD")} +

+ )} +
+ ))} +
+ ); +} + +function ProgressStatusSection({ + columns, + sttsChgHstryList, + elaprDocNo, +}: ProgressStatusSectionProps) { + const { data: elaprDocPrgrsList = [] } = useElaprDocPrgrsByDocNo(elaprDocNo); + + return ( + + + + + {columns.map((column) => ( + {column.label} + ))} + + + + + {columns.map((column) => ( + + + + ))} + + +
+
+ ); +} + +export { ProgressStatusSection };