feat: align controlled AI sessions and MVP controls

This commit is contained in:
2026-07-21 19:19:36 +08:00
parent 8767446b78
commit 122f5d8c52
18 changed files with 758 additions and 468 deletions

View File

@@ -1,115 +1,19 @@
import { useState } from 'react'
import { Avatar, Button, Card, Form, Input, Layout, Modal, Radio, Space, Typography } from '@arco-design/web-react'
import {
IconApps,
IconCalendar,
IconRobot,
IconStorage,
IconUser,
} from '@arco-design/web-react/icon'
import { Layout, Space } from '@arco-design/web-react'
import { IconCheckCircle } from '@arco-design/web-react/icon'
const { Footer } = Layout
const { Text, Title } = Typography
const plans = [
{ id: 'starter', name: '基础版', price: '¥29/月', desc: '个人项目、基础智能体与 20GB 存储。' },
{ id: 'pro', name: '专业版', price: '¥99/月', desc: '团队协作、高级智能体与 200GB 存储。' },
{ id: 'team', name: '团队版', price: '¥299/月', desc: '成员管理、审计日志与私有化部署支持。' },
]
export function ProjectStatusbar() {
const [profileOpen, setProfileOpen] = useState(false)
const [upgradeOpen, setUpgradeOpen] = useState(false)
const [selectedPlan, setSelectedPlan] = useState('pro')
return (
<>
<Footer className="statusbar">
<button className="status-user" type="button" onClick={() => setProfileOpen(true)}>
<Avatar size={24} style={{ backgroundColor: '#165DFF' }}></Avatar>
<span className="status-identity">
<Text className="status-name"></Text>
<span className="status-online-dot" aria-label="在线" title="在线" />
</span>
<Button className="status-upgrade" size="mini" type="primary" onClick={(event) => {
event.stopPropagation()
setUpgradeOpen(true)
}}></Button>
</button>
<Space className="status-system" size={18}>
<span><IconInteractionFallback /> 3 </span>
<span><IconRobot /> AI </span>
<span><IconStorage /> 152GB </span>
<span> <b></b></span>
<IconApps />
</Space>
</Footer>
<Modal
title="个人资料"
visible={profileOpen}
onCancel={() => setProfileOpen(false)}
onOk={() => setProfileOpen(false)}
okText="保存"
cancelText="取消"
>
<Form layout="vertical" className="status-modal-form">
<Form.Item label="头像">
<Space>
<Avatar size={42} style={{ backgroundColor: '#165DFF' }}></Avatar>
<Button icon={<IconUser />}></Button>
</Space>
</Form.Item>
<Form.Item label="名称">
<Input defaultValue="张明" placeholder="请输入名称" />
</Form.Item>
<Form.Item label="邮箱">
<Input defaultValue="zhangming@senlin.ai" placeholder="请输入邮箱" />
</Form.Item>
<Form.Item label="当前密码">
<Input.Password placeholder="用于确认身份" />
</Form.Item>
<Form.Item label="新密码">
<Input.Password placeholder="不修改密码可留空" />
</Form.Item>
</Form>
</Modal>
<Modal
title="升级套餐"
visible={upgradeOpen}
onCancel={() => setUpgradeOpen(false)}
onOk={() => setUpgradeOpen(false)}
okText="去支付"
cancelText="取消"
>
<Radio.Group value={selectedPlan} onChange={setSelectedPlan} className="billing-plan-group">
{plans.map((plan) => (
<Card className={selectedPlan === plan.id ? 'billing-plan active' : 'billing-plan'} key={plan.id} bordered>
<Radio value={plan.id}>
<div>
<Title heading={6}>{plan.name}</Title>
<Text className="billing-price">{plan.price}</Text>
<Text type="secondary">{plan.desc}</Text>
</div>
</Radio>
</Card>
))}
</Radio.Group>
<div className="billing-payments">
<Text type="secondary"></Text>
<Space>
<Button></Button>
<Button></Button>
<Button></Button>
</Space>
</div>
</Modal>
</>
<Footer className="statusbar">
<div className="status-user">
<span className="status-avatar" aria-hidden="true"></span>
<span className="status-name"></span>
</div>
<Space className="status-system" size={8}>
<IconCheckCircle />
<span></span>
</Space>
</Footer>
)
}
function IconInteractionFallback() {
return <IconCalendar />
}