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:
179
components/dashboard/dashboard-overview.tsx
Normal file
179
components/dashboard/dashboard-overview.tsx
Normal file
@@ -0,0 +1,179 @@
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
||||
import { formatNumber, getGrowthClass } from "@/lib/utils"
|
||||
import { ArrowDown, ArrowUp } from "lucide-react"
|
||||
|
||||
export function DashboardOverview() {
|
||||
// 这里应该从API获取实际数据
|
||||
const overviewData = {
|
||||
userAcquisition: {
|
||||
total: 12458,
|
||||
growth: 12.5,
|
||||
sources: [
|
||||
{ name: "微信", value: 4523, growth: 15.2 },
|
||||
{ name: "抖音", value: 3254, growth: 24.3 },
|
||||
{ name: "小红书", value: 2145, growth: 8.7 },
|
||||
{ name: "公众号", value: 1536, growth: -3.2 },
|
||||
{ name: "官网", value: 1000, growth: 5.6 },
|
||||
],
|
||||
},
|
||||
userRetention: {
|
||||
rate: 68.5,
|
||||
growth: 2.3,
|
||||
periods: [
|
||||
{ name: "7天", value: 85.2, growth: 1.2 },
|
||||
{ name: "30天", value: 68.5, growth: 2.3 },
|
||||
{ name: "90天", value: 42.3, growth: 3.5 },
|
||||
{ name: "180天", value: 28.7, growth: -1.2 },
|
||||
{ name: "365天", value: 15.4, growth: -2.5 },
|
||||
],
|
||||
},
|
||||
userConversion: {
|
||||
rate: 12.5,
|
||||
growth: 3.2,
|
||||
stages: [
|
||||
{ name: "浏览", value: 100, growth: 0 },
|
||||
{ name: "注册", value: 35.2, growth: 2.1 },
|
||||
{ name: "首次购买", value: 12.5, growth: 3.2 },
|
||||
{ name: "复购", value: 8.3, growth: 5.4 },
|
||||
{ name: "会员", value: 4.2, growth: 1.8 },
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
return (
|
||||
<Tabs defaultValue="acquisition" className="w-full">
|
||||
<TabsList className="grid w-full grid-cols-3">
|
||||
<TabsTrigger value="acquisition">用户获取</TabsTrigger>
|
||||
<TabsTrigger value="retention">用户留存</TabsTrigger>
|
||||
<TabsTrigger value="conversion">用户转化</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="acquisition">
|
||||
<Card className="border shadow-sm">
|
||||
<CardHeader>
|
||||
<CardTitle>用户获取分析</CardTitle>
|
||||
<CardDescription>各渠道用户获取情况及增长趋势</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm font-medium">总获取用户</p>
|
||||
<p className="text-2xl font-bold">{formatNumber(overviewData.userAcquisition.total)}</p>
|
||||
</div>
|
||||
<div className={`flex items-center ${getGrowthClass(overviewData.userAcquisition.growth)}`}>
|
||||
{overviewData.userAcquisition.growth > 0 ? (
|
||||
<ArrowUp className="h-4 w-4 mr-1" />
|
||||
) : (
|
||||
<ArrowDown className="h-4 w-4 mr-1" />
|
||||
)}
|
||||
<span>{Math.abs(overviewData.userAcquisition.growth)}%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
{overviewData.userAcquisition.sources.map((source) => (
|
||||
<div key={source.name} className="flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<span className="text-sm">{source.name}</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<span className="text-sm">{formatNumber(source.value)}</span>
|
||||
<span className={`text-xs ${getGrowthClass(source.growth)}`}>
|
||||
{source.growth > 0 ? "+" : ""}
|
||||
{source.growth}%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
<TabsContent value="retention">
|
||||
<Card className="border shadow-sm">
|
||||
<CardHeader>
|
||||
<CardTitle>用户留存分析</CardTitle>
|
||||
<CardDescription>不同时间段的用户留存率及变化趋势</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm font-medium">30天留存率</p>
|
||||
<p className="text-2xl font-bold">{overviewData.userRetention.rate}%</p>
|
||||
</div>
|
||||
<div className={`flex items-center ${getGrowthClass(overviewData.userRetention.growth)}`}>
|
||||
{overviewData.userRetention.growth > 0 ? (
|
||||
<ArrowUp className="h-4 w-4 mr-1" />
|
||||
) : (
|
||||
<ArrowDown className="h-4 w-4 mr-1" />
|
||||
)}
|
||||
<span>{Math.abs(overviewData.userRetention.growth)}%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
{overviewData.userRetention.periods.map((period) => (
|
||||
<div key={period.name} className="flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<span className="text-sm">{period.name}</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<span className="text-sm">{period.value}%</span>
|
||||
<span className={`text-xs ${getGrowthClass(period.growth)}`}>
|
||||
{period.growth > 0 ? "+" : ""}
|
||||
{period.growth}%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
<TabsContent value="conversion">
|
||||
<Card className="border shadow-sm">
|
||||
<CardHeader>
|
||||
<CardTitle>用户转化分析</CardTitle>
|
||||
<CardDescription>用户转化漏斗各阶段转化率及变化趋势</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm font-medium">首次购买转化率</p>
|
||||
<p className="text-2xl font-bold">{overviewData.userConversion.rate}%</p>
|
||||
</div>
|
||||
<div className={`flex items-center ${getGrowthClass(overviewData.userConversion.growth)}`}>
|
||||
{overviewData.userConversion.growth > 0 ? (
|
||||
<ArrowUp className="h-4 w-4 mr-1" />
|
||||
) : (
|
||||
<ArrowDown className="h-4 w-4 mr-1" />
|
||||
)}
|
||||
<span>{Math.abs(overviewData.userConversion.growth)}%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
{overviewData.userConversion.stages.map((stage) => (
|
||||
<div key={stage.name} className="flex items-center justify-between">
|
||||
<div className="flex items-center">
|
||||
<span className="text-sm">{stage.name}</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<span className="text-sm">{stage.value}%</span>
|
||||
<span className={`text-xs ${getGrowthClass(stage.growth)}`}>
|
||||
{stage.growth > 0 ? "+" : ""}
|
||||
{stage.growth}%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user