feat: adopt kumo green ui system
This commit is contained in:
@@ -2,6 +2,7 @@ import { Activity, Building2, Server, ShieldCheck, Users } from "lucide-react";
|
||||
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Table } from "@/components/ui/table";
|
||||
import type {
|
||||
AuditLog,
|
||||
JoinRequest,
|
||||
@@ -191,39 +192,39 @@ export function SettingsOverview({
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="overflow-x-auto rounded-md border">
|
||||
<table className="w-full min-w-[560px] text-sm">
|
||||
<thead className="bg-secondary text-left text-xs text-muted-foreground">
|
||||
<tr>
|
||||
<th className="px-4 py-3 font-medium">机构</th>
|
||||
<th className="px-4 py-3 font-medium">Slug</th>
|
||||
<th className="px-4 py-3 font-medium">状态</th>
|
||||
<th className="px-4 py-3 text-right font-medium">创建时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y bg-card">
|
||||
<Table className="w-full min-w-[560px] text-sm">
|
||||
<Table.Header className="bg-secondary text-left text-xs text-muted-foreground">
|
||||
<Table.Row>
|
||||
<Table.Head className="px-4 py-3 font-medium">机构</Table.Head>
|
||||
<Table.Head className="px-4 py-3 font-medium">Slug</Table.Head>
|
||||
<Table.Head className="px-4 py-3 font-medium">状态</Table.Head>
|
||||
<Table.Head className="px-4 py-3 text-right font-medium">创建时间</Table.Head>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body className="divide-y bg-card">
|
||||
{organizations.map((organization) => (
|
||||
<tr key={organization.id}>
|
||||
<td className="px-4 py-3 font-medium">{organization.name}</td>
|
||||
<td className="px-4 py-3 text-muted-foreground">{organization.slug}</td>
|
||||
<td className="px-4 py-3">
|
||||
<Table.Row key={organization.id}>
|
||||
<Table.Cell className="px-4 py-3 font-medium">{organization.name}</Table.Cell>
|
||||
<Table.Cell className="px-4 py-3 text-muted-foreground">{organization.slug}</Table.Cell>
|
||||
<Table.Cell className="px-4 py-3">
|
||||
<Badge variant={organization.status === "active" ? "success" : "danger"}>
|
||||
{organization.status === "active" ? "启用" : "停用"}
|
||||
</Badge>
|
||||
</td>
|
||||
<td className="px-4 py-3 text-right text-muted-foreground">
|
||||
</Table.Cell>
|
||||
<Table.Cell className="px-4 py-3 text-right text-muted-foreground">
|
||||
{new Date(organization.createdAt).toLocaleString("zh-CN")}
|
||||
</td>
|
||||
</tr>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
{organizations.length === 0 ? (
|
||||
<tr>
|
||||
<td className="px-4 py-8 text-center text-muted-foreground" colSpan={4}>
|
||||
<Table.Row>
|
||||
<Table.Cell className="px-4 py-8 text-center text-muted-foreground" colSpan={4}>
|
||||
暂无机构
|
||||
</td>
|
||||
</tr>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
) : null}
|
||||
</tbody>
|
||||
</table>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -285,35 +286,35 @@ export function SettingsOverview({
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="overflow-x-auto rounded-md border">
|
||||
<table className="w-full min-w-[620px] text-sm">
|
||||
<thead className="bg-secondary text-left text-xs text-muted-foreground">
|
||||
<tr>
|
||||
<th className="px-4 py-3 font-medium">账号</th>
|
||||
<th className="px-4 py-3 font-medium">角色</th>
|
||||
<th className="px-4 py-3 font-medium">状态</th>
|
||||
<th className="px-4 py-3 text-right font-medium">创建时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y bg-card">
|
||||
<Table className="w-full min-w-[620px] text-sm">
|
||||
<Table.Header className="bg-secondary text-left text-xs text-muted-foreground">
|
||||
<Table.Row>
|
||||
<Table.Head className="px-4 py-3 font-medium">账号</Table.Head>
|
||||
<Table.Head className="px-4 py-3 font-medium">角色</Table.Head>
|
||||
<Table.Head className="px-4 py-3 font-medium">状态</Table.Head>
|
||||
<Table.Head className="px-4 py-3 text-right font-medium">创建时间</Table.Head>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body className="divide-y bg-card">
|
||||
{accounts.map((account) => (
|
||||
<tr key={account.id}>
|
||||
<td className="px-4 py-3">
|
||||
<Table.Row key={account.id}>
|
||||
<Table.Cell className="px-4 py-3">
|
||||
<p className="font-medium">{account.name}</p>
|
||||
<p className="text-xs text-muted-foreground">{account.email}</p>
|
||||
</td>
|
||||
<td className="px-4 py-3">{formatRoleLabel(account.role)}</td>
|
||||
<td className="px-4 py-3">
|
||||
</Table.Cell>
|
||||
<Table.Cell className="px-4 py-3">{formatRoleLabel(account.role)}</Table.Cell>
|
||||
<Table.Cell className="px-4 py-3">
|
||||
<Badge variant={account.status === "active" ? "success" : account.status === "pending" ? "warning" : "danger"}>
|
||||
{account.status === "active" ? "启用" : account.status === "pending" ? "待审批" : "停用"}
|
||||
</Badge>
|
||||
</td>
|
||||
<td className="px-4 py-3 text-right text-muted-foreground">
|
||||
</Table.Cell>
|
||||
<Table.Cell className="px-4 py-3 text-right text-muted-foreground">
|
||||
{new Date(account.createdAt).toLocaleString("zh-CN")}
|
||||
</td>
|
||||
</tr>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -325,41 +326,41 @@ export function SettingsOverview({
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="overflow-x-auto rounded-md border">
|
||||
<table className="w-full min-w-[720px] text-sm">
|
||||
<thead className="bg-secondary text-left text-xs text-muted-foreground">
|
||||
<tr>
|
||||
<th className="px-4 py-3 font-medium">账号 ID</th>
|
||||
<th className="px-4 py-3 font-medium">机构 ID</th>
|
||||
<th className="px-4 py-3 font-medium">角色</th>
|
||||
<th className="px-4 py-3 font-medium">状态</th>
|
||||
<th className="px-4 py-3 text-right font-medium">创建时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y bg-card">
|
||||
<Table className="w-full min-w-[720px] text-sm">
|
||||
<Table.Header className="bg-secondary text-left text-xs text-muted-foreground">
|
||||
<Table.Row>
|
||||
<Table.Head className="px-4 py-3 font-medium">账号 ID</Table.Head>
|
||||
<Table.Head className="px-4 py-3 font-medium">机构 ID</Table.Head>
|
||||
<Table.Head className="px-4 py-3 font-medium">角色</Table.Head>
|
||||
<Table.Head className="px-4 py-3 font-medium">状态</Table.Head>
|
||||
<Table.Head className="px-4 py-3 text-right font-medium">创建时间</Table.Head>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body className="divide-y bg-card">
|
||||
{memberships.map((membership) => (
|
||||
<tr key={membership.id}>
|
||||
<td className="px-4 py-3 text-muted-foreground">{membership.accountId.slice(0, 8)}</td>
|
||||
<td className="px-4 py-3 text-muted-foreground">{membership.organizationId.slice(0, 8)}</td>
|
||||
<td className="px-4 py-3">{membership.roleLabel}</td>
|
||||
<td className="px-4 py-3">
|
||||
<Table.Row key={membership.id}>
|
||||
<Table.Cell className="px-4 py-3 text-muted-foreground">{membership.accountId.slice(0, 8)}</Table.Cell>
|
||||
<Table.Cell className="px-4 py-3 text-muted-foreground">{membership.organizationId.slice(0, 8)}</Table.Cell>
|
||||
<Table.Cell className="px-4 py-3">{membership.roleLabel}</Table.Cell>
|
||||
<Table.Cell className="px-4 py-3">
|
||||
<Badge variant={membership.status === "active" ? "success" : membership.status === "pending" ? "warning" : "danger"}>
|
||||
{membership.status}
|
||||
</Badge>
|
||||
</td>
|
||||
<td className="px-4 py-3 text-right text-muted-foreground">
|
||||
</Table.Cell>
|
||||
<Table.Cell className="px-4 py-3 text-right text-muted-foreground">
|
||||
{new Date(membership.createdAt).toLocaleString("zh-CN")}
|
||||
</td>
|
||||
</tr>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
{memberships.length === 0 ? (
|
||||
<tr>
|
||||
<td className="px-4 py-8 text-center text-muted-foreground" colSpan={5}>
|
||||
<Table.Row>
|
||||
<Table.Cell className="px-4 py-8 text-center text-muted-foreground" colSpan={5}>
|
||||
暂无成员关系
|
||||
</td>
|
||||
</tr>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
) : null}
|
||||
</tbody>
|
||||
</table>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -370,30 +371,30 @@ export function SettingsOverview({
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="overflow-x-auto rounded-md border">
|
||||
<table className="w-full min-w-[860px] text-sm">
|
||||
<thead className="bg-secondary text-left text-xs text-muted-foreground">
|
||||
<tr>
|
||||
<th className="px-4 py-3 font-medium">时间</th>
|
||||
<th className="px-4 py-3 font-medium">操作者</th>
|
||||
<th className="px-4 py-3 font-medium">动作</th>
|
||||
<th className="px-4 py-3 font-medium">对象</th>
|
||||
<th className="px-4 py-3 font-medium">结果</th>
|
||||
<th className="px-4 py-3 font-medium">原因</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y bg-card">
|
||||
<Table className="w-full min-w-[860px] text-sm">
|
||||
<Table.Header className="bg-secondary text-left text-xs text-muted-foreground">
|
||||
<Table.Row>
|
||||
<Table.Head className="px-4 py-3 font-medium">时间</Table.Head>
|
||||
<Table.Head className="px-4 py-3 font-medium">操作者</Table.Head>
|
||||
<Table.Head className="px-4 py-3 font-medium">动作</Table.Head>
|
||||
<Table.Head className="px-4 py-3 font-medium">对象</Table.Head>
|
||||
<Table.Head className="px-4 py-3 font-medium">结果</Table.Head>
|
||||
<Table.Head className="px-4 py-3 font-medium">原因</Table.Head>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body className="divide-y bg-card">
|
||||
{auditLogs.map((log) => (
|
||||
<tr key={log.id}>
|
||||
<td className="px-4 py-3 text-muted-foreground">
|
||||
<Table.Row key={log.id}>
|
||||
<Table.Cell className="px-4 py-3 text-muted-foreground">
|
||||
{new Date(log.timestamp).toLocaleString("zh-CN")}
|
||||
</td>
|
||||
<td className="px-4 py-3">{log.actorEmail ?? "系统"}</td>
|
||||
<td className="px-4 py-3">{log.action}</td>
|
||||
<td className="px-4 py-3 text-muted-foreground">
|
||||
</Table.Cell>
|
||||
<Table.Cell className="px-4 py-3">{log.actorEmail ?? "系统"}</Table.Cell>
|
||||
<Table.Cell className="px-4 py-3">{log.action}</Table.Cell>
|
||||
<Table.Cell className="px-4 py-3 text-muted-foreground">
|
||||
{log.targetType}
|
||||
{log.targetId ? ` / ${log.targetId.slice(0, 8)}` : ""}
|
||||
</td>
|
||||
<td className="px-4 py-3">
|
||||
</Table.Cell>
|
||||
<Table.Cell className="px-4 py-3">
|
||||
<Badge
|
||||
variant={
|
||||
log.result === "success" ? "success" : log.result === "denied" ? "warning" : "danger"
|
||||
@@ -401,19 +402,19 @@ export function SettingsOverview({
|
||||
>
|
||||
{log.result}
|
||||
</Badge>
|
||||
</td>
|
||||
<td className="px-4 py-3 text-muted-foreground">{log.reason}</td>
|
||||
</tr>
|
||||
</Table.Cell>
|
||||
<Table.Cell className="px-4 py-3 text-muted-foreground">{log.reason}</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
{auditLogs.length === 0 ? (
|
||||
<tr>
|
||||
<td className="px-4 py-8 text-center text-muted-foreground" colSpan={6}>
|
||||
<Table.Row>
|
||||
<Table.Cell className="px-4 py-8 text-center text-muted-foreground" colSpan={6}>
|
||||
暂无审计日志
|
||||
</td>
|
||||
</tr>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
) : null}
|
||||
</tbody>
|
||||
</table>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
Reference in New Issue
Block a user