diff --git a/src/components/MetricsDashboard.tsx b/src/components/MetricsDashboard.tsx
index beaf8a2..8b325b8 100644
--- a/src/components/MetricsDashboard.tsx
+++ b/src/components/MetricsDashboard.tsx
@@ -11,6 +11,8 @@ import {
TrendingUp,
Users,
MousePointerClick,
+ Globe,
+ Search,
} from 'lucide-react';
import {
AdDailyRow,
@@ -300,6 +302,29 @@ export default function MetricsDashboard({
hasCohort && periodTotals.revenue <= 0 && cohortFromLeads;
const showWow = rangeDaySpan(since, until) <= 7;
+ const organicPeriod = useMemo(() => {
+ const rows = organicRows.filter((r) => {
+ const d = (r.day || r.date || '').slice(0, 10);
+ return d >= since && d <= until;
+ });
+ const gscClicks = rows.reduce((a, r) => a + (Number(r.gsc_clicks) || 0), 0);
+ const ga4Sessions = rows.reduce(
+ (a, r) => a + (Number(r.ga4_sessions) || 0),
+ 0
+ );
+ const ga4Conversions = rows.reduce(
+ (a, r) => a + (Number(r.ga4_conversions) || 0),
+ 0
+ );
+ const denom = periodTotals.leads + ga4Conversions;
+ return {
+ gscClicks,
+ ga4Sessions,
+ ga4Conversions,
+ organicShare: denom > 0 ? (ga4Conversions / denom) * 100 : 0,
+ };
+ }, [organicRows, since, until, periodTotals.leads]);
+
const cards: Card[] = [
{
key: 'spend',
@@ -311,7 +336,7 @@ export default function MetricsDashboard({
{
key: 'leads',
label: 'Leads plataforma',
- hint: 'Conversiones reportadas por ads',
+ hint: 'Conversiones reportadas por ads (no CRM)',
format: formatNum,
icon:
- {s.label} -
-- {s.value} -
-+ Leads CRM +
++ {hasCrm ? formatNum(crmPeriodTotal) : '—'} +
++ Altas Clientify en el periodo (no es el mismo número que ads) +
++ CPL CRM +
++ {hasCrm && crmPeriodTotal > 0 + ? `${formatNum(periodTotals.spend / crmPeriodTotal)} €` + : '—'} +
++ Inversión ads ÷ leads CRM (distinto del CPL ads) +
++ Gap plat vs CRM +
++ {hasCrm + ? `${crmPeriodTotal - periodTotals.leads > 0 ? '+' : ''}${formatNum(crmPeriodTotal - periodTotals.leads)}` + : '—'} +
++ CRM − leads plataforma · detalle por canal abajo +
+
+
+ {formatNum(organicPeriod.gscClicks)} +
+Search Console · mismo periodo
+
+
+ {formatNum(organicPeriod.ga4Sessions)} +
++ GA4 · {formatNum(organicPeriod.ga4Conversions)} conv. web +
++ Cuota orgánica +
++ {formatPct(organicPeriod.organicShare)} +
++ Conv. GA4 / (leads ads + conv. web) +
+- Atribución omnicanal y métricas agregadas multi-red (Google Ads, Meta Ads, GA4, Search - Console y CRM) consolidadas en el warehouse de 4Ventures. + Lo de arriba es el scorecard ads+CRM. Aquí solo el detalle que no + cabe ahí: campañas Google, SEO/GA4 y mix paid vs orgánico.
+ Campañas Google, SEO/GA4 y mix paid vs orgánico · mismo periodo + del header. +
+
-
+ Clics SEO (GSC)
- {formatEur(blendedTotals.totalMediaSpend)} + {formatNum(organicData.gscClicks)}
-- Meta ({googleData.totalSpend > 0 ? Math.round((metaData.spend / blendedTotals.totalMediaSpend) * 100) : 100}%) + Google Ads ({googleData.totalSpend > 0 ? Math.round((googleData.totalSpend / blendedTotals.totalMediaSpend) * 100) : 0}%) +
+ {gscSite || 'Search Console'}
-
+ Sesiones web (GA4)
- {formatNum(blendedTotals.totalWebInteractions)} + {formatNum(organicData.ga4Sessions)}
-- Ads ({formatNum(blendedTotals.totalPaidClicks)}) + SEO ({formatNum(organicData.gscClicks)}) + Web ({formatNum(organicData.ga4Sessions)}) +
+ {ga4Id || 'Sin GA4 enlazado'}
-
+ Conv. web (GA4)
- {formatNum(Math.round(blendedTotals.totalConversions))} -
-- {formatNum(Math.round(blendedTotals.totalPaidLeads))} leads ads + {formatNum(Math.round(organicData.ga4Conversions))} web + {formatNum(organicData.ga4Conversions)}
+No son leads de ads
-
- {blendedTotals.blendedCpl > 0 ? `${formatNum(blendedTotals.blendedCpl)} €` : '—'} -
-- Inversión media por conversión multi-canal -
-
-
+ Cuota orgánica
{formatPct(blendedTotals.organicAcquisitionShare)}
-- Conversiones generadas sin coste de pauta +
+ Conv. GA4 / (leads ads + conv. web)