diff --git a/apps/as/package.json b/apps/as/package.json
index 389b5bc05..0ca386f38 100644
--- a/apps/as/package.json
+++ b/apps/as/package.json
@@ -17,6 +17,7 @@
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@faker-js/faker": "^9.9.0",
+ "@frontend-opensource/use-react-hooks": "^1.1.4",
"@hookform/resolvers": "^4.1.3",
"@tanstack/react-query": "^5.75.5",
"@tanstack/react-query-devtools": "^5.75.5",
diff --git a/apps/as/src/app/providers/index.tsx b/apps/as/src/app/providers/index.tsx
index 35ca749f8..20ec0b72e 100644
--- a/apps/as/src/app/providers/index.tsx
+++ b/apps/as/src/app/providers/index.tsx
@@ -1,11 +1,13 @@
"use client";
+import { ConfirmProvider } from "@frontend-opensource/use-react-hooks";
import { QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import { queryClient } from "@/shared/lib";
import { StoreProvider } from "@/shared/providers";
import { AlertDialog } from "@/shared/ui/alert-dialog";
+import { ConfirmDialog } from "@/shared/ui/confirm-dialog";
import { AuthWrapper } from "@/entities/auth";
import { MenuWrapper } from "@/entities/menu";
@@ -17,10 +19,13 @@ export function Providers({ children }: ProvidersProps) {
return (
-
- {children}
-
-
+
+
+ {children}
+
+
+
+
diff --git a/apps/as/src/pages/approval-line-management/ui/elapr-apln-grid.tsx b/apps/as/src/pages/approval-line-management/ui/elapr-apln-grid.tsx
index e3647d441..d2112c011 100644
--- a/apps/as/src/pages/approval-line-management/ui/elapr-apln-grid.tsx
+++ b/apps/as/src/pages/approval-line-management/ui/elapr-apln-grid.tsx
@@ -4,6 +4,7 @@ import { useState } from "react";
import { closestCenter, DndContext, type DragEndEvent } from "@dnd-kit/core";
import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
+import { useConfirm } from "@frontend-opensource/use-react-hooks";
import { useAlertStore } from "@/shared/lib";
import {
@@ -37,6 +38,7 @@ interface ElaprAplnGridProps {
}
function ElaprAplnGrid({ elaprTmpltId }: ElaprAplnGridProps) {
+ const { confirm } = useConfirm();
const [pickerOpen, setPickerOpen] = useState(false);
const [pickingRowKey, setPickingRowKey] = useState(null);
@@ -129,7 +131,7 @@ function ElaprAplnGrid({ elaprTmpltId }: ElaprAplnGridProps) {
};
const handleRowDelete = async (row: ElaprAplnRow) => {
- if (!window.confirm("선택한 결재선을 삭제하시겠습니까?")) return;
+ if (!(await confirm("선택한 결재선을 삭제하시겠습니까?"))) return;
if (row.isNew) {
removeRowLocal(row.rowKey);
diff --git a/apps/as/src/pages/approval-line-management/ui/elapr-tmplt-list.tsx b/apps/as/src/pages/approval-line-management/ui/elapr-tmplt-list.tsx
index ae2b97e4c..23e929610 100644
--- a/apps/as/src/pages/approval-line-management/ui/elapr-tmplt-list.tsx
+++ b/apps/as/src/pages/approval-line-management/ui/elapr-tmplt-list.tsx
@@ -2,6 +2,7 @@
import { useMemo, useState } from "react";
+import { useConfirm } from "@frontend-opensource/use-react-hooks";
import { getCoreRowModel, type RowSelectionState } from "@tanstack/react-table";
import { useDataTable } from "@/shared/lib";
@@ -24,6 +25,7 @@ interface ElaprTmpltListProps {
}
function ElaprTmpltList({ selectedTmpltId, onSelectTmplt }: ElaprTmpltListProps) {
+ const { confirm } = useConfirm();
const [dialogMode, setDialogMode] = useState<"create" | "edit" | null>(null);
const [editingTmplt, setEditingTmplt] = useState(null);
const [rowSelection, setRowSelection] = useState({});
@@ -46,14 +48,14 @@ function ElaprTmpltList({ selectedTmpltId, onSelectTmplt }: ElaprTmpltListProps)
setDialogMode("edit");
},
onDelete: async (row) => {
- if (!window.confirm("선택한 결재서식을 삭제하시겠습니까?")) return;
+ if (!(await confirm("선택한 결재서식을 삭제하시겠습니까?"))) return;
await deleteMutation.mutateAsync(row.elaprTmpltId);
if (selectedTmpltId === row.elaprTmpltId) {
onSelectTmplt(null);
}
},
}),
- [deleteMutation, onSelectTmplt, selectedTmpltId],
+ [confirm, deleteMutation, onSelectTmplt, selectedTmpltId],
);
const { tableComponent } = useDataTable({
diff --git a/apps/as/src/pages/checklist-management/ui/cklst-artcl-list.tsx b/apps/as/src/pages/checklist-management/ui/cklst-artcl-list.tsx
index 6b0eec77b..3f4bdd3f5 100644
--- a/apps/as/src/pages/checklist-management/ui/cklst-artcl-list.tsx
+++ b/apps/as/src/pages/checklist-management/ui/cklst-artcl-list.tsx
@@ -2,6 +2,7 @@
import { useMemo, useState } from "react";
+import { useConfirm } from "@frontend-opensource/use-react-hooks";
import { getCoreRowModel, useReactTable } from "@tanstack/react-table";
import { matchQueryStatus } from "@/shared/lib";
@@ -24,6 +25,7 @@ interface CklstArtclListProps {
}
function CklstArtclList({ cklstSn }: CklstArtclListProps) {
+ const { confirm } = useConfirm();
const [dialogMode, setDialogMode] = useState<"create" | "edit" | null>(null);
const [editingArtcl, setEditingArtcl] = useState(null);
@@ -40,14 +42,14 @@ function CklstArtclList({ cklstSn }: CklstArtclListProps) {
setDialogMode("edit");
},
onDelete: async (row) => {
- if (!window.confirm("선택한 점검항목을 삭제하시겠습니까?")) return;
+ if (!(await confirm("선택한 점검항목을 삭제하시겠습니까?"))) return;
await deleteMutation.mutateAsync({
cklstArtclSn: row.cklstArtclSn,
cklstSn: row.cklstSn,
});
},
}),
- [deleteMutation],
+ [confirm, deleteMutation],
);
const table = useReactTable({
diff --git a/apps/as/src/pages/checklist-management/ui/cklst-mng-form-dialog.tsx b/apps/as/src/pages/checklist-management/ui/cklst-mng-form-dialog.tsx
index f00eead5d..8ff919256 100644
--- a/apps/as/src/pages/checklist-management/ui/cklst-mng-form-dialog.tsx
+++ b/apps/as/src/pages/checklist-management/ui/cklst-mng-form-dialog.tsx
@@ -95,7 +95,7 @@ function CklstMngFormDialog({
diff --git a/apps/as/src/pages/checklist-management/ui/cklst-mng-list.tsx b/apps/as/src/pages/checklist-management/ui/cklst-mng-list.tsx
index bf9f11376..a6a3eaa0e 100644
--- a/apps/as/src/pages/checklist-management/ui/cklst-mng-list.tsx
+++ b/apps/as/src/pages/checklist-management/ui/cklst-mng-list.tsx
@@ -2,6 +2,7 @@
import { useMemo, useState } from "react";
+import { useConfirm } from "@frontend-opensource/use-react-hooks";
import { getCoreRowModel, type RowSelectionState } from "@tanstack/react-table";
import { useDataTable } from "@/shared/lib";
@@ -24,6 +25,7 @@ interface CklstMngListProps {
}
function CklstMngList({ selectedCklstSn, onSelectCklst }: CklstMngListProps) {
+ const { confirm } = useConfirm();
const [dialogMode, setDialogMode] = useState<"create" | "edit" | null>(null);
const [editingCklst, setEditingCklst] = useState(null);
const [rowSelection, setRowSelection] = useState(() =>
@@ -48,7 +50,7 @@ function CklstMngList({ selectedCklstSn, onSelectCklst }: CklstMngListProps) {
setDialogMode("edit");
},
onDelete: async (row) => {
- if (!window.confirm("선택한 점검표를 삭제하시겠습니까?")) return;
+ if (!(await confirm("선택한 점검표를 삭제하시겠습니까?"))) return;
await deleteMutation.mutateAsync(row.cklstSn);
if (selectedCklstSn === row.cklstSn) {
onSelectCklst(null);
@@ -56,7 +58,7 @@ function CklstMngList({ selectedCklstSn, onSelectCklst }: CklstMngListProps) {
}
},
}),
- [deleteMutation, onSelectCklst, selectedCklstSn],
+ [confirm, deleteMutation, onSelectCklst, selectedCklstSn],
);
const { tableComponent } = useDataTable({
diff --git a/apps/as/src/pages/checklist-management/ui/cklst-rvw-grid.tsx b/apps/as/src/pages/checklist-management/ui/cklst-rvw-grid.tsx
index 8c9b41b81..e44a7743b 100644
--- a/apps/as/src/pages/checklist-management/ui/cklst-rvw-grid.tsx
+++ b/apps/as/src/pages/checklist-management/ui/cklst-rvw-grid.tsx
@@ -2,6 +2,8 @@
import { useCallback, useEffect, useMemo, useState } from "react";
+import { useConfirm } from "@frontend-opensource/use-react-hooks";
+
import { useAlertStore } from "@/shared/lib";
import type { CklstMng, CklstRvw } from "@/entities/cklst";
import {
@@ -51,6 +53,7 @@ function validateRvwRow(row: CklstRvwRow): string | null {
}
function CklstRvwGrid({ selectedCklst }: CklstRvwGridProps) {
+ const { confirm } = useConfirm();
const [rows, setRows] = useState([]);
const [previewOpen, setPreviewOpen] = useState(false);
@@ -152,7 +155,7 @@ function CklstRvwGrid({ selectedCklst }: CklstRvwGridProps) {
);
const handleDelete = async (row: CklstRvwRow) => {
- if (!window.confirm("선택한 항목을 삭제하시겠습니까?")) return;
+ if (!(await confirm("선택한 항목을 삭제하시겠습니까?"))) return;
if (row.isNew) {
removeRowLocal(row.rowKey);
diff --git a/apps/as/src/shared/ui/confirm-dialog.tsx b/apps/as/src/shared/ui/confirm-dialog.tsx
new file mode 100644
index 000000000..1b41e3c19
--- /dev/null
+++ b/apps/as/src/shared/ui/confirm-dialog.tsx
@@ -0,0 +1,45 @@
+"use client";
+
+import { useConfirm } from "@frontend-opensource/use-react-hooks";
+
+import {
+ Button,
+ type ButtonProps,
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogFooter,
+} from "@common/components";
+
+type ConfirmDialogProps = {
+ isOpen?: boolean;
+ confirmButtonProps?: ButtonProps & { label?: string };
+ cancelButtonProps?: ButtonProps & { label?: string };
+};
+
+function ConfirmDialog({ isOpen, confirmButtonProps, cancelButtonProps }: ConfirmDialogProps) {
+ const { message, isOpen: isGlobalOpen, onConfirm, onCancel } = useConfirm();
+ return (
+
+ );
+}
+
+export { ConfirmDialog };
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index ffdec8326..8384faaea 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -104,10 +104,10 @@ importers:
devDependencies:
eslint:
specifier: ^9.0.0
- version: 9.39.4(jiti@2.6.1)
+ version: 9.39.4(jiti@1.21.7)
eslint-config-next:
specifier: 15.3.8
- version: 15.3.8(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)
+ version: 15.3.8(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3)
postcss:
specifier: ^8.4.49
version: 8.5.8
@@ -150,6 +150,9 @@ importers:
'@faker-js/faker':
specifier: ^9.9.0
version: 9.9.0
+ '@frontend-opensource/use-react-hooks':
+ specifier: ^1.1.4
+ version: 1.1.4
'@hookform/resolvers':
specifier: ^4.1.3
version: 4.1.3(react-hook-form@7.72.0(react@19.2.4))
@@ -192,13 +195,13 @@ importers:
version: 3.0.6
eslint:
specifier: ^9.0.0
- version: 9.39.4(jiti@1.21.7)
+ version: 9.39.4(jiti@2.6.1)
eslint-config-next:
specifier: 15.3.8
- version: 15.3.8(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3)
+ version: 15.3.8(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)
eslint-plugin-react-hooks:
specifier: ^5.0.0
- version: 5.2.0(eslint@9.39.4(jiti@1.21.7))
+ version: 5.2.0(eslint@9.39.4(jiti@2.6.1))
postcss:
specifier: ^8.4.49
version: 8.5.8