Files
freno-dev/src/lib/useCountdown.ts
Michael Freno 898c891bd5 chore: remediate pygienium audit findings
Dead code: 77 verified-unused exports, files (BackArrow, MenuBars,
cookies.ts, db/create.ts, schemas/comment.ts, security-headers.ts) and
12 unused dependencies removed
Comments: ~370 RESTATE comments stripped across 53 files; 2 verbose
blocks tightened; dead commented-out config removed
Complexity: bulkUpsert extracted into 11 per-entity helpers (CCN 156->~10);
login formHandler split into 3 submitters (CCN 63->~5); account page render
split into 8 section components (CCN 40); updatePost SQL builder rebuilt;
assert*Owned consolidated behind generic assertOwnedBy
Defensive guards: 4 redundant rethrow/nullish guards removed
2026-08-11 13:36:18 -04:00

75 lines
1.7 KiB
TypeScript

import { createSignal, onCleanup } from "solid-js";
export interface UseCountdownOptions {
/**
* Initial remaining time in seconds
*/
initialTime?: number;
/**
* Cookie name to read expiration time from
*/
cookieName?: string;
/**
* Callback when countdown reaches zero
*/
onComplete?: () => void;
}
/**
* Hook for managing countdown timers from expiration timestamps
* @param options Configuration options
* @returns [remainingTime, startCountdown]
*/
export function useCountdown(options: UseCountdownOptions = {}) {
const [remainingTime, setRemainingTime] = createSignal(
options.initialTime ?? 0
);
let intervalId: ReturnType<typeof setInterval> | null = null;
const calculateRemaining = (expiresAt: string | Date) => {
const expires =
typeof expiresAt === "string" ? new Date(expiresAt) : expiresAt;
const remaining = expires.getTime() - Date.now();
const remainingInSeconds = remaining / 1000;
if (remainingInSeconds <= 0) {
setRemainingTime(0);
if (intervalId !== null) {
clearInterval(intervalId);
intervalId = null;
}
options.onComplete?.();
} else {
setRemainingTime(remainingInSeconds);
}
};
const startCountdown = (expiresAt: string | Date) => {
if (intervalId !== null) {
clearInterval(intervalId);
}
calculateRemaining(expiresAt);
intervalId = setInterval(() => calculateRemaining(expiresAt), 1000);
};
const stopCountdown = () => {
if (intervalId !== null) {
clearInterval(intervalId);
intervalId = null;
}
};
onCleanup(() => {
stopCountdown();
});
return {
remainingTime,
startCountdown,
stopCountdown,
setRemainingTime
};
}