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 <cursoragent@cursor.com>
This commit is contained in:
@@ -123,19 +123,42 @@ export default function CrmDashboard({
|
|||||||
return m;
|
return m;
|
||||||
}, [attribution]);
|
}, [attribution]);
|
||||||
|
|
||||||
const paidChannels = channelRows.filter((r) =>
|
// Include paid channels that have ad spend/ventas even with 0 CRM leads
|
||||||
['meta', 'google'].includes(r.channel)
|
// (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));
|
const statusMax = Math.max(1, ...statusRows.map((r) => r.count));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -330,9 +353,9 @@ export default function CrmDashboard({
|
|||||||
hint="Estado ganado en el CRM. Ads spend y CAC del periodo son referencia."
|
hint="Estado ganado en el CRM. Ads spend y CAC del periodo son referencia."
|
||||||
/>
|
/>
|
||||||
<Surface padded={false}>
|
<Surface padded={false}>
|
||||||
{!channelRows.length && !extraCacChannels.length ? (
|
{!channelRowsWithAds.length ? (
|
||||||
<p className="text-sm text-gray-500 py-10 text-center">
|
<p className="text-sm text-gray-500 py-10 text-center">
|
||||||
Sin leads en esta lente/periodo.
|
Sin leads ni gasto ads en esta lente/periodo.
|
||||||
</p>
|
</p>
|
||||||
) : (
|
) : (
|
||||||
<div className="overflow-x-auto">
|
<div className="overflow-x-auto">
|
||||||
@@ -350,7 +373,7 @@ export default function CrmDashboard({
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{[...paidChannels, ...otherChannels].map((row) => {
|
{channelRowsWithAds.map((row) => {
|
||||||
const cacRow = cacByChannel.get(row.channel);
|
const cacRow = cacByChannel.get(row.channel);
|
||||||
return (
|
return (
|
||||||
<tr
|
<tr
|
||||||
@@ -375,7 +398,9 @@ export default function CrmDashboard({
|
|||||||
row.clienteRate
|
row.clienteRate
|
||||||
)}`}
|
)}`}
|
||||||
>
|
>
|
||||||
{row.clienteRate.toFixed(1)}%
|
{row.leads > 0
|
||||||
|
? `${row.clienteRate.toFixed(1)}%`
|
||||||
|
: '—'}
|
||||||
</td>
|
</td>
|
||||||
<td className="py-3 pr-4 tabular-nums text-gray-700">
|
<td className="py-3 pr-4 tabular-nums text-gray-700">
|
||||||
{cacRow && cacRow.spend > 0
|
{cacRow && cacRow.spend > 0
|
||||||
|
|||||||
Reference in New Issue
Block a user