unis_crm/frontend/src/pages/Dashboard.tsx

95 lines
5.0 KiB
TypeScript
Raw Normal View History

2026-03-19 06:23:03 +00:00
import { BarChart3, TrendingUp, Users, CheckCircle2 } from "lucide-react";
import { motion } from "motion/react";
export default function Dashboard() {
const stats = [
{ name: "本月新增商机", value: "12", icon: TrendingUp, color: "text-emerald-600 dark:text-emerald-400", bg: "bg-emerald-100 dark:bg-emerald-500/20" },
{ name: "跟进中客户", value: "48", icon: Users, color: "text-blue-600 dark:text-blue-400", bg: "bg-blue-100 dark:bg-blue-500/20" },
{ name: "已成单项目", value: "3", icon: CheckCircle2, color: "text-violet-600 dark:text-violet-400", bg: "bg-violet-100 dark:bg-violet-500/20" },
{ name: "本月打卡天数", value: "20", icon: BarChart3, color: "text-amber-600 dark:text-amber-400", bg: "bg-amber-100 dark:bg-amber-500/20" },
];
return (
<div className="space-y-6">
<header>
<h1 className="text-2xl font-bold tracking-tight text-slate-900 dark:text-white"></h1>
<p className="text-sm text-slate-500 dark:text-slate-400"> 365 </p>
</header>
<div className="grid grid-cols-2 gap-4 md:grid-cols-4">
{stats.map((stat, i) => (
<motion.div
key={stat.name}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: i * 0.1 }}
className="rounded-2xl border border-slate-100 dark:border-slate-800 bg-white dark:bg-slate-900/50 p-5 shadow-sm backdrop-blur-sm transition-all hover:shadow-md dark:hover:bg-slate-900"
>
<div className="flex items-center gap-4">
<div className={`flex h-12 w-12 items-center justify-center rounded-xl ${stat.bg}`}>
<stat.icon className={`h-6 w-6 ${stat.color}`} />
</div>
<div>
<p className="text-sm font-medium text-slate-500 dark:text-slate-400">{stat.name}</p>
<p className="text-2xl font-bold text-slate-900 dark:text-white">{stat.value}</p>
</div>
</div>
</motion.div>
))}
</div>
<div className="grid gap-6 md:grid-cols-2">
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.4 }}
className="rounded-2xl border border-slate-100 dark:border-slate-800 bg-white dark:bg-slate-900/50 p-6 shadow-sm backdrop-blur-sm"
>
<h2 className="mb-4 text-lg font-semibold text-slate-900 dark:text-white"></h2>
<ul className="space-y-3">
{[
"跟进 A 公司云桌面扩容项目",
"提交本周销售日报",
"拜访 B 渠道商王总",
"更新 C 项目商机阶段",
].map((task, i) => (
<li key={i} className="group flex cursor-pointer items-center gap-3 rounded-xl border border-slate-50 dark:border-slate-800/50 p-3 transition-all hover:bg-slate-50 dark:hover:bg-slate-800">
<div className="flex h-5 w-5 items-center justify-center rounded-full border-2 border-slate-300 dark:border-slate-600 group-hover:border-violet-500 dark:group-hover:border-violet-400 transition-colors" />
<span className="text-sm text-slate-700 dark:text-slate-300 group-hover:text-slate-900 dark:group-hover:text-white transition-colors">{task}</span>
</li>
))}
</ul>
</motion.div>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.5 }}
className="rounded-2xl border border-slate-100 dark:border-slate-800 bg-white dark:bg-slate-900/50 p-6 shadow-sm backdrop-blur-sm"
>
<h2 className="mb-4 text-lg font-semibold text-slate-900 dark:text-white"></h2>
<div className="space-y-5">
{[
{ title: "商机阶段更新", desc: "D 项目已推进至方案交流阶段", time: "10分钟前" },
{ title: "日报已点评", desc: "主管对你昨天的日报给出了 95 分", time: "2小时前" },
{ title: "新渠道录入", desc: "成功录入 E 渠道商信息", time: "昨天" },
].map((news, i) => (
<div key={i} className="flex gap-4">
<div className="relative mt-1 flex h-3 w-3 items-center justify-center">
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-violet-400 opacity-20"></span>
<span className="relative inline-flex h-2 w-2 rounded-full bg-violet-500"></span>
</div>
<div>
<p className="text-sm font-medium text-slate-900 dark:text-white">{news.title}</p>
<p className="text-xs text-slate-500 dark:text-slate-400 mt-0.5">{news.desc}</p>
<p className="mt-1 text-[10px] text-slate-400 dark:text-slate-500">{news.time}</p>
</div>
</div>
))}
</div>
</motion.div>
</div>
</div>
);
}