/* AAU CRM — Marketing shared widgets: TimeControl, CompareLineChart, Heatmap, AlertBanner, SummaryTable, SourceBadge. Exposes on window. */ // ---- period state hook (per-page; consistent control everywhere) ---- // now backed by the shared resolvePeriod() so the user can step back through history function useTimeRange(init = '30d') { const [period, setPeriodRaw] = useState(init); const [offset, setOffset] = useState(0); const [from, setFrom] = useState('2026-05-04'); const [to, setTo] = useState('2026-06-02'); const [compare, setCompare] = useState(true); const [cmpMode, setCmpMode] = useState('prev'); const cur = resolvePeriod(period, offset, { from, to }); const prev = resolvePeriod(period, offset - 1, { from, to }); const setPeriod = p => { setPeriodRaw(p); setOffset(0); }; return { period, setPeriod, offset, setOffset, from, setFrom, to, setTo, compare, setCompare, cmpMode, setCmpMode, cur, prev, curLabel: cur.label, scale: periodScale(period, offset), step: d => setOffset(o => Math.min(0, o + d)), reset: () => setOffset(0), }; } const PERIOD_LABEL = { today: 'Hôm nay', '7d': '7 ngày qua', '30d': '30 ngày qua', month: 'Tháng này', custom: 'Tùy chọn' }; const CMP_LABEL = { prev: 'Kỳ liền trước', year: 'Cùng kỳ năm trước', custom: 'Mốc tùy chọn' }; function TimeControl({ t }) { const [open, setOpen] = useState(false); const ref = useRef(null); useEffect(() => { if (!open) return; const h = e => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); }; document.addEventListener('mousedown', h); return () => document.removeEventListener('mousedown', h); }, [open]); const cmpVal = t.compare ? t.cmpMode : 'off'; const onCmp = (v) => { if (v === 'off') { t.setCompare(false); } else { t.setCompare(true); t.setCmpMode(v); } }; const isCustom = t.period === 'custom'; const atNow = t.offset === 0; const jumpList = Array.from({ length: 6 }).map((_, i) => resolvePeriod(t.period, -i, { from: t.from, to: t.to })); return (
{isCustom ? (
t.setFrom(e.target.value)} /> t.setTo(e.target.value)} />
) : (
{open && (
Tra cứu lịch sử · {t.cur.kind}
{jumpList.map(j => ( ))}
)}
)} {!isCustom && !atNow && }