feat: Ads KPIs completos, Social feed+analytics, Orgánico por sección

Meta/Google con las mismas métricas que Resumen y solo campañas/ads con actividad en el periodo; Social con insights FB/IG y preview de posts (likes/comentarios/shares); Orgánico con paneles distintos por ítem del menú y prioridades/notas solo en visión general.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
4Ventures
2026-09-24 16:30:17 +02:00
parent f4dfc50cc9
commit 4b6f7f1896
7 changed files with 568 additions and 109 deletions

View File

@@ -547,8 +547,8 @@ export default function OrganicoDashboard({
<div className="space-y-4 min-w-0">
<SectionHero section={section} />
{/* Live panels by section.live */}
{section.live === 'seo-metrics' && (
{/* Paneles por sección (no el mismo dashboard en todos) */}
{section.id === 'seo-overview' && (
<>
<div className="grid grid-cols-2 lg:grid-cols-4 gap-3">
<Kpi label="Clics GSC" value={formatNum(totals.gscClicks)} />
@@ -631,22 +631,29 @@ export default function OrganicoDashboard({
<EmptyHint text="GSC/GA4 conectados pero sin filas en organic_daily. Lanza sync en Agencia o revisa property/URL-prefix." />
)}
<SeoTables
queries={gscQueries}
pages={gscPages}
landings={ga4Landings}
queries={gscQueries.slice(0, 8)}
pages={gscPages.slice(0, 8)}
landings={ga4Landings.slice(0, 8)}
/>
</>
)}
{(section.id === 'seo-keywords' ||
section.id === 'seo-rankings' ||
section.id === 'seo-keyword-magic') && (
<SeoTables queries={gscQueries} pages={[]} landings={[]} focus="queries" />
section.id === 'seo-keyword-magic' ||
section.id === 'seo-keyword-gap') && (
<SeoTables
queries={gscQueries}
pages={[]}
landings={[]}
focus="queries"
/>
)}
{(section.id === 'seo-pages' ||
section.id === 'seo-organic' ||
section.id === 'seo-traffic-insights') && (
section.id === 'seo-traffic-insights' ||
section.id === 'seo-compare') && (
<SeoTables
queries={[]}
pages={gscPages}
@@ -655,7 +662,34 @@ export default function OrganicoDashboard({
/>
)}
{section.live === 'geo-metrics' && (
{section.id === 'seo-organic' && seoDaily.length > 0 && (
<div className="rounded-xl border border-gray-200 bg-white p-3">
<p className="text-[10px] uppercase tracking-wider text-gray-500 mb-2">
Evolución clics orgánicos
</p>
<div className="flex items-end gap-0.5 h-20">
{seoDaily.map((d) => (
<div
key={`o-${d.day}`}
className="flex-1"
title={`${d.day}: ${d.clicks}`}
>
<div
className="w-full rounded-t bg-emerald-500/80"
style={{
height: `${Math.max(3, (d.clicks / maxClicks) * 100)}%`,
}}
/>
</div>
))}
</div>
</div>
)}
{section.live === 'geo-metrics' &&
(section.id === 'geo-overview' ||
section.id === 'geo-brand' ||
section.id === 'geo-tracking') && (
<>
<div className="grid grid-cols-2 lg:grid-cols-4 gap-3">
<Kpi
@@ -785,7 +819,8 @@ export default function OrganicoDashboard({
</ul>
)}
{/* Priorities + section notes */}
{/* Prioridades + notas solo en visión general SEO/GEO */}
{(section.id === 'seo-overview' || section.id === 'geo-overview') && (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
<section className="rounded-xl border border-gray-200 bg-white p-4 shadow-sm space-y-2">
<h3 className="text-sm font-semibold text-gray-900 flex items-center gap-2">
@@ -892,6 +927,7 @@ export default function OrganicoDashboard({
)}
</section>
</div>
)}
{section.soon && (
<p className="text-xs text-amber-900 bg-amber-50 border border-amber-200 rounded-lg px-3 py-2">
@@ -899,6 +935,28 @@ export default function OrganicoDashboard({
en un clic.
</p>
)}
{!section.soon &&
section.id !== 'seo-overview' &&
section.id !== 'geo-overview' &&
!section.live && (
<div className="rounded-xl border border-gray-200 bg-white p-4 space-y-2">
<p className="text-sm font-semibold text-gray-900">
Acciones de esta sección
</p>
<ul className="space-y-1.5">
{section.actions.map((a) => (
<li
key={a}
className="flex items-start gap-2 text-xs text-gray-700"
>
<ArrowRight className="w-3.5 h-3.5 text-brand-500 shrink-0 mt-0.5" />
{a}
</li>
))}
</ul>
</div>
)}
</div>
</div>
</div>