From b4e843762ee5af3551b842c19608c90c72be0ff0 Mon Sep 17 00:00:00 2001 From: 4Ventures <4ventures@MacBook-Air-de-4Ventures.local> Date: Thu, 8 Oct 2026 10:35:11 +0200 Subject: [PATCH] Show Google Ads platform leads separately from CRM-sourced leads. Clarifies BPS case: Google Ads conversions exist while Clientify has no source=google contacts; ventas stay on ecommerce until UTM/gclid maps the deal. Co-authored-by: Cursor --- src/components/CrmDashboard.tsx | 61 +++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/src/components/CrmDashboard.tsx b/src/components/CrmDashboard.tsx index 341d5bd..f00ba64 100644 --- a/src/components/CrmDashboard.tsx +++ b/src/components/CrmDashboard.tsx @@ -116,9 +116,24 @@ export default function CrmDashboard({ ventasTotal > 0 && spendTotal > 0 ? spendTotal / ventasTotal : 0; const cacByChannel = useMemo(() => { - const m = new Map(); + const m = new Map< + string, + { + cac: number; + spend: number; + ventas: number; + platformLeads: number; + importe: number; + } + >(); for (const r of attribution) { - m.set(r.channel, { cac: r.cac, spend: r.spend, ventas: r.ventas }); + m.set(r.channel, { + cac: r.cac, + spend: r.spend, + ventas: r.ventas, + platformLeads: r.platformLeads, + importe: r.importe, + }); } return m; }, [attribution]); @@ -189,9 +204,15 @@ export default function CrmDashboard({

{LENS_HELP[lens]}

- El % a cliente es del CRM, no de ads. El{' '} - CAC = inversión ads del periodo ÷ ventas ganadas - (deals won) del periodo; por canal usa la atribución del deal. + Leads ads = conversiones que reporta Meta/Google Ads.{' '} + Leads CRM = contactos en Clientify/GHL con esa fuente. + Si Google Ads tiene leads pero el CRM no, el contacto llegó sin UTM / + source=google (hay que mapear la fuente en el CRM). +

+

+ Ventas / CAC usan deals won del CRM. Un pedido + WooCommerce suele entrar como ecommerce, aunque el clic haya + sido de Google Brand — sin UTM/gclid no se reasigna a Google.

@@ -274,7 +295,7 @@ export default function CrmDashboard({ } title="CAC por canal" - hint="Inversión ads ÷ ventas won atribuidas al canal (mismo criterio que Métricas)." + hint="Leads ads = conversiones Meta/Google. Ventas = deals won en CRM con esa fuente." /> {!attribution.some((r) => r.spend > 0 || r.ventas > 0) ? ( @@ -288,7 +309,8 @@ export default function CrmDashboard({ Canal Inversión - Ventas + Leads ads + Ventas CRM CAC Importe @@ -307,6 +329,11 @@ export default function CrmDashboard({ {row.spend > 0 ? formatEur(row.spend) : '—'} + + {row.platformLeads > 0 + ? formatNum(Math.round(row.platformLeads)) + : '—'} + {row.ventas > 0 ? formatNum(row.ventas) : '—'} @@ -325,6 +352,13 @@ export default function CrmDashboard({ {spendTotal > 0 ? formatEur(spendTotal) : '—'} + + {formatNum( + Math.round( + attribution.reduce((a, r) => a + r.platformLeads, 0) + ) + )} + {ventasTotal > 0 ? formatNum(ventasTotal) : '—'} @@ -350,7 +384,7 @@ export default function CrmDashboard({ } title="% a cliente por canal" - hint="Estado ganado en el CRM. Ads spend y CAC del periodo son referencia." + hint="Leads CRM = fuente en Clientify. Leads ads = conversiones de la plataforma. No tienen por qué coincidir." /> {!channelRowsWithAds.length ? ( @@ -363,18 +397,20 @@ export default function CrmDashboard({ Canal - - Leads + Leads ads + + Leads CRM Clientes % a cliente - Inversión ads + Inversión CAC {channelRowsWithAds.map((row) => { const cacRow = cacByChannel.get(row.channel); + const plat = Math.round(cacRow?.platformLeads || 0); return ( {row.channel} + + {plat > 0 ? formatNum(plat) : '—'} +