feat: custom prompt UI + AI-style tab in ChannelEdit

ChannelEdit:
- Вкладка «AI-стиль»: textarea для ai_style_prompt, выбор image_quality (standard/hd)
- Описание моделей: gpt-5-image-mini vs gpt-5.4-image-2 с ценами в кредитах

ChannelView:
- Коллапсируемое поле «Доп. инструкции для AI» под темой поста
- Индикатор (синяя точка) если промт заполнен
- customPrompt передаётся в /api/generate
This commit is contained in:
Ник (Claude)
2026-06-11 15:15:22 +03:00
parent f4860f0e70
commit 8d015add30
2 changed files with 119 additions and 1 deletions
+34 -1
View File
@@ -38,6 +38,8 @@ function stripCaption(text) {
export default function ChannelView({ channel }) {
const [topic, setTopic] = useState('');
const [customPrompt, setCustomPrompt] = useState('');
const [showCustomPrompt, setShowCustomPrompt] = useState(false);
const [generating, setGenerating] = useState(false);
const [post, setPost] = useState(null);
const [error, setError] = useState('');
@@ -225,6 +227,7 @@ export default function ChannelView({ channel }) {
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
type: 'post', channelId: channel.id, topic: useTopic, useCritique: true,
customPrompt: customPrompt.trim() || undefined,
}),
});
const job = await createRes.json();
@@ -407,12 +410,42 @@ export default function ChannelView({ channel }) {
)}
<textarea
className="input min-h-[80px] mb-3"
className="input min-h-[80px] mb-2"
value={topic}
onChange={e => setTopic(e.target.value)}
placeholder="Тема поста — конкретный заход, не общая категория. Например: «OpenAI выпустил Memory — что это даёт маркетологу»"
disabled={generating}
/>
{/* Дополнительные инструкции */}
<div className="mb-3">
<button
type="button"
onClick={() => setShowCustomPrompt(v => !v)}
className="text-xs text-gray-500 hover:text-accent flex items-center gap-1 transition-colors"
>
<span>{showCustomPrompt ? '▾' : '▸'}</span>
Дополнительные инструкции для AI
{customPrompt.trim() && <span className="ml-1 w-1.5 h-1.5 rounded-full bg-accent inline-block" />}
</button>
{showCustomPrompt && (
<div className="mt-2 space-y-1">
<textarea
rows={3}
className="input w-full text-sm resize-none"
placeholder={`Например: «Сделай акцент на кейсах из сельского хозяйства» или «Добавь призыв подписаться в конце»`}
value={customPrompt}
onChange={e => setCustomPrompt(e.target.value)}
disabled={generating}
/>
<p className="text-xs text-gray-500">
Перебивает стиль канала для этой генерации.
{channel.ai_style_prompt && ' Канальный промт также будет применён.'}
</p>
</div>
)}
</div>
<div className="flex items-center justify-between gap-3">
<div className="text-xs text-gray-500">
ИИ напишет пост в стиле твоего канала с учётом примеров