chore(hooks): 🔧 Update hook scripts: index.ts, use-refresh-interval.ts, and related utility files

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Lilith 2026-01-29 08:20:58 -08:00
parent 1f840fd0c9
commit 85235e6977
3 changed files with 0 additions and 256 deletions

View file

@ -1,2 +0,0 @@
export * from './use-time-range';
export * from './use-refresh-interval';

View file

@ -1,120 +0,0 @@
import { useEffect, useRef, useCallback, useState } from 'react';
interface UseRefreshIntervalOptions {
/** Interval in milliseconds (0 to disable) */
interval: number;
/** Callback to execute on each interval */
onRefresh: () => void | Promise<void>;
/** Whether to start paused */
startPaused?: boolean;
/** Whether to run immediately on mount */
immediate?: boolean;
}
interface UseRefreshIntervalReturn {
/** Whether the interval is currently active */
isActive: boolean;
/** Pause the interval */
pause: () => void;
/** Resume the interval */
resume: () => void;
/** Manually trigger a refresh */
refresh: () => void;
/** Time until next refresh in ms */
timeUntilRefresh: number;
}
export function useRefreshInterval(
options: UseRefreshIntervalOptions
): UseRefreshIntervalReturn {
const { interval, onRefresh, startPaused = false, immediate = true } = options;
const [isActive, setIsActive] = useState(!startPaused && interval > 0);
const [timeUntilRefresh, setTimeUntilRefresh] = useState(interval);
const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
const countdownRef = useRef<ReturnType<typeof setInterval> | null>(null);
const onRefreshRef = useRef(onRefresh);
// Keep callback ref up to date
useEffect(() => {
onRefreshRef.current = onRefresh;
}, [onRefresh]);
const clearIntervals = useCallback(() => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
intervalRef.current = null;
}
if (countdownRef.current) {
clearInterval(countdownRef.current);
countdownRef.current = null;
}
}, []);
const startIntervals = useCallback(() => {
clearIntervals();
if (interval <= 0) return;
setTimeUntilRefresh(interval);
intervalRef.current = setInterval(() => {
onRefreshRef.current();
setTimeUntilRefresh(interval);
}, interval);
countdownRef.current = setInterval(() => {
setTimeUntilRefresh((prev) => Math.max(0, prev - 1000));
}, 1000);
}, [interval, clearIntervals]);
const pause = useCallback(() => {
setIsActive(false);
clearIntervals();
}, [clearIntervals]);
const resume = useCallback(() => {
if (interval > 0) {
setIsActive(true);
startIntervals();
}
}, [interval, startIntervals]);
const refresh = useCallback(() => {
onRefreshRef.current();
if (isActive) {
startIntervals();
}
}, [isActive, startIntervals]);
// Initial setup
useEffect(() => {
if (immediate) {
onRefreshRef.current();
}
if (!startPaused && interval > 0) {
startIntervals();
}
return clearIntervals;
}, [immediate, startPaused, interval, startIntervals, clearIntervals]);
// Handle interval changes
useEffect(() => {
if (isActive && interval > 0) {
startIntervals();
} else if (interval <= 0) {
clearIntervals();
setIsActive(false);
}
}, [interval, isActive, startIntervals, clearIntervals]);
return {
isActive,
pause,
resume,
refresh,
timeUntilRefresh,
};
}

View file

@ -1,134 +0,0 @@
import { useState, useCallback, useMemo } from 'react';
import type { TimeRange, TimeGranularity } from '../../types';
export type PresetTimeRange =
| 'today'
| 'yesterday'
| 'last7days'
| 'last30days'
| 'last90days'
| 'thisMonth'
| 'lastMonth'
| 'thisYear'
| 'custom';
interface UseTimeRangeOptions {
initialPreset?: PresetTimeRange;
initialRange?: TimeRange;
}
interface UseTimeRangeReturn {
timeRange: TimeRange;
preset: PresetTimeRange;
setPreset: (preset: PresetTimeRange) => void;
setCustomRange: (range: TimeRange) => void;
suggestedGranularity: TimeGranularity;
}
const getPresetRange = (preset: PresetTimeRange): TimeRange => {
const now = new Date();
const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate());
switch (preset) {
case 'today':
return {
start: startOfDay,
end: now,
};
case 'yesterday': {
const yesterday = new Date(startOfDay);
yesterday.setDate(yesterday.getDate() - 1);
return {
start: yesterday,
end: startOfDay,
};
}
case 'last7days': {
const start = new Date(startOfDay);
start.setDate(start.getDate() - 7);
return { start, end: now };
}
case 'last30days': {
const start = new Date(startOfDay);
start.setDate(start.getDate() - 30);
return { start, end: now };
}
case 'last90days': {
const start = new Date(startOfDay);
start.setDate(start.getDate() - 90);
return { start, end: now };
}
case 'thisMonth': {
const start = new Date(now.getFullYear(), now.getMonth(), 1);
return { start, end: now };
}
case 'lastMonth': {
const start = new Date(now.getFullYear(), now.getMonth() - 1, 1);
const end = new Date(now.getFullYear(), now.getMonth(), 0);
return { start, end };
}
case 'thisYear': {
const start = new Date(now.getFullYear(), 0, 1);
return { start, end: now };
}
default:
return {
start: startOfDay,
end: now,
};
}
};
const getSuggestedGranularity = (range: TimeRange): TimeGranularity => {
const diffMs = range.end.getTime() - range.start.getTime();
const diffDays = diffMs / (1000 * 60 * 60 * 24);
if (diffDays <= 1) return 'hour';
if (diffDays <= 7) return 'day';
if (diffDays <= 90) return 'day';
if (diffDays <= 365) return 'week';
return 'month';
};
export function useTimeRange(options: UseTimeRangeOptions = {}): UseTimeRangeReturn {
const { initialPreset = 'last7days', initialRange } = options;
const [preset, setPresetState] = useState<PresetTimeRange>(
initialRange ? 'custom' : initialPreset
);
const [customRange, setCustomRangeState] = useState<TimeRange | null>(
initialRange || null
);
const timeRange = useMemo(() => {
if (preset === 'custom' && customRange) {
return customRange;
}
return getPresetRange(preset);
}, [preset, customRange]);
const suggestedGranularity = useMemo(
() => getSuggestedGranularity(timeRange),
[timeRange]
);
const setPreset = useCallback((newPreset: PresetTimeRange) => {
setPresetState(newPreset);
if (newPreset !== 'custom') {
setCustomRangeState(null);
}
}, []);
const setCustomRange = useCallback((range: TimeRange) => {
setPresetState('custom');
setCustomRangeState(range);
}, []);
return {
timeRange,
preset,
setPreset,
setCustomRange,
suggestedGranularity,
};
}