feat: add AirShelf core implementation

This commit is contained in:
zyc
2026-06-05 10:21:40 +08:00
parent 2ba1058329
commit cfdcd84a30
252 changed files with 70828 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
import { useState } from "react";
import { CircleDollarSign, KeyRound, Settings, UserPlus } from "lucide-react";
import type { Team, TeamMember, User } from "../types";
import type { Page } from "./route-config";
import { money, statusPill } from "./stage-config";
import { TeamModal } from "../components/overlays";
export function TeamPage({ team, user, members, navigate }: { team: Team; user: User; members: TeamMember[]; navigate: (page: Page) => void }) {
const [modal, setModal] = useState<"" | "invite" | "limit">("");
const rows = members.length ? members : [{ id: "owner", role: "owner", status: "active", monthly_credit_limit: "3000.00", user } as TeamMember];
return (
<>
<div className="page-head"><div><h1>团队管理</h1><div className="sub"><span className="mono">// 成员 · 角色 · 额度 · 共享资产库</span></div></div><button className="btn btn-primary" type="button" onClick={() => setModal("invite")}><UserPlus size={13} />创建账户</button></div>
<div className="team-top"><div className="team-banner"><span className="corner-tr">+</span><span className="corner-bl">+</span><div className="banner-head"><div className="banner-id"><div className="lbl">[ TEAM ]</div><div className="nm">{team.name} <span className="tag">企业</span></div><div className="meta">// 团队 ID: {team.id.slice(0, 8)} · {rows.length} 名成员</div></div><div className="banner-actions"><button className="btn btn-sm" type="button" onClick={() => navigate("account")}>充值</button><button className="btn btn-ghost btn-sm" type="button" onClick={() => setModal("limit")}>设置月限额</button></div></div></div></div>
<div className="team-grid"><div className="pane" style={{ padding: 0 }}><div className="pane-table-h"><h3>成员列表 <span className="ct">// {rows.length} 人</span></h3><input className="input" placeholder="搜索姓名 / 手机号" /></div><table className="t members-table"><thead><tr><th>成员</th><th>角色</th><th>月度额度</th><th>状态</th><th /></tr></thead><tbody>{rows.map((member) => <tr key={member.id}><td><div className="proj-name-cell"><div className="av">{member.user.username.slice(0, 1).toUpperCase()}</div><div><div className="proj-name">{member.user.username}</div><div className="proj-sub">{member.user.email || "未填写邮箱"}</div></div></div></td><td><span className="pill info"><span className="dot" />{member.role}</span></td><td>{money(member.monthly_credit_limit)}</td><td><span className={`pill ${statusPill(member.status)}`}><span className="dot" />{member.status}</span></td><td><button className="icon-btn-sm" type="button"><Settings size={13} /></button><button className="icon-btn-sm" type="button"><KeyRound size={13} /></button></td></tr>)}</tbody></table></div></div>
<TeamModal open={modal === "limit"} title="设置月限额" subtitle="// 自然月重置 · 仅超管可改" icon={<CircleDollarSign size={16} />} close={() => setModal("")}><div className="field"><label className="field-label">月限额 ¥</label><input className="input" defaultValue="3000" /></div></TeamModal>
<TeamModal open={modal === "invite"} title="创建账户" subtitle="// 直接生成账号 · 分享给成员登录" icon={<UserPlus size={16} />} close={() => setModal("")}><div className="field"><label className="field-label">用户名</label><input className="input" defaultValue="zhang.yunying" /></div><div className="field"><label className="field-label">登录密码</label><input className="input mono" defaultValue="AirShelf2026" /></div></TeamModal>
</>
);
}