feat(core/frontend): wire P0 team mgmt / recharge / notifications
- App.tsx: load notifications, expose team/recharge/notification handlers, real unread bell count (was hardcoded 12) - team.tsx: create/edit/reset-password/remove member + team recharge modals - account.tsx: recharge via wechat/alipay buttons + custom amount - messages.tsx: real notification inbox, mark-read on select, mark-all-read - verified: tsc --noEmit clean; e2e create->update->reset->recharge->mark-read->delete all green Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
d41e487f08
commit
25bf3293df
@@ -4,11 +4,11 @@ import { money } from "./stage-config";
|
||||
|
||||
type Tab = "overview" | "by-project" | "by-member" | "bills";
|
||||
|
||||
const RECHARGE: Array<{ amt: number; gift: string; bonus: boolean; ribbon?: string }> = [
|
||||
{ amt: 100, gift: "无赠送", bonus: false },
|
||||
{ amt: 500, gift: "+ ¥30 赠送", bonus: true, ribbon: "推荐" },
|
||||
{ amt: 1000, gift: "+ ¥80 赠送", bonus: true },
|
||||
{ amt: 3000, gift: "+ ¥300 赠送", bonus: true }
|
||||
const RECHARGE: Array<{ amt: number; gift: string; bonus: boolean; bonusAmt: number; ribbon?: string }> = [
|
||||
{ amt: 100, gift: "无赠送", bonus: false, bonusAmt: 0 },
|
||||
{ amt: 500, gift: "+ ¥30 赠送", bonus: true, bonusAmt: 30, ribbon: "推荐" },
|
||||
{ amt: 1000, gift: "+ ¥80 赠送", bonus: true, bonusAmt: 80 },
|
||||
{ amt: 3000, gift: "+ ¥300 赠送", bonus: true, bonusAmt: 300 }
|
||||
];
|
||||
|
||||
const STAGES: Array<{ k: string; color: string }> = [
|
||||
@@ -18,14 +18,26 @@ const STAGES: Array<{ k: string; color: string }> = [
|
||||
{ k: "脚本 LLM", color: "var(--black-alpha-32)" }
|
||||
];
|
||||
|
||||
export function AccountPage({ billing, ledgers, projects, teamMembers }: {
|
||||
export function AccountPage({ billing, ledgers, projects, teamMembers, onRecharge }: {
|
||||
billing: BillingSummary | null;
|
||||
ledgers: Ledger[];
|
||||
projects: Project[];
|
||||
teamMembers: TeamMember[];
|
||||
onRecharge: (amount: number, bonus: number) => void | Promise<unknown>;
|
||||
}) {
|
||||
const [tab, setTab] = useState<Tab>("overview");
|
||||
const [recharge, setRecharge] = useState(500);
|
||||
const [customAmt, setCustomAmt] = useState("");
|
||||
|
||||
const selectedCard = RECHARGE.find((item) => item.amt === recharge);
|
||||
const effectiveAmount = Number(customAmt) > 0 ? Number(customAmt) : recharge;
|
||||
const effectiveBonus = Number(customAmt) > 0 ? 0 : selectedCard?.bonusAmt || 0;
|
||||
|
||||
async function submitRecharge() {
|
||||
if (effectiveAmount <= 0) return;
|
||||
await onRecharge(effectiveAmount, effectiveBonus);
|
||||
setCustomAmt("");
|
||||
}
|
||||
|
||||
const balance = Number(billing?.account.balance || 0);
|
||||
const used = Number(billing?.charged_total || 0);
|
||||
@@ -78,7 +90,7 @@ export function AccountPage({ billing, ledgers, projects, teamMembers }: {
|
||||
<h3>快速充值</h3>
|
||||
<div className="desc">// 充值后立刻到账,可开发票 · 仅超管可操作</div>
|
||||
</div>
|
||||
<div className="topup-selected">已选 ¥{recharge}</div>
|
||||
<div className="topup-selected">已选 ¥{effectiveAmount}{effectiveBonus > 0 ? ` + ¥${effectiveBonus} 赠送` : ""}</div>
|
||||
</div>
|
||||
<div className="recharge-row">
|
||||
{RECHARGE.map((item) => (
|
||||
@@ -98,13 +110,13 @@ export function AccountPage({ billing, ledgers, projects, teamMembers }: {
|
||||
</div>
|
||||
<div className="pay-row">
|
||||
<div className="pay-title">自定义金额</div>
|
||||
<input className="input" placeholder="最低 ¥50,可输入任意金额" />
|
||||
<input className="input" placeholder="最低 ¥50,可输入任意金额" type="number" value={customAmt} onChange={(event) => setCustomAmt(event.target.value)} />
|
||||
<div className="pay-btn-row">
|
||||
<button className="btn pay-method-btn pay-wechat" type="button" aria-label="微信支付">
|
||||
<button className="btn pay-method-btn pay-wechat" type="button" aria-label="微信支付" onClick={submitRecharge}>
|
||||
<span className="pay-logo" aria-hidden="true"><img src="/assets/pay-wechat.png" alt="" /></span>
|
||||
微信支付
|
||||
</button>
|
||||
<button className="btn pay-method-btn pay-alipay" type="button" aria-label="支付宝">
|
||||
<button className="btn pay-method-btn pay-alipay" type="button" aria-label="支付宝" onClick={submitRecharge}>
|
||||
<span className="pay-logo" aria-hidden="true"><img src="/assets/pay-alipay.png" alt="" /></span>
|
||||
支付宝
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user