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;
Loading...