feat: 拆解单文件 Demo 为 Vite + React 前端工程
- 保留根目录 index.html 作为 v1 单文件原型(不参与构建) - app/ 下新建 Vite + React 工程(vite.config root 指向 app/,两版互不干扰) - 状态收敛到 useAppStore(表单/消息/串行确认/一键发品 + 4 条异步编排流) - 生成卡片重构为结构化数据驱动渲染,按钮为真实 React 事件 - 6 大表单模块卡片化;Agent 意图解析与偏好学习抽为独立 lib - 功能与视觉与 v1 完全一致,浏览器端全流程回归通过
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import { useStore } from '../store/context'
|
||||
|
||||
/** 生成卡片:head / lines / foot / tips,foot 按钮为真实 React 事件 */
|
||||
export default function GenCardView({ gen, confirm }) {
|
||||
const { applyGen, regen, showToast, serialConfirm, serialRegen, countdown } = useStore()
|
||||
const { card } = gen
|
||||
const serial = !!confirm
|
||||
|
||||
const body = (
|
||||
<div className="gen-card">
|
||||
<div className="gc-head">{card.head}</div>
|
||||
<div className="gc-body">
|
||||
{card.lines.map((l, i) => <span key={i} className="line" dangerouslySetInnerHTML={{ __html: l }} />)}
|
||||
</div>
|
||||
{card.foot && (
|
||||
<div className="gc-foot">
|
||||
<button
|
||||
className="gc-btn"
|
||||
onClick={() => card.foot.apply ? applyGen(card.foot.apply) : showToast('SEO 词已复制(演示)')}
|
||||
>{card.foot.label}</button>
|
||||
{card.foot.regen && <button className="gc-btn ghost" onClick={() => regen(gen.type)}>🔄 换一版</button>}
|
||||
</div>
|
||||
)}
|
||||
{card.tips.length > 0 && (
|
||||
<div className="tips-row">
|
||||
{card.tips.map((t, i) => <span key={i} className={'tip-pill ' + t.cls}>{t.text}</span>)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
/* 串行流程:外层包 serial-card,底部附确认栏 */
|
||||
if (serial) {
|
||||
return (
|
||||
<div className="serial-card">
|
||||
<div dangerouslySetInnerHTML={{ __html: gen.pre }} />
|
||||
{body}
|
||||
{confirm.status === 'confirmed' ? (
|
||||
<div className="ag-confirm-bar" style={{ opacity: 0.55 }}>
|
||||
<span style={{ color: '#22c55e', fontSize: 12, fontWeight: 600 }}>✓ 已确认,填入表单中…</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className="ag-confirm-bar">
|
||||
<button className="ag-cf-btn" onClick={serialConfirm}>
|
||||
{card.foot?.apply ? '✅ 确认填入' : '✅ 确认'}
|
||||
</button>
|
||||
<button className="ag-regen-btn" onClick={serialRegen}>🔄 换一版</button>
|
||||
{confirm.mode
|
||||
? <span className="ag-cd">{countdown}s 后自动确认</span>
|
||||
: <span className="ag-cd manual">⏸ 等待您确认…</span>}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div dangerouslySetInnerHTML={{ __html: gen.pre }} />
|
||||
{body}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user