Created
May 17, 2022 00:57
-
-
Save vicasas/46843d099969478bf9c7fe435fb76dfc to your computer and use it in GitHub Desktop.
How to do a countdown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useEffect, useState } from 'react' | |
import Head from 'next/head' | |
import { Box, Typography } from '@mui/material' | |
const getReturnValues = (countDown: number) => { | |
const days = Math.floor(countDown / (1000 * 60 * 60 * 24)) | |
const hours = Math.floor((countDown % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) | |
const minutes = Math.floor((countDown % (1000 * 60 * 60)) / (1000 * 60)) | |
const seconds = Math.floor((countDown % (1000 * 60)) / 1000) | |
return [ | |
{ value: days, label: 'days' }, | |
{ value: hours, label: 'hours' }, | |
{ value: minutes, label: 'minutes' }, | |
{ value: seconds, label: 'seconds' }, | |
] | |
} | |
const useCountdown = (dateEnd, serverDate) => { | |
const [timer, setTimer] = useState(0) | |
useEffect(() => { | |
const difference = dateEnd - serverDate | |
setTimer(difference > 0 ? difference : 0) | |
}, []) | |
useEffect(() => { | |
const interval = setInterval(() => { | |
setTimer(timer - 1000) | |
}, 1000) | |
return () => clearInterval(interval) | |
}, [timer]) | |
return getReturnValues(timer) | |
} | |
interface CounterProps { | |
children: React.ReactNode | |
} | |
function Counter({ children }: CounterProps) { | |
return <Box sx={{ display: 'flex', gap: 1 }}>{children}</Box> | |
} | |
interface CounterItemProps { | |
label: string | |
value: string | |
} | |
function CounterItem({ value, label }: CounterItemProps) { | |
return ( | |
<Box | |
sx={{ | |
display: 'flex', | |
flexDirection: 'column', | |
textAlign: 'center', | |
minWidth: 50, | |
}} | |
> | |
<Typography | |
component='span' | |
variant='h5' | |
fontWeight='bold' | |
sx={{ bgcolor: '#cc0077', color: '#fff', borderRadius: 1, px: 1, width: '100%' }} | |
> | |
{value} | |
</Typography> | |
<Typography | |
component='span' | |
sx={{ | |
fontSize: (theme) => theme.typography.pxToRem(7), | |
textTransform: 'uppercase', | |
mt: 0.25, | |
}} | |
> | |
{label} | |
</Typography> | |
</Box> | |
) | |
} | |
interface CountdownProps { | |
dateEnd: number | |
serverDate: number | |
} | |
function Countdown({ dateEnd, serverDate }: CountdownProps) { | |
const times = useCountdown(dateEnd, serverDate) | |
return ( | |
<Counter> | |
{times.map(({ value, label }) => ( | |
<CounterItem key={label} value={String(value).padStart(2, '0')} label={label} /> | |
))} | |
</Counter> | |
) | |
} | |
export default function Docs() { | |
const NOW_IN_MS = new Date().getTime() | |
return ( | |
<div> | |
<Head> | |
<title>Create Next App</title> | |
<meta name='description' content='Generated by create next app' /> | |
<link rel='icon' href='/favicon.ico' /> | |
</Head> | |
<Box sx={{ display: 'flex', justifyContent: 'center', py: 2 }}> | |
<Countdown dateEnd={1652623260000} serverDate={NOW_IN_MS} /> | |
</Box> | |
</div> | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment