From 0c76036529ce2e7ab8b644fe088bede9041738c8 Mon Sep 17 00:00:00 2001 From: bicochan Date: Thu, 19 Jun 2025 13:39:27 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20=EC=84=A0?= =?UTF-8?q?=ED=83=9D=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EC=9E=91?= =?UTF-8?q?=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/admin/ui/add-admin-dialog.tsx | 8 +- apps/cs/src/pages/admin/ui/admin-page.tsx | 101 ++++++++++++++++-- 2 files changed, 99 insertions(+), 10 deletions(-) diff --git a/apps/cs/src/pages/admin/ui/add-admin-dialog.tsx b/apps/cs/src/pages/admin/ui/add-admin-dialog.tsx index 1723f39f0..c7ce5fb85 100644 --- a/apps/cs/src/pages/admin/ui/add-admin-dialog.tsx +++ b/apps/cs/src/pages/admin/ui/add-admin-dialog.tsx @@ -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({ @@ -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 ( - + diff --git a/apps/cs/src/pages/admin/ui/admin-page.tsx b/apps/cs/src/pages/admin/ui/admin-page.tsx index 6507e98fa..2599fa752 100644 --- a/apps/cs/src/pages/admin/ui/admin-page.tsx +++ b/apps/cs/src/pages/admin/ui/admin-page.tsx @@ -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({ keywordType: "", keyword: "", @@ -30,6 +47,7 @@ function AdminPage() { pageIndex: 0, pageSize: 10, }); + const [rowSelection, setRowSelection] = useState({}); const { data: groupOptions } = useQuery({ queryKey: [ENDPOINT.CMS_SERVICE.GROUPS], @@ -57,16 +75,47 @@ function AdminPage() { }), }); + const adminColumns = [ + { + id: "select", + header: ({ table }: { table: Table }) => ( + table.toggleAllPageRowsSelected(!!value)} + aria-label="전체 선택" + /> + ), + cell: ({ row }: { row: Row }) => ( + 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 (
@@ -110,7 +190,7 @@ function AdminPage() { setAdminQuery({ ...adminQuery, keywordType: value }) } > - + @@ -119,7 +199,7 @@ function AdminPage() { setAdminQuery({ ...adminQuery, keyword: e.target.value }) @@ -140,6 +220,13 @@ function AdminPage() {
+