feat: pre-preenche contexto do modal de novo anuncio com a copy existente

A geracao de copy/imagem por IA exigia que o usuario descrevesse o
anuncio do zero. Agora getAdSetDefaultCreative tambem extrai o texto
do criativo de um anuncio ja existente no ad set (headline, mensagem
e descricao) e o AddAdModal usa isso para preencher automaticamente
o campo de contexto, permitindo gerar variacoes no mesmo tom sem
digitar nada.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcio Bevervanso 2026-06-08 13:18:41 -03:00
parent d2406f0152
commit b4ad2e0585
2 changed files with 30 additions and 3 deletions

View file

@ -26,6 +26,9 @@ interface CreativeDefaults {
is_whatsapp: boolean;
whatsapp_link?: string;
whatsapp_phone_number?: string;
sample_primary_text?: string;
sample_headline?: string;
sample_description?: string;
}
export function AddAdModal({
@ -63,8 +66,17 @@ export function AddAdModal({
const res = await fetch(`/api/adsets/${adsetId}/creative-defaults`);
const data = await res.json();
if (!cancelled && data.success) {
setDefaults(data.data);
setLink(data.data?.link || '');
const d: CreativeDefaults | undefined = data.data;
setDefaults(d ?? null);
setLink(d?.link || '');
// Seed do contexto com a copy de um anúncio já existente no ad set,
// pra IA gerar variações no mesmo "tom" sem o usuário escrever do zero.
const seed =
d?.sample_primary_text ||
[d?.sample_headline, d?.sample_description].filter(Boolean).join(' — ') ||
`Anúncio para a campanha "${campaignName}" (conjunto "${adsetName}")`;
setContext((prev) => prev || seed);
}
} catch {
// Segue sem defaults — o usuário ainda pode publicar informando o link.
@ -76,7 +88,7 @@ export function AddAdModal({
return () => {
cancelled = true;
};
}, [adsetId]);
}, [adsetId, campaignName, adsetName]);
const generateCopy = async () => {
if (!context.trim()) {

View file

@ -251,6 +251,9 @@ export interface AdSetDefaultCreative {
is_whatsapp: boolean;
whatsapp_link?: string;
whatsapp_phone_number?: string;
sample_primary_text?: string;
sample_headline?: string;
sample_description?: string;
}
interface AdSetDefaultCreativeApiResponse {
@ -262,12 +265,18 @@ interface AdSetDefaultCreativeApiResponse {
instagram_actor_id?: string;
link_data?: {
link?: string;
message?: string;
name?: string;
description?: string;
call_to_action?: { type?: string };
};
};
asset_feed_spec?: {
link_urls?: Array<{ website_url?: string }>;
call_to_action_types?: string[];
bodies?: Array<{ text?: string }>;
titles?: Array<{ text?: string }>;
descriptions?: Array<{ text?: string }>;
};
};
}>;
@ -311,6 +320,9 @@ export async function getAdSetDefaultCreative(
is_whatsapp: isWhatsapp,
whatsapp_link: isWhatsapp ? linkData?.link || undefined : undefined,
whatsapp_phone_number: undefined,
sample_primary_text: linkData?.message || undefined,
sample_headline: linkData?.name || undefined,
sample_description: linkData?.description || undefined,
};
}
@ -327,6 +339,9 @@ export async function getAdSetDefaultCreative(
is_whatsapp: isWhatsapp,
whatsapp_link: isWhatsapp ? link : undefined,
whatsapp_phone_number: undefined,
sample_primary_text: assetFeed.bodies?.[0]?.text || undefined,
sample_headline: assetFeed.titles?.[0]?.text || undefined,
sample_description: assetFeed.descriptions?.[0]?.text || undefined,
};
}