Autosave: 20260517-161152
This commit is contained in:
parent
de3ba95d58
commit
3782363b24
@ -426,6 +426,29 @@ const LEAD_REPLY_TEMPLATE_PRESETS: AgentTemplatePreset[] = [
|
|||||||
|
|
||||||
const ALL_AGENT_TEMPLATE_PRESETS = [...AGENT_TEMPLATE_PRESETS, ...LEAD_REPLY_TEMPLATE_PRESETS];
|
const ALL_AGENT_TEMPLATE_PRESETS = [...AGENT_TEMPLATE_PRESETS, ...LEAD_REPLY_TEMPLATE_PRESETS];
|
||||||
|
|
||||||
|
const TEMPLATE_SECTION_OPTIONS: Array<{
|
||||||
|
value: AgentTemplateFocus;
|
||||||
|
label: string;
|
||||||
|
description: string;
|
||||||
|
icon: string;
|
||||||
|
countLabel: string;
|
||||||
|
}> = [
|
||||||
|
{
|
||||||
|
value: 'content',
|
||||||
|
label: 'Контент-шаблоны',
|
||||||
|
description: 'Посты, Reels, Stories, кейсы и FAQ для публикаций.',
|
||||||
|
icon: mdiBullhornOutline,
|
||||||
|
countLabel: `${AGENT_TEMPLATE_PRESETS.length} сценариев`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'lead_reply',
|
||||||
|
label: 'Lead-шаблоны',
|
||||||
|
description: 'Ответы в директ, вопрос о цене, follow-up и запись на замер.',
|
||||||
|
icon: mdiAccountArrowRight,
|
||||||
|
countLabel: `${LEAD_REPLY_TEMPLATE_PRESETS.length} сценариев`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const GOAL_OPTIONS: Array<{ value: GoalValue; label: string }> = [
|
const GOAL_OPTIONS: Array<{ value: GoalValue; label: string }> = [
|
||||||
{ value: 'lead_generation', label: 'Лиды и заявки' },
|
{ value: 'lead_generation', label: 'Лиды и заявки' },
|
||||||
{ value: 'brand_awareness', label: 'Узнаваемость бренда' },
|
{ value: 'brand_awareness', label: 'Узнаваемость бренда' },
|
||||||
@ -976,6 +999,7 @@ const AgentStudio = () => {
|
|||||||
const [saveResult, setSaveResult] = useState<SaveResult | null>(null);
|
const [saveResult, setSaveResult] = useState<SaveResult | null>(null);
|
||||||
const [copyMessage, setCopyMessage] = useState('');
|
const [copyMessage, setCopyMessage] = useState('');
|
||||||
const [activeTemplateId, setActiveTemplateId] = useState('');
|
const [activeTemplateId, setActiveTemplateId] = useState('');
|
||||||
|
const [activeTemplateSection, setActiveTemplateSection] = useState<AgentTemplateFocus>('lead_reply');
|
||||||
|
|
||||||
const canReadBriefs = hasPermission(currentUser, 'READ_CONTENT_BRIEFS');
|
const canReadBriefs = hasPermission(currentUser, 'READ_CONTENT_BRIEFS');
|
||||||
const canReadChannels = hasPermission(currentUser, 'READ_SOCIAL_CHANNELS');
|
const canReadChannels = hasPermission(currentUser, 'READ_SOCIAL_CHANNELS');
|
||||||
@ -1132,6 +1156,7 @@ const AgentStudio = () => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
setActiveTemplateId(template.id);
|
setActiveTemplateId(template.id);
|
||||||
|
setActiveTemplateSection(template.focus || 'content');
|
||||||
setGeneratedDraft(null);
|
setGeneratedDraft(null);
|
||||||
setValidationErrors([]);
|
setValidationErrors([]);
|
||||||
setGenerationError('');
|
setGenerationError('');
|
||||||
@ -1473,11 +1498,71 @@ const AgentStudio = () => {
|
|||||||
<BaseIcon path={mdiStarFourPointsOutline} size={18} className="mr-2 text-blue-600" />
|
<BaseIcon path={mdiStarFourPointsOutline} size={18} className="mr-2 text-blue-600" />
|
||||||
Бриф → AI → сохранение в CRM
|
Бриф → AI → сохранение в CRM
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<BaseDivider />
|
<BaseDivider />
|
||||||
|
|
||||||
<div className="rounded-[28px] border border-blue-100 bg-gradient-to-br from-slate-50 to-blue-50/70 p-5">
|
<div className="rounded-[28px] border border-slate-200 bg-slate-50/90 p-3 shadow-sm">
|
||||||
|
<div className="px-1 pb-1">
|
||||||
|
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-slate-500">Быстрый выбор шаблонов</p>
|
||||||
|
<p className="mt-2 text-sm leading-6 text-slate-500">Не нужно искать нужный блок ниже — выберите тип сценария одной кнопкой.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-3 grid gap-3 lg:grid-cols-2">
|
||||||
|
{TEMPLATE_SECTION_OPTIONS.map((section) => {
|
||||||
|
const isActive = activeTemplateSection === section.value;
|
||||||
|
const isLeadSection = section.value === 'lead_reply';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={section.value}
|
||||||
|
type="button"
|
||||||
|
onClick={() => setActiveTemplateSection(section.value)}
|
||||||
|
aria-pressed={isActive}
|
||||||
|
className={`rounded-[24px] border p-4 text-left transition-all ${
|
||||||
|
isActive
|
||||||
|
? isLeadSection
|
||||||
|
? 'border-emerald-300 bg-emerald-50 shadow-sm ring-2 ring-emerald-100'
|
||||||
|
: 'border-blue-300 bg-blue-50 shadow-sm ring-2 ring-blue-100'
|
||||||
|
: 'border-white bg-white hover:border-slate-200 hover:shadow-sm'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="flex items-start justify-between gap-3">
|
||||||
|
<div
|
||||||
|
className={`flex h-12 w-12 items-center justify-center rounded-2xl ${
|
||||||
|
isLeadSection ? 'bg-emerald-100 text-emerald-700' : 'bg-blue-100 text-blue-700'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<BaseIcon path={section.icon} size={22} />
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
className={`inline-flex rounded-full px-3 py-1 text-xs font-semibold ${
|
||||||
|
isLeadSection ? 'bg-emerald-100 text-emerald-700' : 'bg-blue-100 text-blue-700'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{section.countLabel}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p className="mt-4 text-lg font-semibold text-slate-900">{section.label}</p>
|
||||||
|
<p className="mt-2 text-sm leading-6 text-slate-500">{section.description}</p>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={`mt-4 inline-flex items-center text-sm font-semibold ${
|
||||||
|
isLeadSection ? 'text-emerald-700' : 'text-blue-700'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{isActive ? 'Раздел открыт' : 'Открыть раздел'}
|
||||||
|
<BaseIcon path={mdiArrowRight} size={16} className="ml-1" />
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{activeTemplateSection === 'content' ? (
|
||||||
|
<div className="mt-6 rounded-[28px] border border-blue-100 bg-gradient-to-br from-slate-50 to-blue-50/70 p-5">
|
||||||
<div className="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
|
<div className="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-blue-700">Контент-шаблоны</p>
|
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-blue-700">Контент-шаблоны</p>
|
||||||
@ -1555,9 +1640,11 @@ const AgentStudio = () => {
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
<div className="mt-6 rounded-[28px] border border-emerald-100 bg-gradient-to-br from-emerald-50 to-white p-5">
|
{activeTemplateSection === 'lead_reply' ? (
|
||||||
|
<div className="mt-6 rounded-[28px] border border-emerald-100 bg-gradient-to-br from-emerald-50 to-white p-5">
|
||||||
<div className="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
|
<div className="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-emerald-700">Lead-шаблоны</p>
|
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-emerald-700">Lead-шаблоны</p>
|
||||||
@ -1635,6 +1722,7 @@ const AgentStudio = () => {
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
<BaseDivider />
|
<BaseDivider />
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user