[as] refactor: useConfirm 적용

This commit is contained in:
2026-05-21 11:35:47 +09:00
parent 24c446b880
commit 0ef375310f
10 changed files with 83 additions and 18 deletions
+1
View File
@@ -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",
+9 -4
View File
@@ -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 (
<QueryClientProvider client={queryClient}>
<StoreProvider>
<AuthWrapper>
<MenuWrapper>{children}</MenuWrapper>
<AlertDialog />
</AuthWrapper>
<ConfirmProvider>
<AuthWrapper>
<MenuWrapper>{children}</MenuWrapper>
<AlertDialog />
<ConfirmDialog />
</AuthWrapper>
</ConfirmProvider>
</StoreProvider>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
@@ -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<string | null>(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);
@@ -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<ElaprTmplt | null>(null);
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
@@ -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({
@@ -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<CklstArtcl | null>(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({
@@ -95,7 +95,7 @@ function CklstMngFormDialog({
<Label htmlFor="cklstNm">점검표명</Label>
<Input
id="cklstNm"
placeholder="예: 설치인가 체크리스트"
placeholder="점검표명 입력"
{...register("cklstNm", { required: true })}
/>
</div>
@@ -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<CklstMng | null>(null);
const [rowSelection, setRowSelection] = useState<RowSelectionState>(() =>
@@ -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({
@@ -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<CklstRvwRow[]>([]);
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);
+45
View File
@@ -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 (
<Dialog open={isOpen ?? isGlobalOpen} onOpenChange={onCancel}>
<DialogContent aria-describedby={undefined}>
<div className="py-10">
<p className="whitespace-pre-line text-center text-[1.4rem] text-foreground">{message}</p>
</div>
<DialogFooter className="!justify-center">
<DialogClose asChild>
<Button onClick={onConfirm} {...confirmButtonProps}>
{confirmButtonProps?.label ?? "확인"}
</Button>
</DialogClose>
<DialogClose asChild>
<Button onClick={onCancel} color="white" {...cancelButtonProps}>
{cancelButtonProps?.label ?? "취소"}
</Button>
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
export { ConfirmDialog };
+8 -5
View File
@@ -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