'use client'; import React, { useEffect } from 'react'; import type { AdCreativeCard, CreativeAsset } from '@/lib/ad-creatives-meta'; import { formatEur, formatNum } from '@/lib/metrics'; import { ImageIcon, Play, Maximize2, X, ExternalLink } from 'lucide-react'; export function proxiedMediaUrl(raw: string): string { if (!raw) return ''; if (raw.startsWith('/api/')) return raw; return `/api/ad-tracker/media?url=${encodeURIComponent(raw)}`; } function adHeadlines(ad: AdCreativeCard): string[] { if (ad.headlines?.length) return ad.headlines; return (ad.headline || '') .split('\n') .map((s) => s.trim()) .filter(Boolean); } function adDescriptions(ad: AdCreativeCard): string[] { if (ad.descriptions?.length) return ad.descriptions; return (ad.primaryText || '') .split('\n') .map((s) => s.trim()) .filter(Boolean); } function adAssets(ad: AdCreativeCard): CreativeAsset[] { if (ad.assets?.length) return ad.assets; const out: CreativeAsset[] = []; const u = ad.imageUrl || ad.thumbnailUrl; if (u) out.push({ kind: 'image', url: u, label: 'preview' }); if (ad.youtubeId) { out.push({ kind: 'youtube', url: `https://i.ytimg.com/vi/${ad.youtubeId}/hqdefault.jpg`, youtubeId: ad.youtubeId, label: 'YOUTUBE', }); } return out; } function previewUrlFor(ad: AdCreativeCard): string { const assets = adAssets(ad); const portrait = assets.find( (a) => a.kind === 'image' && /portrait|vertical|tall|TALL|PORTRAIT|story|4.?5|9.?16/i.test( a.label || '' ) ); const raw = portrait?.url || ad.imageUrl || ad.thumbnailUrl || assets.find((a) => a.kind === 'image')?.url || (ad.youtubeId ? `https://i.ytimg.com/vi/${ad.youtubeId}/hqdefault.jpg` : '') || assets.find((a) => a.youtubeId)?.url || ''; return raw ? proxiedMediaUrl(raw) : ''; } function MiniKpi({ label, value }: { label: string; value: string }) { return (

{label}

{value}

); } export function CreativesGallery({ platform, ads, loading, warning, onZoom, }: { platform: 'meta' | 'google'; ads: AdCreativeCard[]; loading: boolean; warning?: string | null; onZoom: (ad: AdCreativeCard) => void; }) { const filtered = ads.filter((a) => a.platform === platform); const platformWarning = warning ?.split(' · ') .find((w) => platform === 'meta' ? /meta|token meta|sin ads meta/i.test(w) : /google|pmax|rsa|sin ads google|sin assets/i.test(w) ) || null; const shownWarning = filtered.length === 0 && warning ? platformWarning || (ads.length === 0 ? warning : null) : platformWarning && filtered.length === 0 ? platformWarning : null; return (

Creatividades · preview por anuncio

{platform === 'meta' ? 'Meta Ads' : 'Google Ads'} · creatividades

Preview vertical + textos. Pulsa Zoom para ver todas las piezas.

{shownWarning ? (

{shownWarning}

) : null} {loading ? (

Cargando creatividades…

) : filtered.length === 0 ? (

Sin creatividades para este periodo.

) : (
{filtered.map((ad) => ( onZoom(ad)} /> ))}
)}
); } function CreativeCard({ ad, onZoom, }: { ad: AdCreativeCard; onZoom: () => void; }) { const preview = previewUrlFor(ad); const isVideo = ad.mediaType === 'video' || Boolean(ad.youtubeId); const headlines = adHeadlines(ad); const bodies = adDescriptions(ad); const assets = adAssets(ad); const extraCount = Math.max(0, assets.length - 1); return (

{ad.adName || 'Sin nombre'}

{ad.status || ad.platform}

{ad.campaignName || '—'}

{ad.adsetName ? (

Conjunto: {ad.adsetName}

) : null}
{ad.platform === 'meta' ? 'Meta' : 'Google'} {ad.mediaType && ad.mediaType !== 'unknown' ? ( {ad.mediaType} ) : null} {assets.length > 0 ? ( {assets.length} piezas ) : null}
{(headlines.length > 0 || bodies.length > 0) && (
{headlines.length > 0 ? (

Titulares

    {headlines.slice(0, 4).map((h) => (
  • {h}
  • ))} {headlines.length > 4 ? (
  • +{headlines.length - 4} más
  • ) : null}
) : null} {bodies.length > 0 ? (

Textos / descripciones

    {bodies.slice(0, 3).map((b) => (
  • {b}
  • ))} {bodies.length > 3 ? (
  • +{bodies.length - 3} más
  • ) : null}
) : null} {ad.cta ? (

CTA · {ad.cta}

) : null}
)}
); } export function CreativeZoomModal({ ad, onClose, }: { ad: AdCreativeCard; onClose: () => void; }) { const headlines = adHeadlines(ad); const bodies = adDescriptions(ad); const longH = ad.longHeadlines || []; const assets = adAssets(ad); const images = assets.filter((a) => a.kind === 'image' || a.kind === 'logo'); const videos = assets.filter((a) => a.kind === 'youtube' || a.kind === 'video'); const main = previewUrlFor(ad); useEffect(() => { const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }; window.addEventListener('keydown', onKey); const prev = document.body.style.overflow; document.body.style.overflow = 'hidden'; return () => { window.removeEventListener('keydown', onKey); document.body.style.overflow = prev; }; }, [onClose]); return (
e.stopPropagation()} >

Zoom creatividades ·{' '} {ad.platform === 'meta' ? 'Meta Ads' : 'Google Ads'}

{ad.adName || 'Anuncio'}

{ad.campaignName} {ad.adsetName ? ` · ${ad.adsetName}` : ''}

{main ? ( // eslint-disable-next-line @next/next/no-img-element {ad.adName} ) : (
Sin preview
)}

Impresiones:{' '} {formatNum(ad.impressions)}

Formato:{' '} {ad.mediaType || '—'}

Estado:{' '} {ad.status || '—'}

{ad.cta ? (

CTA: {ad.cta}

) : null} {ad.businessName ? (

Negocio:{' '} {ad.businessName}

) : null} {ad.linkUrl ? ( {ad.linkUrl} ) : null}
{images.length > 0 ? (

Imágenes y logos ({images.length})

{images.map((asset, i) => (
{/* eslint-disable-next-line @next/next/no-img-element */} {asset.label
{asset.label ? (
{asset.label} {asset.kind === 'logo' ? ' · logo' : ''}
) : null}
))}
) : null} {videos.length > 0 ? (

Vídeos ({videos.length})

{videos.map((v, i) => (
{v.youtubeId ? (