Timer
timer
import React, {useEffect, useRef, useState} from 'react';
import {View, Flexbox, Text} from '@evlop/native-components';
const AppBlock: NativeAppBLock = function (props) {
const {data = {}} = props;
const [timeComponents, setTimeComponents] = useState<Array<{value: number; unit: string}>>([
{value: 0, unit: 'day'},
{value: 0, unit: 'hr'},
{value: 0, unit: 'min'},
{value: 0, unit: 'sec'},
]);
const [showTimer, setShowTimer] = useState<boolean>(true);
const intervalRef = useRef<number | null>(null);
useEffect(() => {
if (!data?.date) {
setShowTimer(false);
return;
}
const endDate = new Date(data.date);
const updateTime = () => {
const now = new Date();
const difference = endDate.getTime() - now.getTime();
if (difference >= 0) {
const days = Math.floor(difference / (1000 * 60 * 60 * 24));
const hours = Math.floor((difference / (1000 * 60 * 60)) % 24);
const minutes = Math.floor((difference / (1000 * 60)) % 60);
const seconds = Math.floor((difference / 1000) % 60);
setTimeComponents([
{value: days, unit: days === 1 ? 'day' : 'days'},
{value: hours, unit: hours === 1 ? 'hr' : 'hrs'},
{value: minutes, unit: minutes === 1 ? 'min' : 'mins'},
{value: seconds, unit: seconds === 1 ? 'sec' : 'secs'},
]);
setShowTimer(true);
} else {
setShowTimer(false);
if (intervalRef.current) {
clearInterval(intervalRef.current);
intervalRef.current = null;
}
}
};
// run immediately
updateTime();
// then every second
intervalRef.current = setInterval(updateTime, 1000) as unknown as number;
return () => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
intervalRef.current = null;
}
};
}, [data?.date]);
if (!showTimer) return null;
return (
<Flexbox style={{flexDirection: 'column', padding: 20, alignItems: 'center'}}>
{data?.title ? (
<Text style={{marginBottom: 16, fontWeight: '700', fontSize: 20}} content={data.title} />
) : null}
<Flexbox style={{flexDirection: 'row', alignItems: 'center', gap: 10}}>
{timeComponents.map((tc, idx) => (
<Flexbox
key={idx}
style={{
alignItems: 'center',
justifyContent: 'center',
minWidth: 70,
paddingHorizontal: 6,
paddingVertical: 6,
aspectRatio: 1,
}}
aspectRatio={1}
borderWidth={1}
borderColor="primary-200"
borderRadius={5}
bg="gray-50"
flexDirection="column"
>
<Text style={{fontWeight: '700', textAlign: 'center'}}>{tc.value}</Text>
<Text style={{marginTop: 4, color: '#6B7280', fontSize: 12, textAlign: 'center'}}>
{tc.unit}
</Text>
</Flexbox>
))}
</Flexbox>
</Flexbox>
);
};
export default AppBlock;
{
"title": "Starts in",
"date": "2030-12-31T23:59:59"
}Loading...