All files / app/pages/stacking/delegated-stacking/components duration-cycles-form.tsx

0% Statements 0/38
0% Branches 0/5
0% Functions 0/10
0% Lines 0/32

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85                                                                                                                                                                         
import { CircleButton } from '@components/circle-button';
import { MAX_STACKING_CYCLES, MIN_STACKING_CYCLES } from '@constants/index';
import { Flex, InputProps, Text, Box, color } from '@stacks/ui';
import { RootState } from '@store/index';
import { selectNextCycleInfo } from '@store/stacking';
import { decrement, increment } from '@utils/mutate-numbers';
import { formatCycles } from '@utils/stacking';
import dayjs from 'dayjs';
import advancedFormat from 'dayjs/plugin/advancedFormat';
import duration from 'dayjs/plugin/duration';
import relativeTime from 'dayjs/plugin/relativeTime';
import updateLocale from 'dayjs/plugin/updateLocale';
import React, { FC, useMemo } from 'react';
import { useSelector } from 'react-redux';
 
dayjs.extend(duration);
dayjs.extend(updateLocale);
dayjs.extend(relativeTime);
dayjs.extend(advancedFormat);
 
interface DurationCycleFromProps extends Omit<InputProps, 'form'> {
  duration: number | null;
  onUpdate(duration: number): void;
}
 
const createCycleArray = () => new Array(12).fill(null).map((_, i) => i + 1);
const durationWithDefault = (duration: number | null) => duration ?? 1;
 
export const DurationCyclesForm: FC<DurationCycleFromProps> = props => {
  const { duration, onUpdate } = props;
 
  const { cycleInfo } = useSelector((state: RootState) => ({
    cycleInfo: selectNextCycleInfo(state),
  }));
 
  const cycleLabels = useMemo(() => {
    Iif (!cycleInfo) return [];
    return createCycleArray().map(cycles => {
      return `
        ${formatCycles(cycles)}
        (ends around ${dayjs()
          .add(cycleInfo.estimateCycleDurationSeconds * cycles, 'seconds')
          .format('Do MMMM')})`;
    });
  }, [cycleInfo]);
 
  return (
    <Flex
      alignItems="center"
      justifyContent="space-between"
      mt="base"
      padding="8px"
      boxShadow="low"
      border={`1px solid ${color('border')}`}
      borderRadius="8px"
      onClick={e => (e.stopPropagation(), e.preventDefault())}
      position="relative"
      zIndex={10}
    >
      <Text alignItems="center" ml="tight" color={color('text-title')}>
        {cycleLabels[durationWithDefault(duration) - 1]}
      </Text>
      <Box>
        <CircleButton
          onClick={e => {
            e.stopPropagation();
            onUpdate(Math.max(MIN_STACKING_CYCLES, decrement(durationWithDefault(duration))));
          }}
        >
          -
        </CircleButton>
        <CircleButton
          ml={[null, 'extra-tight']}
          onClick={e => {
            e.stopPropagation();
            onUpdate(Math.min(MAX_STACKING_CYCLES, increment(durationWithDefault(duration))));
          }}
        >
          +
        </CircleButton>
      </Box>
    </Flex>
  );
};