Files
xll-bi/src/components/views/UsersView.tsx
kkfluous c5f422a464
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
chore: update mock data from April to June 2026, extend daily range to 9 days
Replace all prototype data across Overall/Efficiency/Users views with
June 2026 data (06/01-06/09), add fabricated entries for 06/01-06/07
alongside real 06/08-06/09 data, and make weekly trend fluctuate for
better demo visuals.
2026-06-09 13:29:03 +08:00

104 lines
4.7 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.
import React from 'react';
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend, BarChart, Bar, Cell } from 'recharts';
import { StatCard } from '../ui/StatCard';
import { Users, Truck, Smartphone } from 'lucide-react';
const driverGrowth = [
{ date: '06/01', 活跃APP: 15, 绑定车辆: 2 },
{ date: '06/02', 活跃APP: 14, 绑定车辆: 2 },
{ date: '06/03', 活跃APP: 13, 绑定车辆: 1 },
{ date: '06/04', 活跃APP: 12, 绑定车辆: 2 },
{ date: '06/05', 活跃APP: 11, 绑定车辆: 1 },
{ date: '06/06', 活跃APP: 10, 绑定车辆: 1 },
{ date: '06/07', 活跃APP: 10, 绑定车辆: 1 },
{ date: '06/08', 活跃APP: 9, 绑定车辆: 1 },
{ date: '06/09', 活跃APP: 4, 绑定车辆: 0 },
];
const driverByStation = [
{ name: '嘉兴嘉锦', value: 10 },
{ name: '嘉兴嘉燃', value: 8 },
{ name: '嘉燃经开', value: 5 },
{ name: '如皋华神', value: 3 },
{ name: '桐乡绿能', value: 2 },
{ name: '花桥/嘉善等', value: 2 },
];
export function UsersView() {
return (
<div className="space-y-6 animate-in fade-in slide-in-from-bottom-4 duration-500">
<div className="grid grid-cols-1 md:grid-cols-4 gap-6">
<StatCard
title="累计入池APP用户总数"
value="32 人"
subValue="近期活跃司机达到16人"
icon={Smartphone}
highlight
/>
<StatCard
title="累计绑定车辆司机总数"
value="19 人"
subValue="系统全量历史转化留存"
icon={Truck}
/>
<StatCard
title="总核验车辆绑定率"
value="59 %"
subValue="公司自营与核心车队"
icon={Users}
trend={-36}
/>
<StatCard
title="近期最佳外拓来源区"
value="如皋/桐乡"
subValue="如皋及桐乡累计贡献外围散户活跃"
icon={Users}
/>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div className="bg-white rounded-xl border border-slate-100 p-6 shadow-sm">
<div className="mb-6">
<h3 className="text-lg font-bold text-slate-800">APP渗透与车辆绑定追踪</h3>
<p className="text-sm text-slate-500 mt-1"></p>
</div>
<div className="h-[300px]">
<ResponsiveContainer width="100%" height="100%">
<LineChart data={driverGrowth} margin={{ top: 10, right: 10, left: -25, bottom: 0 }}>
<CartesianGrid vertical={false} stroke="#f1f5f9" strokeDasharray="3 3"/>
<XAxis dataKey="date" axisLine={false} tickLine={false} tick={{fill: '#64748b', fontSize: 12}} dy={10} />
<YAxis axisLine={false} tickLine={false} tick={{fill: '#64748b', fontSize: 12}} />
<Tooltip cursor={{stroke: '#e2e8f0', strokeWidth: 2}} contentStyle={{ borderRadius: '12px', border: '1px solid #e2e8f0' }}/>
<Legend verticalAlign="top" height={36} iconType="circle" wrapperStyle={{ fontSize: '12px' }} />
<Line type="monotone" dataKey="绑定车辆" stroke="#6366f1" strokeWidth={3} dot={{r: 4}} activeDot={{r: 6}} />
<Line type="monotone" dataKey="活跃APP" stroke="#14b8a6" strokeWidth={3} dot={{r: 4}} activeDot={{r: 6}} />
</LineChart>
</ResponsiveContainer>
</div>
</div>
<div className="bg-white rounded-xl border border-slate-100 p-6 shadow-sm">
<div className="mb-6">
<h3 className="text-lg font-bold text-slate-800"></h3>
<p className="text-sm text-slate-500 mt-1"></p>
</div>
<div className="h-[300px]">
<ResponsiveContainer width="100%" height="100%">
<BarChart data={driverByStation} layout="vertical" margin={{ top: 0, right: 30, left: 20, bottom: 0 }}>
<XAxis type="number" hide />
<YAxis dataKey="name" type="category" axisLine={false} tickLine={false} tick={{fill: '#475569', fontSize: 12, fontWeight: 500}} width={80} />
<Tooltip cursor={{fill: '#f8fafc'}} contentStyle={{ borderRadius: '12px', border: '1px solid #e2e8f0' }}/>
<Bar dataKey="value" radius={[0, 6, 6, 0]} barSize={28}>
{driverByStation.map((entry, index) => (
<Cell key={`cell-${index}`} fill={index === 0 ? '#f59e0b' : '#94a3b8'} />
))}
</Bar>
</BarChart>
</ResponsiveContainer>
</div>
</div>
</div>
</div>
);
}