244 lines
9.1 KiB
TypeScript
244 lines
9.1 KiB
TypeScript
import { PlusOutlined, SearchOutlined, CompassOutlined, FireOutlined } from '@ant-design/icons';
|
||
import { Col, Row, Empty, Button, Tag, Space, Input, Spin } from 'antd';
|
||
import { useNavigate } from 'react-router-dom';
|
||
import type { MarketplaceAgent } from '../../../api';
|
||
import type { MarketplacePageLogicOutput } from '../MarketplacePageLogic';
|
||
|
||
interface Props {
|
||
logic: MarketplacePageLogicOutput;
|
||
}
|
||
|
||
export default function MarketplacePageH5({ logic }: Props) {
|
||
const navigate = useNavigate();
|
||
const { loading, q, filtered, setQ, handleFork, isImageUrl } = logic;
|
||
|
||
return (
|
||
<div className="h5-marketplace-page">
|
||
<div className="page-hero h5-page-hero" style={{ padding: '20px 16px' }}>
|
||
<div>
|
||
<div
|
||
style={{
|
||
display: 'inline-flex',
|
||
alignItems: 'center',
|
||
gap: 6,
|
||
padding: '4px 10px',
|
||
borderRadius: 999,
|
||
background: 'var(--color-surface)',
|
||
border: '1px solid var(--color-border)',
|
||
color: 'var(--color-text-secondary)',
|
||
fontSize: 11,
|
||
fontWeight: 500,
|
||
marginBottom: 12,
|
||
}}
|
||
>
|
||
<CompassOutlined style={{ color: 'var(--color-brand)', fontSize: 12 }} />
|
||
探索社区智能体
|
||
</div>
|
||
<h1 className="hero-title h5-hero-title" style={{ fontSize: 28, marginBottom: 8 }}>
|
||
找到更适合你的<br />AI 伙伴
|
||
</h1>
|
||
<p className="hero-subtitle h5-hero-subtitle" style={{ fontSize: 14, lineHeight: 1.6 }}>
|
||
浏览社区创建的智能体,快速复制、微调并投入你的日常工作流。
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="page-container h5-page-container" style={{ paddingTop: 20, paddingLeft: 12, paddingRight: 12 }}>
|
||
<div
|
||
style={{
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
gap: 12,
|
||
marginBottom: 20,
|
||
}}
|
||
>
|
||
<div style={{ width: '100%' }}>
|
||
<Input
|
||
placeholder="搜索智能体名称、描述或作者..."
|
||
prefix={<SearchOutlined style={{ color: 'var(--color-text-tertiary)' }} />}
|
||
value={q}
|
||
onChange={(e) => setQ(e.target.value)}
|
||
style={{ height: 40, borderRadius: 10 }}
|
||
allowClear
|
||
/>
|
||
</div>
|
||
<Button
|
||
type="primary"
|
||
size="middle"
|
||
icon={<PlusOutlined />}
|
||
onClick={() => navigate('/agents/new')}
|
||
style={{
|
||
height: 40,
|
||
width: '100%',
|
||
borderRadius: 10,
|
||
fontWeight: 600,
|
||
}}
|
||
>
|
||
创建新智能体
|
||
</Button>
|
||
</div>
|
||
|
||
{loading ? (
|
||
<div style={{ padding: '40px 0', textAlign: 'center' }}>
|
||
<Spin size="large" />
|
||
</div>
|
||
) : (
|
||
<Row gutter={[12, 12]}>
|
||
{/* Create New Card - always show on H5 */}
|
||
<Col xs={24} sm={24} key="create-new">
|
||
<div onClick={() => navigate('/agents/new')} className="create-card h5-create-card" style={{ padding: 16 }}>
|
||
<div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between' }}>
|
||
<div className="create-icon" style={{ width: 44, height: 44 }}>
|
||
<PlusOutlined style={{ fontSize: 20, color: '#0891b2' }} />
|
||
</div>
|
||
</div>
|
||
|
||
<div style={{ marginTop: 12 }}>
|
||
<div style={{ fontWeight: 700, fontSize: 15, color: 'var(--color-text)', marginBottom: 4 }}>
|
||
新建智能体
|
||
</div>
|
||
<div style={{ fontSize: 12, color: 'var(--color-text-tertiary)', marginBottom: 8 }}>
|
||
从空白开始
|
||
</div>
|
||
<div className="desc" style={{ minHeight: 36, fontSize: 12 }}>
|
||
从名称、提示词、模型和能力配置开始,搭建你的专属 AI 助手。
|
||
</div>
|
||
</div>
|
||
|
||
<div style={{ marginTop: 'auto', paddingTop: 12 }}>
|
||
<Button
|
||
type="default"
|
||
block
|
||
style={{
|
||
height: 36,
|
||
borderRadius: 8,
|
||
fontWeight: 600,
|
||
borderStyle: 'dashed',
|
||
}}
|
||
>
|
||
开始创建
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</Col>
|
||
|
||
{filtered.map((a) => (
|
||
<Col xs={24} sm={24} key={a.id}>
|
||
<div className="agent-card h5-agent-card" style={{ padding: 14, borderRadius: 12 }}>
|
||
<div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 8 }}>
|
||
<div
|
||
style={{
|
||
width: 44,
|
||
height: 44,
|
||
borderRadius: '50%',
|
||
background: a.avatar || 'var(--gradient-brand)',
|
||
color: '#fff',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
fontWeight: 700,
|
||
fontSize: 18,
|
||
boxShadow: 'var(--shadow-sm)',
|
||
overflow: 'hidden',
|
||
}}
|
||
>
|
||
{isImageUrl(a.avatar) ? (
|
||
<img src={a.avatar} className="w-full h-full object-cover" alt="avatar" />
|
||
) : (
|
||
(a.name?.charAt(0) || '?').toUpperCase()
|
||
)}
|
||
</div>
|
||
{a.fork_count > 10 && (
|
||
<Tag
|
||
bordered={false}
|
||
icon={<FireOutlined />}
|
||
style={{
|
||
borderRadius: 999,
|
||
margin: 0,
|
||
background: 'var(--color-warning-soft)',
|
||
color: 'var(--color-warning)',
|
||
fontSize: 11,
|
||
}}
|
||
>
|
||
热门
|
||
</Tag>
|
||
)}
|
||
</div>
|
||
|
||
<div style={{ marginTop: 12 }}>
|
||
<div
|
||
style={{
|
||
fontWeight: 700,
|
||
fontSize: 15,
|
||
color: 'var(--color-text)',
|
||
marginBottom: 4,
|
||
letterSpacing: '-0.01em',
|
||
}}
|
||
>
|
||
{a.name}
|
||
</div>
|
||
<div style={{ fontSize: 12, color: 'var(--color-text-tertiary)', marginBottom: 8 }}>
|
||
by {a.ownerName || '匿名作者'}
|
||
</div>
|
||
<div className="desc" style={{ minHeight: 36, fontSize: 12 }}>{a.description || '暂无详细描述'}</div>
|
||
</div>
|
||
|
||
<div style={{ marginTop: 'auto', paddingTop: 12 }}>
|
||
<Space size={4} wrap style={{ marginBottom: 12 }}>
|
||
{a.kbCount > 0 && (
|
||
<Tag
|
||
bordered={false}
|
||
style={{
|
||
background: 'var(--color-info-soft)',
|
||
color: 'var(--color-info)',
|
||
borderRadius: 999,
|
||
fontSize: 11,
|
||
margin: 0,
|
||
}}
|
||
>
|
||
📚 {a.kbCount} 知识
|
||
</Tag>
|
||
)}
|
||
{a.skillCount > 0 && (
|
||
<Tag
|
||
bordered={false}
|
||
style={{
|
||
background: 'var(--color-success-soft)',
|
||
color: 'var(--color-success)',
|
||
borderRadius: 999,
|
||
fontSize: 11,
|
||
margin: 0,
|
||
}}
|
||
>
|
||
🛠 {a.skillCount} 技能
|
||
</Tag>
|
||
)}
|
||
</Space>
|
||
|
||
<Button
|
||
type="default"
|
||
block
|
||
onClick={() => handleFork(a)}
|
||
style={{
|
||
height: 36,
|
||
borderRadius: 8,
|
||
fontWeight: 600,
|
||
}}
|
||
>
|
||
📥 复制到我的
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</Col>
|
||
))}
|
||
</Row>
|
||
)}
|
||
|
||
{filtered.length === 0 && !loading && (
|
||
<Empty description="没有找到匹配的智能体" style={{ marginTop: 40 }} />
|
||
)}
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|