[as] feat: 결재현황 ui 수정

This commit is contained in:
2026-08-10 15:27:53 +09:00
parent 0459c0b231
commit dbda77a75b
3 changed files with 52 additions and 21 deletions
@@ -6,11 +6,26 @@ export interface ApproverStatusConfig {
}
export const APPROVER_STATUS_MAP: Record<string, ApproverStatusConfig> = {
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",
}
);
@@ -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 = (
<span
className={cn(
"inline-flex items-center rounded-sm px-2 py-1 text-lg font-medium",
"inline-flex items-center rounded-sm px-4 py-1.5 text-2xl font-semibold",
status.badgeClass,
isRejected && rjctRsn && "cursor-help underline decoration-dotted underline-offset-4",
)}
@@ -38,7 +38,7 @@ function ElaprDocPrgrsStep({ item }: { item: ElaprDocPrgrsClientResponseDto }) {
);
return (
<div className="flex min-w-[12rem] flex-1 flex-col items-center gap-3 p-4 text-center">
<div className="card card-border flex min-w-[12rem] flex-1 flex-col items-center gap-4 border p-6 text-center">
{isRejected && rjctRsn ? (
<Tooltip>
<TooltipTrigger asChild>{statusBadge}</TooltipTrigger>
@@ -51,11 +51,16 @@ function ElaprDocPrgrsStep({ item }: { item: ElaprDocPrgrsClientResponseDto }) {
)}
<div className="flex flex-col items-center gap-1">
<div className="flex items-center gap-2">
<span className="text-xl text-muted-foreground">[{item.atrzSeComNm || "-"}]</span>
<span className="text-xl font-semibold">{item.aprvrNm || item.aprvrUuid || "-"}</span>
<p className="text-2xl font-semibold text-foreground">
<span className="text-muted-foreground">[{item.atrzSeComNm || "-"}]</span>{" "}
{item.aprvrNm || item.aprvrUuid || "-"}
</p>
</div>
{metaParts.length > 0 && (
<span className="text-base text-gray-500">{metaParts.join(" · ")}</span>
<span className="text-lg text-gray-500">{metaParts.join(" · ")}</span>
)}
{item.atrzDt && (
<span className="text-lg text-gray-500">{dayjs(item.atrzDt).format("YYYY-MM-DD")}</span>
)}
</div>
</div>
@@ -84,17 +89,19 @@ function ElaprDocPrgrsStatus({ elaprDocNo }: ElaprDocPrgrsStatusProps) {
}
if (steps.length === 0) {
return <div className="py-8 text-center text-xl text-gray-500">결재 정보가 없습니다.</div>;
return null;
}
return (
<SectionCollapsible title="결재현황">
<div className="flex flex-wrap items-stretch justify-start gap-4 overflow-x-auto">
<div className="flex flex-wrap items-stretch justify-start gap-4 overflow-x-auto p-4">
{steps.map((item, index) => (
<Fragment key={item.elaprPrgrsId ?? `${item.atrzSeqNo}-${item.aprvrUuid ?? index}`}>
<div className="flex items-center">
{index > 0 && <ChevronRight className="size-8 text-muted-foreground" />}
</div>
{index > 0 && (
<div className="flex items-center">
{<ChevronRight className="size-8 text-muted-foreground" />}
</div>
)}
<ElaprDocPrgrsStep item={item} />
</Fragment>
))}
@@ -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" },