From b53161dc4daef7d4ae796b1115ea5d70b4a65644 Mon Sep 17 00:00:00 2001 From: 4Ventures <4ventures@MacBook-Air-de-4Ventures.local> Date: Thu, 8 Oct 2026 10:11:30 +0200 Subject: [PATCH] Include paid ad channels with spend in CRM % a cliente table. Google (and other channels with ads but no CRM-sourced leads) now appear with 0 leads so investment and CAC stay visible. Co-authored-by: Cursor --- src/components/CrmDashboard.tsx | 57 ++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/src/components/CrmDashboard.tsx b/src/components/CrmDashboard.tsx index 83fbbb2..341d5bd 100644 --- a/src/components/CrmDashboard.tsx +++ b/src/components/CrmDashboard.tsx @@ -123,19 +123,42 @@ export default function CrmDashboard({ return m; }, [attribution]); - const paidChannels = channelRows.filter((r) => - ['meta', 'google'].includes(r.channel) + // Include paid channels that have ad spend/ventas even with 0 CRM leads + // (e.g. Google Ads spend but no leads sourced as "google" in Clientify). + const channelRowsWithAds: CrmChannelStats[] = useMemo(() => { + const byCh = new Map(channelRows.map((r) => [r.channel, r])); + for (const r of attribution) { + if (r.spend <= 0 && r.ventas <= 0) continue; + if (byCh.has(r.channel)) continue; + byCh.set(r.channel, { + channel: r.channel, + leads: 0, + cliente: 0, + enOportunidad: 0, + leadFrio: 0, + leadPerdido: 0, + other: 0, + clienteRate: 0, + }); + } + const all = [...byCh.values()]; + const paid = all + .filter((r) => ['meta', 'google'].includes(r.channel)) + .sort((a, b) => { + const sa = cacByChannel.get(a.channel)?.spend || 0; + const sb = cacByChannel.get(b.channel)?.spend || 0; + return sb - sa || b.leads - a.leads; + }); + const other = all + .filter((r) => !['meta', 'google'].includes(r.channel)) + .sort((a, b) => b.cliente - a.cliente || b.leads - a.leads); + return [...paid, ...other]; + }, [channelRows, attribution, cacByChannel]); + + const leadMax = Math.max( + 1, + ...channelRowsWithAds.map((r) => r.leads) ); - const otherChannels = channelRows.filter( - (r) => !['meta', 'google'].includes(r.channel) - ); - // Channels with ads spend / ventas but maybe no CRM lead row in this lens - const extraCacChannels = attribution.filter( - (r) => - (r.spend > 0 || r.ventas > 0) && - !channelRows.some((c) => c.channel === r.channel) - ); - const leadMax = Math.max(1, ...channelRows.map((r) => r.leads)); const statusMax = Math.max(1, ...statusRows.map((r) => r.count)); return ( @@ -330,9 +353,9 @@ export default function CrmDashboard({ hint="Estado ganado en el CRM. Ads spend y CAC del periodo son referencia." /> - {!channelRows.length && !extraCacChannels.length ? ( + {!channelRowsWithAds.length ? (

- Sin leads en esta lente/periodo. + Sin leads ni gasto ads en esta lente/periodo.

) : (
@@ -350,7 +373,7 @@ export default function CrmDashboard({ - {[...paidChannels, ...otherChannels].map((row) => { + {channelRowsWithAds.map((row) => { const cacRow = cacByChannel.get(row.channel); return ( - {row.clienteRate.toFixed(1)}% + {row.leads > 0 + ? `${row.clienteRate.toFixed(1)}%` + : '—'} {cacRow && cacRow.spend > 0