93 lines
3.4 KiB
TypeScript
93 lines
3.4 KiB
TypeScript
"use client"
|
|
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
|
import { TrendingUp, BarChart3 } from "lucide-react"
|
|
import { useDashboard } from "../_lib/contexts/DashboardContext"
|
|
import { useEffect, useState } from "react"
|
|
|
|
export default function GrowthChart() {
|
|
const { config } = useDashboard()
|
|
const [chartData, setChartData] = useState<number[]>([])
|
|
|
|
// 生成模拟的增长数据,确保与私域粉丝总数匹配
|
|
useEffect(() => {
|
|
const generateData = () => {
|
|
const currentFans = config.totalFans || 460000
|
|
const data = []
|
|
// 生成有波动的7天数据
|
|
const baseGrowthRates = [0.015, 0.035, 0.008, 0.042, 0.025, 0.018, 0.028]
|
|
|
|
for (let i = 6; i >= 0; i--) {
|
|
if (i === 0) {
|
|
data.push(currentFans)
|
|
} else {
|
|
const growthRate = baseGrowthRates[6 - i] + (Math.random() - 0.5) * 0.01
|
|
const pastValue = currentFans / Math.pow(1 + growthRate, i)
|
|
data.push(Math.floor(pastValue))
|
|
}
|
|
}
|
|
return data
|
|
}
|
|
|
|
setChartData(generateData())
|
|
}, [config.totalFans])
|
|
|
|
// 计算增长率
|
|
const growthRate =
|
|
chartData.length > 1 ? (((chartData[chartData.length - 1] - chartData[0]) / chartData[0]) * 100).toFixed(1) : "0"
|
|
|
|
return (
|
|
<Card className="wz-glass-card border-border/50 shadow-xl hover:border-white/20 transition-all duration-300">
|
|
<CardHeader className="pb-2">
|
|
<CardTitle className="text-lg font-medium text-slate-300 flex items-center">
|
|
<BarChart3 className="w-5 h-5 mr-2 text-white/80" />
|
|
用户增长趋势
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-4">
|
|
{/* 增长统计 */}
|
|
<div className="bg-white/5 rounded-lg p-4 border border-white/10">
|
|
<div className="flex items-center justify-between mb-3">
|
|
<div>
|
|
<div className="text-sm text-slate-400">7日增长</div>
|
|
<div className="text-xl font-bold text-green-400 flex items-center">
|
|
<TrendingUp className="w-4 h-4 mr-1" />+{growthRate}%
|
|
</div>
|
|
</div>
|
|
<div className="text-right">
|
|
<div className="text-sm text-slate-400">私域粉丝总数</div>
|
|
<div className="text-lg font-bold text-white">
|
|
{((config.totalFans || 460000) / 10000).toFixed(1)}万
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="h-20 flex items-end space-x-1">
|
|
{chartData.map((value, index) => {
|
|
const height =
|
|
((value - Math.min(...chartData)) / (Math.max(...chartData) - Math.min(...chartData))) * 60 + 10
|
|
const isLast = index === chartData.length - 1
|
|
return (
|
|
<div
|
|
key={index}
|
|
className={`flex-1 rounded-t transition-all duration-300 ${
|
|
isLast
|
|
? "bg-white/30 shadow-lg"
|
|
: "bg-white/20 hover:bg-white/25"
|
|
}`}
|
|
style={{ height: `${height}px` }}
|
|
/>
|
|
)
|
|
})}
|
|
</div>
|
|
|
|
<div className="flex justify-between text-xs text-slate-500 mt-2">
|
|
<span>7天前</span>
|
|
<span className="text-cyan-400">今天</span>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
)
|
|
}
|