Untitled

 avatar
unknown
plain_text
2 years ago
8.2 kB
6
Indexable
/* eslint-disable quotes */
import {
  Box,
  Center,
  Flex,
  Img,
  Spinner,
  Text,
  useDisclosure,
  useToast,
} from '@chakra-ui/react';
import cameraic from 'assets/camera_ic.svg';
import { Button, Form } from 'components';
import { useFetch, useRequest } from 'hooks';
import { IScanCamera } from 'interfaces/cameraVM';
import { useState } from 'react';
import {
  authenCamera,
  createCameraApi,
  getScanResult,
  scanBox,
} from 'requests';
import { useCreateCamerasStore } from 'stores';
import { useDocumentTitle } from 'usehooks-ts';
import { AuthVerifyModal } from './AuthVerifyModal';
import { findIndex, update } from 'ramda';

export function VerifyCamera(): JSX.Element {
  useDocumentTitle('Add Camera');
  const { serial, setActiveStep, hub_id } = useCreateCamerasStore((state) => ({
    setActiveStep: state.setActiveStep,
    hub_name: state.hub_name,
    serial: state.serial,
    hub_id: state.hub_id,
  }));
  const toast = useToast();
  const [scanRefId, setScanRefId] = useState<string>('');
  const [scanResult, setScanResult] = useState<IScanCamera[]>([]);
  const [loading, setLoading] = useState<boolean>(false);
  const [errorUpdateCount, setErrorUpdateCount] = useState<number>(0);
  const { isOpen, onOpen, onClose } = useDisclosure();
  const [camera, setCamera] = useState<IScanCamera>();

  const onScanbox = useRequest(scanBox, {
    onSuccess: (data) => {
      setScanRefId(data.refId);
      setLoading(true);
    },
    onError: (_error) => {
      toast({
        duration: 9000,
        status: 'error',
        isClosable: true,
        title: 'Scan không thành công',
        description: _error?.data?.message || 'Scan không thành công',
      });
    },
  });

  useFetch(
    () => getScanResult({ serial: serial as string, scan_ref_id: scanRefId }),
    // @ts-expect-error don'tfix
    ['fetchScanResult', [[scanRefId]]],
    {
      onSuccess: (data) => {
        setScanResult(data);
        setLoading(false);
      },
      onError: (_error) => {
        if (errorUpdateCount >= 18) {
          toast({
            duration: 9000,
            status: 'error',
            isClosable: true,
            title: 'Scan không thành công',
            description: _error?.data?.message || 'Scan không thành công',
          });
          setLoading(false);
          setErrorUpdateCount(0);
        } else {
          setErrorUpdateCount((preState) => preState + 1);
        }
      },
      enabled: !!scanRefId,
      refetchIntervalInBackground: true,
      refetchInterval: (_data, query) =>
        query.state.errorUpdateCount > 18 || scanResult.length > 0
          ? false
          : 5000,
    },
  );

  const { mutate: createCamera, isLoading } = useRequest(createCameraApi, {
    onSuccess: () => {
      toast({
        duration: 9000,
        status: 'success',
        isClosable: true,
        title: 'Thêm camera thành công',
        description: 'Thêm camera thành công',
      });
      setScanResult((preState: IScanCamera[]) => {
        const index = findIndex((item: IScanCamera) => item.id === camera?.id)(
          preState,
        );
        if (index !== -1) {
          return update(
            index,
            { ...camera, is_authorized: 'created' } as any,
            preState,
          );
        }
        return preState;
      });
    },
    onError: (_error) => {
      toast({
        duration: 9000,
        status: 'error',
        isClosable: true,
        title: 'Thêm camera không thành công',
        description: _error?.data?.message || 'Thêm camera không thành công',
      });
    },
  });
  const handleScanBox = () => {
    if (loading) return;
    setScanResult([]);
    onScanbox.mutate({ serial: serial as string });
  };

  const handleAuthen = (data: IScanCamera) => {
    setCamera(data);
    if (data.is_authorized) {
      createCamera({
        name: data.name,
        hub_id: Number(hub_id),
        stream_main: data?.streamMain as string,
        stream_sub: data?.streamSub as string,
        device_url: data.xAddr,
        username: data.user,
        password: data.password,
        is_authorized: true,
      });
    } else {
      setCamera(data);
      onOpen();
    }
  };
  return (
    <Flex flexDirection='column' justifyContent='space-between' h='full'>
      <AuthVerifyModal
        serial={serial}
        camera={camera as IScanCamera}
        isOpen={isOpen}
        onClose={onClose}
        setScanResult={setScanResult}
      />
      <Box>
        <Flex
          mb='28px'
          alignItems='center'
          justifyContent='space-between'
          px='45px'
        >
          <Text fontSize='32px' fontWeight='semibold' lineHeight='40px'>
            Xác thực và thêm camera
          </Text>
          <Text
            onClick={handleScanBox}
            cursor={loading ? 'not-allowed' : 'pointer'}
            fontWeight='bold'
            color='main.500'
          >
            Scan
          </Text>
        </Flex>
        {loading ? (
          <Center>
            <Text fontSize='3xl' color='neutral.black-7'>
              Scanning
            </Text>
            <Spinner ml='4' color='neutral.black-7' />
          </Center>
        ) : (
          <Form>
            <Flex
              overflow='auto'
              maxH='calc(100vh - 443px)'
              gap='24px'
              px='48px'
              flexDirection='column'
            >
              {scanResult.length > 0 ? (
                <Flex flexDirection='column'>
                  <Box
                    py='3'
                    borderBottom='1px solid #D6D9DC'
                    fontWeight='semibold'
                  >
                    <Text>
                      Danh sách camera cùng mạng với vBox ({scanResult.length})
                    </Text>
                  </Box>
                  <Box mt='3'>
                    {scanResult.map((data: any) => (
                      <Flex justifyContent='space-between' alignItems='center'>
                        <Flex alignItems='center'>
                          <Img mr='2' src={cameraic} />
                          <Text>{data.name}</Text>
                        </Flex>
                        <Button
                          onClick={() => handleAuthen(data)}
                          borderRadius='8px'
                          fontSize='sm'
                          isDisabled={
                            data?.is_authorized === 'loading' ||
                            data?.is_authorized === 'created'
                          }
                          size='sm'
                          bg='secondary.blue-500'
                          _hover={{
                            bg: 'secondary.blue-500',
                          }}
                        >
                          {data?.is_authorized === 'loading' ? (
                            <Spinner />
                          ) : data?.is_authorized === 'verified' ? (
                            'Thêm camera'
                          ) : (
                            'Xác thực'
                          )}
                        </Button>
                      </Flex>
                    ))}
                  </Box>
                </Flex>
              ) : (
                <Center>
                  <Text fontSize='3xl' color='neutral.black-7'>
                    Không có dữ liệu
                  </Text>
                </Center>
              )}
            </Flex>
          </Form>
        )}
      </Box>
      <Flex
        borderTop='1px solid #D6D9DC'
        py='28px'
        px='45px'
        gap='24px'
        justifyContent='end'
      >
        <Button
          borderRadius='8px'
          border='1px solid #BABFC4'
          color='neutral.black-10'
          fontSize='sm'
          bg='white'
          onClick={() => setActiveStep(2)}
        >
          Quay lại
        </Button>
        <Button
          //   onClick={() => handleSubmitChooseMethod(type)}
          borderRadius='8px'
          fontSize='sm'
          bg='main.orange-500'
        >
          Tiếp theo
        </Button>
      </Flex>
    </Flex>
  );
}
Editor is loading...
Leave a Comment