diff --git a/apps/as/app/(main)/(with-base-layout)/design-cnstn/[id]/page.tsx b/apps/as/app/(main)/(with-base-layout)/design-cnstn/[id]/page.tsx
index 1b0fc983c..f603f8e39 100644
--- a/apps/as/app/(main)/(with-base-layout)/design-cnstn/[id]/page.tsx
+++ b/apps/as/app/(main)/(with-base-layout)/design-cnstn/[id]/page.tsx
@@ -1,4 +1,4 @@
-import { DesignViewPage } from "@/pages/design-cnstn";
+import { DesignDetailGate } from "@/pages/design-cnstn";
interface PageProps {
params: Promise<{ id: string }>;
@@ -6,5 +6,5 @@ interface PageProps {
export default async function Page({ params }: PageProps) {
const { id } = await params;
- return ;
+ return ;
}
diff --git a/apps/as/app/(main)/(with-base-layout)/fnrs-cnsltn/[id]/page.tsx b/apps/as/app/(main)/(with-base-layout)/fnrs-cnsltn/[id]/page.tsx
index ec9a3911e..0d0df0607 100644
--- a/apps/as/app/(main)/(with-base-layout)/fnrs-cnsltn/[id]/page.tsx
+++ b/apps/as/app/(main)/(with-base-layout)/fnrs-cnsltn/[id]/page.tsx
@@ -1,4 +1,4 @@
-import { FnrsViewPage } from "@/pages/fnrs-cnsltn";
+import { FnrsDetailGate } from "@/pages/fnrs-cnsltn";
interface PageProps {
params: Promise<{ id: string }>;
@@ -6,5 +6,5 @@ interface PageProps {
export default async function Page({ params }: PageProps) {
const { id } = await params;
- return ;
+ return ;
}
diff --git a/apps/as/app/(main)/(with-base-layout)/instl-sncn/[id]/page.tsx b/apps/as/app/(main)/(with-base-layout)/instl-sncn/[id]/page.tsx
index 89cd7a329..f89257bcc 100644
--- a/apps/as/app/(main)/(with-base-layout)/instl-sncn/[id]/page.tsx
+++ b/apps/as/app/(main)/(with-base-layout)/instl-sncn/[id]/page.tsx
@@ -1,6 +1,6 @@
-import { InstlViewPage } from "@/pages/instl-sncn";
+import { InstlSncnDetailGate } from "@/pages/instl-sncn";
export default async function InstlSncnDetailPage({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
- return ;
+ return ;
}
diff --git a/apps/as/app/(main)/(with-base-layout)/sewer-bsc-plan/[id]/page.tsx b/apps/as/app/(main)/(with-base-layout)/sewer-bsc-plan/[id]/page.tsx
index 1b864a7c0..dec6502a8 100644
--- a/apps/as/app/(main)/(with-base-layout)/sewer-bsc-plan/[id]/page.tsx
+++ b/apps/as/app/(main)/(with-base-layout)/sewer-bsc-plan/[id]/page.tsx
@@ -1,4 +1,4 @@
-import { SewerBscPlanViewPage } from "@/pages/sewer-bsc-plan";
+import { SewerBscPlanDetailGate } from "@/pages/sewer-bsc-plan";
interface PageProps {
params: Promise<{ id: string }>;
@@ -9,5 +9,5 @@ export default async function Page({ params, searchParams }: PageProps) {
const { id } = await params;
const { chgCycl } = await searchParams;
const propChgCycl = chgCycl ? Number(chgCycl) : undefined;
- return ;
+ return ;
}
diff --git a/apps/as/src/pages/design-cnstn/index.ts b/apps/as/src/pages/design-cnstn/index.ts
index fcaaab3ed..8e1323aae 100644
--- a/apps/as/src/pages/design-cnstn/index.ts
+++ b/apps/as/src/pages/design-cnstn/index.ts
@@ -1,3 +1,4 @@
+export { DesignDetailGate } from "./ui/design-detail-gate";
export { DesignEditPage } from "./ui/design-edit-page";
export { DesignFormPage } from "./ui/design-form-page";
export { DesignListPage } from "./ui/design-list-page";
diff --git a/apps/as/src/pages/design-cnstn/ui/design-detail-gate.tsx b/apps/as/src/pages/design-cnstn/ui/design-detail-gate.tsx
new file mode 100644
index 000000000..723ae5f03
--- /dev/null
+++ b/apps/as/src/pages/design-cnstn/ui/design-detail-gate.tsx
@@ -0,0 +1,35 @@
+"use client";
+
+import { useUserStore } from "@/shared/lib";
+import { useDesignCnstnMng } from "@/entities/design-cnstn";
+import { canEditPbadmsDoc, PbadmsDetailGate } from "@/widgets/pbadms-sprt";
+
+import { DesignViewPage } from "./design-view-page";
+
+interface DesignDetailGateProps {
+ id: string;
+}
+
+function DesignDetailGate({ id }: DesignDetailGateProps) {
+ const userInfo = useUserStore((state) => state.userInfo);
+ const { data, isLoading, isError } = useDesignCnstnMng(id);
+ const shouldRedirectToEdit = canEditPbadmsDoc({
+ docSeComCd: "CNFM",
+ prgrsSttsComCd: data?.detDto?.prgrsSttsComCd,
+ rgtr: data?.detDto?.rgtr,
+ loggedInUserUnqId: userInfo?.userUnqId,
+ });
+
+ return (
+
+
+
+ );
+}
+
+export { DesignDetailGate };
diff --git a/apps/as/src/pages/design-cnstn/ui/design-list.tsx b/apps/as/src/pages/design-cnstn/ui/design-list.tsx
index a23f2e9ea..f9652d833 100644
--- a/apps/as/src/pages/design-cnstn/ui/design-list.tsx
+++ b/apps/as/src/pages/design-cnstn/ui/design-list.tsx
@@ -5,7 +5,7 @@ import { useRouter } from "next/navigation";
import { getCoreRowModel, type PaginationState } from "@tanstack/react-table";
-import { useDataTable, useUserStore } from "@/shared/lib";
+import { useDataTable } from "@/shared/lib";
import {
type DesignCnstnMngResponseDto,
type DesignCnstnMngSearchDto,
@@ -24,7 +24,6 @@ interface DesignListProps {
}
function DesignList({ searchParams, pagination, onPaginationChange }: DesignListProps) {
- const userInfo = useUserStore((state) => state.userInfo);
const router = useRouter();
const [isTaskSeDialogOpen, setIsTaskSeDialogOpen] = useState(false);
@@ -44,13 +43,7 @@ function DesignList({ searchParams, pagination, onPaginationChange }: DesignList
const columns = useMemo(() => createDesignCnstnColumns(), []);
const handleRowClick = (row: DesignCnstnMngResponseDto) => {
- const canEdit = row.prgrsSttsComCd === "CV" && row.rgtr === userInfo?.userUnqId;
-
- router.push(
- canEdit
- ? `/design-cnstn/${row.designCnstnDocNo}/edit`
- : `/design-cnstn/${row.designCnstnDocNo}`,
- );
+ router.push(`/design-cnstn/${row.designCnstnDocNo}`);
};
const { tableComponent } = useDataTable({
diff --git a/apps/as/src/pages/fnrs-cnsltn/index.ts b/apps/as/src/pages/fnrs-cnsltn/index.ts
index 0193bd7c8..0531c9fb8 100644
--- a/apps/as/src/pages/fnrs-cnsltn/index.ts
+++ b/apps/as/src/pages/fnrs-cnsltn/index.ts
@@ -1,3 +1,4 @@
+export { FnrsDetailGate } from "./ui/fnrs-detail-gate";
export { FnrsEditPage } from "./ui/fnrs-edit-page";
export { FnrsFormPage } from "./ui/fnrs-form-page";
export { FnrsListPage } from "./ui/fnrs-list-page";
diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-detail-gate.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-detail-gate.tsx
new file mode 100644
index 000000000..153d491ff
--- /dev/null
+++ b/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-detail-gate.tsx
@@ -0,0 +1,35 @@
+"use client";
+
+import { useUserStore } from "@/shared/lib";
+import { useFnrsCnsltnMng } from "@/entities/fnrs-cnsltn";
+import { canEditPbadmsDoc, PbadmsDetailGate } from "@/widgets/pbadms-sprt";
+
+import { FnrsViewPage } from "./fnrs-view-page";
+
+interface FnrsDetailGateProps {
+ id: string;
+}
+
+function FnrsDetailGate({ id }: FnrsDetailGateProps) {
+ const userInfo = useUserStore((state) => state.userInfo);
+ const { data, isLoading, isError } = useFnrsCnsltnMng(id);
+ const shouldRedirectToEdit = canEditPbadmsDoc({
+ docSeComCd: "FNRS",
+ prgrsSttsComCd: data?.detDto?.prgrsSttsComCd,
+ rgtr: data?.detDto?.rgtr,
+ loggedInUserUnqId: userInfo?.userUnqId,
+ });
+
+ return (
+
+
+
+ );
+}
+
+export { FnrsDetailGate };
diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-list.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-list.tsx
index 6f584074d..e09a86b1a 100644
--- a/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-list.tsx
+++ b/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-list.tsx
@@ -5,7 +5,7 @@ import { useRouter } from "next/navigation";
import { getCoreRowModel, type PaginationState } from "@tanstack/react-table";
-import { useDataTable, useUserStore } from "@/shared/lib";
+import { useDataTable } from "@/shared/lib";
import {
FnrsCnsltnMngResponseDto,
type FnrsCnsltnMngSearchDto,
@@ -24,7 +24,6 @@ interface FnrsListProps {
}
function FnrsList({ searchParams, pagination, onPaginationChange }: FnrsListProps) {
- const userInfo = useUserStore((state) => state.userInfo);
const router = useRouter();
const [isTaskSeDialogOpen, setIsTaskSeDialogOpen] = useState(false);
@@ -44,13 +43,7 @@ function FnrsList({ searchParams, pagination, onPaginationChange }: FnrsListProp
const columns = useMemo(() => createFnrsCnsltnColumns(), []);
const handleRowClick = (row: FnrsCnsltnMngResponseDto) => {
- const canEdit =
- (row.prgrsSttsComCd === "SV" || row.prgrsSttsComCd === "SL") &&
- row.rgtr === userInfo?.userUnqId;
-
- router.push(
- canEdit ? `/fnrs-cnsltn/${row.fnrsCnsltnDocNo}/edit` : `/fnrs-cnsltn/${row.fnrsCnsltnDocNo}`,
- );
+ router.push(`/fnrs-cnsltn/${row.fnrsCnsltnDocNo}`);
};
const { tableComponent } = useDataTable({
diff --git a/apps/as/src/pages/instl-sncn/index.ts b/apps/as/src/pages/instl-sncn/index.ts
index 3957b0c66..0b48c115b 100644
--- a/apps/as/src/pages/instl-sncn/index.ts
+++ b/apps/as/src/pages/instl-sncn/index.ts
@@ -1,3 +1,4 @@
+export { InstlSncnDetailGate } from "./ui/instl-detail-gate";
export { InstlEditPage } from "./ui/instl-edit-page";
export { InstlFormPage } from "./ui/instl-form-page";
export { InstlListPage } from "./ui/instl-list-page";
diff --git a/apps/as/src/pages/instl-sncn/ui/instl-detail-gate.tsx b/apps/as/src/pages/instl-sncn/ui/instl-detail-gate.tsx
new file mode 100644
index 000000000..321f92940
--- /dev/null
+++ b/apps/as/src/pages/instl-sncn/ui/instl-detail-gate.tsx
@@ -0,0 +1,35 @@
+"use client";
+
+import { useUserStore } from "@/shared/lib";
+import { useInstlSncnDetail } from "@/entities/instl-sncn";
+import { canEditPbadmsDoc, PbadmsDetailGate } from "@/widgets/pbadms-sprt";
+
+import { InstlViewPage } from "./instl-view-page";
+
+interface InstlSncnDetailGateProps {
+ id: string;
+}
+
+function InstlSncnDetailGate({ id }: InstlSncnDetailGateProps) {
+ const userInfo = useUserStore((state) => state.userInfo);
+ const { data, isLoading, isError } = useInstlSncnDetail(id);
+ const shouldRedirectToEdit = canEditPbadmsDoc({
+ docSeComCd: "INSTL",
+ prgrsSttsComCd: data?.detDto.prgrsSttsComCd,
+ rgtr: data?.detDto.rgtr,
+ loggedInUserUnqId: userInfo?.userUnqId,
+ });
+
+ return (
+
+
+
+ );
+}
+
+export { InstlSncnDetailGate };
diff --git a/apps/as/src/pages/instl-sncn/ui/instl-list.tsx b/apps/as/src/pages/instl-sncn/ui/instl-list.tsx
index e54b41578..43981e896 100644
--- a/apps/as/src/pages/instl-sncn/ui/instl-list.tsx
+++ b/apps/as/src/pages/instl-sncn/ui/instl-list.tsx
@@ -5,7 +5,7 @@ import { useRouter } from "next/navigation";
import { getCoreRowModel, type PaginationState } from "@tanstack/react-table";
-import { useDataTable, useUserStore } from "@/shared/lib";
+import { useDataTable } from "@/shared/lib";
import {
type InstlSncnMngResponseDto,
type InstlSncnMngSearchParams,
@@ -24,7 +24,6 @@ interface InstlListProps {
}
function InstlList({ searchParams, pagination, onPaginationChange }: InstlListProps) {
- const userInfo = useUserStore((state) => state.userInfo);
const router = useRouter();
const [isTaskSeDialogOpen, setIsTaskSeDialogOpen] = useState(false);
@@ -44,13 +43,7 @@ function InstlList({ searchParams, pagination, onPaginationChange }: InstlListPr
const columns = useMemo(() => createInstlSncnColumns(), []);
const handleRowClick = (row: InstlSncnMngResponseDto) => {
- const canEdit =
- (row.prgrsSttsComCd === "SV" || row.prgrsSttsComCd === "SL") &&
- row.rgtr === userInfo?.userUnqId;
-
- router.push(
- canEdit ? `/instl-sncn/${row.instlSncnDocNo}/edit` : `/instl-sncn/${row.instlSncnDocNo}`,
- );
+ router.push(`/instl-sncn/${row.instlSncnDocNo}`);
};
const { tableComponent } = useDataTable({
diff --git a/apps/as/src/pages/my-pbadms-sprt/lib/resolve-detail-path.ts b/apps/as/src/pages/my-pbadms-sprt/lib/resolve-detail-path.ts
index f855d4394..d37d453cb 100644
--- a/apps/as/src/pages/my-pbadms-sprt/lib/resolve-detail-path.ts
+++ b/apps/as/src/pages/my-pbadms-sprt/lib/resolve-detail-path.ts
@@ -1,42 +1,19 @@
import type { MyAdssDocResponseDto } from "@/entities/elapr";
-function canEditByDocSe(
- docSeComCd: string,
- prgrsSttsComCd: string | undefined,
- rgtr: string | undefined,
- loggedInUserUnqId: string | undefined,
-): boolean {
- if (!loggedInUserUnqId || !rgtr || rgtr !== loggedInUserUnqId) return false;
-
- if (docSeComCd === "CNFM") return prgrsSttsComCd === "CV";
-
- if (docSeComCd === "INSTL" || docSeComCd === "FNRS" || docSeComCd === "SEWER")
- return prgrsSttsComCd === "SV" || prgrsSttsComCd === "SL";
-
- return false;
-}
-
-function resolveMyPbadmsSprtDetailPath(
- row: MyAdssDocResponseDto,
- loggedInUserUnqId: string | undefined,
-): string | null {
- const { docNo, docSeComCd, prgrsSttsComCd, rgtr, chgCycl } = row;
+function resolveMyPbadmsSprtDetailPath(row: MyAdssDocResponseDto): string | null {
+ const { docNo, docSeComCd, chgCycl } = row;
if (!docNo || !docSeComCd) return null;
- const canEdit = canEditByDocSe(docSeComCd, prgrsSttsComCd, rgtr, loggedInUserUnqId);
-
switch (docSeComCd) {
case "FNRS":
- return canEdit ? `/fnrs-cnsltn/${docNo}/edit` : `/fnrs-cnsltn/${docNo}`;
+ return `/fnrs-cnsltn/${docNo}`;
case "INSTL":
- return canEdit ? `/instl-sncn/${docNo}/edit` : `/instl-sncn/${docNo}`;
+ return `/instl-sncn/${docNo}`;
case "CNFM":
- return canEdit ? `/design-cnstn/${docNo}/edit` : `/design-cnstn/${docNo}`;
+ return `/design-cnstn/${docNo}`;
case "SEWER": {
const cycl = chgCycl ?? 1;
- return canEdit
- ? `/sewer-bsc-plan/${docNo}/edit?chgCycl=${cycl}`
- : `/sewer-bsc-plan/${docNo}?chgCycl=${cycl}`;
+ return `/sewer-bsc-plan/${docNo}?chgCycl=${cycl}`;
}
default:
return null;
diff --git a/apps/as/src/pages/my-pbadms-sprt/ui/my-pbadms-sprt-list.tsx b/apps/as/src/pages/my-pbadms-sprt/ui/my-pbadms-sprt-list.tsx
index 29cf221c4..06e64ee55 100644
--- a/apps/as/src/pages/my-pbadms-sprt/ui/my-pbadms-sprt-list.tsx
+++ b/apps/as/src/pages/my-pbadms-sprt/ui/my-pbadms-sprt-list.tsx
@@ -5,7 +5,7 @@ import { useRouter } from "next/navigation";
import { getCoreRowModel, type PaginationState } from "@tanstack/react-table";
-import { useDataTable, useUserStore } from "@/shared/lib";
+import { useDataTable } from "@/shared/lib";
import {
type ElaprMyDocSearchDto,
type MyAdssDocResponseDto,
@@ -28,7 +28,6 @@ function toOptionalParam(value: string | undefined) {
function MyPbadmsSprtList({ searchParams, pagination, onPaginationChange }: MyPbadmsSprtListProps) {
const router = useRouter();
- const userInfo = useUserStore((state) => state.userInfo);
const queryParams = useMemo(
(): ElaprMyDocSearchDto => ({
@@ -54,7 +53,7 @@ function MyPbadmsSprtList({ searchParams, pagination, onPaginationChange }: MyPb
);
const handleRowClick = (row: MyAdssDocResponseDto) => {
- const path = resolveMyPbadmsSprtDetailPath(row, userInfo?.userUnqId);
+ const path = resolveMyPbadmsSprtDetailPath(row);
if (path) router.push(path);
};
diff --git a/apps/as/src/pages/nti-hstry/ui/nti-hstry-list.tsx b/apps/as/src/pages/nti-hstry/ui/nti-hstry-list.tsx
index ea78f44ef..83aadc91c 100644
--- a/apps/as/src/pages/nti-hstry/ui/nti-hstry-list.tsx
+++ b/apps/as/src/pages/nti-hstry/ui/nti-hstry-list.tsx
@@ -26,14 +26,6 @@ function toOptionalParam(value: string | undefined) {
return trimmed ? trimmed : undefined;
}
-function navigateNotiUrl(url: string, push: (href: string) => void) {
- if (/^https?:\/\//i.test(url)) {
- window.location.href = url;
- return;
- }
- push(url.startsWith("/") ? url : `/${url}`);
-}
-
function NtiHstryList({ searchParams, pagination, onPaginationChange }: NtiHstryListProps) {
const router = useRouter();
const { mutateAsync: readNoti, isPending: isReadPending } = useReadNoti();
@@ -57,7 +49,7 @@ function NtiHstryList({ searchParams, pagination, onPaginationChange }: NtiHstry
await readNoti(row.notiId);
const notiUrl = row.notiUrl?.trim();
if (!notiUrl) return;
- navigateNotiUrl(notiUrl, (href) => router.push(href));
+ router.push(notiUrl);
},
[readNoti, router],
);
diff --git a/apps/as/src/pages/sewer-bsc-plan/index.ts b/apps/as/src/pages/sewer-bsc-plan/index.ts
index c77a4da99..f8329573d 100644
--- a/apps/as/src/pages/sewer-bsc-plan/index.ts
+++ b/apps/as/src/pages/sewer-bsc-plan/index.ts
@@ -1,3 +1,4 @@
+export { SewerBscPlanDetailGate } from "./ui/sewer-bsc-plan-detail-gate";
export { SewerBscPlanEditPage } from "./ui/sewer-bsc-plan-edit-page";
export { SewerBscPlanFormPage } from "./ui/sewer-bsc-plan-form-page";
export { SewerBscPlanListPage } from "./ui/sewer-bsc-plan-list-page";
diff --git a/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-detail-gate.tsx b/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-detail-gate.tsx
new file mode 100644
index 000000000..c5f6f4a44
--- /dev/null
+++ b/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-detail-gate.tsx
@@ -0,0 +1,37 @@
+"use client";
+
+import { useUserStore } from "@/shared/lib";
+import { useSewerBscPlan } from "@/entities/sewer-bsc-plan";
+import { canEditPbadmsDoc, PbadmsDetailGate } from "@/widgets/pbadms-sprt";
+
+import { SewerBscPlanViewPage } from "./sewer-bsc-plan-view-page";
+
+interface SewerBscPlanDetailGateProps {
+ id: string;
+ propChgCycl?: number;
+}
+
+function SewerBscPlanDetailGate({ id, propChgCycl }: SewerBscPlanDetailGateProps) {
+ const userInfo = useUserStore((state) => state.userInfo);
+ const chgCycl = propChgCycl ?? 1;
+ const { data, isLoading, isError } = useSewerBscPlan(id);
+ const shouldRedirectToEdit = canEditPbadmsDoc({
+ docSeComCd: "SEWER",
+ prgrsSttsComCd: data?.prgrsSttsComCd,
+ rgtr: data?.rgtr,
+ loggedInUserUnqId: userInfo?.userUnqId,
+ });
+
+ return (
+
+
+
+ );
+}
+
+export { SewerBscPlanDetailGate };
diff --git a/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-list.tsx b/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-list.tsx
index b2f80834c..f5156c5b7 100644
--- a/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-list.tsx
+++ b/apps/as/src/pages/sewer-bsc-plan/ui/sewer-bsc-plan-list.tsx
@@ -5,7 +5,7 @@ import { useRouter } from "next/navigation";
import { getCoreRowModel, type PaginationState } from "@tanstack/react-table";
-import { useDataTable, useUserStore } from "@/shared/lib";
+import { useDataTable } from "@/shared/lib";
import {
type SewerBscPlanResponseDto,
type SewerBscPlanSearchRequestDto,
@@ -27,7 +27,6 @@ interface SewerBscPlanListProps {
}
function SewerBscPlanList({ searchParams, pagination, onPaginationChange }: SewerBscPlanListProps) {
- const userInfo = useUserStore((state) => state.userInfo);
const router = useRouter();
const [isApplyDialogOpen, setIsApplyDialogOpen] = useState(false);
@@ -48,15 +47,7 @@ function SewerBscPlanList({ searchParams, pagination, onPaginationChange }: Sewe
const columns = useMemo(() => createSewerBscPlanColumns(), []);
const handleRowClick = (row: SewerBscPlanResponseDto) => {
- const canEdit =
- (row.prgrsSttsComCd === "SV" || row.prgrsSttsComCd === "SL") &&
- row.rgtr === userInfo?.userUnqId;
-
- router.push(
- canEdit
- ? `/sewer-bsc-plan/${row.sewerBscPlanDocNo}/edit?chgCycl=${row.chgCycl}`
- : `/sewer-bsc-plan/${row.sewerBscPlanDocNo}?chgCycl=${row.chgCycl}`,
- );
+ router.push(`/sewer-bsc-plan/${row.sewerBscPlanDocNo}?chgCycl=${row.chgCycl}`);
};
const { tableComponent } = useDataTable({
diff --git a/apps/as/src/widgets/pbadms-sprt/index.ts b/apps/as/src/widgets/pbadms-sprt/index.ts
index 4746b9097..e891ec930 100644
--- a/apps/as/src/widgets/pbadms-sprt/index.ts
+++ b/apps/as/src/widgets/pbadms-sprt/index.ts
@@ -11,6 +11,7 @@ export {
recalculateBizCstTotals,
} from "./lib/business-cost-form-utils";
export { buildCnstpScaleItems, recalculateBzScaleTotals } from "./lib/business-scale-form-utils";
+export { canEditPbadmsDoc, type CanEditPbadmsDocParams } from "./lib/can-edit-pbadms-doc";
export {
buildChecklistTabs,
isFormChecklistComplete,
@@ -34,6 +35,7 @@ export { BusinessScaleFormSection } from "./ui/business-scale-form-section";
export { ChecklistFormSection } from "./ui/checklist-form-section";
export { ContactInfoFormSection } from "./ui/contact-info-form-section";
export { FnrsSharFormSection } from "./ui/fnrs-shar-form-section";
+export { PbadmsDetailGate, type PbadmsDetailGateProps } from "./ui/pbadms-detail-gate";
export {
PbadmsTaskApplyDialog,
type PbadmsTaskApplySelection,
diff --git a/apps/as/src/widgets/pbadms-sprt/lib/can-edit-pbadms-doc.ts b/apps/as/src/widgets/pbadms-sprt/lib/can-edit-pbadms-doc.ts
new file mode 100644
index 000000000..ba626a08c
--- /dev/null
+++ b/apps/as/src/widgets/pbadms-sprt/lib/can-edit-pbadms-doc.ts
@@ -0,0 +1,25 @@
+interface CanEditPbadmsDocParams {
+ docSeComCd: string;
+ prgrsSttsComCd: string | undefined;
+ rgtr: string | undefined;
+ loggedInUserUnqId: string | undefined;
+}
+
+function canEditPbadmsDoc({
+ docSeComCd,
+ prgrsSttsComCd,
+ rgtr,
+ loggedInUserUnqId,
+}: CanEditPbadmsDocParams): boolean {
+ if (!loggedInUserUnqId || !rgtr || rgtr !== loggedInUserUnqId) return false;
+
+ if (docSeComCd === "CNFM") return prgrsSttsComCd === "CV";
+
+ if (docSeComCd === "INSTL" || docSeComCd === "FNRS" || docSeComCd === "SEWER")
+ return prgrsSttsComCd === "SV" || prgrsSttsComCd === "SL";
+
+ return false;
+}
+
+export { canEditPbadmsDoc };
+export type { CanEditPbadmsDocParams };
diff --git a/apps/as/src/widgets/pbadms-sprt/ui/pbadms-detail-gate.tsx b/apps/as/src/widgets/pbadms-sprt/ui/pbadms-detail-gate.tsx
new file mode 100644
index 000000000..3d70d21c8
--- /dev/null
+++ b/apps/as/src/widgets/pbadms-sprt/ui/pbadms-detail-gate.tsx
@@ -0,0 +1,59 @@
+"use client";
+
+import { type ReactNode, useEffect } from "react";
+import { useRouter } from "next/navigation";
+
+import { Skeleton } from "@common/components";
+
+interface PbadmsDetailGateProps {
+ isPending: boolean;
+ isError: boolean;
+ shouldRedirectToEdit: boolean;
+ editHref: string;
+ children: ReactNode;
+ errorMessage?: string;
+}
+
+function DetailSkeleton() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+function PbadmsDetailGate({
+ isPending,
+ isError,
+ shouldRedirectToEdit,
+ editHref,
+ children,
+ errorMessage = "상세 정보를 찾을 수 없습니다.",
+}: PbadmsDetailGateProps) {
+ const router = useRouter();
+
+ useEffect(() => {
+ if (!shouldRedirectToEdit) return;
+ router.replace(editHref);
+ }, [editHref, router, shouldRedirectToEdit]);
+
+ if (isPending || shouldRedirectToEdit) return ;
+
+ if (isError) return {errorMessage}
;
+
+ return children;
+}
+
+export { PbadmsDetailGate };
+export type { PbadmsDetailGateProps };