feat: change agent list and edit page style

feat/unify-api-and-responsive-pages
yannyang 2026-06-24 01:12:52 +08:00
parent 25221f7b5e
commit 9536909f53
9 changed files with 523 additions and 186 deletions

View File

@ -134,7 +134,7 @@ export default function ChatPreview({ agent, agentId }: Props) {
const isImageUrl = (url: string | undefined) => url?.startsWith('http') || url?.startsWith('/'); const isImageUrl = (url: string | undefined) => url?.startsWith('http') || url?.startsWith('/');
return ( return (
<div className="flex flex-col h-full bg-gray-50 border-l"> <div className="flex flex-col h-full bg-gray-50">
<div className="p-4 border-b bg-white flex items-center gap-2"> <div className="p-4 border-b bg-white flex items-center gap-2">
<div <div
className="rounded-full text-white flex items-center justify-center font-bold overflow-hidden" className="rounded-full text-white flex items-center justify-center font-bold overflow-hidden"

View File

@ -0,0 +1,45 @@
.agent-editor-shell-container {
position: fixed;
inset: 0;
display: flex;
flex-direction: column;
background-color: #fff;
z-index: 100;
}
.agent-editor-workbench-container {
flex: 1;
min-height: 0;
display: flex;
}
.agent-editor-workbench-container.is-mobile {
flex-direction: column;
overflow-y: auto;
padding: 8px;
gap: 12px;
}
.agent-editor-workbench-container.is-desktop {
overflow: hidden;
}
.agent-editor-mobile-footer-bar {
padding: 1rem;
border-top: 1px solid var(--color-border);
background-color: #fff;
display: flex;
align-items: center;
justify-content: space-between;
flex-shrink: 0;
}
.agent-editor-footer-status {
font-size: 0.75rem;
color: var(--color-text-tertiary);
}
.agent-editor-footer-actions {
display: flex;
gap: 0.5rem;
}

View File

@ -8,9 +8,10 @@ interface HeaderProps {
autoSaveStatus: 'saved' | 'dirty' | 'saving' | 'error'; autoSaveStatus: 'saved' | 'dirty' | 'saving' | 'error';
saving: boolean; saving: boolean;
onSave: () => Promise<void>; onSave: () => Promise<void>;
isMobile?: boolean;
} }
export default function Header({ isNew, currentName, navigate, autoSaveStatus, saving, onSave }: HeaderProps) { export default function Header({ isNew, currentName, navigate, autoSaveStatus, saving, onSave, isMobile }: HeaderProps) {
return ( return (
<header className="monica-header agent-editor-header"> <header className="monica-header agent-editor-header">
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
@ -27,34 +28,38 @@ export default function Header({ isNew, currentName, navigate, autoSaveStatus, s
{isNew ? '创建新智能体' : currentName || ''} {isNew ? '创建新智能体' : currentName || ''}
</span> </span>
</div> </div>
<div className="agent-editor-header-subtitle"> {!isMobile && (
AI <div className="agent-editor-header-subtitle">
</div> AI
</div>
)}
</div> </div>
</div> </div>
<div className="flex items-center gap-4"> {!isMobile && (
<span className="agent-editor-save-state text-xs text-gray-400"> <div className="flex items-center gap-4">
{autoSaveStatus === 'saving' <span className="agent-editor-save-state text-xs text-gray-400">
? '正在保存...' {autoSaveStatus === 'saving'
: autoSaveStatus === 'dirty' ? '正在保存...'
? '有未保存更改' : autoSaveStatus === 'dirty'
: autoSaveStatus === 'error' ? '有未保存更改'
? '保存失败' : autoSaveStatus === 'error'
: '已保存'} ? '保存失败'
</span> : '已保存'}
<Button icon={<FileTextOutlined />} className="agent-editor-header-action"> </span>
<Button icon={<FileTextOutlined />} className="agent-editor-header-action">
</Button>
<Button </Button>
type="primary" <Button
icon={<SaveOutlined />} type="primary"
loading={saving} icon={<SaveOutlined />}
onClick={onSave} loading={saving}
className="agent-editor-save-action" onClick={onSave}
> className="agent-editor-save-action"
>
</Button>
</div> </Button>
</div>
)}
</header> </header>
); );
} }

View File

@ -9,9 +9,9 @@ interface PreviewPaneProps {
export default function PreviewPane({ liveAgent, agentId }: PreviewPaneProps) { export default function PreviewPane({ liveAgent, agentId }: PreviewPaneProps) {
return ( return (
<div className="flex-1 h-full agent-editor-pane"> <div className="min-h-0 agent-editor-pane">
<div className="agent-editor-pane-body agent-editor-preview-shell"> <div className="agent-editor-pane-body agent-editor-preview-shell flex flex-col h-full">
<div className="agent-editor-pane-header"> <div className="agent-editor-pane-header shrink-0">
<div> <div>
<h3 className="agent-editor-pane-title"></h3> <h3 className="agent-editor-pane-title"></h3>
<p className="agent-editor-pane-subtitle"> <p className="agent-editor-pane-subtitle">
@ -23,13 +23,13 @@ export default function PreviewPane({ liveAgent, agentId }: PreviewPaneProps) {
Live Preview Live Preview
</span> </span>
</div> </div>
<div className="agent-editor-intro agent-editor-preview-intro"> <div className="agent-editor-intro agent-editor-preview-intro shrink-0">
<div className="agent-editor-intro-title"></div> <div className="agent-editor-intro-title"></div>
<div className="agent-editor-intro-text"> <div className="agent-editor-intro-text">
{liveAgent?.name || '未命名智能体'} Prompt {liveAgent?.name || '未命名智能体'} Prompt
</div> </div>
</div> </div>
<div className="agent-editor-surface agent-editor-preview-surface"> <div className="agent-editor-surface agent-editor-preview-surface min-h-0 overflow-auto">
<ChatPreview agent={liveAgent} agentId={agentId} /> <ChatPreview agent={liveAgent} agentId={agentId} />
</div> </div>
</div> </div>

View File

@ -1,15 +1,18 @@
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import { Form } from 'antd'; import { Form, Button } from 'antd';
import { useNavigate, useParams } from 'react-router-dom'; import { useNavigate, useParams } from 'react-router-dom';
import { App as AntApp } from 'antd'; import { App as AntApp } from 'antd';
import { FileTextOutlined, SaveOutlined } from '@ant-design/icons';
import SkillEditor from '../../components/SkillEditor'; import SkillEditor from '../../components/SkillEditor';
import { useAgentEditor } from './hooks/useAgentEditor'; import { useAgentEditor } from './hooks/useAgentEditor';
import { useIsMobile } from '../../hooks/useIsMobile';
import Header from './components/Header'; import Header from './components/Header';
import PromptEditor from './components/PromptEditor'; import PromptEditor from './components/PromptEditor';
import CapabilitySettings from './components/CapabilitySettings'; import CapabilitySettings from './components/CapabilitySettings';
import PreviewPane from './components/PreviewPane'; import PreviewPane from './components/PreviewPane';
import InitModal from './components/InitModal'; import InitModal from './components/InitModal';
import AvatarSelector from './components/AvatarSelector'; import AvatarSelector from './components/AvatarSelector';
import './AgentEditor.css';
import './styles/agent-editor-capability.css'; import './styles/agent-editor-capability.css';
import './styles/agent-editor-panels.css'; import './styles/agent-editor-panels.css';
import './styles/agent-editor-modal.css'; import './styles/agent-editor-modal.css';
@ -54,9 +57,11 @@ export default function AgentEditor() {
markDirty, markDirty,
} = useAgentEditor({ id, isNew, form, message, navigate }); } = useAgentEditor({ id, isNew, form, message, navigate });
const isMobile = useIsMobile();
return ( return (
<> <>
<div className="fixed inset-0 flex flex-col bg-white z-100 agent-editor-shell"> <div className="agent-editor-shell-container">
<Header <Header
isNew={isNew} isNew={isNew}
currentName={currentName} currentName={currentName}
@ -64,9 +69,10 @@ export default function AgentEditor() {
autoSaveStatus={autoSaveStatus} autoSaveStatus={autoSaveStatus}
saving={saving} saving={saving}
onSave={handleSave} onSave={handleSave}
isMobile={isMobile}
/> />
<div className="flex-1 overflow-hidden agent-editor-workbench"> <div className={`agent-editor-workbench-container ${isMobile ? 'is-mobile' : 'is-desktop'}`}>
<PromptEditor form={form} markDirty={markDirty} /> <PromptEditor form={form} markDirty={markDirty} />
<CapabilitySettings <CapabilitySettings
form={form} form={form}
@ -84,6 +90,34 @@ export default function AgentEditor() {
<PreviewPane liveAgent={liveAgent} agentId={id} /> <PreviewPane liveAgent={liveAgent} agentId={id} />
</div> </div>
{isMobile && (
<div className="agent-editor-mobile-footer-bar">
<span className="agent-editor-footer-status">
{autoSaveStatus === 'saving'
? '正在保存...'
: autoSaveStatus === 'dirty'
? '有未保存更改'
: autoSaveStatus === 'error'
? '保存失败'
: '已保存'}
</span>
<div className="agent-editor-footer-actions">
<Button icon={<FileTextOutlined />} size="middle">
</Button>
<Button
type="primary"
icon={<SaveOutlined />}
loading={saving}
onClick={() => handleSave()}
size="middle"
>
</Button>
</div>
</div>
)}
{!isNew && ( {!isNew && (
<SkillEditor <SkillEditor
open={skillEditorOpen} open={skillEditorOpen}

View File

@ -0,0 +1,312 @@
.h5-agent-list-container {
padding: 16px;
}
.h5-stats-banner {
border-radius: 16px;
padding: 20px 16px 18px;
background: linear-gradient(135deg, rgba(255,255,255,0.98) 0%, rgba(236,253,245,0.92) 48%, rgba(239,246,255,0.96) 100%);
border: 1px solid rgba(8, 145, 178, 0.12);
box-shadow: 0 10px 24px rgba(15, 23, 42, 0.06);
margin-bottom: 16px;
}
.h5-stats-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 12px;
flex-wrap: wrap;
margin-bottom: 16px;
}
.h5-stats-header-info {
width: 100%;
}
.h5-stats-badge {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
border-radius: 999px;
background: rgba(255,255,255,0.78);
border: 1px solid rgba(8, 145, 178, 0.10);
color: var(--color-text-secondary);
font-size: 11px;
font-weight: 600;
margin-bottom: 12px;
}
.h5-stats-title {
margin-bottom: 8px !important;
font-size: 22px !important;
}
.h5-stats-subtitle {
margin-top: 0 !important;
font-size: 13px !important;
line-height: 1.6 !important;
}
.h5-stats-marketplace-btn {
border-radius: 10px !important;
height: 40px !important;
padding: 0 16px !important;
font-weight: 600 !important;
width: 100% !important;
}
/* 统计卡片网格 - 横向排列 */
.h5-stats-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
}
.h5-stats-card {
border-radius: 12px;
padding: 12px 10px;
background: rgba(255,255,255,0.72);
border: 1px solid rgba(255,255,255,0.7);
display: flex;
flex-direction: column;
}
.h5-stats-card-label {
font-size: 11px;
color: var(--color-text-secondary);
margin-bottom: 6px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* 统计数值与标签容器 - 换行显示 */
.h5-stats-value-wrap {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 4px;
}
.h5-stats-value {
font-size: 22px;
font-weight: 700;
color: var(--color-text);
line-height: 1;
}
.h5-stats-tag {
border-radius: 999px;
padding: 2px 6px;
font-size: 10px;
font-weight: 600;
white-space: nowrap;
}
.h5-agent-card-item {
border-radius: 12px;
padding: 12px;
background: linear-gradient(180deg, rgba(255,255,255,0.98) 0%, rgba(252,252,253,1) 100%);
box-shadow: 0 4px 12px rgba(15, 23, 42, 0.04);
height: 100%;
display: flex;
flex-direction: column;
gap: 8px;
position: relative; /* 为右上角标签提供定位参考 */
overflow: hidden;
}
.h5-agent-card-badge {
position: absolute;
top: 0;
right: 0;
z-index: 1;
}
.h5-agent-card-badge .h5-agent-tag-item {
border-top-left-radius: 0 !important;
border-top-right-radius: 0 !important;
border-bottom-right-radius: 0 !important;
border-bottom-left-radius: 8px !important;
padding: 2px 8px !important;
height: auto !important;
font-size: 10px !important;
}
.h5-agent-card-header {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: 8px;
padding-top: 4px;
}
.h5-agent-avatar {
border-radius: 50%;
overflow: hidden;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-weight: bold;
font-size: 16px;
flex-shrink: 0;
}
.h5-agent-info {
flex: 1;
min-width: 0;
width: 100%;
}
.h5-agent-name {
font-weight: 700;
font-size: 13px;
color: var(--color-text);
margin-bottom: 0;
/* 支持最多展示两行 */
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
line-height: 1.4;
min-height: 1.4em; /* 调整为单行高度占位,因为下面加了描述 */
}
.h5-agent-desc {
font-size: 11px;
color: var(--color-text-tertiary);
margin-top: 4px;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
line-height: 1.4;
min-height: 2.8em;
text-align: center;
}
.h5-agent-tags {
display: flex;
flex-wrap: wrap;
gap: 4px;
justify-content: center;
min-height: 40px;
}
.h5-agent-tag-item {
border-radius: 999px !important;
margin: 0 !important;
font-size: 10px !important;
border: none !important;
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
padding: 0 6px !important;
height: 18px !important;
line-height: 1 !important;
}
.tag-public {
background: var(--color-success-soft) !important;
color: var(--color-success) !important;
}
.tag-team {
background: var(--color-info-soft) !important;
color: var(--color-info) !important;
}
.tag-private {
background: var(--color-surface-2) !important;
color: var(--color-text-secondary) !important;
}
.tag-model {
background: var(--color-brand-soft) !important;
color: var(--color-brand) !important;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.h5-agent-actions {
display: flex;
gap: 4px;
margin-top: auto;
padding-top: 8px;
border-top: 1px solid var(--color-border);
justify-content: space-around;
}
.h5-agent-action-link {
flex: 0 0 auto;
}
.h5-agent-action-btn {
border-radius: 6px !important;
height: 28px !important;
width: 28px !important;
padding: 0 !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
color: var(--color-text-secondary) !important;
background: transparent !important;
}
.h5-agent-action-btn:hover {
background: var(--color-surface-2) !important;
}
.h5-agent-action-btn .anticon {
font-size: 16px;
}
.h5-agent-delete-btn {
flex-shrink: 0;
}
.h5-footer-promo {
margin-top: 16px;
border-radius: 14px;
padding: 14px 16px;
background: var(--color-surface);
border: 1px solid var(--color-border);
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
flex-wrap: wrap;
}
.h5-footer-promo-info {
width: 100%;
}
.h5-footer-promo-title {
font-size: 14px;
font-weight: 600;
color: var(--color-text);
margin-bottom: 3px;
}
.h5-footer-promo-subtitle {
font-size: 12px;
color: var(--color-text-secondary);
}
.h5-footer-promo-btn {
color: var(--color-brand) !important;
font-weight: 600 !important;
width: 100% !important;
text-align: left !important;
}

View File

@ -11,6 +11,7 @@ import { Link, useNavigate } from 'react-router-dom';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import type { Agent } from '../../../api'; import type { Agent } from '../../../api';
import type { AgentListLogicOutput } from '../AgentListLogic'; import type { AgentListLogicOutput } from '../AgentListLogic';
import './AgentListH5.css';
interface Props { interface Props {
logic: AgentListLogicOutput; logic: AgentListLogicOutput;
@ -22,52 +23,19 @@ export default function AgentListH5({ logic }: Props) {
const { list, loading, stats, handleDelete, isImageUrl, getModelLabel } = logic; const { list, loading, stats, handleDelete, isImageUrl, getModelLabel } = logic;
return ( return (
<div className="page-container h5-page-container"> <div className="page-container h5-page-container h5-agent-list-container">
<div <div className="h5-stats-banner">
style={{ <div className="h5-stats-header">
borderRadius: 16, <div className="h5-stats-header-info">
padding: '20px 16px 18px', <div className="h5-stats-badge">
background:
'linear-gradient(135deg, rgba(255,255,255,0.98) 0%, rgba(236,253,245,0.92) 48%, rgba(239,246,255,0.96) 100%)',
border: '1px solid rgba(8, 145, 178, 0.12)',
boxShadow: '0 10px 24px rgba(15, 23, 42, 0.06)',
marginBottom: 16,
}}
>
<div
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'flex-start',
gap: 12,
flexWrap: 'wrap',
marginBottom: 16,
}}
>
<div style={{ width: '100%' }}>
<div
style={{
display: 'inline-flex',
alignItems: 'center',
gap: 6,
padding: '4px 10px',
borderRadius: 999,
background: 'rgba(255,255,255,0.78)',
border: '1px solid rgba(8, 145, 178, 0.10)',
color: 'var(--color-text-secondary)',
fontSize: 11,
fontWeight: 600,
marginBottom: 12,
}}
>
<RobotOutlined style={{ color: 'var(--color-brand)', fontSize: 12 }} /> <RobotOutlined style={{ color: 'var(--color-brand)', fontSize: 12 }} />
Agent Agent
</div> </div>
<h2 className="page-title h5-page-title" style={{ marginBottom: 8, fontSize: 22 }}> <h2 className="page-title h5-page-title h5-stats-title">
</h2> </h2>
<div className="page-subtitle h5-page-subtitle" style={{ marginTop: 0, fontSize: 13, lineHeight: 1.6 }}> <div className="page-subtitle h5-page-subtitle h5-stats-subtitle">
AI AI
</div> </div>
</div> </div>
@ -76,34 +44,23 @@ export default function AgentListH5({ logic }: Props) {
size="middle" size="middle"
icon={<CompassOutlined />} icon={<CompassOutlined />}
onClick={() => navigate('/marketplace')} onClick={() => navigate('/marketplace')}
style={{ borderRadius: 10, height: 40, padding: '0 16px', fontWeight: 600, width: '100%' }} className="h5-stats-marketplace-btn"
> >
广 广
</Button> </Button>
</div> </div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(1, minmax(0, 1fr))', gap: 10 }}> <div className="h5-stats-grid">
{stats.map((item) => ( {stats.map((item) => (
<div <div key={item.label} className="h5-stats-card">
key={item.label} <div className="h5-stats-card-label">{item.label}</div>
style={{ <div className="h5-stats-value-wrap">
borderRadius: 12, <span className="h5-stats-value">{item.value}</span>
padding: '12px 14px',
background: 'rgba(255,255,255,0.72)',
border: '1px solid rgba(255,255,255,0.7)',
}}
>
<div style={{ fontSize: 11, color: 'var(--color-text-secondary)', marginBottom: 6 }}>{item.label}</div>
<div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>
<span style={{ fontSize: 22, fontWeight: 700, color: 'var(--color-text)' }}>{item.value}</span>
<span <span
className="h5-stats-tag"
style={{ style={{
borderRadius: 999,
padding: '3px 6px',
background: item.tone, background: item.tone,
color: item.color, color: item.color,
fontSize: 10,
fontWeight: 600,
}} }}
> >
@ -123,22 +80,33 @@ export default function AgentListH5({ logic }: Props) {
</Empty> </Empty>
</div> </div>
) : ( ) : (
<Row gutter={[12, 12]}> <Row gutter={[8, 8]}>
{list.map((a) => ( {list.map((a) => (
<Col xs={24} sm={24} md={12} key={a.id}> <Col xs={12} sm={12} md={12} key={a.id}>
<div <div className="agent-card h5-agent-card h5-agent-card-item">
className="agent-card h5-agent-card" {/* 右上角可见性标签 */}
style={{ <div className="h5-agent-card-badge">
borderRadius: 14, {a.visibility === 'public' && (
padding: 16, <Tag bordered={false} className="h5-agent-tag-item tag-public">
background: 'linear-gradient(180deg, rgba(255,255,255,0.98) 0%, rgba(252,252,253,1) 100%)',
boxShadow: '0 6px 16px rgba(15, 23, 42, 0.045)', </Tag>
}} )}
> {a.visibility === 'team' && (
<div style={{ display: 'flex', alignItems: 'flex-start', gap: 10 }}> <Tag bordered={false} className="h5-agent-tag-item tag-team">
</Tag>
)}
{a.visibility === 'private' && (
<Tag bordered={false} className="h5-agent-tag-item tag-private">
</Tag>
)}
</div>
<div className="h5-agent-card-header">
<div <div
className="avatar" className="avatar h5-agent-avatar"
style={{ background: a.avatar || 'var(--gradient-brand)', borderRadius: '50%', overflow: 'hidden', width: 46, height: 46 }} style={{ background: a.avatar || 'var(--gradient-brand)' }}
> >
{isImageUrl(a.avatar) ? ( {isImageUrl(a.avatar) ? (
<img src={a.avatar} className="w-full h-full object-cover" alt="avatar" /> <img src={a.avatar} className="w-full h-full object-cover" alt="avatar" />
@ -146,72 +114,26 @@ export default function AgentListH5({ logic }: Props) {
(a.name?.charAt(0) || '?').toUpperCase() (a.name?.charAt(0) || '?').toUpperCase()
)} )}
</div> </div>
<div style={{ flex: 1, minWidth: 0 }}> <div className="h5-agent-info">
<div style={{ fontWeight: 700, fontSize: 15, color: 'var(--color-text)', marginBottom: 3 }}>{a.name}</div> <div className="h5-agent-name">{a.name}</div>
<div style={{ fontSize: 11, color: 'var(--color-text-tertiary)' }}>
{dayjs(a.updated_at).format('YYYY-MM-DD')}
</div>
</div> </div>
</div> </div>
<div {a.description && (
style={{ <div className="h5-agent-desc">
marginTop: 12, {a.description}
padding: '12px 12px 14px',
borderRadius: 12,
background: 'linear-gradient(180deg, rgba(248,250,252,0.9) 0%, rgba(255,255,255,0.95) 100%)',
border: '1px solid rgba(148, 163, 184, 0.14)',
}}
>
<div className="desc" style={{ minHeight: 50, fontSize: 12.5, lineHeight: 1.6 }}>
{a.description || '还没有填写描述,可以补充这个智能体适合解决什么问题。'}
</div> </div>
</div> )}
<Space size={4} wrap style={{ marginTop: 10 }}> <div className="h5-agent-actions">
{a.visibility === 'public' && ( <Link to={`/chat/${a.id}`} className="h5-agent-action-link">
<Tag bordered={false} style={{ background: 'var(--color-success-soft)', color: 'var(--color-success)', borderRadius: 999, margin: 0, fontSize: 11 }}> <Button type="text" size="small" block icon={<MessageOutlined />} className="h5-agent-action-btn" />
</Tag>
)}
{a.visibility === 'team' && (
<Tag bordered={false} style={{ background: 'var(--color-info-soft)', color: 'var(--color-info)', borderRadius: 999, margin: 0, fontSize: 11 }}>
</Tag>
)}
{a.visibility === 'private' && (
<Tag bordered={false} style={{ background: 'var(--color-surface-2)', color: 'var(--color-text-secondary)', borderRadius: 999, margin: 0, fontSize: 11 }}>
</Tag>
)}
{getModelLabel(a.model) && (
<Tag bordered={false} style={{ background: 'var(--color-brand-soft)', color: 'var(--color-brand)', borderRadius: 999, margin: 0, maxWidth: '100%', fontSize: 11 }}>
<span style={{ display: 'inline-block', maxWidth: 150, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
{getModelLabel(a.model)}
</span>
</Tag>
)}
{(a.fork_count ?? 0) > 0 && (
<Tag bordered={false} style={{ background: 'var(--color-surface-2)', color: 'var(--color-text-secondary)', borderRadius: 999, margin: 0, fontSize: 11 }}>
Fork {a.fork_count}
</Tag>
)}
</Space>
<div style={{ display: 'flex', gap: 6, marginTop: 'auto', paddingTop: 12, borderTop: '1px solid var(--color-border)' }}>
<Link to={`/chat/${a.id}`} style={{ flex: 1 }}>
<Button type="primary" block icon={<MessageOutlined />} style={{ borderRadius: 8, height: 36, fontWeight: 600, fontSize: 13 }}>
</Button>
</Link> </Link>
<Link to={`/agents/${a.id}`} style={{ flex: 1 }}> <Link to={`/agents/${a.id}`} className="h5-agent-action-link">
<Button block icon={<EditOutlined />} style={{ borderRadius: 8, height: 36, fontSize: 13 }}> <Button type="text" size="small" block icon={<EditOutlined />} className="h5-agent-action-btn" />
</Button>
</Link> </Link>
<Popconfirm <Popconfirm
title="确定删除该智能体?" title="确定删除?"
description="将删除其知识库与对话记录"
onConfirm={() => { onConfirm={() => {
handleDelete(a.id); handleDelete(a.id);
message.success('已删除'); message.success('已删除');
@ -219,7 +141,7 @@ export default function AgentListH5({ logic }: Props) {
okText="删除" okText="删除"
cancelText="取消" cancelText="取消"
> >
<Button danger icon={<DeleteOutlined />} style={{ borderRadius: 8, width: 36, height: 36, padding: 0 }} /> <Button type="text" size="small" icon={<DeleteOutlined />} className="h5-agent-action-btn h5-agent-delete-btn" />
</Popconfirm> </Popconfirm>
</div> </div>
</div> </div>
@ -229,29 +151,16 @@ export default function AgentListH5({ logic }: Props) {
)} )}
{list.length > 0 && ( {list.length > 0 && (
<div <div className="h5-footer-promo">
style={{ <div className="h5-footer-promo-info">
marginTop: 16, <div className="h5-footer-promo-title">
borderRadius: 14,
padding: '14px 16px',
background: 'var(--color-surface)',
border: '1px solid var(--color-border)',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
gap: 12,
flexWrap: 'wrap',
}}
>
<div style={{ width: '100%' }}>
<div style={{ fontSize: 14, fontWeight: 600, color: 'var(--color-text)', marginBottom: 3 }}>
</div> </div>
<div style={{ fontSize: 12, color: 'var(--color-text-secondary)' }}> <div className="h5-footer-promo-subtitle">
广 广
</div> </div>
</div> </div>
<Button type="text" icon={<ArrowRightOutlined />} onClick={() => navigate('/marketplace')} style={{ color: 'var(--color-brand)', fontWeight: 600, width: '100%', textAlign: 'left' }}> <Button type="text" icon={<ArrowRightOutlined />} onClick={() => navigate('/marketplace')} className="h5-footer-promo-btn">
广 广
</Button> </Button>
</div> </div>

View File

@ -42,7 +42,35 @@
font-size: 1.75rem; font-size: 1.75rem;
} }
.stats-page-h5 .stats-page-cards-grid, .stats-page-h5 .stats-page-cards-grid {
grid-template-columns: repeat(3, 1fr);
gap: 8px;
}
.stats-page-h5 .stats-page-card {
padding: 10px 8px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.stats-page-h5 .stats-page-card-label {
flex-direction: column;
gap: 4px;
font-size: 11px;
margin-bottom: 6px;
}
.stats-page-h5 .stats-page-card-icon {
width: 24px;
height: 24px;
}
.stats-page-h5 .stats-page-card-value {
font-size: 18px;
}
.stats-page-h5 .points-integration-row, .stats-page-h5 .points-integration-row,
.stats-page-h5 .stats-page-token-cards-grid, .stats-page-h5 .stats-page-token-cards-grid,
.stats-page-h5 .stats-page-token-charts-grid { .stats-page-h5 .stats-page-token-charts-grid {

View File

@ -1493,6 +1493,10 @@ body {
padding: 40px 32px 60px; padding: 40px 32px 60px;
} }
.page-container.h5-page-container {
padding: 12px;
}
.feature-cover-container { .feature-cover-container {
position: relative; position: relative;
} }