style: refine detail generation panel ui and scrolling
This commit is contained in:
parent
25f962415a
commit
4533547d68
@ -3274,13 +3274,13 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
data-canvas-chat-input-anchor="true"
|
||||
>
|
||||
{isDetailGenerationMode && (
|
||||
<div className="mx-3 mt-3 rounded-2xl border border-violet-200/80 bg-violet-50/70 p-3 dark:border-violet-500/35 dark:bg-violet-500/10">
|
||||
<div className="mx-3 mt-3 max-h-[54vh] overflow-y-auto rounded-2xl border border-black/10 bg-white/95 p-3 pr-2">
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div>
|
||||
<p className="text-sm font-semibold text-violet-950 dark:text-violet-100">
|
||||
<p className="text-sm font-semibold text-black">
|
||||
AI详情生成工作台(PC)
|
||||
</p>
|
||||
<p className="mt-0.5 text-[11px] text-violet-700/80 dark:text-violet-200/70">
|
||||
<p className="mt-0.5 text-[11px] text-black/55">
|
||||
固定规格 {DETAIL_TARGET_WIDTH} x {DETAIL_TARGET_HEIGHT},先分析后生成,保持整套详情图风格统一。
|
||||
</p>
|
||||
</div>
|
||||
@ -3288,12 +3288,12 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
className={cn(
|
||||
"rounded-full px-2 py-0.5 text-[10px] font-medium",
|
||||
detailProgress.status === "running"
|
||||
? "bg-violet-100 text-violet-700 dark:bg-violet-500/20 dark:text-violet-100"
|
||||
? "bg-blue-50 text-blue-700"
|
||||
: detailProgress.status === "done"
|
||||
? "bg-emerald-100 text-emerald-700 dark:bg-emerald-500/20 dark:text-emerald-100"
|
||||
? "bg-emerald-100 text-emerald-700"
|
||||
: detailProgress.status === "error"
|
||||
? "bg-red-100 text-red-700 dark:bg-red-500/20 dark:text-red-100"
|
||||
: "bg-white/80 text-violet-700 dark:bg-zinc-900/60 dark:text-violet-200"
|
||||
? "bg-red-100 text-red-700"
|
||||
: "bg-black/5 text-black/65"
|
||||
)}
|
||||
>
|
||||
{detailProgress.status === "running"
|
||||
@ -3306,22 +3306,22 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="mt-3 rounded-xl border border-violet-200/70 bg-white/80 p-2 dark:border-violet-500/30 dark:bg-zinc-900/60">
|
||||
<div className="mb-1 flex items-center justify-between text-[11px] text-violet-700/80 dark:text-violet-200/70">
|
||||
<div className="mt-3 rounded-xl border border-black/10 bg-black/[0.02] p-2">
|
||||
<div className="mb-1 flex items-center justify-between text-[11px] text-black/55">
|
||||
<span>{detailProgress.stage || "待开始:请先补齐输入信息与素材。"}</span>
|
||||
<span>
|
||||
{detailProgress.current}/{detailProgress.total || 0}
|
||||
</span>
|
||||
</div>
|
||||
<div className="h-1.5 overflow-hidden rounded-full bg-violet-100 dark:bg-violet-500/20">
|
||||
<div className="h-1.5 overflow-hidden rounded-full bg-black/10">
|
||||
<div
|
||||
className={cn(
|
||||
"h-full rounded-full transition-all duration-300",
|
||||
detailProgress.status === "error"
|
||||
? "bg-red-500"
|
||||
: detailProgress.status === "done"
|
||||
: detailProgress.status === "done"
|
||||
? "bg-emerald-500"
|
||||
: "bg-violet-500"
|
||||
: "bg-blue-500"
|
||||
)}
|
||||
style={{ width: `${detailProgressPercent}%` }}
|
||||
/>
|
||||
@ -3329,162 +3329,162 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
</div>
|
||||
|
||||
<div className="mt-3 space-y-2">
|
||||
<div className="rounded-xl border border-violet-200/70 bg-white/85 dark:border-violet-500/30 dark:bg-zinc-900/50">
|
||||
<div className="rounded-xl border border-black/10 bg-white">
|
||||
<button
|
||||
type="button"
|
||||
className="flex w-full items-center justify-between px-3 py-2 text-left"
|
||||
onClick={() => toggleDetailSection("required")}
|
||||
>
|
||||
<div>
|
||||
<p className="text-xs font-semibold text-violet-900 dark:text-violet-100">必填信息</p>
|
||||
<p className="text-[11px] text-violet-700/75 dark:text-violet-200/70">人群 / 场景 / 核心需求为必填</p>
|
||||
<p className="text-xs font-semibold text-black">必填信息</p>
|
||||
<p className="text-[11px] text-black/55">人群 / 场景 / 核心需求为必填</p>
|
||||
</div>
|
||||
<ChevronDown
|
||||
className={cn(
|
||||
"h-4 w-4 text-violet-600 transition-transform dark:text-violet-200",
|
||||
"h-4 w-4 text-black/55 transition-transform",
|
||||
detailSections.required && "rotate-180"
|
||||
)}
|
||||
/>
|
||||
</button>
|
||||
{detailSections.required ? (
|
||||
<div className="grid grid-cols-2 gap-2 border-t border-violet-200/70 p-3 xl:grid-cols-4 dark:border-violet-500/25">
|
||||
<div className="grid grid-cols-2 gap-2 border-t border-black/10 p-3 xl:grid-cols-4">
|
||||
<input
|
||||
value={detailBrief.targetAudience}
|
||||
onChange={(event) => updateDetailBriefField("targetAudience", event.target.value)}
|
||||
className="h-8 rounded-lg border border-violet-200/80 bg-white/90 px-2 text-xs outline-none focus:border-violet-400 dark:border-violet-500/30 dark:bg-zinc-900/60"
|
||||
className="h-8 rounded-lg border border-black/15 bg-white px-2 text-xs outline-none focus:border-blue-400"
|
||||
placeholder="主购买人群 *"
|
||||
/>
|
||||
<input
|
||||
value={detailBrief.usageScenario}
|
||||
onChange={(event) => updateDetailBriefField("usageScenario", event.target.value)}
|
||||
className="h-8 rounded-lg border border-violet-200/80 bg-white/90 px-2 text-xs outline-none focus:border-violet-400 dark:border-violet-500/30 dark:bg-zinc-900/60"
|
||||
className="h-8 rounded-lg border border-black/15 bg-white px-2 text-xs outline-none focus:border-blue-400"
|
||||
placeholder="需求场景 *"
|
||||
/>
|
||||
<input
|
||||
value={detailBrief.coreNeed}
|
||||
onChange={(event) => updateDetailBriefField("coreNeed", event.target.value)}
|
||||
className="h-8 rounded-lg border border-violet-200/80 bg-white/90 px-2 text-xs outline-none focus:border-violet-400 dark:border-violet-500/30 dark:bg-zinc-900/60"
|
||||
className="h-8 rounded-lg border border-black/15 bg-white px-2 text-xs outline-none focus:border-blue-400"
|
||||
placeholder="核心需求 *"
|
||||
/>
|
||||
<input
|
||||
value={detailBrief.productName}
|
||||
onChange={(event) => updateDetailBriefField("productName", event.target.value)}
|
||||
className="h-8 rounded-lg border border-violet-200/80 bg-white/90 px-2 text-xs outline-none focus:border-violet-400 dark:border-violet-500/30 dark:bg-zinc-900/60"
|
||||
className="h-8 rounded-lg border border-black/15 bg-white px-2 text-xs outline-none focus:border-blue-400"
|
||||
placeholder="产品名称(选填)"
|
||||
/>
|
||||
<input
|
||||
value={detailBrief.mainUser}
|
||||
onChange={(event) => updateDetailBriefField("mainUser", event.target.value)}
|
||||
className="h-8 rounded-lg border border-violet-200/80 bg-white/90 px-2 text-xs outline-none focus:border-violet-400 dark:border-violet-500/30 dark:bg-zinc-900/60"
|
||||
className="h-8 rounded-lg border border-black/15 bg-white px-2 text-xs outline-none focus:border-blue-400"
|
||||
placeholder="主使用者(选填)"
|
||||
/>
|
||||
<input
|
||||
value={detailBrief.triggerMoment}
|
||||
onChange={(event) => updateDetailBriefField("triggerMoment", event.target.value)}
|
||||
className="h-8 rounded-lg border border-violet-200/80 bg-white/90 px-2 text-xs outline-none focus:border-violet-400 dark:border-violet-500/30 dark:bg-zinc-900/60"
|
||||
className="h-8 rounded-lg border border-black/15 bg-white px-2 text-xs outline-none focus:border-blue-400"
|
||||
placeholder="触发时刻(选填)"
|
||||
/>
|
||||
<input
|
||||
value={detailBrief.riskConcern}
|
||||
onChange={(event) => updateDetailBriefField("riskConcern", event.target.value)}
|
||||
className="h-8 rounded-lg border border-violet-200/80 bg-white/90 px-2 text-xs outline-none focus:border-violet-400 dark:border-violet-500/30 dark:bg-zinc-900/60"
|
||||
className="h-8 rounded-lg border border-black/15 bg-white px-2 text-xs outline-none focus:border-blue-400"
|
||||
placeholder="用户顾虑(选填)"
|
||||
/>
|
||||
<input
|
||||
value={detailBrief.expectedResult}
|
||||
onChange={(event) => updateDetailBriefField("expectedResult", event.target.value)}
|
||||
className="h-8 rounded-lg border border-violet-200/80 bg-white/90 px-2 text-xs outline-none focus:border-violet-400 dark:border-violet-500/30 dark:bg-zinc-900/60"
|
||||
className="h-8 rounded-lg border border-black/15 bg-white px-2 text-xs outline-none focus:border-blue-400"
|
||||
placeholder="期望结果(选填)"
|
||||
/>
|
||||
<input
|
||||
value={detailBrief.coreSellingPoint}
|
||||
onChange={(event) => updateDetailBriefField("coreSellingPoint", event.target.value)}
|
||||
className="h-8 rounded-lg border border-violet-200/80 bg-white/90 px-2 text-xs outline-none focus:border-violet-400 xl:col-span-2 dark:border-violet-500/30 dark:bg-zinc-900/60"
|
||||
className="h-8 rounded-lg border border-black/15 bg-white px-2 text-xs outline-none focus:border-blue-400 xl:col-span-2"
|
||||
placeholder="核心卖点关键词(选填)"
|
||||
/>
|
||||
<input
|
||||
value={detailBrief.positioningStatement}
|
||||
onChange={(event) => updateDetailBriefField("positioningStatement", event.target.value)}
|
||||
className="h-8 rounded-lg border border-violet-200/80 bg-white/90 px-2 text-xs outline-none focus:border-violet-400 xl:col-span-2 dark:border-violet-500/30 dark:bg-zinc-900/60"
|
||||
className="h-8 rounded-lg border border-black/15 bg-white px-2 text-xs outline-none focus:border-blue-400 xl:col-span-2"
|
||||
placeholder="一句话定位(选填)"
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-violet-200/70 bg-white/85 dark:border-violet-500/30 dark:bg-zinc-900/50">
|
||||
<div className="rounded-xl border border-black/10 bg-white">
|
||||
<button
|
||||
type="button"
|
||||
className="flex w-full items-center justify-between px-3 py-2 text-left"
|
||||
onClick={() => toggleDetailSection("strategy")}
|
||||
>
|
||||
<div>
|
||||
<p className="text-xs font-semibold text-violet-900 dark:text-violet-100">策略信息</p>
|
||||
<p className="text-[11px] text-violet-700/75 dark:text-violet-200/70">品牌语气、竞品参考、禁用词</p>
|
||||
<p className="text-xs font-semibold text-black">策略信息</p>
|
||||
<p className="text-[11px] text-black/55">品牌语气、竞品参考、禁用词</p>
|
||||
</div>
|
||||
<ChevronDown
|
||||
className={cn(
|
||||
"h-4 w-4 text-violet-600 transition-transform dark:text-violet-200",
|
||||
"h-4 w-4 text-black/55 transition-transform",
|
||||
detailSections.strategy && "rotate-180"
|
||||
)}
|
||||
/>
|
||||
</button>
|
||||
{detailSections.strategy ? (
|
||||
<div className="grid grid-cols-2 gap-2 border-t border-violet-200/70 p-3 xl:grid-cols-4 dark:border-violet-500/25">
|
||||
<div className="grid grid-cols-2 gap-2 border-t border-black/10 p-3 xl:grid-cols-4">
|
||||
<input
|
||||
value={detailBrief.priceBand}
|
||||
onChange={(event) => updateDetailBriefField("priceBand", event.target.value)}
|
||||
className="h-8 rounded-lg border border-violet-200/80 bg-white/90 px-2 text-xs outline-none focus:border-violet-400 dark:border-violet-500/30 dark:bg-zinc-900/60"
|
||||
className="h-8 rounded-lg border border-black/15 bg-white px-2 text-xs outline-none focus:border-blue-400"
|
||||
placeholder="价格带(选填)"
|
||||
/>
|
||||
<input
|
||||
value={detailBrief.brandTone}
|
||||
onChange={(event) => updateDetailBriefField("brandTone", event.target.value)}
|
||||
className="h-8 rounded-lg border border-violet-200/80 bg-white/90 px-2 text-xs outline-none focus:border-violet-400 dark:border-violet-500/30 dark:bg-zinc-900/60"
|
||||
className="h-8 rounded-lg border border-black/15 bg-white px-2 text-xs outline-none focus:border-blue-400"
|
||||
placeholder="品牌语气(选填)"
|
||||
/>
|
||||
<input
|
||||
value={detailBrief.competitorReference}
|
||||
onChange={(event) => updateDetailBriefField("competitorReference", event.target.value)}
|
||||
className="h-8 rounded-lg border border-violet-200/80 bg-white/90 px-2 text-xs outline-none focus:border-violet-400 xl:col-span-2 dark:border-violet-500/30 dark:bg-zinc-900/60"
|
||||
className="h-8 rounded-lg border border-black/15 bg-white px-2 text-xs outline-none focus:border-blue-400 xl:col-span-2"
|
||||
placeholder="竞品对标(选填)"
|
||||
/>
|
||||
<input
|
||||
value={detailBrief.bannedWords}
|
||||
onChange={(event) => updateDetailBriefField("bannedWords", event.target.value)}
|
||||
className="h-8 rounded-lg border border-violet-200/80 bg-white/90 px-2 text-xs outline-none focus:border-violet-400 xl:col-span-2 dark:border-violet-500/30 dark:bg-zinc-900/60"
|
||||
className="h-8 rounded-lg border border-black/15 bg-white px-2 text-xs outline-none focus:border-blue-400 xl:col-span-2"
|
||||
placeholder="禁用表达(选填,逗号分隔)"
|
||||
/>
|
||||
<textarea
|
||||
value={detailBrief.userVoice}
|
||||
onChange={(event) => updateDetailBriefField("userVoice", event.target.value)}
|
||||
className="min-h-[64px] resize-y rounded-lg border border-violet-200/80 bg-white/90 px-2 py-1.5 text-xs outline-none focus:border-violet-400 xl:col-span-4 dark:border-violet-500/30 dark:bg-zinc-900/60"
|
||||
className="min-h-[64px] resize-y rounded-lg border border-black/15 bg-white px-2 py-1.5 text-xs outline-none focus:border-blue-400 xl:col-span-4"
|
||||
placeholder="用户原话样本(选填,建议3-5条)"
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-violet-200/70 bg-white/85 dark:border-violet-500/30 dark:bg-zinc-900/50">
|
||||
<div className="rounded-xl border border-black/10 bg-white">
|
||||
<button
|
||||
type="button"
|
||||
className="flex w-full items-center justify-between px-3 py-2 text-left"
|
||||
onClick={() => toggleDetailSection("assets")}
|
||||
>
|
||||
<div>
|
||||
<p className="text-xs font-semibold text-violet-900 dark:text-violet-100">素材上传</p>
|
||||
<p className="text-[11px] text-violet-700/75 dark:text-violet-200/70">固定 5 张产品图 + 1 张模特图</p>
|
||||
<p className="text-xs font-semibold text-black">素材上传</p>
|
||||
<p className="text-[11px] text-black/55">固定 5 张产品图 + 1 张模特图</p>
|
||||
</div>
|
||||
<ChevronDown
|
||||
className={cn(
|
||||
"h-4 w-4 text-violet-600 transition-transform dark:text-violet-200",
|
||||
"h-4 w-4 text-black/55 transition-transform",
|
||||
detailSections.assets && "rotate-180"
|
||||
)}
|
||||
/>
|
||||
</button>
|
||||
{detailSections.assets ? (
|
||||
<div className="border-t border-violet-200/70 p-3 dark:border-violet-500/25">
|
||||
<div className="mb-2 text-[11px] text-violet-700/80 dark:text-violet-200/70">
|
||||
<div className="border-t border-black/10 p-3">
|
||||
<div className="mb-2 text-[11px] text-black/55">
|
||||
Agent 会自动判断是否使用模特图,人物相关分镜将固定使用同一模特。
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-2 xl:grid-cols-6">
|
||||
@ -3494,7 +3494,7 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
return (
|
||||
<div
|
||||
key={config.key}
|
||||
className="group relative h-28 overflow-hidden rounded-xl border border-violet-200/80 bg-white/90 dark:border-violet-500/30 dark:bg-zinc-900/60"
|
||||
className="group relative h-28 overflow-hidden rounded-xl border border-black/15 bg-white"
|
||||
>
|
||||
<input
|
||||
type="file"
|
||||
@ -3541,7 +3541,7 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="flex h-full w-full cursor-pointer flex-col items-center justify-center gap-1 text-[11px] text-violet-700 dark:text-violet-200"
|
||||
className="flex h-full w-full cursor-pointer flex-col items-center justify-center gap-1 text-[11px] text-black/65"
|
||||
onClick={() => detailSlotInputRefs.current[index]?.click()}
|
||||
disabled={isSubmitting || isUploading}
|
||||
>
|
||||
@ -3557,7 +3557,7 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="mt-2 text-[11px] text-violet-700/80 dark:text-violet-200/80">
|
||||
<div className="mt-2 text-[11px] text-black/55">
|
||||
当前素材:产品图 {detailProductCount}/5,模特图 {detailModelReady ? "1/1" : "0/1"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user