-
+
+ void loadData()} disabled={loading}>
+
+ 刷新
+
+ }
+ >
+
setGroupNameInput(event.target.value)}
onKeyDown={handleFilterKeyDown}
placeholder="按分组筛选"
- className="w-full xl:w-48"
+ className="w-full sm:w-44"
/>
-
+
+
+
-
-
-
-
+
+
{
+ setLimit(nextLimit)
+ setPage(1)
+ }}
+ />
+ }
+ >
@@ -202,28 +200,17 @@ export default function DashboardPermissionsPage() {
))}
- {!loading && result.results.length === 0 ? (
-
-
- 没有匹配的权限数据
-
-
+ {loading || result.results.length === 0 ? (
+
) : null}
-
-
{
- setLimit(nextLimit)
- setPage(1)
- }}
- />
-
-
+
+
)
}
diff --git a/web/app/dashboard/quick-replies/page.tsx b/web/app/dashboard/quick-replies/page.tsx
index 2aee8fc..67b1ed1 100644
--- a/web/app/dashboard/quick-replies/page.tsx
+++ b/web/app/dashboard/quick-replies/page.tsx
@@ -11,6 +11,32 @@ import {
} from "lucide-react"
import { toast } from "sonner"
+import {
+ DashboardPage,
+ DashboardTableShell,
+ DashboardTableStateRow,
+ DashboardToolbar,
+} from "@/components/dashboard-page"
+import { ListPagination } from "@/components/list-pagination"
+import { OptionCombobox } from "@/components/option-combobox"
+import { Badge } from "@/components/ui/badge"
+import { Button } from "@/components/ui/button"
+import { ButtonGroup } from "@/components/ui/button-group"
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from "@/components/ui/dropdown-menu"
+import { Input } from "@/components/ui/input"
+import {
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from "@/components/ui/table"
import {
createQuickReply,
deleteQuickReply,
@@ -23,32 +49,6 @@ import {
import { getEnumLabel, getEnumOptions } from "@/lib/enums"
import { Status, StatusLabels } from "@/lib/generated/enums"
import { EditDialog } from "./_components/edit"
-import { Badge } from "@/components/ui/badge"
-import { Button } from "@/components/ui/button"
-import { ButtonGroup } from "@/components/ui/button-group"
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuTrigger,
-} from "@/components/ui/dropdown-menu"
-import { Input } from "@/components/ui/input"
-import { ListPagination } from "@/components/list-pagination"
-import {
- Select,
- SelectContent,
- SelectItem,
- SelectTrigger,
- SelectValue,
-} from "@/components/ui/select"
-import {
- Table,
- TableBody,
- TableCell,
- TableHead,
- TableHeader,
- TableRow,
-} from "@/components/ui/table"
const listStatusOptions = [
{ value: "all", label: "全部状态" },
@@ -60,13 +60,6 @@ const listStatusOptions = [
})),
] as const
-function getStatusLabel(
- value: string,
- options: ReadonlyArray<{ value: string; label: string }>
-) {
- return options.find((item) => item.value === value)?.label ?? "请选择状态"
-}
-
export default function DashboardQuickRepliesPage() {
const [keywordInput, setKeywordInput] = useState("")
const [groupNameInput, setGroupNameInput] = useState("")
@@ -108,10 +101,6 @@ export default function DashboardQuickRepliesPage() {
void loadData()
}, [loadData])
- function handleStatusFilterChange(value: string | null) {
- setStatusFilterInput(value ?? "all")
- }
-
function applyFilters() {
setKeyword(keywordInput)
setGroupName(groupNameInput)
@@ -221,9 +210,22 @@ export default function DashboardQuickRepliesPage() {
return (
<>
-
-
-
+
+
+
+
+ >
+ }
+ >
+
setGroupNameInput(event.target.value)}
onKeyDown={handleFilterKeyDown}
placeholder="按分组筛选"
- className="w-full xl:w-48"
+ className="w-full sm:w-44"
/>
-
+
+
+
-
-
-
-
+
+
{
+ setLimit(nextLimit)
+ setPage(1)
+ }}
+ />
+ }
+ >
@@ -282,7 +286,7 @@ export default function DashboardQuickRepliesPage() {
-
+
@@ -345,29 +349,18 @@ export default function DashboardQuickRepliesPage() {
))}
- {!loading && result.results.length === 0 ? (
-
-
- 没有匹配的快捷回复
-
-
+ {loading || result.results.length === 0 ? (
+
) : null}
-
-
{
- setLimit(nextLimit)
- setPage(1)
- }}
- />
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+ >
+ }
+ >
+
+ 拖拽行可调整角色顺序
+
+
+
+
+ 第 {result.page.page} 页 / 每页 {result.page.limit} 条
+
+ 共 {result.page.total} 条记录
+
+ }
+ >
))}
- {!loading && result.results.length === 0 ? (
-
-
- 暂无角色数据
-
-
+ {loading || result.results.length === 0 ? (
+
) : null}
-
-
-
- 第 {result.page.page} 页 / 每页 {result.page.limit} 条
-
- 共 {result.page.total} 条记录
-
-
+
-
+
)
}
diff --git a/web/app/dashboard/tags/page.tsx b/web/app/dashboard/tags/page.tsx
index 71820e2..ac820bc 100644
--- a/web/app/dashboard/tags/page.tsx
+++ b/web/app/dashboard/tags/page.tsx
@@ -44,6 +44,12 @@ import {
type Tag,
type TagTree,
} from "@/lib/api/admin"
+import {
+ DashboardPage,
+ DashboardTableShell,
+ DashboardTableStateRow,
+ DashboardToolbar,
+} from "@/components/dashboard-page"
import { EditDialog } from "./_components/edit"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
@@ -531,9 +537,28 @@ export default function DashboardTagsPage() {
return (
<>
-
-
-
+
+
+
+
+
+
+ >
+ }
+ >
+
查询
-
-
-
-
-
-
-
+
+
))}
- {!loading && flatList.length === 0 ? (
-
-
- 没有匹配的标签
-
-
+ {loading || flatList.length === 0 ? (
+
) : null}
-
-
-
+
+
+ {children}
+
+ )
+}
+
+export function DashboardPageHeader({
+ title,
+ description,
+ actions,
+}: {
+ title: string
+ description?: ReactNode
+ actions?: ReactNode
+}) {
+ return (
+
+
+
{title}
+ {description ? (
+
+ {description}
+
+ ) : null}
+
+ {actions ? (
+
{actions}
+ ) : null}
+
+ )
+}
+
+export function DashboardToolbar({
+ className,
+ actions,
+ children,
+}: {
+ className?: string
+ actions?: ReactNode
+ children: ReactNode
+}) {
+ return (
+
+
+ {children}
+
+ {actions ? (
+
{actions}
+ ) : null}
+
+ )
+}
+
+export function DashboardTableShell({
+ className,
+ pagination,
+ children,
+}: {
+ className?: string
+ pagination?: ReactNode
+ children: ReactNode
+}) {
+ return (
+
+
+ {children}
+
+ {pagination ?
{pagination}
: null}
+
+ )
+}
+
+export function DashboardTableStateRow({
+ colSpan,
+ loading,
+ loadingText = "正在加载数据...",
+ emptyText = "暂无数据",
+}: {
+ colSpan: number
+ loading?: boolean
+ loadingText?: string
+ emptyText?: string
+}) {
+ return (
+
+
+ {loading ? loadingText : emptyText}
+
+
+ )
+}
+
+export function DashboardTableSummary({
+ children,
+}: {
+ children: ReactNode
+}) {
+ return (
+
+ {children}
+
+ )
+}