feat(ui): refine dashboard configuration pages

This commit is contained in:
zetaloop
2026-04-25 21:48:57 +08:00
parent 14f6f5509a
commit ac382960dd
4 changed files with 95 additions and 34 deletions
@@ -10,6 +10,7 @@ import {
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { EmptyState } from "@/components/ui/empty-state"
import { Input } from "@/components/ui/input"
import {
Table,
@@ -30,7 +31,7 @@ import { toApiError } from "@/lib/errors"
import { useMyShop } from "@/lib/hooks/use-my-shop"
import { notifyInfo, notifySuccess } from "@/lib/toast"
import type { Player } from "@/lib/types"
import { MoreHorizontal, Star, UserPlus } from "lucide-react"
import { AlertCircle, MoreHorizontal, Star, UserPlus } from "lucide-react"
import Link from "next/link"
import { useCallback, useEffect, useMemo, useState } from "react"
@@ -131,15 +132,27 @@ export default function EmployeesPage() {
)
if (loading) {
return <div className="text-sm text-muted-foreground">...</div>
return (
<div className="container mx-auto max-w-6xl px-4 py-8">
<EmptyState title="员工信息加载中" icon={UserPlus} />
</div>
)
}
if (error) {
return <div className="text-sm text-muted-foreground">{error}</div>
return (
<div className="container mx-auto max-w-6xl px-4 py-8">
<EmptyState title="员工信息加载失败" description={error} icon={AlertCircle} />
</div>
)
}
if (!shop) {
return <div className="text-sm text-muted-foreground"></div>
return (
<div className="container mx-auto max-w-6xl px-4 py-8">
<EmptyState title="当前账号没有可管理的店铺" icon={UserPlus} />
</div>
)
}
const handleInvite = async () => {
@@ -185,7 +198,7 @@ export default function EmployeesPage() {
</Button>
</div>
<Card className="hover:shadow-card-hover">
<Card className="border-border/80 shadow-sm">
<CardHeader>
<div className="flex items-center justify-between">
<CardTitle className="text-base"> ({filteredPlayers.length})</CardTitle>
@@ -212,14 +225,19 @@ export default function EmployeesPage() {
<TableBody>
{dataLoading ? (
<TableRow>
<TableCell colSpan={6} className="text-center text-sm text-muted-foreground">
...
<TableCell colSpan={6} className="py-6">
<EmptyState title="员工加载中" icon={UserPlus} className="min-h-[180px]" />
</TableCell>
</TableRow>
) : filteredPlayers.length === 0 ? (
<TableRow>
<TableCell colSpan={6} className="text-center text-sm text-muted-foreground">
<TableCell colSpan={6} className="py-6">
<EmptyState
title="暂无签约打手"
description="邀请打手加入后会出现在这里。"
icon={UserPlus}
className="min-h-[180px] border-dashed"
/>
</TableCell>
</TableRow>
) : (
@@ -248,7 +266,7 @@ export default function EmployeesPage() {
</TableCell>
<TableCell>
<div className="flex items-center gap-1">
<Star className="h-3.5 w-3.5 fill-yellow-400 text-yellow-400" />
<Star className="h-3.5 w-3.5 fill-warning text-warning" />
{player.rating}
</div>
</TableCell>
+20 -7
View File
@@ -2,6 +2,7 @@
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { EmptyState } from "@/components/ui/empty-state"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import {
@@ -17,22 +18,34 @@ import { toApiError } from "@/lib/errors"
import { useMyShop } from "@/lib/hooks/use-my-shop"
import { notifyInfo, notifySuccess } from "@/lib/toast"
import type { Shop } from "@/lib/types"
import { Save } from "lucide-react"
import { AlertCircle, Save } from "lucide-react"
import { useState } from "react"
export default function ShopRulesPage() {
const { shop, setShop, loading, error } = useMyShop()
if (loading) {
return <div className="text-sm text-muted-foreground">...</div>
return (
<div className="container mx-auto max-w-4xl px-4 py-8">
<EmptyState title="规则加载中" icon={Save} />
</div>
)
}
if (error) {
return <div className="text-sm text-muted-foreground">{error}</div>
return (
<div className="container mx-auto max-w-4xl px-4 py-8">
<EmptyState title="规则加载失败" description={error} icon={AlertCircle} />
</div>
)
}
if (!shop) {
return <div className="text-sm text-muted-foreground"></div>
return (
<div className="container mx-auto max-w-4xl px-4 py-8">
<EmptyState title="当前账号没有可管理的店铺" icon={Save} />
</div>
)
}
return <ShopRulesForm key={shop.id} shop={shop} setShop={setShop} />
@@ -83,7 +96,7 @@ function ShopRulesForm({ shop, setShop }: { shop: Shop; setShop: (shop: Shop | n
</div>
<div className="grid gap-6">
<Card className="hover:shadow-card-hover">
<Card className="border-border/80 shadow-sm">
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
@@ -117,7 +130,7 @@ function ShopRulesForm({ shop, setShop }: { shop: Shop; setShop: (shop: Shop | n
</CardContent>
</Card>
<Card className="hover:shadow-card-hover">
<Card className="border-border/80 shadow-sm">
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
@@ -143,7 +156,7 @@ function ShopRulesForm({ shop, setShop }: { shop: Shop; setShop: (shop: Shop | n
</CardContent>
</Card>
<Card className="hover:shadow-card-hover">
<Card className="border-border/80 shadow-sm">
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
@@ -2,6 +2,7 @@
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { EmptyState } from "@/components/ui/empty-state"
import { Switch } from "@/components/ui/switch"
import { updateShopTemplate } from "@/lib/api"
import { getShopSections } from "@/lib/domain/shop-template"
@@ -9,7 +10,7 @@ import { toApiError } from "@/lib/errors"
import { useMyShop } from "@/lib/hooks/use-my-shop"
import { notifyInfo } from "@/lib/toast"
import type { Shop, ShopSection } from "@/lib/types"
import { Eye, EyeOff, GripVertical } from "lucide-react"
import { AlertCircle, Eye, EyeOff, GripVertical } from "lucide-react"
import Link from "next/link"
import { type DragEvent, useEffect, useState } from "react"
@@ -35,15 +36,27 @@ export default function ShopTemplatesPage() {
const { shop, setShop, loading, error } = useMyShop()
if (loading) {
return <div className="text-sm text-muted-foreground">...</div>
return (
<div className="container mx-auto max-w-4xl px-4 py-8">
<EmptyState title="模板加载中" icon={GripVertical} />
</div>
)
}
if (error) {
return <div className="text-sm text-muted-foreground">{error}</div>
return (
<div className="container mx-auto max-w-4xl px-4 py-8">
<EmptyState title="模板加载失败" description={error} icon={AlertCircle} />
</div>
)
}
if (!shop) {
return <div className="text-sm text-muted-foreground"></div>
return (
<div className="container mx-auto max-w-4xl px-4 py-8">
<EmptyState title="当前账号没有可管理的店铺" icon={GripVertical} />
</div>
)
}
return <ShopTemplatesEditor key={shop.id} shop={shop} setShop={setShop} />
@@ -136,7 +149,7 @@ function ShopTemplatesEditor({
return (
<div className="container mx-auto max-w-4xl px-4 py-8 space-y-8">
{showSavedToast ? (
<div className="fixed right-6 top-6 z-50 rounded-md border bg-background px-4 py-2 text-sm shadow-md">
<div className="fixed right-6 top-6 z-50 rounded-md border border-border/80 bg-background px-4 py-2 text-sm shadow-sm">
</div>
) : null}
@@ -146,7 +159,7 @@ function ShopTemplatesEditor({
<p className="text-sm text-muted-foreground mt-1"></p>
</div>
<div className="flex gap-2">
<Button variant="outline" asChild>
<Button variant="outline" className="border-border/60" asChild>
<Link href={`/shop/${shop.id}`}></Link>
</Button>
<Button
@@ -160,7 +173,7 @@ function ShopTemplatesEditor({
</div>
</div>
<Card className="hover:shadow-card-hover">
<Card className="border-border/80 shadow-sm">
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
@@ -168,7 +181,7 @@ function ShopTemplatesEditor({
{sections.map((section, index) => (
<div
key={section.type}
className={`flex items-center gap-3 rounded-lg border p-3 transition-colors ${dragIndex === index ? "opacity-50" : "opacity-100"} ${dropIndex === index ? "border-t-2 border-b-2 border-t-primary border-b-primary" : ""}`}
className={`flex items-center gap-3 rounded-lg border border-border/60 p-3 transition-colors ${dragIndex === index ? "opacity-50" : "opacity-100"} ${dropIndex === index ? "border-b-2 border-t-2 border-b-primary border-t-primary" : ""}`}
>
<button
type="button"
@@ -203,7 +216,7 @@ function ShopTemplatesEditor({
</CardContent>
</Card>
<Card className="hover:shadow-card-hover">
<Card className="border-border/80 shadow-sm">
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>