162 lines
4.8 KiB
TypeScript
162 lines
4.8 KiB
TypeScript
"use client";
|
|
|
|
import { Fragment } from "react";
|
|
|
|
import { createColumnHelper } from "@tanstack/react-table";
|
|
|
|
import { dayjs } from "@/shared/lib";
|
|
import type { DesignCnstnMngResponseDto } from "@/entities/design-cnstn";
|
|
import { Badge } from "@common/components";
|
|
|
|
const columnHelper = createColumnHelper<DesignCnstnMngResponseDto>();
|
|
|
|
const MAIN_STEP_LABELS = {
|
|
save: "저장",
|
|
apply: "신청완료",
|
|
review: "설계자문 검토",
|
|
reply: "설계검토 회신",
|
|
} as const;
|
|
|
|
const REVIEW_STATUS_CODES = new Set(["CS", "CR"]);
|
|
|
|
type BadgeState = "completed" | "current" | "pending" | "action";
|
|
|
|
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;
|
|
|
|
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.reply, state: "pending" },
|
|
];
|
|
}
|
|
|
|
if (prgrsSttsComCd === "CT") {
|
|
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.reply, state: "pending" },
|
|
];
|
|
}
|
|
|
|
if (prgrsSttsComCd === "CP" || prgrsSttsComCd === "EP") {
|
|
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" },
|
|
];
|
|
}
|
|
|
|
return [{ label: prgrsSttsCdNm || prgrsSttsComCd || "-", state: "current" }];
|
|
}
|
|
|
|
function getBadgeColor(state: BadgeState) {
|
|
switch (state) {
|
|
case "completed":
|
|
return "green";
|
|
case "current":
|
|
return "blue";
|
|
case "pending":
|
|
return "lightGray";
|
|
case "action":
|
|
return "orange";
|
|
}
|
|
}
|
|
|
|
function formatOptional(value: string | undefined) {
|
|
return value?.trim() ? value : "-";
|
|
}
|
|
|
|
interface ProgressStepBadgeProps {
|
|
prgrsSttsComCd: string;
|
|
prgrsSttsCdNm: string;
|
|
}
|
|
|
|
function ProgressStepBadge({ prgrsSttsComCd, prgrsSttsCdNm }: ProgressStepBadgeProps) {
|
|
const badges = buildProgressBadges(prgrsSttsComCd, prgrsSttsCdNm);
|
|
|
|
return (
|
|
<div className="flex flex-wrap items-center justify-start">
|
|
{badges.map((badge, index) => (
|
|
<Fragment key={`${badge.label}-${index}`}>
|
|
{index > 0 && <span className="mx-2">></span>}
|
|
<Badge color={getBadgeColor(badge.state)}>{badge.label}</Badge>
|
|
</Fragment>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function createDesignCnstnColumns() {
|
|
return [
|
|
columnHelper.accessor("sido", {
|
|
header: "시도",
|
|
meta: { align: "center" },
|
|
cell: ({ getValue }) => formatOptional(getValue()),
|
|
}),
|
|
columnHelper.accessor("gugun", {
|
|
header: "시군구",
|
|
meta: { align: "center" },
|
|
cell: ({ getValue }) => formatOptional(getValue()),
|
|
}),
|
|
columnHelper.accessor("bizNm", {
|
|
header: "사업명",
|
|
meta: { align: "left" },
|
|
cell: ({ getValue }) => formatOptional(getValue()),
|
|
}),
|
|
columnHelper.accessor("taskSeCdNm", {
|
|
header: "업무구분",
|
|
meta: { align: "center" },
|
|
cell: ({ row }) => formatOptional(row.original.taskSeCdNm || row.original.taskSeComCd),
|
|
}),
|
|
columnHelper.accessor("aplcntNm", {
|
|
header: "담당자",
|
|
meta: { align: "center" },
|
|
cell: ({ getValue }) => formatOptional(getValue()),
|
|
}),
|
|
columnHelper.accessor("envoSeCdNm", {
|
|
header: "해당기관",
|
|
meta: { align: "center" },
|
|
cell: ({ getValue }) => formatOptional(getValue()),
|
|
}),
|
|
columnHelper.display({
|
|
id: "progress",
|
|
header: "진행상황",
|
|
meta: { align: "center" },
|
|
cell: ({ row }) => (
|
|
<ProgressStepBadge
|
|
prgrsSttsComCd={row.original.prgrsSttsComCd || ""}
|
|
prgrsSttsCdNm={row.original.prgrsSttsCdNm || ""}
|
|
/>
|
|
),
|
|
}),
|
|
columnHelper.accessor("regDt", {
|
|
header: "신청일",
|
|
meta: { align: "center" },
|
|
cell: ({ getValue }) => {
|
|
const value = getValue();
|
|
return value ? dayjs(value).format("YYYY-MM-DD") : "-";
|
|
},
|
|
}),
|
|
];
|
|
}
|