peer-at-code-web/ui/Timer.tsx
2023-04-12 20:14:05 +02:00

53 lines
1.4 KiB
TypeScript

import clsx from 'clsx';
import { useEffect, useReducer } from 'react';
type State = {
hours: number;
minutes: number;
seconds: number;
};
type Action = {
type: string;
payload: Partial<State>;
};
function reducer(state: State, action: Action): State {
switch (action.type) {
case 'SET_TIME_REMAINING':
return { ...state, ...action.payload };
default:
return state;
}
}
export function Timer({ targetDate, className }: { targetDate: Date; className?: string }) {
const [timeRemaining, dispatch] = useReducer(reducer, {
hours: 0,
minutes: 0,
seconds: 0
});
useEffect(() => {
const intervalId = setInterval(() => {
const timeDifference = targetDate.getTime() - Date.now();
const hours = Math.floor(timeDifference / (1000 * 60 * 60));
const minutes = Math.floor((timeDifference / (1000 * 60)) % 60);
const seconds = Math.floor((timeDifference / 1000) % 60);
dispatch({
type: 'SET_TIME_REMAINING',
payload: { hours, minutes, seconds }
});
}, 1000);
return () => clearInterval(intervalId);
}, [targetDate]);
return (
<span className={clsx('', className)}>
{`${timeRemaining.hours.toString().padStart(2, '0')}:${timeRemaining.minutes
.toString()
.padStart(2, '0')}:${timeRemaining.seconds.toString().padStart(2, '0')}`}
</span>
);
}