feat: 관리자 선택삭제 기능 작업

This commit is contained in:
2025-06-19 13:39:27 +09:00
parent 46a96a04fb
commit 0c76036529
2 changed files with 99 additions and 10 deletions
@@ -38,10 +38,12 @@ import { GroupApi } from "@/entities/group";
import { GroupUsersApi } from "@/entities/group-user";
import { ENDPOINT } from "@/shared/config";
import { useAlertStore, useDataTable } from "@/shared/lib";
import { useConfirm } from "@frontend-opensource/use-react-hooks";
function AddAdminDialog() {
const queryClient = useQueryClient();
const alert = useAlertStore((state) => state.setMessage);
const { confirm } = useConfirm();
const [open, setOpen] = useState(false);
const [userSearchQuery, setUserSearchQuery] = useState<UserSearchParams>({
@@ -145,8 +147,8 @@ function AddAdminDialog() {
const handleAddAdmins = async () => {
const selectedRows = Object.keys(rowSelection);
if (selectedRows.length === 0 || !selectedGroupId) {
alert("그룹과 사용자를 선택해주세요.");
if (!(await confirm("관리자를 추가하시겠습니까?"))) {
return;
}
@@ -182,7 +184,7 @@ function AddAdminDialog() {
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button>관리자 추가</Button>
<Button>관리자추가</Button>
</DialogTrigger>
<DialogContent className="max-w-4xl">
<DialogHeader>
+94 -7
View File
@@ -1,8 +1,14 @@
"use client";
import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { getCoreRowModel, type PaginationState } from "@tanstack/react-table";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import {
getCoreRowModel,
type PaginationState,
type RowSelectionState,
type Table,
type Row,
} from "@tanstack/react-table";
import {
Button,
Input,
@@ -12,15 +18,26 @@ import {
SelectItem,
SelectTrigger,
SelectValue,
Checkbox,
} from "@common/components";
import { GroupApi } from "@/entities/group";
import { UserApi, type UserSearchParams } from "@/entities/user";
import {
UserApi,
type UserSearchParams,
type AdminUserListResponse,
} from "@/entities/user";
import { ENDPOINT } from "@/shared/config";
import { useDataTable } from "@/shared/lib";
import { useDataTable, useAlertStore } from "@/shared/lib";
import { columns } from "../model/table-columns";
import { AddAdminDialog } from "./add-admin-dialog";
import { GroupUsersApi } from "@/entities/group-user";
import { useConfirm } from "@frontend-opensource/use-react-hooks";
function AdminPage() {
const queryClient = useQueryClient();
const alert = useAlertStore((state) => state.setMessage);
const { confirm } = useConfirm();
const [adminQuery, setAdminQuery] = useState<UserSearchParams>({
keywordType: "",
keyword: "",
@@ -30,6 +47,7 @@ function AdminPage() {
pageIndex: 0,
pageSize: 10,
});
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
const { data: groupOptions } = useQuery({
queryKey: [ENDPOINT.CMS_SERVICE.GROUPS],
@@ -57,16 +75,47 @@ function AdminPage() {
}),
});
const adminColumns = [
{
id: "select",
header: ({ table }: { table: Table<AdminUserListResponse> }) => (
<Checkbox
checked={
table.getIsAllPageRowsSelected() ||
(table.getIsSomePageRowsSelected() && "indeterminate")
}
onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
aria-label="전체 선택"
/>
),
cell: ({ row }: { row: Row<AdminUserListResponse> }) => (
<Checkbox
checked={row.getIsSelected()}
onCheckedChange={(value) => row.toggleSelected(!!value)}
aria-label="행 선택"
/>
),
enableSorting: false,
enableHiding: false,
},
...columns,
];
const { tableComponent } = useDataTable({
query,
tableOptions: {
columns,
columns: adminColumns,
state: {
pagination,
rowSelection,
},
manualPagination: true,
enableRowSelection: true,
enableMultiRowSelection: true,
getCoreRowModel: getCoreRowModel(),
onPaginationChange: setPagination,
onRowSelectionChange: setRowSelection,
getRowId: (row) => row.userUnqId,
},
dataTableOptions: {
viewPagination: true,
@@ -78,6 +127,37 @@ function AdminPage() {
query.refetch();
};
const handleDeleteAdmins = async () => {
const selectedRows = Object.keys(rowSelection);
if (!(await confirm("관리자를 삭제하시겠습니까?"))) {
return;
}
try {
const usersToDelete = selectedRows.map((userUnqId) => {
const admin = query.data?.content.find(
(item) => item.userUnqId === userUnqId,
);
return {
mode: "D",
groupId: admin?.groupId || "",
userUnqId,
};
});
await GroupUsersApi.saveGroupUser(usersToDelete);
queryClient.invalidateQueries({
queryKey: [ENDPOINT.USER_SERVICE.USERS],
});
alert("관리자 삭제를 완료했습니다.");
setRowSelection({});
} catch (error) {
console.error(error);
}
};
return (
<div className="card card-border !mt-6">
<div className="card card-border">
@@ -110,7 +190,7 @@ function AdminPage() {
setAdminQuery({ ...adminQuery, keywordType: value })
}
>
<SelectTrigger className="h-[3.2rem] w-[12rem] !text-[1.3rem]">
<SelectTrigger className="h-[3.2rem] w-[10rem] !text-[1.3rem]">
<SelectValue placeholder="선택" />
</SelectTrigger>
<SelectContent>
@@ -119,7 +199,7 @@ function AdminPage() {
</SelectContent>
</Select>
<Input
className="h-[3.2rem] w-[20rem] rounded-sm !text-[1.3rem]"
className="h-[3.2rem] w-[24rem] rounded-sm !text-[1.3rem]"
value={adminQuery.keyword}
onChange={(e) =>
setAdminQuery({ ...adminQuery, keyword: e.target.value })
@@ -140,6 +220,13 @@ function AdminPage() {
</h3>
<div className="flex gap-2">
<AddAdminDialog />
<Button
color="red"
onClick={handleDeleteAdmins}
disabled={Object.keys(rowSelection).length === 0}
>
선택삭제
</Button>
</div>
</div>
</div>