217 lines
6.6 KiB
TypeScript
217 lines
6.6 KiB
TypeScript
"use client";
|
|
|
|
import { Fragment } from "react";
|
|
|
|
import { createColumnHelper } from "@tanstack/react-table";
|
|
|
|
import { dayjs } from "@/shared/lib";
|
|
import type { FnrsCnsltnMngResponseDto } from "@/entities/fnrs-cnsltn";
|
|
import { Badge } from "@common/components";
|
|
|
|
const columnHelper = createColumnHelper<FnrsCnsltnMngResponseDto>();
|
|
|
|
const MAIN_STEP_LABELS = {
|
|
apply: "재원협의 신청",
|
|
envoReview: "재원협의 검토",
|
|
techReview: "기술검토",
|
|
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 {
|
|
label: string;
|
|
state: BadgeState;
|
|
}
|
|
|
|
function buildProgressBadges(prgrsSttsComCd: string, techRplyHstryYn: "Y" | "N"): ProgressBadge[] {
|
|
if (prgrsSttsComCd === "SV") {
|
|
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" },
|
|
];
|
|
}
|
|
|
|
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.apply, state: "completed" },
|
|
{ label: MAIN_STEP_LABELS.envoReview, state: "current" },
|
|
{ label: MAIN_STEP_LABELS.techReview, state: "pending" },
|
|
{ label: MAIN_STEP_LABELS.reply, state: "pending" },
|
|
];
|
|
}
|
|
|
|
if (["FV", "ER", "AC", "TE", "RB", "RA", "AV", "EV", "RK", "RR", "SL"].includes(prgrsSttsComCd)) {
|
|
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" || 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: 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 getProgressStatusBadge(prgrsSttsComCd?: string | null) {
|
|
if (prgrsSttsComCd === "SL") {
|
|
return <Badge color="orange">보완요청</Badge>;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function getBadgeColor(state: BadgeState) {
|
|
switch (state) {
|
|
case "completed":
|
|
return "green";
|
|
case "current":
|
|
return "blue";
|
|
case "pending":
|
|
return "lightGray";
|
|
}
|
|
}
|
|
|
|
function getBadgeStateText(state: BadgeState) {
|
|
switch (state) {
|
|
case "completed":
|
|
return "완료";
|
|
case "current":
|
|
return "진행중";
|
|
case "pending":
|
|
return "대기";
|
|
}
|
|
}
|
|
|
|
function formatOptional(value: string | null | undefined) {
|
|
return value?.trim() ? value : "-";
|
|
}
|
|
|
|
interface ProgressStepBadgeProps {
|
|
prgrsSttsComCd: string;
|
|
techRplyHstryYn: "Y" | "N";
|
|
}
|
|
|
|
function ProgressStepBadge({ prgrsSttsComCd, techRplyHstryYn }: ProgressStepBadgeProps) {
|
|
const badges = buildProgressBadges(prgrsSttsComCd, techRplyHstryYn);
|
|
|
|
return (
|
|
<div className="flex flex-wrap items-center justify-start">
|
|
{badges.map((badge, index) => (
|
|
<Fragment key={badge.label}>
|
|
{index > 0 && <span className="mx-2">></span>}
|
|
<Badge color={getBadgeColor(badge.state)}>
|
|
{badge.label}({getBadgeStateText(badge.state)})
|
|
</Badge>
|
|
</Fragment>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function createFnrsCnsltnColumns() {
|
|
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: ({ row, getValue }) => (
|
|
<>
|
|
{getProgressStatusBadge(row.original.prgrsSttsComCd)} {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 || ""}
|
|
techRplyHstryYn={row.original.techRplyHstryYn || "N"}
|
|
/>
|
|
),
|
|
}),
|
|
columnHelper.accessor("regDt", {
|
|
header: "신청일",
|
|
meta: { align: "center" },
|
|
cell: ({ getValue }) => {
|
|
const value = getValue();
|
|
return value ? dayjs(value).format("YYYY-MM-DD") : "-";
|
|
},
|
|
}),
|
|
];
|
|
}
|