peer-at-code-web/ui/Timer.tsx
2023-04-26 18:13:50 +02:00

66 lines
1.6 KiB
TypeScript

import clsx from 'clsx';
import { useEffect, useReducer } from 'react';
import { useWindowSize } from 'react-use';
import Confetti from 'react-confetti';
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 { width, height } = useWindowSize();
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]);
if (timeRemaining.hours < 0) {
return (
<>
{/* <Confetti width={width} height={height} /> */}
<span className={clsx(className)}>Terminé</span>
</>
);
}
return (
<span className={clsx(className)}>
{timeRemaining.hours}h {timeRemaining.minutes}m {timeRemaining.seconds}s
</span>
);
}