import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import type { AxiosError } from "axios"; import { Loader2, Mail, MoreHorizontal, Plus, User, UserMinus, UserPlus, } from "lucide-react"; import { Link, useNavigate, useParams } from "react-router-dom"; import { commonStickyTableHeaderClass } from "../../../../../common/ui/table"; import { Badge } from "../../../components/ui/badge"; import { Button } from "../../../components/ui/button"; import { Card, CardContent, CardHeader, CardTitle, } from "../../../components/ui/card"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "../../../components/ui/dropdown-menu"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "../../../components/ui/table"; import { toast } from "../../../components/ui/use-toast"; import { fetchTenant, fetchUsers, updateUser } from "../../../lib/adminApi"; import { t } from "../../../lib/i18n"; function TenantUsersPage() { const params = useParams<{ tenantId: string }>(); const navigate = useNavigate(); const tenantId = params.tenantId ?? ""; const queryClient = useQueryClient(); // 테넌트의 슬러그(tenantSlug)를 먼저 가져옴 const tenantQuery = useQuery({ queryKey: ["tenant", tenantId], queryFn: () => fetchTenant(tenantId), enabled: tenantId.length > 0, }); const tenantSlug = tenantQuery.data?.slug; // 해당 슬러그로 사용자 검색 const usersQuery = useQuery({ queryKey: ["users", { tenantSlug }], queryFn: () => fetchUsers(100, 0, undefined, tenantSlug), enabled: !!tenantSlug, }); const removeTenantMutation = useMutation({ mutationFn: ({ userId, slug }: { userId: string; slug: string }) => updateUser(userId, { tenantSlug: slug, isRemoveTenant: true }), onSuccess: () => { toast.success( t( "msg.admin.tenants.members.remove_success", "조직에서 제외되었습니다.", ), ); usersQuery.refetch(); queryClient.invalidateQueries({ queryKey: ["tenant", tenantId] }); }, onError: (err: AxiosError<{ error?: string }>) => { toast.error( err.response?.data?.error || t("msg.admin.tenants.members.remove_error", "제외 실패"), ); }, }); const handleRemoveMember = (userId: string, userName: string) => { if (!tenantSlug) return; if ( window.confirm( t( "msg.admin.tenants.members.remove_confirm", "'{{name}}'님을 이 조직에서 제외하시겠습니까?", { name: userName }, ), ) ) { removeTenantMutation.mutate({ userId, slug: tenantSlug }); } }; const users = usersQuery.data?.items ?? []; return ( {t("ui.admin.tenants.members.title", "Tenant Members ({{count}})", { count: users.length, })}
{t("ui.admin.tenants.members.table.name", "NAME")} {t("ui.admin.tenants.members.table.email", "EMAIL")} {t("ui.admin.tenants.members.table.role", "ROLE")} {t("ui.admin.tenants.members.table.status", "STATUS")} {usersQuery.isLoading ? (
{t("ui.common.loading", "Loading...")}
) : users.length === 0 ? ( {t( "msg.admin.tenants.members.empty", "소속된 사용자가 없습니다.", )} ) : ( users.map((user) => ( navigate(`/users/${user.id}`)} > {user.name}
{user.email}
{t( `ui.common.role.${user.role}`, user.role.replace("_", " "), )} {t(`ui.common.status.${user.status}`, user.status)}
)) )}
); } export default TenantUsersPage;