// SATMELI — Detalle de búsqueda: historial + gráfico de actividad. function ActivityChart({ data, mode }) { const [hover, setHover] = React.useState(null); const max = Math.max(1, ...data); const desktop = mode === 'desktop'; const h = desktop ? 150 : 120; const n = data.length; // etiquetas de día relativas (14 -> hoy) const dayName = (i) => { const back = n - 1 - i; if (back === 0) return 'hoy'; if (back === 1) return 'ayer'; return `-${back}d`; }; const total = data.reduce((a, b) => a + b, 0); return (
Actividad
coincidencias · últimos 14 días
{total}
en el período
{data.map((v, i) => { const bh = (v / max) * (h - 22) + 3; const on = hover === i; return (
setHover(i)} onMouseLeave={() => setHover(null)} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'flex-end', height: '100%', cursor: 'default', position: 'relative' }}> {on && (
{v} · {dayName(i)}
)}
{dayName(i)}
); })}
); } function StatCell({ k, v, sub, accent }) { return (
{k}
{v}
{sub &&
{sub}
}
); } function HistoryRow({ n, cat, onGoMeli }) { return (
{n.title}
{fmtARS(n.price)} {ago(n.foundAt)} {!n.read && }
); } function Detail({ search, notifs, mode, onBack, onEdit, onToggle, onDelete, onGoMeli }) { const desktop = mode === 'desktop'; const c = SAT_CATS[search.cat]; const matches = notifs.filter((n) => n.searchId === search.id).sort((a, b) => a.foundAt - b.foundAt); const prices = matches.map((m) => m.price); const best = prices.length ? Math.min(...prices) : null; const avg = prices.length ? Math.round(prices.reduce((a, b) => a + b, 0) / prices.length) : null; // chequeos estimados según frecuencia y antigüedad const perDay = { '5m': 288, '15m': 96, '1h': 24, '6h': 4, '1d': 1 }[search.freq] || 24; const checks = Math.round(perDay * Math.min(search.createdAt, 30) * (search.active ? 1 : 0.6)); const header = (
{search.active ? 'EN VIVO' : 'PAUSADA'} · {freqLabel(search.freq)}

{search.term}

); const actions = (
{search.active ? 'Pausar' : 'Reanudar'} Editar {desktop ? 'Eliminar' : ''}
); const filters = (
{c.label} {priceRangeLabel(search)} {condLabel(search.condition)} {search.location}
); const stats = (
); const history = (
Historial de coincidencias {matches.length} guardadas
{matches.length ? matches.map((n) => ) :
Todavía sin coincidencias.
}
); return (
{header} {filters} {actions} {desktop ? (
{stats} {history}
) : ( <> {stats} {history} )}
); } Object.assign(window, { Detail, ActivityChart });