refactor: streamline mobile interface for data analysis focus
Remove settings, optimize mobile layout, highlight data analysis features Use generic company names, simulate today's timeline, responsive design Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
This commit is contained in:
@@ -27,12 +27,12 @@ import {
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "@/components/ui/dialog"
|
||||
|
||||
// 真实用户数据
|
||||
// 使用通用公司名称和当天时间线的用户数据
|
||||
const mockUsers = [
|
||||
{
|
||||
id: "1",
|
||||
name: "李明华",
|
||||
company: "阿里巴巴集团",
|
||||
name: "张明华",
|
||||
company: "科技创新有限公司",
|
||||
recency: 1,
|
||||
frequency: 28,
|
||||
monetary: 45600,
|
||||
@@ -42,11 +42,12 @@ const mockUsers = [
|
||||
upgradeFromDays: 45,
|
||||
nextUpgrade: "VIP客户",
|
||||
upgradeProbability: 85,
|
||||
lastActive: "今天 14:30",
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
name: "张雨婷",
|
||||
company: "腾讯科技",
|
||||
name: "李雨婷",
|
||||
company: "数字营销公司",
|
||||
recency: 3,
|
||||
frequency: 22,
|
||||
monetary: 32800,
|
||||
@@ -56,11 +57,12 @@ const mockUsers = [
|
||||
upgradeFromDays: 28,
|
||||
nextUpgrade: "白金会员",
|
||||
upgradeProbability: 78,
|
||||
lastActive: "今天 13:45",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
name: "王建国",
|
||||
company: "字节跳动",
|
||||
company: "软件开发工作室",
|
||||
recency: 2,
|
||||
frequency: 25,
|
||||
monetary: 38900,
|
||||
@@ -70,11 +72,12 @@ const mockUsers = [
|
||||
upgradeFromDays: 38,
|
||||
nextUpgrade: "企业VIP",
|
||||
upgradeProbability: 82,
|
||||
lastActive: "今天 12:20",
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
name: "刘思琪",
|
||||
company: "美团点评",
|
||||
company: "数据分析咨询",
|
||||
recency: 7,
|
||||
frequency: 18,
|
||||
monetary: 25400,
|
||||
@@ -84,11 +87,12 @@ const mockUsers = [
|
||||
upgradeFromDays: 12,
|
||||
nextUpgrade: "高价值用户",
|
||||
upgradeProbability: 68,
|
||||
lastActive: "今天 11:15",
|
||||
},
|
||||
{
|
||||
id: "5",
|
||||
name: "陈浩然",
|
||||
company: "京东集团",
|
||||
company: "云计算服务商",
|
||||
recency: 4,
|
||||
frequency: 20,
|
||||
monetary: 28700,
|
||||
@@ -98,11 +102,12 @@ const mockUsers = [
|
||||
upgradeFromDays: 22,
|
||||
nextUpgrade: "高价值用户",
|
||||
upgradeProbability: 72,
|
||||
lastActive: "今天 10:30",
|
||||
},
|
||||
{
|
||||
id: "6",
|
||||
name: "周欣妍",
|
||||
company: "滴滴出行",
|
||||
company: "用户体验设计",
|
||||
recency: 12,
|
||||
frequency: 15,
|
||||
monetary: 18600,
|
||||
@@ -112,11 +117,12 @@ const mockUsers = [
|
||||
upgradeFromDays: 8,
|
||||
nextUpgrade: "中高价值用户",
|
||||
upgradeProbability: 55,
|
||||
lastActive: "今天 09:45",
|
||||
},
|
||||
{
|
||||
id: "7",
|
||||
name: "马志强",
|
||||
company: "华为技术",
|
||||
company: "企业解决方案",
|
||||
recency: 6,
|
||||
frequency: 16,
|
||||
monetary: 22100,
|
||||
@@ -126,11 +132,12 @@ const mockUsers = [
|
||||
upgradeFromDays: 15,
|
||||
nextUpgrade: "中高价值用户",
|
||||
upgradeProbability: 61,
|
||||
lastActive: "今天 08:20",
|
||||
},
|
||||
{
|
||||
id: "8",
|
||||
name: "赵丽娟",
|
||||
company: "小米科技",
|
||||
company: "品牌营销策划",
|
||||
recency: 15,
|
||||
frequency: 12,
|
||||
monetary: 15800,
|
||||
@@ -140,6 +147,7 @@ const mockUsers = [
|
||||
upgradeFromDays: 5,
|
||||
nextUpgrade: "中高价值用户",
|
||||
upgradeProbability: 45,
|
||||
lastActive: "今天 07:30",
|
||||
},
|
||||
]
|
||||
|
||||
@@ -186,33 +194,33 @@ export default function UserValuePage() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container mx-auto p-4 space-y-6">
|
||||
<div className="container mx-auto p-4 space-y-4 md:space-y-6">
|
||||
{/* 页面标题和工具栏 */}
|
||||
<div className="flex flex-col md:flex-row md:justify-between md:items-center gap-4">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold">用户估值</h1>
|
||||
<p className="text-muted-foreground mt-1">用户价值评估与升级路径分析</p>
|
||||
<h1 className="text-2xl md:text-3xl font-bold">价值评估</h1>
|
||||
<p className="text-sm md:text-base text-muted-foreground mt-1">用户价值分析与升级路径</p>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<Select value={timeRange} onValueChange={setTimeRange}>
|
||||
<SelectTrigger className="w-[140px]">
|
||||
<SelectValue placeholder="选择时间范围" />
|
||||
<SelectTrigger className="w-[120px] md:w-[140px] text-sm">
|
||||
<SelectValue placeholder="时间范围" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="7days">最近7天</SelectItem>
|
||||
<SelectItem value="30days">最近30天</SelectItem>
|
||||
<SelectItem value="90days">最近90天</SelectItem>
|
||||
<SelectItem value="7days">近7天</SelectItem>
|
||||
<SelectItem value="30days">近30天</SelectItem>
|
||||
<SelectItem value="90days">近90天</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Button variant="outline" size="icon">
|
||||
<Button variant="outline" size="icon" className="h-9 w-9 bg-transparent">
|
||||
<Filter className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button variant="outline" size="icon">
|
||||
<Button variant="outline" size="icon" className="h-9 w-9 bg-transparent">
|
||||
<RefreshCw className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button variant="outline">
|
||||
<Button variant="outline" size="sm" className="hidden md:flex bg-transparent">
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
导出报告
|
||||
导出
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -224,118 +232,122 @@ export default function UserValuePage() {
|
||||
>
|
||||
<Card className="border-none shadow-md">
|
||||
<CollapsibleTrigger className="w-full">
|
||||
<CardHeader className="bg-gradient-to-r from-green-50 to-emerald-50 border-b hover:from-green-100 hover:to-emerald-100 transition-colors cursor-pointer">
|
||||
<CardHeader className="bg-gradient-to-r from-green-50 to-emerald-50 border-b hover:from-green-100 hover:to-emerald-100 transition-colors cursor-pointer py-3 md:py-4">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex items-center gap-3">
|
||||
<Target className="h-5 w-5 text-green-600" />
|
||||
<Target className="h-4 w-4 md:h-5 md:w-5 text-green-600" />
|
||||
<div className="text-left">
|
||||
<CardTitle>用户估值概览</CardTitle>
|
||||
<CardDescription>用户价值评估整体情况</CardDescription>
|
||||
<CardTitle className="text-base md:text-lg">价值概览</CardTitle>
|
||||
<CardDescription className="text-xs md:text-sm">用户价值评估整体情况</CardDescription>
|
||||
</div>
|
||||
</div>
|
||||
{expandedSections.overview ? <ChevronDown className="h-5 w-5" /> : <ChevronRight className="h-5 w-5" />}
|
||||
{expandedSections.overview ? (
|
||||
<ChevronDown className="h-4 w-4 md:h-5 md:w-5" />
|
||||
) : (
|
||||
<ChevronRight className="h-4 w-4 md:h-5 md:w-5" />
|
||||
)}
|
||||
</div>
|
||||
</CardHeader>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent>
|
||||
<CardContent className="p-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-3 md:gap-4">
|
||||
<Card className="bg-gradient-to-br from-green-50 to-emerald-50 border-none shadow-sm">
|
||||
<CardContent className="p-4">
|
||||
<CardContent className="p-3 md:p-4">
|
||||
<div className="flex justify-between items-start">
|
||||
<div>
|
||||
<div className="text-sm font-medium text-green-600">平均用户估值</div>
|
||||
<div className="text-2xl font-bold mt-2">¥3,248</div>
|
||||
<div className="text-sm text-green-600 mt-1 flex items-center">
|
||||
<ArrowUpRight className="h-4 w-4 mr-1" />
|
||||
较上月增长 8.2%
|
||||
<div className="text-xs md:text-sm font-medium text-green-600">平均估值</div>
|
||||
<div className="text-lg md:text-2xl font-bold mt-1 md:mt-2">¥3,248</div>
|
||||
<div className="text-xs text-green-600 mt-1 flex items-center">
|
||||
<ArrowUpRight className="h-3 w-3 md:h-4 md:w-4 mr-1" />
|
||||
+8.2%
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-green-100 p-2 rounded-full">
|
||||
<Target className="h-5 w-5 text-green-600" />
|
||||
<div className="bg-green-100 p-1.5 md:p-2 rounded-full">
|
||||
<Target className="h-3 w-3 md:h-5 md:w-5 text-green-600" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
<div className="mt-2 md:mt-3">
|
||||
<div className="flex justify-between text-xs mb-1">
|
||||
<span>预期目标</span>
|
||||
<span>目标</span>
|
||||
<span>94%</span>
|
||||
</div>
|
||||
<Progress value={94} className="h-1.5 bg-green-100" />
|
||||
<Progress value={94} className="h-1 md:h-1.5 bg-green-100" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="bg-gradient-to-br from-purple-50 to-pink-50 border-none shadow-sm">
|
||||
<CardContent className="p-4">
|
||||
<CardContent className="p-3 md:p-4">
|
||||
<div className="flex justify-between items-start">
|
||||
<div>
|
||||
<div className="text-sm font-medium text-purple-600">高价值用户</div>
|
||||
<div className="text-2xl font-bold mt-2">45,678</div>
|
||||
<div className="text-sm text-green-600 mt-1 flex items-center">
|
||||
<ArrowUpRight className="h-4 w-4 mr-1" />
|
||||
较上月增长 12.3%
|
||||
<div className="text-xs md:text-sm font-medium text-purple-600">高价值用户</div>
|
||||
<div className="text-lg md:text-2xl font-bold mt-1 md:mt-2">45,678</div>
|
||||
<div className="text-xs text-green-600 mt-1 flex items-center">
|
||||
<ArrowUpRight className="h-3 w-3 md:h-4 md:w-4 mr-1" />
|
||||
+12.3%
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-purple-100 p-2 rounded-full">
|
||||
<TrendingUp className="h-5 w-5 text-purple-600" />
|
||||
<div className="bg-purple-100 p-1.5 md:p-2 rounded-full">
|
||||
<TrendingUp className="h-3 w-3 md:h-5 md:w-5 text-purple-600" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
<div className="mt-2 md:mt-3">
|
||||
<div className="flex justify-between text-xs mb-1">
|
||||
<span>占总用户比例</span>
|
||||
<span>占比</span>
|
||||
<span>28.6%</span>
|
||||
</div>
|
||||
<Progress value={28.6} className="h-1.5 bg-purple-100" />
|
||||
<Progress value={28.6} className="h-1 md:h-1.5 bg-purple-100" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="bg-gradient-to-br from-blue-50 to-indigo-50 border-none shadow-sm">
|
||||
<CardContent className="p-4">
|
||||
<CardContent className="p-3 md:p-4">
|
||||
<div className="flex justify-between items-start">
|
||||
<div>
|
||||
<div className="text-sm font-medium text-blue-600">用户价值增长率</div>
|
||||
<div className="text-2xl font-bold mt-2">15.8%</div>
|
||||
<div className="text-sm text-green-600 mt-1 flex items-center">
|
||||
<ArrowUpRight className="h-4 w-4 mr-1" />
|
||||
较上月提升 2.1%
|
||||
<div className="text-xs md:text-sm font-medium text-blue-600">价值增长率</div>
|
||||
<div className="text-lg md:text-2xl font-bold mt-1 md:mt-2">15.8%</div>
|
||||
<div className="text-xs text-green-600 mt-1 flex items-center">
|
||||
<ArrowUpRight className="h-3 w-3 md:h-4 md:w-4 mr-1" />
|
||||
+2.1%
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-blue-100 p-2 rounded-full">
|
||||
<BarChart3 className="h-5 w-5 text-blue-600" />
|
||||
<div className="bg-blue-100 p-1.5 md:p-2 rounded-full">
|
||||
<BarChart3 className="h-3 w-3 md:h-5 md:w-5 text-blue-600" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
<div className="mt-2 md:mt-3">
|
||||
<div className="flex justify-between text-xs mb-1">
|
||||
<span>行业平均</span>
|
||||
<span>11.2%</span>
|
||||
</div>
|
||||
<Progress value={141} className="h-1.5 bg-blue-100" />
|
||||
<Progress value={141} className="h-1 md:h-1.5 bg-blue-100" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="bg-gradient-to-br from-amber-50 to-yellow-50 border-none shadow-sm">
|
||||
<CardContent className="p-4">
|
||||
<CardContent className="p-3 md:p-4">
|
||||
<div className="flex justify-between items-start">
|
||||
<div>
|
||||
<div className="text-sm font-medium text-amber-600">用户升级率</div>
|
||||
<div className="text-2xl font-bold mt-2">12.5%</div>
|
||||
<div className="text-sm text-green-600 mt-1 flex items-center">
|
||||
<ArrowUpRight className="h-4 w-4 mr-1" />
|
||||
较上月提升 1.8%
|
||||
<div className="text-xs md:text-sm font-medium text-amber-600">升级率</div>
|
||||
<div className="text-lg md:text-2xl font-bold mt-1 md:mt-2">12.5%</div>
|
||||
<div className="text-xs text-green-600 mt-1 flex items-center">
|
||||
<ArrowUpRight className="h-3 w-3 md:h-4 md:w-4 mr-1" />
|
||||
+1.8%
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-amber-100 p-2 rounded-full">
|
||||
<Users className="h-5 w-5 text-amber-600" />
|
||||
<div className="bg-amber-100 p-1.5 md:p-2 rounded-full">
|
||||
<Users className="h-3 w-3 md:h-5 md:w-5 text-amber-600" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
<div className="mt-2 md:mt-3">
|
||||
<div className="flex justify-between text-xs mb-1">
|
||||
<span>目标</span>
|
||||
<span>15%</span>
|
||||
</div>
|
||||
<Progress value={83} className="h-1.5 bg-amber-100" />
|
||||
<Progress value={83} className="h-1 md:h-1.5 bg-amber-100" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -352,13 +364,13 @@ export default function UserValuePage() {
|
||||
>
|
||||
<Card className="border-none shadow-md">
|
||||
<CollapsibleTrigger className="w-full">
|
||||
<CardHeader className="bg-gradient-to-r from-blue-50 to-indigo-50 border-b hover:from-blue-100 hover:to-indigo-100 transition-colors cursor-pointer">
|
||||
<CardHeader className="bg-gradient-to-r from-blue-50 to-indigo-50 border-b hover:from-blue-100 hover:to-indigo-100 transition-colors cursor-pointer py-3 md:py-4">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex items-center gap-3">
|
||||
<BarChart3 className="h-5 w-5 text-blue-600" />
|
||||
<BarChart3 className="h-4 w-4 md:h-5 md:w-5 text-blue-600" />
|
||||
<div className="text-left">
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
RFM用户价值模型
|
||||
<CardTitle className="flex items-center gap-2 text-base md:text-lg">
|
||||
RFM估值模型
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
@@ -366,44 +378,48 @@ export default function UserValuePage() {
|
||||
e.stopPropagation()
|
||||
setShowModelDialog(true)
|
||||
}}
|
||||
className="h-6 w-6 p-0"
|
||||
className="h-5 w-5 md:h-6 md:w-6 p-0"
|
||||
>
|
||||
<HelpCircle className="h-4 w-4" />
|
||||
<HelpCircle className="h-3 w-3 md:h-4 md:w-4" />
|
||||
</Button>
|
||||
</CardTitle>
|
||||
<CardDescription>基于用户行为的价值评估模型</CardDescription>
|
||||
<CardDescription className="text-xs md:text-sm">基于用户行为的价值评估</CardDescription>
|
||||
</div>
|
||||
</div>
|
||||
{expandedSections.model ? <ChevronDown className="h-5 w-5" /> : <ChevronRight className="h-5 w-5" />}
|
||||
{expandedSections.model ? (
|
||||
<ChevronDown className="h-4 w-4 md:h-5 md:w-5" />
|
||||
) : (
|
||||
<ChevronRight className="h-4 w-4 md:h-5 md:w-5" />
|
||||
)}
|
||||
</div>
|
||||
</CardHeader>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent>
|
||||
<CardContent className="p-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 md:gap-6">
|
||||
<div className="space-y-2">
|
||||
<h3 className="font-semibold flex items-center">
|
||||
<span className="bg-red-100 text-red-800 w-6 h-6 rounded-full flex items-center justify-center mr-2">
|
||||
<h3 className="font-semibold flex items-center text-sm md:text-base">
|
||||
<span className="bg-red-100 text-red-800 w-5 h-5 md:w-6 md:h-6 rounded-full flex items-center justify-center mr-2 text-xs md:text-sm">
|
||||
R
|
||||
</span>
|
||||
Recency (最近消费时间)
|
||||
最近消费时间
|
||||
</h3>
|
||||
<p className="text-sm text-muted-foreground">用户最近一次交易的时间间隔,时间越短价值越高。</p>
|
||||
<div className="bg-gray-50 p-3 rounded-md">
|
||||
<div className="text-sm">
|
||||
<div className="flex justify-between mb-1">
|
||||
<p className="text-xs md:text-sm text-muted-foreground">时间间隔越短价值越高</p>
|
||||
<div className="bg-gray-50 p-2 md:p-3 rounded-md">
|
||||
<div className="text-xs md:text-sm space-y-1">
|
||||
<div className="flex justify-between">
|
||||
<span>1-3天</span>
|
||||
<span className="font-medium">5分</span>
|
||||
</div>
|
||||
<div className="flex justify-between mb-1">
|
||||
<div className="flex justify-between">
|
||||
<span>4-7天</span>
|
||||
<span className="font-medium">4分</span>
|
||||
</div>
|
||||
<div className="flex justify-between mb-1">
|
||||
<div className="flex justify-between">
|
||||
<span>8-14天</span>
|
||||
<span className="font-medium">3分</span>
|
||||
</div>
|
||||
<div className="flex justify-between mb-1">
|
||||
<div className="flex justify-between">
|
||||
<span>15-30天</span>
|
||||
<span className="font-medium">2分</span>
|
||||
</div>
|
||||
@@ -416,28 +432,28 @@ export default function UserValuePage() {
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<h3 className="font-semibold flex items-center">
|
||||
<span className="bg-green-100 text-green-800 w-6 h-6 rounded-full flex items-center justify-center mr-2">
|
||||
<h3 className="font-semibold flex items-center text-sm md:text-base">
|
||||
<span className="bg-green-100 text-green-800 w-5 h-5 md:w-6 md:h-6 rounded-full flex items-center justify-center mr-2 text-xs md:text-sm">
|
||||
F
|
||||
</span>
|
||||
Frequency (消费频率)
|
||||
消费频率
|
||||
</h3>
|
||||
<p className="text-sm text-muted-foreground">用户在一段时间内的交易次数,频率越高价值越高。</p>
|
||||
<div className="bg-gray-50 p-3 rounded-md">
|
||||
<div className="text-sm">
|
||||
<div className="flex justify-between mb-1">
|
||||
<p className="text-xs md:text-sm text-muted-foreground">频率越高价值越高</p>
|
||||
<div className="bg-gray-50 p-2 md:p-3 rounded-md">
|
||||
<div className="text-xs md:text-sm space-y-1">
|
||||
<div className="flex justify-between">
|
||||
<span>25次以上/月</span>
|
||||
<span className="font-medium">5分</span>
|
||||
</div>
|
||||
<div className="flex justify-between mb-1">
|
||||
<div className="flex justify-between">
|
||||
<span>20-24次/月</span>
|
||||
<span className="font-medium">4分</span>
|
||||
</div>
|
||||
<div className="flex justify-between mb-1">
|
||||
<div className="flex justify-between">
|
||||
<span>15-19次/月</span>
|
||||
<span className="font-medium">3分</span>
|
||||
</div>
|
||||
<div className="flex justify-between mb-1">
|
||||
<div className="flex justify-between">
|
||||
<span>10-14次/月</span>
|
||||
<span className="font-medium">2分</span>
|
||||
</div>
|
||||
@@ -450,28 +466,28 @@ export default function UserValuePage() {
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<h3 className="font-semibold flex items-center">
|
||||
<span className="bg-blue-100 text-blue-800 w-6 h-6 rounded-full flex items-center justify-center mr-2">
|
||||
<h3 className="font-semibold flex items-center text-sm md:text-base">
|
||||
<span className="bg-blue-100 text-blue-800 w-5 h-5 md:w-6 md:h-6 rounded-full flex items-center justify-center mr-2 text-xs md:text-sm">
|
||||
M
|
||||
</span>
|
||||
Monetary (消费金额)
|
||||
消费金额
|
||||
</h3>
|
||||
<p className="text-sm text-muted-foreground">用户在一段时间内的消费金额,金额越高价值越高。</p>
|
||||
<div className="bg-gray-50 p-3 rounded-md">
|
||||
<div className="text-sm">
|
||||
<div className="flex justify-between mb-1">
|
||||
<p className="text-xs md:text-sm text-muted-foreground">金额越高价值越高</p>
|
||||
<div className="bg-gray-50 p-2 md:p-3 rounded-md">
|
||||
<div className="text-xs md:text-sm space-y-1">
|
||||
<div className="flex justify-between">
|
||||
<span>30000元以上</span>
|
||||
<span className="font-medium">5分</span>
|
||||
</div>
|
||||
<div className="flex justify-between mb-1">
|
||||
<div className="flex justify-between">
|
||||
<span>20000-29999元</span>
|
||||
<span className="font-medium">4分</span>
|
||||
</div>
|
||||
<div className="flex justify-between mb-1">
|
||||
<div className="flex justify-between">
|
||||
<span>10000-19999元</span>
|
||||
<span className="font-medium">3分</span>
|
||||
</div>
|
||||
<div className="flex justify-between mb-1">
|
||||
<div className="flex justify-between">
|
||||
<span>5000-9999元</span>
|
||||
<span className="font-medium">2分</span>
|
||||
</div>
|
||||
@@ -484,28 +500,28 @@ export default function UserValuePage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6">
|
||||
<h3 className="font-semibold mb-3">RFM评分等级</h3>
|
||||
<div className="grid grid-cols-2 md:grid-cols-5 gap-3">
|
||||
<div className="bg-green-100 p-3 rounded-md text-center">
|
||||
<p className="font-medium text-green-800">高价值用户</p>
|
||||
<p className="text-sm text-green-700">85-100分</p>
|
||||
<div className="mt-4 md:mt-6">
|
||||
<h3 className="font-semibold mb-3 text-sm md:text-base">RFM评分等级</h3>
|
||||
<div className="grid grid-cols-2 md:grid-cols-5 gap-2 md:gap-3">
|
||||
<div className="bg-green-100 p-2 md:p-3 rounded-md text-center">
|
||||
<p className="font-medium text-green-800 text-xs md:text-sm">高价值用户</p>
|
||||
<p className="text-xs text-green-700">85-100分</p>
|
||||
</div>
|
||||
<div className="bg-blue-100 p-3 rounded-md text-center">
|
||||
<p className="font-medium text-blue-800">中高价值用户</p>
|
||||
<p className="text-sm text-blue-700">70-84分</p>
|
||||
<div className="bg-blue-100 p-2 md:p-3 rounded-md text-center">
|
||||
<p className="font-medium text-blue-800 text-xs md:text-sm">中高价值用户</p>
|
||||
<p className="text-xs text-blue-700">70-84分</p>
|
||||
</div>
|
||||
<div className="bg-yellow-100 p-3 rounded-md text-center">
|
||||
<p className="font-medium text-yellow-800">中等价值用户</p>
|
||||
<p className="text-sm text-yellow-700">55-69分</p>
|
||||
<div className="bg-yellow-100 p-2 md:p-3 rounded-md text-center">
|
||||
<p className="font-medium text-yellow-800 text-xs md:text-sm">中等价值用户</p>
|
||||
<p className="text-xs text-yellow-700">55-69分</p>
|
||||
</div>
|
||||
<div className="bg-gray-100 p-3 rounded-md text-center">
|
||||
<p className="font-medium text-gray-800">低价值用户</p>
|
||||
<p className="text-sm text-gray-700">40-54分</p>
|
||||
<div className="bg-gray-100 p-2 md:p-3 rounded-md text-center">
|
||||
<p className="font-medium text-gray-800 text-xs md:text-sm">低价值用户</p>
|
||||
<p className="text-xs text-gray-700">40-54分</p>
|
||||
</div>
|
||||
<div className="bg-red-100 p-3 rounded-md text-center">
|
||||
<p className="font-medium text-red-800">流失风险用户</p>
|
||||
<p className="text-sm text-red-700">0-39分</p>
|
||||
<div className="bg-red-100 p-2 md:p-3 rounded-md text-center">
|
||||
<p className="font-medium text-red-800 text-xs md:text-sm">流失风险用户</p>
|
||||
<p className="text-xs text-red-700">0-39分</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -521,35 +537,75 @@ export default function UserValuePage() {
|
||||
>
|
||||
<Card className="border-none shadow-md">
|
||||
<CollapsibleTrigger className="w-full">
|
||||
<CardHeader className="bg-gradient-to-r from-purple-50 to-pink-50 border-b hover:from-purple-100 hover:to-pink-100 transition-colors cursor-pointer">
|
||||
<CardHeader className="bg-gradient-to-r from-purple-50 to-pink-50 border-b hover:from-purple-100 hover:to-pink-100 transition-colors cursor-pointer py-3 md:py-4">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex items-center gap-3">
|
||||
<Users className="h-5 w-5 text-purple-600" />
|
||||
<Users className="h-4 w-4 md:h-5 md:w-5 text-purple-600" />
|
||||
<div className="text-left">
|
||||
<CardTitle>用户价值分析</CardTitle>
|
||||
<CardDescription>用户价值分布与详细数据 ({filteredUsers.length})</CardDescription>
|
||||
<CardTitle className="text-base md:text-lg">价值分析</CardTitle>
|
||||
<CardDescription className="text-xs md:text-sm">
|
||||
用户价值详细数据 ({filteredUsers.length})
|
||||
</CardDescription>
|
||||
</div>
|
||||
</div>
|
||||
{expandedSections.analysis ? <ChevronDown className="h-5 w-5" /> : <ChevronRight className="h-5 w-5" />}
|
||||
{expandedSections.analysis ? (
|
||||
<ChevronDown className="h-4 w-4 md:h-5 md:w-5" />
|
||||
) : (
|
||||
<ChevronRight className="h-4 w-4 md:h-5 md:w-5" />
|
||||
)}
|
||||
</div>
|
||||
</CardHeader>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent>
|
||||
<CardContent className="p-4">
|
||||
<div className="mb-4">
|
||||
<div className="relative w-64">
|
||||
<div className="relative w-full md:w-64">
|
||||
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
type="search"
|
||||
placeholder="搜索用户或公司..."
|
||||
className="pl-8"
|
||||
className="pl-8 text-sm"
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-md border">
|
||||
{/* 移动端卡片布局 */}
|
||||
<div className="space-y-3 md:hidden">
|
||||
{filteredUsers.map((user) => (
|
||||
<div key={user.id} className="bg-white border rounded-lg p-3 space-y-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="font-medium text-sm">{user.name}</p>
|
||||
<p className="text-xs text-gray-500">{user.company}</p>
|
||||
</div>
|
||||
<Badge className={`${getRFMLevelColor(user.level)} text-xs`}>{user.rfmScore}</Badge>
|
||||
</div>
|
||||
<div className="grid grid-cols-3 gap-2 text-xs">
|
||||
<div className="text-center">
|
||||
<p className="text-gray-500">R值</p>
|
||||
<p className="font-medium">{user.recency}天</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<p className="text-gray-500">F值</p>
|
||||
<p className="font-medium">{user.frequency}次</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<p className="text-gray-500">M值</p>
|
||||
<p className="font-medium">¥{(user.monetary / 1000).toFixed(0)}K</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-xs text-gray-500">{user.lastActive}</span>
|
||||
<span className="text-xs text-green-600">{user.growth}</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 桌面端表格布局 */}
|
||||
<div className="hidden md:block rounded-md border">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
@@ -593,13 +649,13 @@ export default function UserValuePage() {
|
||||
>
|
||||
<Card className="border-none shadow-md">
|
||||
<CollapsibleTrigger className="w-full">
|
||||
<CardHeader className="bg-gradient-to-r from-orange-50 to-red-50 border-b hover:from-orange-100 hover:to-red-100 transition-colors cursor-pointer">
|
||||
<CardHeader className="bg-gradient-to-r from-orange-50 to-red-50 border-b hover:from-orange-100 hover:to-red-100 transition-colors cursor-pointer py-3 md:py-4">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex items-center gap-3">
|
||||
<TrendingUp className="h-5 w-5 text-orange-600" />
|
||||
<TrendingUp className="h-4 w-4 md:h-5 md:w-5 text-orange-600" />
|
||||
<div className="text-left">
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
用户升级路径分析
|
||||
<CardTitle className="flex items-center gap-2 text-base md:text-lg">
|
||||
升级路径分析
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
@@ -607,45 +663,45 @@ export default function UserValuePage() {
|
||||
e.stopPropagation()
|
||||
setShowUpgradeDialog(true)
|
||||
}}
|
||||
className="h-6 w-6 p-0"
|
||||
className="h-5 w-5 md:h-6 md:w-6 p-0"
|
||||
>
|
||||
<HelpCircle className="h-4 w-4" />
|
||||
<HelpCircle className="h-3 w-3 md:h-4 md:w-4" />
|
||||
</Button>
|
||||
</CardTitle>
|
||||
<CardDescription>用户价值提升路径与策略</CardDescription>
|
||||
<CardDescription className="text-xs md:text-sm">用户价值提升路径与策略</CardDescription>
|
||||
</div>
|
||||
</div>
|
||||
{expandedSections.upgradePaths ? (
|
||||
<ChevronDown className="h-5 w-5" />
|
||||
<ChevronDown className="h-4 w-4 md:h-5 md:w-5" />
|
||||
) : (
|
||||
<ChevronRight className="h-5 w-5" />
|
||||
<ChevronRight className="h-4 w-4 md:h-5 md:w-5" />
|
||||
)}
|
||||
</div>
|
||||
</CardHeader>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent>
|
||||
<CardContent className="p-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-3 md:gap-4 mb-4 md:mb-6">
|
||||
<Card className="bg-white shadow-sm">
|
||||
<CardHeader className="pb-2">
|
||||
<CardTitle className="text-lg flex items-center">
|
||||
<Target className="h-5 w-5 mr-2 text-green-600" />
|
||||
升级潜力分析
|
||||
<CardTitle className="text-sm md:text-lg flex items-center">
|
||||
<Target className="h-4 w-4 md:h-5 md:w-5 mr-2 text-green-600" />
|
||||
升级潜力
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-2">
|
||||
<CardContent className="text-xs md:text-sm">
|
||||
<div className="space-y-1 md:space-y-2">
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm">高潜力用户</span>
|
||||
<span className="text-sm font-medium">2,345</span>
|
||||
<span>高潜力用户</span>
|
||||
<span className="font-medium">2,345</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm">中潜力用户</span>
|
||||
<span className="text-sm font-medium">5,678</span>
|
||||
<span>中潜力用户</span>
|
||||
<span className="font-medium">5,678</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm">低潜力用户</span>
|
||||
<span className="text-sm font-medium">1,234</span>
|
||||
<span>低潜力用户</span>
|
||||
<span className="font-medium">1,234</span>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
@@ -653,24 +709,24 @@ export default function UserValuePage() {
|
||||
|
||||
<Card className="bg-white shadow-sm">
|
||||
<CardHeader className="pb-2">
|
||||
<CardTitle className="text-lg flex items-center">
|
||||
<Layers className="h-5 w-5 mr-2 text-blue-600" />
|
||||
<CardTitle className="text-sm md:text-lg flex items-center">
|
||||
<Layers className="h-4 w-4 md:h-5 md:w-5 mr-2 text-blue-600" />
|
||||
升级成功率
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-2">
|
||||
<CardContent className="text-xs md:text-sm">
|
||||
<div className="space-y-1 md:space-y-2">
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm">本月升级率</span>
|
||||
<span className="text-sm font-medium">12.5%</span>
|
||||
<span>本月升级率</span>
|
||||
<span className="font-medium">12.5%</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm">平均升级周期</span>
|
||||
<span className="text-sm font-medium">28天</span>
|
||||
<span>平均升级周期</span>
|
||||
<span className="font-medium">28天</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm">预期升级用户</span>
|
||||
<span className="text-sm font-medium">1,856</span>
|
||||
<span>预期升级用户</span>
|
||||
<span className="font-medium">1,856</span>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
@@ -678,54 +734,54 @@ export default function UserValuePage() {
|
||||
|
||||
<Card className="bg-white shadow-sm">
|
||||
<CardHeader className="pb-2">
|
||||
<CardTitle className="text-lg flex items-center">
|
||||
<Tag className="h-5 w-5 mr-2 text-purple-600" />
|
||||
升级价值贡献
|
||||
<CardTitle className="text-sm md:text-lg flex items-center">
|
||||
<Tag className="h-4 w-4 md:h-5 md:w-5 mr-2 text-purple-600" />
|
||||
价值贡献
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-2">
|
||||
<CardContent className="text-xs md:text-sm">
|
||||
<div className="space-y-1 md:space-y-2">
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm">升级价值增长</span>
|
||||
<span className="text-sm font-medium">¥2.3M</span>
|
||||
<span>升级价值增长</span>
|
||||
<span className="font-medium">¥2.3M</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm">平均用户价值提升</span>
|
||||
<span className="text-sm font-medium">¥1,245</span>
|
||||
<span>平均价值提升</span>
|
||||
<span className="font-medium">¥1,245</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm">ROI提升</span>
|
||||
<span className="text-sm font-medium">35.8%</span>
|
||||
<span>ROI提升</span>
|
||||
<span className="font-medium">35.8%</span>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-medium">个人升级路径推荐</h3>
|
||||
<div className="space-y-3">
|
||||
<div className="space-y-3 md:space-y-4">
|
||||
<h3 className="text-sm md:text-lg font-medium">个人升级路径推荐</h3>
|
||||
<div className="space-y-2 md:space-y-3">
|
||||
{filteredUsers.slice(0, 5).map((user) => (
|
||||
<div
|
||||
key={user.id}
|
||||
className="flex items-center justify-between p-4 border rounded-lg hover:bg-gray-50"
|
||||
className="flex flex-col md:flex-row md:items-center justify-between p-3 md:p-4 border rounded-lg hover:bg-gray-50 space-y-2 md:space-y-0"
|
||||
>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="flex items-center gap-3 md:gap-4">
|
||||
<div>
|
||||
<p className="font-medium">{user.name}</p>
|
||||
<p className="text-sm text-gray-500">{user.company}</p>
|
||||
<p className="font-medium text-sm md:text-base">{user.name}</p>
|
||||
<p className="text-xs md:text-sm text-gray-500">{user.company}</p>
|
||||
</div>
|
||||
<Badge className={getRFMLevelColor(user.level)}>{user.level}</Badge>
|
||||
<Badge className={`${getRFMLevelColor(user.level)} text-xs`}>{user.level}</Badge>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="text-right">
|
||||
<p className="text-sm font-medium">下一级别: {user.nextUpgrade}</p>
|
||||
<p className="text-sm text-gray-500">升级概率: {user.upgradeProbability}%</p>
|
||||
<div className="flex flex-col md:flex-row items-start md:items-center gap-2 md:gap-4">
|
||||
<div className="text-left md:text-right">
|
||||
<p className="text-xs md:text-sm font-medium">下一级别: {user.nextUpgrade}</p>
|
||||
<p className="text-xs text-gray-500">升级概率: {user.upgradeProbability}%</p>
|
||||
</div>
|
||||
<div className="w-24">
|
||||
<Progress value={user.upgradeProbability} className="h-2" />
|
||||
<div className="w-full md:w-24">
|
||||
<Progress value={user.upgradeProbability} className="h-1.5 md:h-2" />
|
||||
</div>
|
||||
<Button variant="outline" size="sm">
|
||||
<Button variant="outline" size="sm" className="text-xs bg-transparent">
|
||||
查看策略
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user