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 ( + + +
+

{message}

+
+ + + + + + + + +
+
+ ); +} + +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