feat(front-end): 初始化STP前端工程并提交页面框架
引入前端项目基础结构、页面骨架和UI组件,建立可运行的开发与构建配置,方便后续按模块迭代。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import { useNavigate } from "react-router";
|
||||
import { ArrowLeft, Sparkles, Send, Eye, Check, Globe } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "../components/ui/button";
|
||||
import { Card } from "../components/ui/card";
|
||||
import { AiBadge } from "../components/shared/common";
|
||||
import { sourcingRecords } from "../data/mock";
|
||||
|
||||
export function SmartSourcing() {
|
||||
const navigate = useNavigate();
|
||||
const viewed = sourcingRecords.filter((r) => r.viewed).length;
|
||||
const registered = sourcingRecords.filter((r) => r.registered).length;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="mb-5 flex items-center gap-3">
|
||||
<Button variant="ghost" size="icon" onClick={() => navigate(-1)}>
|
||||
<ArrowLeft className="size-5" />
|
||||
</Button>
|
||||
<div className="flex items-center gap-2">
|
||||
<h1 className="text-foreground">AI 智慧寻源结果</h1>
|
||||
<AiBadge label="AI 主动寻源" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mb-6 grid grid-cols-3 gap-4">
|
||||
{[
|
||||
{ l: "AI 外发邀请", v: sourcingRecords.length, c: "#2563eb" },
|
||||
{ l: "已查看回执", v: viewed, c: "#f59e0b" },
|
||||
{ l: "已报名", v: registered, c: "#14b8a6" },
|
||||
].map((s) => (
|
||||
<Card key={s.l} className="gap-0 p-5">
|
||||
<div className="text-sm text-muted-foreground">{s.l}</div>
|
||||
<div className="mt-2 text-2xl font-semibold" style={{ color: s.c }}>{s.v}</div>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<Card className="gap-0 p-0">
|
||||
<div className="flex items-center gap-2 border-b px-6 py-4">
|
||||
<Globe className="size-5 text-primary" />
|
||||
<h3 className="text-foreground">互联网平台主动外发邀请记录</h3>
|
||||
</div>
|
||||
<table className="w-full text-sm">
|
||||
<thead>
|
||||
<tr className="border-b bg-muted/40 text-left text-muted-foreground">
|
||||
<th className="px-6 py-3 font-medium">目标供应商</th>
|
||||
<th className="px-4 py-3 font-medium">外发渠道</th>
|
||||
<th className="px-4 py-3 font-medium">外发时间</th>
|
||||
<th className="px-4 py-3 font-medium">查看回执</th>
|
||||
<th className="px-4 py-3 font-medium">是否报名</th>
|
||||
<th className="px-4 py-3 font-medium">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y">
|
||||
{sourcingRecords.map((r) => (
|
||||
<tr key={r.id} className={`hover:bg-muted/20 ${!r.viewed ? "bg-amber-50/30" : ""}`}>
|
||||
<td className="px-6 py-3 font-medium text-foreground">{r.supplier}</td>
|
||||
<td className="px-4 py-3 text-muted-foreground">{r.channel}</td>
|
||||
<td className="px-4 py-3 text-muted-foreground">{r.sentAt}</td>
|
||||
<td className="px-4 py-3">
|
||||
{r.viewed ? (
|
||||
<span className="inline-flex items-center gap-1 text-emerald-600"><Eye className="size-4" /> 已查看</span>
|
||||
) : (
|
||||
<span className="inline-flex items-center gap-1 text-amber-600"><Send className="size-4" /> 待查看</span>
|
||||
)}
|
||||
</td>
|
||||
<td className="px-4 py-3">
|
||||
{r.registered ? <span className="text-emerald-600">已报名</span> : <span className="text-muted-foreground">未报名</span>}
|
||||
</td>
|
||||
<td className="px-4 py-3">
|
||||
<Button size="sm" variant="outline" className="h-7" onClick={() => toast.success("已确认回执")}>
|
||||
<Check className="size-3.5" /> 确认回执
|
||||
</Button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</Card>
|
||||
|
||||
<div className="mt-4 flex items-start gap-2 rounded-lg border border-violet-200 bg-violet-50/50 p-3 text-sm text-muted-foreground">
|
||||
<Sparkles className="mt-0.5 size-4 shrink-0 text-violet-500" />
|
||||
小滨已根据采购品类与历史成交,自动从全国公共资源交易平台等渠道匹配并外发邀请,未查看回执的供应商已为您高亮提醒。
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user