dappros/ethora

View on GitHub
client-reactnative/src/Screens/Actions/UploadDocumentsScreen.tsx

Summary

Maintainability
F
5 days
Test Coverage
import React, {useState} from 'react';
import {
  Text,
  View,
  StyleSheet,
  ScrollView,
  ActivityIndicator,
  Alert,
  TextInput,
  TouchableOpacity,
  Platform,
} from 'react-native';
import {
  widthPercentageToDP as wp,
  heightPercentageToDP as hp,
} from 'react-native-responsive-screen';
import AntIcon from 'react-native-vector-icons/AntDesign';
import FastImage from 'react-native-fast-image';
import DocumentPicker from 'react-native-document-picker';
import CheckBox from '@react-native-community/checkbox';

import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
import {commonColors, textStyles} from '../../../docs/config';
import SecondaryHeader from '../../components/SecondaryHeader/SecondaryHeader';
import {showError, showSuccess} from '../../components/Toast/toast';
import {httpPost} from '../../config/apiService';
import {docsURL, fileUpload} from '../../config/routesConstants';
import {pdfMimemtype} from '../../constants/mimeTypes';
import {useStores} from '../../stores/context';
import {
  isAudioMimetype,
  isImageMimetype,
  isPdfMimetype,
} from '../../helpers/checkMimetypes';
import {uploadFiles} from '../../helpers/uploadFiles';
import {HStack, VStack} from 'native-base';

const emptyFile = {
  _id: '',
  createdAt: '',
  expiresAt: 0,
  filename: '',
  isVisible: true,
  location: '',
  locationPreview: '',
  mimetype: '',
  originalname: '',
  ownerKey: '',
  size: 0,
  updatedAt: '',
  userId: '',
};

const UploadDocumentsScreen = () => {
  const {loginStore, walletStore, debugStore} = useStores();

  const [itemName, setItemName] = useState<string>('');
  // data api
  // const [doctorsName, setDoctorsName] = useState<string>('');
  // const [reportType, setReportType] = useState<string>('');
  // const [reportKind, setReportKind] = useState<string>('');
  // const [date, setDate] = useState(new Date());

  const [documentUrl, setDocumentUrl] = useState<string>('');

  const [loading, setLoading] = useState<boolean>(false);
  const [uploadedFile, setUploadedFile] = useState<typeof emptyFile>(emptyFile);
  const [distributionRightsApproved, setDistributionRightsApproved] =
    useState<boolean>(true);

  const clearData = () => {
    setLoading(false);
    setDocumentUrl('');
    setItemName('');
    setDistributionRightsApproved(false);
    setUploadedFile(emptyFile);
    // setReportKind('');
    // setReportType('');
    // setDoctorsName('');
    // setDate(new Date());
  };

  const createNftItem = async () => {
    let item = {files: [uploadedFile.location], documentName: itemName};

    // alert(JSON.stringify(item))
    const url = docsURL;
    setLoading(true);
    try {
      const res = await httpPost(url, item, loginStore.userToken);
      // alert(JSON.stringify(res.data))

      debugStore.addLogsApi(res.data);
      walletStore.fetchWalletBalance(loginStore.userToken, true);
    } catch (error) {
      showError('Error', 'Cannot create item, try again later');
      console.log(error.response);
    }
    setLoading(false);
  };

  const onMintClick = async () => {
    if (!documentUrl) {
      showError('Error', 'Please load the image.');
      return;
    }
    if (!itemName.length) {
      showError('Error', 'Please fill the item name.');
      return;
    }
    if (!setDistributionRightsApproved) {
      showError('Error', 'Please confirm distribution rights');
      return;
    }

    await createNftItem();
    walletStore.fetchOwnTransactions(
      loginStore.initialData.walletAddress,
      100,
      0,
    );
    showSuccess(
      'Success',
      'You minted new document, it will appear in your profile',
    );

    clearData();
  };

  const chooseImageOption = () => {
    Alert.alert('Choose a file', '', [
      {text: 'Open from files', onPress: () => setDocumentFile()},
      {text: 'Dismiss', onPress: () => console.log('dismissed')},
    ]);
  };

  const sendFiles = async (data: any) => {
    setLoading(true);
    try {
      const url = fileUpload;
      const response = await uploadFiles(data, loginStore.userToken, url);
      setLoading(false);

      setUploadedFile(response.results[0]);
      debugStore.addLogsApi(response.results[0]);
      // alert(JSON.stringify(response.results[0]))
      const isPdf = !!pdfMimemtype[response.results[0].mimetype];
      setDocumentUrl(
        isPdf
          ? response.results[0].locationPreview
          : response.results[0].location,
      );
    } catch (error) {
      console.log(error);
    }
  };

  const setDocumentFile = async () => {
    try {
      const res = await DocumentPicker.pick({
        type: [
          DocumentPicker.types.images,
          DocumentPicker.types.audio,
          DocumentPicker.types.video,
          DocumentPicker.types.pdf,
        ],
      });
      const data = new FormData();
      data.append('files', {
        name: res[0].name,
        type: res[0].type,
        uri: res[0].uri,
      });
      sendFiles(data);
    } catch (err) {
      if (DocumentPicker.isCancel(err)) {
        // User cancelled the picker, exit any dialogs or menus and move on
      } else {
        throw err;
      }
    }
  };

  return (
    <KeyboardAwareScrollView
      style={{flex: 1, backgroundColor: 'white'}}
      // behavior={ "height"}
      // keyboardVerticalOffset={Platform.OS == "ios" ? 0 : 20}
      // enabled={ false}
    >
      <View>
        <SecondaryHeader title="Upload file" />
      </View>
      <ScrollView style={classes.container}>
        <View style={classes.contentContainer}>
          <View style={classes.section1}>
            <TextInput
              value={itemName}
              onChangeText={setItemName}
              placeholder="Document Name"
              placeholderTextColor={commonColors.primaryColor}
              style={classes.itemNameInput}
              maxLength={50}
            />
          </View>

          <HStack
            justifyContent={'space-between'}
            alignItems={'flex-start'}
            mt={'2'}>
            <TouchableOpacity
              onPress={chooseImageOption}
              style={{alignItems: 'flex-start', width: wp('90%')}}>
              <VStack
                justifyContent={'center'}
                alignItems={'center'}
                style={classes.filePreviewContainer}>
                {documentUrl ? (
                  <>
                    {isAudioMimetype(uploadedFile.mimetype) && (
                      <AntIcon
                        name={'playcircleo'}
                        color={commonColors.primaryColor}
                        size={hp('5%')}
                      />
                    )}
                    {isImageMimetype(uploadedFile.mimetype) && (
                      <FastImage
                        source={{
                          uri: uploadedFile.locationPreview,
                          priority: FastImage.priority.normal,
                        }}
                        resizeMode={FastImage.resizeMode.contain}
                        style={{
                          width: wp('90%'),
                          height: wp('50%'),
                          borderRadius: 10,
                        }}
                      />
                    )}
                    {isPdfMimetype(uploadedFile.mimetype) && (
                      <FastImage
                        source={{
                          uri: uploadedFile.locationPreview,
                          priority: FastImage.priority.normal,
                        }}
                        resizeMode={FastImage.resizeMode.contain}
                        style={{
                          width: wp('40%'),
                          height: wp('40%'),
                          borderRadius: 10,
                        }}
                      />
                    )}
                  </>
                ) : (
                  <View>
                    <AntIcon
                      name="plus"
                      size={hp('10%')}
                      color={commonColors.primaryColor}
                    />
                    <Text style={classes.addFileText}>Add file</Text>
                  </View>
                )}
              </VStack>
            </TouchableOpacity>
          </HStack>

          <TouchableOpacity
            disabled={loading}
            onPress={onMintClick}
            style={classes.createButton}>
            <VStack justifyContent={'center'} alignItems={'center'} flex={1}>
              {loading ? (
                <ActivityIndicator
                  animating={loading}
                  size="small"
                  color={'white'}
                />
              ) : (
                <Text style={classes.createButtonText}>Upload files</Text>
              )}
            </VStack>
          </TouchableOpacity>
          <View style={classes.checkboxContainer}>
            <CheckBox
              onCheckColor={commonColors.primaryColor}
              onTintColor={commonColors.primaryColor}
              value={distributionRightsApproved}
              onValueChange={setDistributionRightsApproved}
              style={{marginRight: 3, color: commonColors.primaryColor}}
            />
            <Text style={{color: commonColors.primaryColor}}>
              By proceeding I confirm that I have the rights to distribute the
              above content.
            </Text>
          </View>
        </View>
      </ScrollView>
    </KeyboardAwareScrollView>
  );
};

export default UploadDocumentsScreen;

const classes = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'white',
  },
  contentContainer: {
    flex: 1,
    margin: 20,
    marginTop: 0,
  },
  section1: {
    flexDirection: 'row',
    marginTop: 20,
  },

  textStyle: {
    fontFamily: textStyles.lightFont,
    color: commonColors.primaryColor,
    position: 'absolute',
  },
  addFileText: {
    marginTop: 'auto',
    fontFamily: textStyles.lightFont,
    fontSize: hp('2.6%'),
    color: commonColors.primaryColor,
  },
  itemNameInput: {
    color: 'black',
    borderWidth: 1,
    borderColor: commonColors.primaryColor,
    borderRadius: 5,
    flex: 1,
    paddingLeft: 20,
    alignItems: 'flex-start',
    // height: wp('10%'),
    fontFamily: textStyles.lightFont,
    fontSize: hp('1.8%'),
    paddingVertical: Platform.OS === 'ios' ? 10 : 0,
  },
  checkboxContainer: {
    flexDirection: 'row',
    width: wp('80%'),
    alignItems: 'center',
    marginTop: 10,
  },

  createButton: {
    backgroundColor: commonColors.primaryColor,
    borderRadius: 5,
    height: hp('7%'),
    marginTop: 20,
  },
  createButtonText: {
    fontSize: hp('2%'),
    color: '#fff',
    fontFamily: textStyles.regularFont,
  },
  filePreviewContainer: {
    width: wp('90%'),
    height: wp('50%'),
    borderRadius: 10,
    borderColor: commonColors.primaryColor,
    borderWidth: 1,
    marginRight: wp('5%'),
  },
});