refactor: overhaul UI for streamlined user experience

Redesign navigation, home overview, user portrait, and valuation pages
with improved functionality and responsive design.

Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
This commit is contained in:
v0
2025-07-18 13:47:12 +00:00
parent 440b310c6f
commit 2408d50cb0
316 changed files with 55785 additions and 0 deletions

View File

@@ -0,0 +1,276 @@
"use client"
import { useState } from "react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Badge } from "@/components/ui/badge"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { PlusCircle, Search, Tag, Edit, Trash2, Users } from "lucide-react"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
interface UserTag {
id: string
name: string
category: string
description: string
userCount: number
source: string
createdAt: Date
updatedAt: Date
}
export function TagManagement() {
const [searchQuery, setSearchQuery] = useState("")
const [selectedCategory, setSelectedCategory] = useState("all")
const [selectedSource, setSelectedSource] = useState("all")
// 模拟数据
const tags: UserTag[] = [
{
id: "1",
name: "高价值客户",
category: "价值分类",
description: "消费金额高且频次高的用户",
userCount: 2450,
source: "系统生成",
createdAt: new Date(2023, 5, 15),
updatedAt: new Date(2023, 6, 20),
},
{
id: "2",
name: "数据分析师",
category: "职业角色",
description: "从事数据分析工作的用户",
userCount: 980,
source: "流量词映射",
createdAt: new Date(2023, 4, 10),
updatedAt: new Date(2023, 6, 18),
},
{
id: "3",
name: "营销决策者",
category: "职业角色",
description: "负责营销决策的管理人员",
userCount: 645,
source: "流量词映射",
createdAt: new Date(2023, 3, 5),
updatedAt: new Date(2023, 5, 25),
},
{
id: "4",
name: "技术爱好者",
category: "兴趣爱好",
description: "对技术有浓厚兴趣的用户",
userCount: 1520,
source: "行为分析",
createdAt: new Date(2023, 2, 20),
updatedAt: new Date(2023, 6, 19),
},
{
id: "5",
name: "活跃用户",
category: "活跃度",
description: "每周登录3次以上的用户",
userCount: 8600,
source: "系统生成",
createdAt: new Date(2023, 1, 15),
updatedAt: new Date(2023, 4, 10),
},
{
id: "6",
name: "上海市",
category: "位置信息",
description: "位于上海市的用户",
userCount: 5200,
source: "消费行为",
createdAt: new Date(2023, 3, 10),
updatedAt: new Date(2023, 6, 15),
},
{
id: "7",
name: "牛排",
category: "菜品偏好",
description: "喜欢牛排的用户",
userCount: 3800,
source: "消费行为",
createdAt: new Date(2023, 4, 5),
updatedAt: new Date(2023, 6, 12),
},
{
id: "8",
name: "晚餐",
category: "消费时段",
description: "晚餐时段消费的用户",
userCount: 7500,
source: "消费行为",
createdAt: new Date(2023, 2, 15),
updatedAt: new Date(2023, 5, 20),
},
{
id: "9",
name: "周末消费",
category: "消费习惯",
description: "周末消费的用户",
userCount: 6200,
source: "消费行为",
createdAt: new Date(2023, 3, 20),
updatedAt: new Date(2023, 6, 10),
},
{
id: "10",
name: "高端餐厅",
category: "消费场所",
description: "在高端餐厅消费的用户",
userCount: 2900,
source: "消费行为",
createdAt: new Date(2023, 4, 25),
updatedAt: new Date(2023, 6, 5),
},
]
// 过滤标签
const filteredTags = tags.filter((tag) => {
// 搜索过滤
const searchMatch =
tag.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
tag.category.toLowerCase().includes(searchQuery.toLowerCase()) ||
tag.description.toLowerCase().includes(searchQuery.toLowerCase())
// 分类过滤
const categoryMatch = selectedCategory === "all" || tag.category === selectedCategory
// 来源过滤
const sourceMatch = selectedSource === "all" || tag.source === selectedSource
return searchMatch && categoryMatch && sourceMatch
})
const formatDate = (date: Date) => {
return date.toLocaleDateString("zh-CN", {
year: "numeric",
month: "2-digit",
day: "2-digit",
})
}
return (
<Card className="border-none shadow-md overflow-hidden">
<CardHeader className="bg-gradient-to-r from-green-50 to-teal-50 border-b">
<div className="flex justify-between items-center">
<div>
<CardTitle></CardTitle>
<CardDescription></CardDescription>
</div>
</div>
</CardHeader>
<CardContent className="p-4">
<div className="space-y-6">
<div className="flex justify-between items-center">
<h2 className="text-xl font-semibold"></h2>
<Button>
<PlusCircle className="mr-2 h-4 w-4" />
</Button>
</div>
<div className="flex justify-between items-center">
<div className="flex space-x-2">
<Select value={selectedCategory} onValueChange={setSelectedCategory}>
<SelectTrigger className="w-[150px]">
<SelectValue placeholder="标签分类" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all"></SelectItem>
<SelectItem value="价值分类"></SelectItem>
<SelectItem value="职业角色"></SelectItem>
<SelectItem value="兴趣爱好"></SelectItem>
<SelectItem value="活跃度"></SelectItem>
<SelectItem value="位置信息"></SelectItem>
<SelectItem value="菜品偏好"></SelectItem>
<SelectItem value="消费时段"></SelectItem>
<SelectItem value="消费习惯"></SelectItem>
<SelectItem value="消费场所"></SelectItem>
</SelectContent>
</Select>
<Select value={selectedSource} onValueChange={setSelectedSource}>
<SelectTrigger className="w-[150px]">
<SelectValue placeholder="标签来源" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all"></SelectItem>
<SelectItem value="系统生成"></SelectItem>
<SelectItem value="流量词映射"></SelectItem>
<SelectItem value="行为分析"></SelectItem>
<SelectItem value="消费行为"></SelectItem>
<SelectItem value="手动创建"></SelectItem>
</SelectContent>
</Select>
</div>
<div className="relative w-64">
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
<Input
placeholder="搜索标签..."
className="pl-8"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
</div>
</div>
<div className="rounded-md border">
<Table>
<TableHeader>
<TableRow>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead className="text-right"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{filteredTags.map((tag) => (
<TableRow key={tag.id}>
<TableCell>
<div className="flex items-center">
<Tag className="h-4 w-4 mr-2 text-muted-foreground" />
<span className="font-medium">{tag.name}</span>
</div>
</TableCell>
<TableCell>
<Badge variant="outline">{tag.category}</Badge>
</TableCell>
<TableCell>{tag.description}</TableCell>
<TableCell>
<div className="flex items-center">
<Users className="h-4 w-4 mr-1 text-muted-foreground" />
{tag.userCount.toLocaleString()}
</div>
</TableCell>
<TableCell>{tag.source}</TableCell>
<TableCell>{formatDate(tag.createdAt)}</TableCell>
<TableCell>{formatDate(tag.updatedAt)}</TableCell>
<TableCell className="text-right">
<div className="flex justify-end space-x-2">
<Button variant="ghost" size="icon">
<Edit className="h-4 w-4" />
</Button>
<Button variant="ghost" size="icon" className="text-red-500">
<Trash2 className="h-4 w-4" />
</Button>
</div>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
</div>
</CardContent>
</Card>
)
}