feat: periodo global, métricas negocio, seguimiento notas, Drive/Social/Orgánico
Selector de fechas en header (con Personalizado) compartido en el dashboard; Métricas con Ventas/CAC/ROAS CRM, cruce canal y gráficas diarias; Seguimiento solo notas + sync Superhuman; Activos con navegación Drive; Social con métricas IG/FB; Orgánico con prioridades SEO/GEO expertas. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,11 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import {
|
||||
RangePreset,
|
||||
normalizePlatform,
|
||||
resolveAdRange,
|
||||
} from '@/lib/ad-tracker-range';
|
||||
import { normalizePlatform } from '@/lib/ad-tracker-range';
|
||||
import { AdDailyRow, formatEur, formatNum } from '@/lib/metrics';
|
||||
import type { AdCreativeCard } from '@/lib/ad-creatives-meta';
|
||||
import {
|
||||
@@ -13,7 +9,7 @@ import {
|
||||
CreativeZoomModal,
|
||||
} from '@/components/AdCreativesGallery';
|
||||
import { PageHeader } from '@/components/ui';
|
||||
import DateRangePicker from '@/components/DateRangePicker';
|
||||
import { useDateRange } from '@/components/DateRangeContext';
|
||||
|
||||
type PlatformKpis = {
|
||||
spend: number;
|
||||
@@ -317,9 +313,7 @@ export default function AdTrackerClient({
|
||||
tagline?: string;
|
||||
rows: AdDailyRow[];
|
||||
}) {
|
||||
const [preset, setPreset] = useState<RangePreset>('last_7d');
|
||||
const [customSince, setCustomSince] = useState('');
|
||||
const [customUntil, setCustomUntil] = useState('');
|
||||
const { since, until, label: rangeLabel } = useDateRange();
|
||||
const [tab, setTab] = useState<Tab>('resumen');
|
||||
const [chartMode, setChartMode] = useState<ChartMode>('combined');
|
||||
const [creatives, setCreatives] = useState<AdCreativeCard[]>([]);
|
||||
@@ -327,10 +321,11 @@ export default function AdTrackerClient({
|
||||
const [creativesWarning, setCreativesWarning] = useState<string | null>(null);
|
||||
const [zoomAd, setZoomAd] = useState<AdCreativeCard | null>(null);
|
||||
|
||||
const range = useMemo(
|
||||
() => resolveAdRange(preset, { since: customSince, until: customUntil }),
|
||||
[preset, customSince, customUntil]
|
||||
);
|
||||
const range = useMemo(() => ({ since, until, label: rangeLabel }), [
|
||||
since,
|
||||
until,
|
||||
rangeLabel,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
@@ -416,26 +411,7 @@ export default function AdTrackerClient({
|
||||
<PageHeader
|
||||
eyebrow={`Ads · ${label}`}
|
||||
title={tagline || 'Meta + Google Ads'}
|
||||
description={`Gasto, clics, conversiones y preview de creatividades. Ventana: ${range.since} → ${range.until}.`}
|
||||
/>
|
||||
|
||||
{/* Period presets */}
|
||||
<DateRangePicker
|
||||
preset={preset}
|
||||
customSince={customSince || range.since}
|
||||
customUntil={customUntil || range.until}
|
||||
onPreset={(p) => {
|
||||
setPreset(p);
|
||||
if (p !== 'custom') {
|
||||
const r = resolveAdRange(p);
|
||||
setCustomSince(r.since);
|
||||
setCustomUntil(r.until);
|
||||
}
|
||||
}}
|
||||
onCustomChange={(since, until) => {
|
||||
setCustomSince(since);
|
||||
setCustomUntil(until);
|
||||
}}
|
||||
description={`Gasto, clics, conversiones y creatividades. Periodo del header: ${rangeLabel}.`}
|
||||
/>
|
||||
|
||||
{/* Tabs */}
|
||||
|
||||
Reference in New Issue
Block a user