From 331c19e87330b18cb48a232eab88aead1820ec11 Mon Sep 17 00:00:00 2001 From: 4Ventures <4ventures@MacBook-Air-de-4Ventures.local> Date: Mon, 28 Sep 2026 18:46:24 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20creatividades=20=E2=80=94=20Google=20sie?= =?UTF-8?q?mpre=20con=20fallback;=20Meta=20preview=209:16=20y=20textos=20r?= =?UTF-8?q?eales?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OAuth Ads caducado: aviso amable + campañas warehouse. Meta deja de volcar todas las variantes del asset_feed. Co-authored-by: Cursor --- src/components/AdCreativesGallery.tsx | 261 +++++++++++--------------- src/components/DriveConnectPanel.tsx | 7 +- src/lib/ad-creatives-google.ts | 131 ++++++------- src/lib/ad-creatives-meta.ts | 137 ++++++++++---- src/lib/ads-discovery.ts | 32 +--- src/lib/ads-sync.ts | 28 +-- src/lib/google-ads-auth.ts | 146 ++++++++++++++ src/lib/google-drive.ts | 7 +- 8 files changed, 435 insertions(+), 314 deletions(-) create mode 100644 src/lib/google-ads-auth.ts diff --git a/src/components/AdCreativesGallery.tsx b/src/components/AdCreativesGallery.tsx index 4c724f5..ae9b1f6 100644 --- a/src/components/AdCreativesGallery.tsx +++ b/src/components/AdCreativesGallery.tsx @@ -1,7 +1,11 @@ 'use client'; import React, { useEffect } from 'react'; -import type { AdCreativeCard, CreativeAsset } from '@/lib/ad-creatives-meta'; +import type { + AdCreativeCard, + CreativeAspect, + CreativeAsset, +} from '@/lib/ad-creatives-meta'; import { formatEur, formatNum } from '@/lib/metrics'; import { ImageIcon, Play, Maximize2, X, ExternalLink } from 'lucide-react'; @@ -31,29 +35,57 @@ 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 (u) out.push({ kind: 'image', url: u, label: 'preview', aspect: '9:16' }); if (ad.youtubeId) { out.push({ kind: 'youtube', url: `https://i.ytimg.com/vi/${ad.youtubeId}/hqdefault.jpg`, youtubeId: ad.youtubeId, label: 'YOUTUBE', + aspect: '16:9', }); } return out; } +function resolveAspect(asset: CreativeAsset): CreativeAspect { + if (asset.aspect && asset.aspect !== 'unknown') return asset.aspect; + const L = (asset.label || '').toLowerCase(); + if (/9\s*:?\s*16|story|reels|vertical|tall/.test(L)) return '9:16'; + if (/4\s*:?\s*5|portrait/.test(L)) return '4:5'; + if (/16\s*:?\s*9|1\.91|landscape|horizontal|youtube|video/.test(L)) { + return '16:9'; + } + if (/1\s*:?\s*1|square|logo/.test(L)) return '1:1'; + return 'unknown'; +} + +function aspectClass(aspect: CreativeAspect): string { + switch (aspect) { + case '9:16': + return 'aspect-[9/16]'; + case '4:5': + return 'aspect-[4/5]'; + case '16:9': + return 'aspect-video'; + case '1:1': + return 'aspect-square'; + default: + return 'aspect-[4/5]'; + } +} + 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 nine = assets.find( + (a) => a.kind === 'image' && resolveAspect(a) === '9:16' + ); + const fourFive = assets.find( + (a) => a.kind === 'image' && resolveAspect(a) === '4:5' ); const raw = - portrait?.url || + nine?.url || + fourFive?.url || ad.imageUrl || ad.thumbnailUrl || assets.find((a) => a.kind === 'image')?.url || @@ -96,14 +128,13 @@ export function CreativesGallery({ .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; + : /google|pmax|rsa|sin ads google|sin assets|oauth|warehouse|reconecta/i.test( + w + ) + ) || + (platform === 'google' && warning && /google|oauth|token/i.test(warning) + ? warning + : null); return (
@@ -115,12 +146,12 @@ export function CreativesGallery({ {platform === 'meta' ? 'Meta Ads' : 'Google Ads'} · creatividades

- Preview vertical + textos. Pulsa Zoom para ver todas las piezas. + Preview 9:16. Pulsa Zoom para ver el resto de piezas en su formato.

- {shownWarning ? ( -

- {shownWarning} + {platformWarning ? ( +

+ {platformWarning}

) : null} {loading ? ( @@ -155,17 +186,17 @@ function CreativeCard({ }) { const preview = previewUrlFor(ad); const isVideo = ad.mediaType === 'video' || Boolean(ad.youtubeId); - const headlines = adHeadlines(ad); - const bodies = adDescriptions(ad); + const headline = adHeadlines(ad)[0] || ''; + const body = adDescriptions(ad)[0] || ''; const assets = adAssets(ad); const extraCount = Math.max(0, assets.length - 1); return ( -
+