need to feel whole progress bar after 30 seconds and keep it in loop for 30 sec

import { Observer } from "mobx-react";
import React, { useRef, useState, useEffect } from "react";
import {
  StyleSheet,
  Text,
  View,
  Image,
  TouchableOpacity,
  TouchableWithoutFeedback,
  FlatList,
  Clipboard,
  Animated,
  Platform,
  Dimensions,
} from "react-native";
import FastImage from "react-native-fast-image";
import AppStore from "../../stores/AppStore";
import Scanstore from "../../stores/Scanstore";
import Iconpack from "../../utils/Iconpack";
import Theme from "../../utils/Theme";
import { Screen } from "../CommonComponent/Screen";
import Toast from "react-native-simple-toast";
import { HeaderOtp } from "../CommonComponent/Header";

const hRem = AppStore.screenHeight / 812;
const wRem = AppStore.screenWidth / 375;

const totp = require("totp-generator");

function useInterval(callback, delay) {
  const savedCallback = useRef();
  // Remember the latest callback.
  useEffect(() => {
    savedCallback.current = callback;
  }, [callback]);

  // Set up the interval.
  useEffect(() => {
    function tick() {
      savedCallback.current();
    }
    if (delay !== null) {
      let id = setInterval(tick, delay);
      return () => clearInterval(id);
    }
  }, [delay]);
}

const OtpScreen = ({ route, params, navigation }) => {
  let animation = useRef(new Animated.Value(0));
  const [progress, setProgress] = useState(0);

  useInterval(() => {
    const d = new Date();
    let sec = d.getSeconds();
    // if (elapsedTime % 30 == 0) {
    //   return maxTimeInSeconds;

    setProgress(sec > 30 ? sec - 30 : sec);
    console.log(".........", sec);
  }, 1000);

  useEffect(() => {
    Animated.timing(animation.current, {
      toValue: progress,
      duration: 1000,
      useNativeDriver: false,
    }).start();
    console.log("---->", Scanstore.rData);
    if (Scanstore.loop) {
      Scanstore.fetchSecretKeyArray();
      Scanstore.checkLoop(false);
    }
  }, [progress]);

  const showToast = () => {
    // ToastAndroid.show("Pin Copied Successfully", ToastAndroid.SHORT);
    Toast.show("Pin Copied Successfully.", Toast.LONG);
  };

  const width = animation.current.interpolate({
    inputRange: [0, 30],
    outputRange: ["0%", "100%"],
    extrapolate: "clamp",
  });
  const copyToClipboard = (title) => {
    Clipboard.setString(totp(title));
    showToast();
  };

  const [copiedText, setCopiedText] = useState("");
  const renderFlatlist = ({ item }) => {
    return (
      <TouchableOpacity
        onPress={() => {
          navigation.navigate("OtpDetails", {
            title: item.title,
            // id: item.id,
            otpFrom: item.otpFrom,
          });
        }}
      >
        <View style={Platform.OS === "ios" ? styles.items : styles.items2}>
          <Animated.View
            style={[
              [StyleSheet.absoluteFill],
              {
                backgroundColor: Theme.selectedColor,
                borderTopLeftRadius: 15,
                borderBottomLeftRadius: 15,
                width,
              },
            ]}
          />
          <Text style={styles.itemsContainer}>{totp(item.title)}</Text>
          <Text style={styles.itemsLogin}>{item.otpFrom}</Text>
          <TouchableWithoutFeedback
            onPress={() => {
              copyToClipboard(item.title);
            }}
          >
            <Image source={Iconpack.OTP_COPY} style={styles.copyIcon} />
          </TouchableWithoutFeedback>
        </View>
      </TouchableOpacity>
    );
  };
  const renderBottomSection = () => {
    return (
      <TouchableOpacity
        onPress={(item) => {
          AppStore.checkUserExist();
          navigation.navigate("MainAdd", {
            myTitle: item.title,
            // id: item.id,
          });
        }}
        style={styles.bottomButton}
      >
        <Image style={styles.plusButton} source={Iconpack.PLUS_ICON} />
      </TouchableOpacity>
    );
  };

  const rightSection = () => {
    return (
      <View style={styles.settingStyle}>
        <TouchableOpacity
          onPress={() => {
            navigation.navigate("Settings");
          }}
        >
          <Image source={Iconpack.OTP_SETTINGS} style={styles.settingIcon} />
        </TouchableOpacity>
      </View>
    );
  };

  return (
    <Observer>
      {() => (
        <>
          {/* <Screen
            style={styles.mod1}
            statusBar={"light-content"}
            variant={true}
            showMenu={false}
            onNavigate={navigation}
          > */}
          <FastImage
            style={styles.container}
            source={Iconpack.OTP_BG}
            resizeMode={FastImage.resizeMode.cover}
          />

          {/* <UniversalNavigationHeader
              hideBack={true}
              title={"OTP’s"}
              goBack={navigation.goBack}
              rightView={rightSection}
              showRightView={true}
            /> */}
          <HeaderOtp
            headerText="OTP's"
            onPress={() => {
              navigation.navigate("Settings");
            }}
          />

          <View style={styles.mod1}>
            <FlatList
              data={Scanstore.rData}
              // keyExtractor={(item) => item.id}
              extraData={Scanstore.rData}
              renderItem={renderFlatlist}
              contentContainerStyle={styles.mod3}
            />
          </View>
          <View>{renderBottomSection()}</View>
          {/* </Screen> */}
        </>
      )}
    </Observer>
  );
};

export default OtpScreen;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    position: "absolute",
    top: 0,
    right: 0,
    left: 0,
    bottom: 0,
    backgroundColor: "#021831",
  },
  settingStyle: {
    marginRight: Dimensions.get("screen").width - 360,
  },
  mod0: {},
  mod1: { flex: 1 },
  headerStyle: {
    flexDirection: "row",
    marginTop: hRem * 56,
    marginHorizontal: wRem * 26.66,
    justifyContent: "space-between",
  },
  mod3: { paddingBottom: 50 },
  otpText: {
    marginLeft: wRem * 136.85,
    ...Theme.encodeSansMed2,
    // lineHeight: hRem * 16,
    color: "#FFFFFF",
    fontWeight: "600",
    marginBottom: hRem * 16,
  },
  settingIcon: {
    width: wRem * 26,
    height: hRem * 26,
  },
  items: {
    backgroundColor: "black",
    marginHorizontal: wRem * 24,
    marginTop: hRem * 16,
    height: hRem * 97,
    flex: 1,
    borderRadius: 15,
    shadowColor: "rgba(27, 100, 206, 0.25)",
    shadowOffset: {
      width: 2,
      height: 2,
    },
    shadowOpacity: 5,
    shadowRadius: 5,
  },
  items2: {
    backgroundColor: "black",
    marginHorizontal: wRem * 24,
    marginTop: hRem * 16,
    height: hRem * 97,
    flex: 1,
    borderRadius: 15,
    shadowColor: "#1b64ce",
    shadowOffset: {
      width: 0,
      height: 3,
    },
    shadowOpacity: 0.36,
    shadowRadius: 6.68,

    elevation: 10,
  },
  itemsContainer: {
    color: "white",
    marginTop: hRem * 28,
    marginLeft: wRem * 29,
    ...Theme.encodeSansMed4,
    // lineHeight: hRem * 16,
  },
  itemsLogin: {
    color: "#898989",
    ...Theme.encodeSansMed5,
    marginLeft: wRem * 29,
    lineHeight: hRem * 19,
  },
  copyIcon: {
    width: wRem * 30,
    height: hRem * 30,
    resizeMode: "contain",
    position: "absolute",
    right: 0,
    // margin: 40,
    marginHorizontal: 24,
    marginTop: 27,
    zIndex: 999,
  },
  bottomButton: {
    justifyContent: "center",
    alignItems: "center",
    position: "absolute",
    bottom: 50,
    width: "100%",
    marginLeft: Theme.devicePixelRatio ? wRem * 150 : wRem * 150,
    borderRadius:
      Math.round(
        Dimensions.get("window").width + Dimensions.get("window").height
      ) / 2,
    width: Dimensions.get("window").width * 0.21,
    height: Dimensions.get("window").width * 0.21,
    backgroundColor: "black",
    shadowColor: "rgba(27, 100, 206, 0.8)",
    shadowOffset: {
      width: 0,
      height: 0,
    },
    shadowOpacity: 10,
    shadowRadius: 15,

    elevation: 10,
  },
  plusButton: {
    position: "absolute",
    textAlign: "center",
    width: wRem * 26,
    height: hRem * 26,
  },
})

here I have pasted the whole code here, ** the problem currently I am facing is, my progress bar feel up after 30 sec but after 30 sec it comes back and it starts at 31sec position, when it reaches 60 sec it does not completely touch the end and it came back and it starting from 0 seconds. I have a little bit of confusion I am just using 30 seconds but it iterating in 60 seconds *

the thing is the progress bar when at 30 seconds position it touches to the end but at 60 it not touches to the end some space like gap it’s leaving after 60 seconds, need to feel whole progress bar after 30 seconds and keep it in the loop for 30-sec pls helped me out, thanks in advance.

i am using new Date() method and getSeconds() method for getting device time