Files
users/components/user-pool/user-pool-table.tsx
v0 2408d50cb0 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>
2025-07-18 13:47:12 +00:00

199 lines
6.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"
import { useState } from "react"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { formatDate } from "@/lib/utils"
import { MoreHorizontal, ChevronLeft, ChevronRight } from "lucide-react"
export function UserPoolTable() {
const [currentPage, setCurrentPage] = useState(1)
const [itemsPerPage] = useState(10)
// 这里应该从API获取实际数据
const users = [
{
id: "1",
name: "张三",
phone: "13812345678",
source: "微信",
registerDate: new Date(2023, 5, 15),
lastActive: new Date(2023, 6, 20),
value: "high",
tags: ["潜在客户", "对产品感兴趣"],
status: "active",
},
{
id: "2",
name: "李四",
phone: "13987654321",
source: "抖音",
registerDate: new Date(2023, 4, 10),
lastActive: new Date(2023, 6, 18),
value: "medium",
tags: ["新用户", "已咨询"],
status: "active",
},
{
id: "3",
name: "王五",
phone: "13765432198",
source: "小红书",
registerDate: new Date(2023, 3, 5),
lastActive: new Date(2023, 5, 25),
value: "low",
tags: ["已购买", "需要跟进"],
status: "inactive",
},
{
id: "4",
name: "赵六",
phone: "13654321987",
source: "官网",
registerDate: new Date(2023, 2, 20),
lastActive: new Date(2023, 6, 19),
value: "high",
tags: ["VIP客户", "高频购买"],
status: "active",
},
{
id: "5",
name: "钱七",
phone: "13543219876",
source: "微信",
registerDate: new Date(2023, 1, 15),
lastActive: new Date(2023, 4, 10),
value: "medium",
tags: ["已流失", "需要挽回"],
status: "lost",
},
]
const totalPages = Math.ceil(users.length / itemsPerPage)
const startIndex = (currentPage - 1) * itemsPerPage
const endIndex = startIndex + itemsPerPage
const currentUsers = users.slice(startIndex, endIndex)
const getUserValueBadge = (value: string) => {
switch (value) {
case "high":
return <Badge className="bg-green-500"></Badge>
case "medium":
return <Badge className="bg-blue-500"></Badge>
case "low":
return <Badge className="bg-gray-500"></Badge>
default:
return <Badge></Badge>
}
}
const getUserStatusBadge = (status: string) => {
switch (status) {
case "active":
return <Badge className="bg-green-500"></Badge>
case "inactive":
return <Badge className="bg-yellow-500"></Badge>
case "lost":
return <Badge className="bg-red-500"></Badge>
default:
return <Badge></Badge>
}
}
return (
<div className="space-y-4">
<div className="rounded-md border">
<Table>
<TableHeader>
<TableRow>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead className="text-right"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{currentUsers.map((user) => (
<TableRow key={user.id}>
<TableCell className="font-medium">{user.name}</TableCell>
<TableCell>{user.phone}</TableCell>
<TableCell>{user.source}</TableCell>
<TableCell>{formatDate(user.registerDate)}</TableCell>
<TableCell>{formatDate(user.lastActive)}</TableCell>
<TableCell>{getUserValueBadge(user.value)}</TableCell>
<TableCell>{getUserStatusBadge(user.status)}</TableCell>
<TableCell>
<div className="flex flex-wrap gap-1">
{user.tags.map((tag) => (
<Badge key={tag} variant="outline" className="text-xs">
{tag}
</Badge>
))}
</div>
</TableCell>
<TableCell className="text-right">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon">
<MoreHorizontal className="h-4 w-4" />
<span className="sr-only"></span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuLabel></DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem></DropdownMenuItem>
<DropdownMenuItem></DropdownMenuItem>
<DropdownMenuItem></DropdownMenuItem>
<DropdownMenuItem></DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem className="text-red-500"></DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
<div className="flex items-center justify-between">
<p className="text-sm text-muted-foreground">
{startIndex + 1} {Math.min(endIndex, users.length)} {users.length}
</p>
<div className="flex items-center space-x-2">
<Button
variant="outline"
size="icon"
onClick={() => setCurrentPage(currentPage - 1)}
disabled={currentPage === 1}
>
<ChevronLeft className="h-4 w-4" />
</Button>
<Button
variant="outline"
size="icon"
onClick={() => setCurrentPage(currentPage + 1)}
disabled={currentPage === totalPages}
>
<ChevronRight className="h-4 w-4" />
</Button>
</div>
</div>
</div>
)
}