- Added `useRateLimit` hook - Integrated hook into `Contact.tsx` - Added translations for rate limit error - Added unit tests - Fixed type error in `Button.tsx` to allow build to pass
39 lines
1.0 KiB
TypeScript
39 lines
1.0 KiB
TypeScript
import { useState, useCallback } from 'react';
|
|
|
|
interface UseRateLimitReturn {
|
|
checkRateLimit: () => boolean;
|
|
remainingTime: number;
|
|
}
|
|
|
|
export function useRateLimit(key: string, cooldownMs: number): UseRateLimitReturn {
|
|
const [remainingTime, setRemainingTime] = useState(0);
|
|
|
|
const checkRateLimit = useCallback(() => {
|
|
try {
|
|
const now = Date.now();
|
|
const lastAttempt = localStorage.getItem(key);
|
|
|
|
if (lastAttempt) {
|
|
const lastTime = parseInt(lastAttempt, 10);
|
|
const timePassed = now - lastTime;
|
|
|
|
if (timePassed < cooldownMs) {
|
|
const remaining = Math.ceil((cooldownMs - timePassed) / 1000);
|
|
setRemainingTime(remaining);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
localStorage.setItem(key, now.toString());
|
|
setRemainingTime(0);
|
|
return true;
|
|
} catch (error) {
|
|
console.warn('LocalStorage not available:', error);
|
|
// Fail safe: allow action if storage fails
|
|
return true;
|
|
}
|
|
}, [key, cooldownMs]);
|
|
|
|
return { checkRateLimit, remainingTime };
|
|
}
|