Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ffc02e887 | ||
|
|
cbacb27bb1 | ||
|
|
5331e10c96 |
@@ -98,7 +98,7 @@ const DomesticPopulationTab = ({ tab, statsYr, onFileButtonClick }: Props) => {
|
|||||||
enableSort={false}
|
enableSort={false}
|
||||||
getGridRef={rightGridRef} // ← 추가
|
getGridRef={rightGridRef} // ← 추가
|
||||||
onDataCellClick={({ row, fieldName }) => {
|
onDataCellClick={({ row, fieldName }) => {
|
||||||
if (fieldName === "mpinCd") return;
|
if (fieldName === "sbstAdmdstCd") return;
|
||||||
if (fieldName === "admdstCd") {
|
if (fieldName === "admdstCd") {
|
||||||
const gridView = rightGridRef.current?.gridView as
|
const gridView = rightGridRef.current?.gridView as
|
||||||
| GridViewWithEditCommit
|
| GridViewWithEditCommit
|
||||||
@@ -108,7 +108,7 @@ const DomesticPopulationTab = ({ tab, statsYr, onFileButtonClick }: Props) => {
|
|||||||
tab.setRightRowData((prev) =>
|
tab.setRightRowData((prev) =>
|
||||||
prev.map((r) =>
|
prev.map((r) =>
|
||||||
r.admdstCd === row.admdstCd
|
r.admdstCd === row.admdstCd
|
||||||
? { ...r, mpinCd: String(row.admdstCd ?? "") }
|
? { ...r, sbstAdmdstCd: String(row.admdstCd ?? "") }
|
||||||
: r,
|
: r,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -117,7 +117,7 @@ const DomesticPopulationTab = ({ tab, statsYr, onFileButtonClick }: Props) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onCellDblClick={({ row, fieldName }) => {
|
onCellDblClick={({ row, fieldName }) => {
|
||||||
if (fieldName !== "mpinCd") return;
|
if (fieldName !== "sbstAdmdstCd") return;
|
||||||
void tab.handleRightRowClick(fromGridRow<DomesticPopulationItem>(row), statsYr);
|
void tab.handleRightRowClick(fromGridRow<DomesticPopulationItem>(row), statsYr);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ const ForeignPopulationTab = ({ tab, statsYr, onFileButtonClick }: Props) => {
|
|||||||
enableSort={false}
|
enableSort={false}
|
||||||
getGridRef={rightGridRef}
|
getGridRef={rightGridRef}
|
||||||
onDataCellClick={({ row, fieldName }) => {
|
onDataCellClick={({ row, fieldName }) => {
|
||||||
if (fieldName === "mpinCd") return;
|
if (fieldName === "sbstAdmdstCd") return;
|
||||||
if (fieldName === "admdstCd") {
|
if (fieldName === "admdstCd") {
|
||||||
const gridView = rightGridRef.current?.gridView as
|
const gridView = rightGridRef.current?.gridView as
|
||||||
| GridViewWithEditCommit
|
| GridViewWithEditCommit
|
||||||
@@ -107,7 +107,7 @@ const ForeignPopulationTab = ({ tab, statsYr, onFileButtonClick }: Props) => {
|
|||||||
tab.setRightRowData((prev) =>
|
tab.setRightRowData((prev) =>
|
||||||
prev.map((r) =>
|
prev.map((r) =>
|
||||||
r.admdstCd === row.admdstCd
|
r.admdstCd === row.admdstCd
|
||||||
? { ...r, mpinCd: String(row.admdstCd ?? "") }
|
? { ...r, sbstAdmdstCd: String(row.admdstCd ?? "") }
|
||||||
: r,
|
: r,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -116,7 +116,7 @@ const ForeignPopulationTab = ({ tab, statsYr, onFileButtonClick }: Props) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onCellDblClick={({ row, fieldName }) => {
|
onCellDblClick={({ row, fieldName }) => {
|
||||||
if (fieldName !== "mpinCd") return;
|
if (fieldName !== "sbstAdmdstCd") return;
|
||||||
void tab.handleRightRowClick(fromGridRow<ForeignPopulationItem>(row), statsYr);
|
void tab.handleRightRowClick(fromGridRow<ForeignPopulationItem>(row), statsYr);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -126,12 +126,12 @@ export function usePopulationMappingTab<TRow extends PopulationMappingRow>(
|
|||||||
|
|
||||||
await run(async () => {
|
await run(async () => {
|
||||||
const regList = rightRowData
|
const regList = rightRowData
|
||||||
.filter((row) => String(row.mpinCd ?? "").trim() !== "")
|
.filter((row) => String(row.sbstAdmdstCd ?? "").trim() !== "")
|
||||||
.map((row) => ({
|
.map((row) => ({
|
||||||
statsYr,
|
statsYr,
|
||||||
admdstCd: String(row.admdstCd ?? ""),
|
admdstCd: String(row.admdstCd ?? ""),
|
||||||
admdstNm: String(row.admdstNm ?? ""),
|
admdstNm: String(row.admdstNm ?? ""),
|
||||||
subAdmdstCd: String(row.mpinCd ?? ""),
|
sbstAdmdstCd: String(row.sbstAdmdstCd ?? ""),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const res = await config.saveFinal(statsYr, regList);
|
const res = await config.saveFinal(statsYr, regList);
|
||||||
@@ -167,7 +167,7 @@ const handleRightRowClick = async (rowData: TRow, statsYr: string) => {
|
|||||||
const rowIndex = selectedRowIndexRef.current;
|
const rowIndex = selectedRowIndexRef.current;
|
||||||
if (rowIndex === null) return;
|
if (rowIndex === null) return;
|
||||||
setRightRowData((prev) =>
|
setRightRowData((prev) =>
|
||||||
prev.map((row, idx) => (idx === rowIndex ? { ...row, mpinCd: item["admdstCd"] ?? "" } : row)),
|
prev.map((row, idx) => (idx === rowIndex ? { ...row, sbstAdmdstCd: item["admdstCd"] ?? "" } : row)),
|
||||||
);
|
);
|
||||||
selectedRowIndexRef.current = null;
|
selectedRowIndexRef.current = null;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export interface ForeignPopulationItem {
|
|||||||
frgnrMlPpltnCnt: number;
|
frgnrMlPpltnCnt: number;
|
||||||
frgnrFmlPpltnCnt: number;
|
frgnrFmlPpltnCnt: number;
|
||||||
/** 미매핑 리스트(우측) 전용 - 매핑 대상 행정구역코드(상위코드) */
|
/** 미매핑 리스트(우측) 전용 - 매핑 대상 행정구역코드(상위코드) */
|
||||||
mpinCd: string;
|
sbstAdmdstCd: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ForeignPopulationListResponse = ApiResponse<ForeignPopulationItem[]>;
|
export type ForeignPopulationListResponse = ApiResponse<ForeignPopulationItem[]>;
|
||||||
@@ -88,7 +88,7 @@ export interface PopulationMappingRegItem {
|
|||||||
statsYr: string;
|
statsYr: string;
|
||||||
admdstCd: string;
|
admdstCd: string;
|
||||||
admdstNm: string;
|
admdstNm: string;
|
||||||
subAdmdstCd: string;
|
sbstAdmdstCd: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 좌/우 그리드 행이 공통으로 가져야 하는 최소 필드 */
|
/** 좌/우 그리드 행이 공통으로 가져야 하는 최소 필드 */
|
||||||
@@ -96,7 +96,7 @@ export interface PopulationMappingRow {
|
|||||||
admdstCd: string;
|
admdstCd: string;
|
||||||
admdstNm: string;
|
admdstNm: string;
|
||||||
/** 우측(미매핑 리스트) 전용 필드. 좌측 데이터에는 존재하지 않을 수 있음 */
|
/** 우측(미매핑 리스트) 전용 필드. 좌측 데이터에는 존재하지 않을 수 있음 */
|
||||||
mpinCd?: string;
|
sbstAdmdstCd?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** usePopulationMappingTab에 주입하는 API/검증 설정 - 내국인/외국인 탭이 이 설정만 다르게 넘김 */
|
/** usePopulationMappingTab에 주입하는 API/검증 설정 - 내국인/외국인 탭이 이 설정만 다르게 넘김 */
|
||||||
|
|||||||
@@ -94,8 +94,8 @@ export const DomesticPopulationRightColumnConfig: ColumnInfoList = {
|
|||||||
styleName: "rg-cell-readonly",
|
styleName: "rg-cell-readonly",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "mpinCd",
|
name: "sbstAdmdstCd",
|
||||||
fieldName: "mpinCd",
|
fieldName: "sbstAdmdstCd",
|
||||||
header: { text: "맵핑코드" },
|
header: { text: "맵핑코드" },
|
||||||
width: 130,
|
width: 130,
|
||||||
editable: true
|
editable: true
|
||||||
@@ -134,7 +134,7 @@ export const DomesticPopulationRightColumnConfig: ColumnInfoList = {
|
|||||||
columnLayout: [
|
columnLayout: [
|
||||||
"admdstCd",
|
"admdstCd",
|
||||||
"admdstNm",
|
"admdstNm",
|
||||||
"mpinCd",
|
"sbstAdmdstCd",
|
||||||
{
|
{
|
||||||
name: "populationGroup",
|
name: "populationGroup",
|
||||||
header: { text: "인구수" },
|
header: { text: "인구수" },
|
||||||
|
|||||||
@@ -111,8 +111,8 @@ export const ForeignPopulationRightColumnConfig: ColumnInfoList = {
|
|||||||
styleName: "rg-cell-readonly",
|
styleName: "rg-cell-readonly",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "mpinCd",
|
name: "sbstAdmdstCd",
|
||||||
fieldName: "mpinCd",
|
fieldName: "sbstAdmdstCd",
|
||||||
header: { text: "맵핑코드" },
|
header: { text: "맵핑코드" },
|
||||||
width: 130,
|
width: 130,
|
||||||
editable: true
|
editable: true
|
||||||
@@ -153,7 +153,7 @@ export const ForeignPopulationRightColumnConfig: ColumnInfoList = {
|
|||||||
"sido",
|
"sido",
|
||||||
"gugun",
|
"gugun",
|
||||||
"admdstNm",
|
"admdstNm",
|
||||||
"mpinCd",
|
"sbstAdmdstCd",
|
||||||
{
|
{
|
||||||
name: "populationGroup",
|
name: "populationGroup",
|
||||||
header: { text: "외국인수" },
|
header: { text: "외국인수" },
|
||||||
|
|||||||
@@ -67,12 +67,15 @@ export interface EcptReqCountResponse {
|
|||||||
|
|
||||||
export interface ThreeStageStatusResponse {
|
export interface ThreeStageStatusResponse {
|
||||||
statsYr: string;
|
statsYr: string;
|
||||||
laeStatusCd: string;
|
lclgvSbmsnSttsCd: string;
|
||||||
laeStatusNm: string;
|
lclgvSbmsnSttsNm: string;
|
||||||
ctpvStatusCd: string;
|
lclgvRejected: boolean;
|
||||||
ctpvStatusNm: string;
|
mctpvPicSbmsnSttsCd: string;
|
||||||
pbcpStatusCd: string;
|
mctpvPicSbmsnSttsNm: string;
|
||||||
pbcpStatusNm: string;
|
mctpvRejected: boolean;
|
||||||
|
pbcpSbmsnSttsCd: string;
|
||||||
|
pbcpSbmsnSttsNm: string;
|
||||||
|
pbcpRejected: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DashboardService {
|
export interface DashboardService {
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ export interface DomesticPopulationItem {
|
|||||||
domplMlPpltnCnt: number; // 내국인 남성 인구수
|
domplMlPpltnCnt: number; // 내국인 남성 인구수
|
||||||
domplFmlPpltnCnt: number; // 내국인 여성 인구수
|
domplFmlPpltnCnt: number; // 내국인 여성 인구수
|
||||||
/** 미매핑 리스트 전용 - 매핑 대상 행정구역코드 (상위코드) */
|
/** 미매핑 리스트 전용 - 매핑 대상 행정구역코드 (상위코드) */
|
||||||
mpinCd: string;
|
sbstAdmdstCd: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 엑셀 업로드 요청 파라미터 */
|
/** 엑셀 업로드 요청 파라미터 */
|
||||||
|
|||||||
@@ -15,31 +15,67 @@ interface StepDef {
|
|||||||
label: string;
|
label: string;
|
||||||
subLabel: string;
|
subLabel: string;
|
||||||
description: string;
|
description: string;
|
||||||
|
rejectedDescription: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const STEPS: StepDef[] = [
|
const STEPS: StepDef[] = [
|
||||||
{ key: "input", label: "입력", subLabel: "작성자", description: "담당자가 통계 자료를 입력합니다." },
|
{
|
||||||
{ key: "submit", label: "제출", subLabel: "작성자", description: "입력을 마친 자료를 제출합니다." },
|
key: "input",
|
||||||
{ key: "approve", label: "승인", subLabel: "승인자", description: "지자체 승인자가 제출 내용을 승인합니다." },
|
label: "입력",
|
||||||
{ key: "review", label: "검토", subLabel: "시도", description: "광역시도 담당자가 자료를 검토합니다." },
|
subLabel: "작성자",
|
||||||
{ key: "verify", label: "검증", subLabel: "공단", description: "환경공단이 최종 검증을 진행합니다." },
|
description: "담당자가 통계 자료를 입력합니다.",
|
||||||
|
rejectedDescription: "반려된 자료에 대한 수정보완 후 제출합니다.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "submit",
|
||||||
|
label: "제출",
|
||||||
|
subLabel: "작성자",
|
||||||
|
description: "입력을 마친 자료를 제출합니다.",
|
||||||
|
rejectedDescription: "반려된 자료에 대한 수정보완 후 제출합니다.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "approve",
|
||||||
|
label: "승인",
|
||||||
|
subLabel: "승인자",
|
||||||
|
description: "지자체 승인자가 제출 내용을 승인합니다.",
|
||||||
|
rejectedDescription: "반려된 자료에 대한 수정보완 후 제출합니다.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "review",
|
||||||
|
label: "검토",
|
||||||
|
subLabel: "시도",
|
||||||
|
description: "광역시도 담당자가 자료를 검토합니다.",
|
||||||
|
rejectedDescription: "반려된 자료에 대한 수정보완 후 재검토를 요청합니다.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "verify",
|
||||||
|
label: "검증",
|
||||||
|
subLabel: "공단",
|
||||||
|
description: "환경공단이 최종 검증을 진행합니다.",
|
||||||
|
rejectedDescription: "반려된 자료에 대한 수정보완 후 재검증을 요청합니다.",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
interface ThreeStageData {
|
||||||
|
lclgvSbmsnSttsCd: string;
|
||||||
|
lclgvRejected: boolean;
|
||||||
|
mctpvPicSbmsnSttsCd: string;
|
||||||
|
mctpvRejected: boolean;
|
||||||
|
pbcpSbmsnSttsCd: string;
|
||||||
|
pbcpRejected: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lae_sbmsn_stts_cd(지자체) : 0=미작성 1=작성중 2=제출완료 3=승인
|
* lae_sbmsn_stts_cd(지자체) : 0=미작성 1=작성중 2=제출완료 3=승인
|
||||||
* stat_pic_sbmsn_stts_cd(광역시도), pbcp_sbmsn_stts_cd(공단) 도 동일 코드 도메인 가정
|
* stat_pic_sbmsn_stts_cd(광역시도), pbcp_sbmsn_stts_cd(공단) 도 동일 코드 도메인 가정
|
||||||
* - 실제 코드값 의미는 STINPUTSTP 코드 그룹 기준 재확인 필요
|
* - 실제 코드값 의미는 STINPUTSTP 코드 그룹 기준 재확인 필요
|
||||||
*/
|
*/
|
||||||
function resolveCheckedSteps(data?: {
|
function resolveCheckedSteps(data?: ThreeStageData): boolean[] {
|
||||||
laeStatusCd: string;
|
|
||||||
ctpvStatusCd: string;
|
|
||||||
pbcpStatusCd: string;
|
|
||||||
}): boolean[] {
|
|
||||||
if (!data) return STEPS.map(() => false);
|
if (!data) return STEPS.map(() => false);
|
||||||
|
|
||||||
const lae = Number(data.laeStatusCd);
|
const lae = Number(data.lclgvSbmsnSttsCd);
|
||||||
const ctpv = Number(data.ctpvStatusCd);
|
const ctpv = Number(data.mctpvPicSbmsnSttsCd);
|
||||||
const pbcp = Number(data.pbcpStatusCd);
|
const pbcp = Number(data.pbcpSbmsnSttsCd);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
lae >= 1,
|
lae >= 1,
|
||||||
@@ -50,6 +86,18 @@ function resolveCheckedSteps(data?: {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// input/submit/approve → lclgv 반려여부, review → mctpv, verify → pbcp
|
||||||
|
function resolveRejectedFlags(data?: ThreeStageData): boolean[] {
|
||||||
|
if (!data) return STEPS.map(() => false);
|
||||||
|
return [
|
||||||
|
data.lclgvRejected,
|
||||||
|
data.lclgvRejected,
|
||||||
|
data.lclgvRejected,
|
||||||
|
data.mctpvRejected,
|
||||||
|
data.pbcpRejected,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
interface ThreeStageStatusPanelProps {
|
interface ThreeStageStatusPanelProps {
|
||||||
params: DashboardSearchParams | null;
|
params: DashboardSearchParams | null;
|
||||||
}
|
}
|
||||||
@@ -59,10 +107,23 @@ export function ThreeStageStatusPanel({ params }: ThreeStageStatusPanelProps) {
|
|||||||
const { data, isLoading, isFetching } = useDashboardThreeStageStatus(params);
|
const { data, isLoading, isFetching } = useDashboardThreeStageStatus(params);
|
||||||
|
|
||||||
const checkedList = resolveCheckedSteps(data);
|
const checkedList = resolveCheckedSteps(data);
|
||||||
|
const rejectedFlags = resolveRejectedFlags(data);
|
||||||
const currentIndex = checkedList.findIndex((v) => !v);
|
const currentIndex = checkedList.findIndex((v) => !v);
|
||||||
const isAllDone = currentIndex === -1;
|
const isAllDone = currentIndex === -1;
|
||||||
const currentStep = STEPS[isAllDone ? STEPS.length - 1 : currentIndex]!;
|
const currentStep = STEPS[isAllDone ? STEPS.length - 1 : currentIndex]!;
|
||||||
const currentLabel = isAllDone ? "전 단계 완료" : `${currentStep.label} 대기중`;
|
const isCurrentRejected = !isAllDone && rejectedFlags[currentIndex];
|
||||||
|
|
||||||
|
const currentLabel = isAllDone
|
||||||
|
? "전 단계 완료"
|
||||||
|
: isCurrentRejected
|
||||||
|
? `${currentStep.label} 반려`
|
||||||
|
: `${currentStep.label} 대기중`;
|
||||||
|
|
||||||
|
const currentDescription = isAllDone
|
||||||
|
? "모든 절차가 완료되었습니다."
|
||||||
|
: isCurrentRejected
|
||||||
|
? currentStep.rejectedDescription
|
||||||
|
: currentStep.description;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card card-border !m-0 flex h-full flex-col border-border bg-background text-foreground">
|
<div className="card card-border !m-0 flex h-full flex-col border-border bg-background text-foreground">
|
||||||
@@ -76,7 +137,9 @@ export function ThreeStageStatusPanel({ params }: ThreeStageStatusPanelProps) {
|
|||||||
className={`rounded-full px-4 py-1.5 text-base font-medium ${
|
className={`rounded-full px-4 py-1.5 text-base font-medium ${
|
||||||
isAllDone
|
isAllDone
|
||||||
? "bg-blue-50 text-blue-600"
|
? "bg-blue-50 text-blue-600"
|
||||||
: "bg-amber-50 text-amber-600"
|
: isCurrentRejected
|
||||||
|
? "bg-red-50 text-red-600"
|
||||||
|
: "bg-amber-50 text-amber-600"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{currentLabel}
|
{currentLabel}
|
||||||
@@ -94,6 +157,7 @@ export function ThreeStageStatusPanel({ params }: ThreeStageStatusPanelProps) {
|
|||||||
{STEPS.map((step, index) => {
|
{STEPS.map((step, index) => {
|
||||||
const isChecked = checkedList[index];
|
const isChecked = checkedList[index];
|
||||||
const isCurrent = index === currentIndex;
|
const isCurrent = index === currentIndex;
|
||||||
|
const isRejectedStep = isCurrent && rejectedFlags[index];
|
||||||
const isLast = index === STEPS.length - 1;
|
const isLast = index === STEPS.length - 1;
|
||||||
const lineFilled = checkedList[index];
|
const lineFilled = checkedList[index];
|
||||||
|
|
||||||
@@ -101,16 +165,29 @@ export function ThreeStageStatusPanel({ params }: ThreeStageStatusPanelProps) {
|
|||||||
<Fragment key={step.key}>
|
<Fragment key={step.key}>
|
||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
<div className="relative flex flex-col items-center">
|
<div className="relative flex flex-col items-center">
|
||||||
{isCurrent && (
|
{isRejectedStep && (
|
||||||
|
<div className="absolute -top-11 flex flex-col items-center">
|
||||||
|
<span className="whitespace-nowrap rounded-lg bg-slate-700 px-3 py-1.5 text-base font-bold text-white shadow-md">
|
||||||
|
반려
|
||||||
|
</span>
|
||||||
|
<span className="-mt-px h-0 w-0 border-x-[6px] border-t-[6px] border-x-transparent border-t-slate-700" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{isCurrent && !isRejectedStep && (
|
||||||
<span className="absolute inset-0 -m-1.5 animate-ping rounded-full bg-blue-400 opacity-40" />
|
<span className="absolute inset-0 -m-1.5 animate-ping rounded-full bg-blue-400 opacity-40" />
|
||||||
)}
|
)}
|
||||||
|
{isRejectedStep && (
|
||||||
|
<span className="absolute inset-0 -m-1.5 animate-ping rounded-full bg-red-400 opacity-40" />
|
||||||
|
)}
|
||||||
<div
|
<div
|
||||||
className={`relative flex size-20 items-center justify-center rounded-full border-4 transition-colors ${
|
className={`relative flex size-20 items-center justify-center rounded-full border-4 transition-colors ${
|
||||||
isChecked
|
isChecked
|
||||||
? "border-blue-600 bg-blue-600 shadow-lg shadow-blue-600/20"
|
? "border-blue-600 bg-blue-600 shadow-lg shadow-blue-600/20"
|
||||||
: isCurrent
|
: isRejectedStep
|
||||||
? "border-blue-500 bg-white"
|
? "border-red-500 bg-white"
|
||||||
: "border-gray-200 bg-white"
|
: isCurrent
|
||||||
|
? "border-blue-500 bg-white"
|
||||||
|
: "border-gray-200 bg-white"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{isChecked ? (
|
{isChecked ? (
|
||||||
@@ -128,7 +205,11 @@ export function ThreeStageStatusPanel({ params }: ThreeStageStatusPanelProps) {
|
|||||||
) : (
|
) : (
|
||||||
<span
|
<span
|
||||||
className={`size-4 rounded-full ${
|
className={`size-4 rounded-full ${
|
||||||
isCurrent ? "bg-blue-500" : "bg-gray-200"
|
isRejectedStep
|
||||||
|
? "bg-red-500"
|
||||||
|
: isCurrent
|
||||||
|
? "bg-blue-500"
|
||||||
|
: "bg-gray-200"
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -139,9 +220,11 @@ export function ThreeStageStatusPanel({ params }: ThreeStageStatusPanelProps) {
|
|||||||
className={`text-xl font-bold ${
|
className={`text-xl font-bold ${
|
||||||
isChecked
|
isChecked
|
||||||
? "text-blue-700"
|
? "text-blue-700"
|
||||||
: isCurrent
|
: isRejectedStep
|
||||||
? "text-blue-600"
|
? "text-red-600"
|
||||||
: "text-gray-400"
|
: isCurrent
|
||||||
|
? "text-blue-600"
|
||||||
|
: "text-gray-400"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{step.label}
|
{step.label}
|
||||||
@@ -164,15 +247,22 @@ export function ThreeStageStatusPanel({ params }: ThreeStageStatusPanelProps) {
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-full rounded-2xl border border-border bg-blue-50/40 px-7 py-6 text-center">
|
<div
|
||||||
<p className="text-base font-medium text-blue-600">
|
className={`w-full rounded-2xl border px-7 py-6 text-center ${
|
||||||
|
isCurrentRejected
|
||||||
|
? "border-red-200 bg-red-50/50"
|
||||||
|
: "border-border bg-blue-50/40"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
className={`text-base font-medium ${
|
||||||
|
isCurrentRejected ? "text-red-600" : "text-blue-600"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
{isAllDone ? "현재 단계" : "다음 진행 단계"} · {currentStep.label}
|
{isAllDone ? "현재 단계" : "다음 진행 단계"} · {currentStep.label}
|
||||||
|
{isCurrentRejected ? " (반려)" : ""}
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-2 text-lg text-foreground">
|
<p className="mt-2 text-lg text-foreground">{currentDescription}</p>
|
||||||
{isAllDone
|
|
||||||
? "모든 절차가 완료되었습니다."
|
|
||||||
: currentStep.description}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user