forked from baron/baron-sso
역할부여 페이지 제거
This commit is contained in:
@@ -1,34 +0,0 @@
|
|||||||
import { ChevronLeft } from "lucide-react";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import { Button } from "../../components/ui/button";
|
|
||||||
|
|
||||||
function RoleCreatePage() {
|
|
||||||
return (
|
|
||||||
<div className="space-y-8">
|
|
||||||
<header className="space-y-2">
|
|
||||||
<Link
|
|
||||||
to="/roles"
|
|
||||||
className="flex items-center gap-1 text-sm text-[var(--color-muted)] hover:text-foreground"
|
|
||||||
>
|
|
||||||
<ChevronLeft size={14} />
|
|
||||||
Back to list
|
|
||||||
</Link>
|
|
||||||
<h2 className="text-3xl font-semibold">새 역할 추가</h2>
|
|
||||||
<p className="text-sm text-[var(--color-muted)]">
|
|
||||||
새로운 사용자 역할을 정의하고 권한을 할당합니다.
|
|
||||||
</p>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div className="rounded-lg border border-dashed p-12 text-center">
|
|
||||||
<p className="text-[var(--color-muted)]">
|
|
||||||
역할 생성 폼이 여기에 구현될 예정입니다.
|
|
||||||
</p>
|
|
||||||
<Button className="mt-4" disabled>
|
|
||||||
추가하기 (준비 중)
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default RoleCreatePage;
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import { ChevronLeft } from "lucide-react";
|
|
||||||
import { Link, useParams } from "react-router-dom";
|
|
||||||
import { Button } from "../../components/ui/button";
|
|
||||||
|
|
||||||
function RoleDetailPage() {
|
|
||||||
const { id } = useParams();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="space-y-8">
|
|
||||||
<header className="space-y-2">
|
|
||||||
<Link
|
|
||||||
to="/roles"
|
|
||||||
className="flex items-center gap-1 text-sm text-[var(--color-muted)] hover:text-foreground"
|
|
||||||
>
|
|
||||||
<ChevronLeft size={14} />
|
|
||||||
Back to list
|
|
||||||
</Link>
|
|
||||||
<h2 className="text-3xl font-semibold">역할 상세</h2>
|
|
||||||
<p className="text-sm text-[var(--color-muted)]">역할 ID: {id}</p>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div className="rounded-lg border border-dashed p-12 text-center">
|
|
||||||
<p className="text-[var(--color-muted)]">
|
|
||||||
역할 상세 정보 및 권한 편집 화면이 여기에 구현될 예정입니다.
|
|
||||||
</p>
|
|
||||||
<Button className="mt-4" variant="outline" disabled>
|
|
||||||
수정하기 (준비 중)
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default RoleDetailPage;
|
|
||||||
@@ -1,172 +0,0 @@
|
|||||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
||||||
import type { AxiosError } from "axios";
|
|
||||||
import { Plus, RefreshCw, Shield, Trash2 } from "lucide-react";
|
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
|
||||||
import { Badge } from "../../components/ui/badge";
|
|
||||||
import { Button } from "../../components/ui/button";
|
|
||||||
import {
|
|
||||||
Card,
|
|
||||||
CardContent,
|
|
||||||
CardDescription,
|
|
||||||
CardHeader,
|
|
||||||
CardTitle,
|
|
||||||
} from "../../components/ui/card";
|
|
||||||
import {
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableHead,
|
|
||||||
TableHeader,
|
|
||||||
TableRow,
|
|
||||||
} from "../../components/ui/table";
|
|
||||||
import { deleteRole, fetchRoles } from "../../lib/adminApi";
|
|
||||||
|
|
||||||
function RoleListPage() {
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const query = useQuery({
|
|
||||||
queryKey: ["roles", { limit: 50, offset: 0 }],
|
|
||||||
queryFn: () => fetchRoles(50, 0),
|
|
||||||
});
|
|
||||||
|
|
||||||
const deleteMutation = useMutation({
|
|
||||||
mutationFn: (id: string) => deleteRole(id),
|
|
||||||
onSuccess: () => {
|
|
||||||
query.refetch();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const errorMsg = (query.error as AxiosError<{ error?: string }>)?.response
|
|
||||||
?.data?.error;
|
|
||||||
const fallbackError =
|
|
||||||
!errorMsg && query.isError ? "역할 목록 조회에 실패했습니다." : null;
|
|
||||||
|
|
||||||
const items = query.data?.items ?? [];
|
|
||||||
|
|
||||||
const handleDelete = (id: string, name: string) => {
|
|
||||||
if (!window.confirm(`역할 "${name}"을 삭제할까요?`)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
deleteMutation.mutate(id);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="space-y-8">
|
|
||||||
<header className="flex flex-wrap items-start justify-between gap-4">
|
|
||||||
<div className="space-y-2">
|
|
||||||
<div className="flex items-center gap-2 text-sm text-[var(--color-muted)]">
|
|
||||||
<span>Roles</span>
|
|
||||||
<span>/</span>
|
|
||||||
<span className="text-foreground">List</span>
|
|
||||||
</div>
|
|
||||||
<h2 className="text-3xl font-semibold">역할 및 권한 (RBAC)</h2>
|
|
||||||
<p className="text-sm text-[var(--color-muted)]">
|
|
||||||
사용자에게 부여할 역할과 해당 역할의 세부 권한을 관리합니다.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
onClick={() => query.refetch()}
|
|
||||||
disabled={query.isFetching}
|
|
||||||
>
|
|
||||||
<RefreshCw size={16} />
|
|
||||||
새로고침
|
|
||||||
</Button>
|
|
||||||
<Button asChild>
|
|
||||||
<Link to="/roles/new">
|
|
||||||
<Plus size={16} />
|
|
||||||
역할 추가
|
|
||||||
</Link>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<Card className="bg-[var(--color-panel)]">
|
|
||||||
<CardHeader className="flex flex-row items-center justify-between">
|
|
||||||
<div>
|
|
||||||
<CardTitle>Role Management</CardTitle>
|
|
||||||
<CardDescription>
|
|
||||||
총 {query.data?.total ?? 0}개 역할 정의됨
|
|
||||||
</CardDescription>
|
|
||||||
</div>
|
|
||||||
<Badge variant="muted">RBAC</Badge>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
{(errorMsg || fallbackError) && (
|
|
||||||
<div className="mb-4 rounded-lg border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive">
|
|
||||||
{errorMsg ?? fallbackError}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Table>
|
|
||||||
<TableHeader>
|
|
||||||
<TableRow>
|
|
||||||
<TableHead>ROLE NAME</TableHead>
|
|
||||||
<TableHead>DESCRIPTION</TableHead>
|
|
||||||
<TableHead>PERMISSIONS</TableHead>
|
|
||||||
<TableHead className="text-right">ACTIONS</TableHead>
|
|
||||||
</TableRow>
|
|
||||||
</TableHeader>
|
|
||||||
<TableBody>
|
|
||||||
{query.isLoading && (
|
|
||||||
<TableRow>
|
|
||||||
<TableCell colSpan={4}>로딩 중...</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
)}
|
|
||||||
{!query.isLoading && items.length === 0 && (
|
|
||||||
<TableRow>
|
|
||||||
<TableCell colSpan={4}>정의된 역할이 없습니다.</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
)}
|
|
||||||
{items.map((role) => (
|
|
||||||
<TableRow key={role.id}>
|
|
||||||
<TableCell className="font-semibold">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<Shield size={14} className="text-[var(--color-muted)]" />
|
|
||||||
{role.name}
|
|
||||||
</div>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="text-sm">{role.description}</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<div className="flex flex-wrap gap-1">
|
|
||||||
{role.permissions.map((p) => (
|
|
||||||
<Badge
|
|
||||||
key={p}
|
|
||||||
variant="default"
|
|
||||||
className="text-[10px]"
|
|
||||||
>
|
|
||||||
{p}
|
|
||||||
</Badge>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="text-right">
|
|
||||||
<div className="flex justify-end gap-2">
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => navigate(`/roles/${role.id}`)}
|
|
||||||
>
|
|
||||||
상세
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => handleDelete(role.id, role.name)}
|
|
||||||
disabled={deleteMutation.isPending}
|
|
||||||
>
|
|
||||||
<Trash2 size={14} />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default RoleListPage;
|
|
||||||
Reference in New Issue
Block a user