# Code coverage report for atlas-mobile-ts/src/components/Auth/RegistrationSteps/RegisterImage.tsx

# All files / atlas-mobile-ts/src/components/Auth/RegistrationSteps RegisterImage.tsx

0% Statements 0/48
0% Branches 0/10
0% Functions 0/8
0% Lines 0/47

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
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136

     ﻿/* Copyright (C) Click & Push Accessibility, Inc - All Rights Reserved
     * Unauthorized copying of this file, via any medium is strictly prohibited
     * Proprietary and confidential
     * Written and maintained by the Click & Push Development team
     * <dev@clicknpush.ca>, January 2022
     */

    import axios from 'axios';
    import React, { useState } from 'react';
    import { Image, TouchableOpacity, View } from 'react-native';
    import 'react-native-get-random-values';
    import { ActivityIndicator, Text } from 'react-native-paper';
    import { API_URL, reportAxiosError } from '../../../utils/RequestUtils';
    import { PrimaryButton, SecondaryButton } from '../../Buttons';
    import { PhotoPicker } from '../../PhotoPicker';
    import { Separator } from '../../Separator';
    import { RegisterStepProps } from '../RegisterMain';

    /**
     * This component displays an interface to upload a profile picture
     */
    const RegisterImage: React.FC<RegisterStepProps> = ({changeStep, formValues}) => {
      /**
       * Stores the base64 of the user's selected profile pic
       */
      const [photoBase64, setPhotoBase64] = useState<string>();
      /**
       * This flag is set to true when the registration submission is being processed. An activity spinner will display while it is true
       */
      const [loadingSubmission, toggleLoading] = useState<boolean>(false);
      /**
       * This flag toggles the menu that is used to choose a photo source (Library or Camera).
       */
      const [photoSourceMenuOpened, togglePhotoSourceMenu] = useState<boolean>(false)

      /**
         * Reverse back to measurements step
         */
      const back = () => {
        console.log("[Registration]: Registration form values updated")
        changeStep(3, "Will you be using a Sagitta?")
      }

      /**
       * Prepares and sends a registration request to the api
       */
      const register = async () => {
        // toggle the loading flag and change status
        toggleLoading(true);
        changeStep(4, 'Hang tight for a moment while we create your account.')

        // create FormData and send request
        const formData = prepareFormData()
        await sendRegisterRequest(formData)
      }

      // Returns a FormData object containing all the form values from each registration step, including the image (in b64) chosen on this step
      const prepareFormData = (): FormData =>  {
        console.log("[Registration]: Preparing form data...")
        let formData = new FormData();
        let processedFormValues;
        if (formValues.height && formValues.weight) {
          processedFormValues = {...formValues, height: parseFloat(formValues.height), weight: parseFloat(formValues.weight)}
        }
        else {
          processedFormValues = {
            email: formValues.email,
            username: formValues.username,
            password: formValues.password,
          };
        }
        formData.append('userInfo', JSON.stringify(processedFormValues));
        formData.append('avatar', 'data:image/png;base64,' + photoBase64);

        console.log("[Registration]: Form data prepared")
        return formData
      }

      const sendRegisterRequest = async (formData: FormData) => {
        // initialize registration result message
        let resultMessage = '';

        console.log("[Registration]: Sending registration request...")
        // send request, notify user of result

        try {
          const response = await axios({
            method: 'post',
            url: API_URL + '/api/register/',
            timeout: 50000,
            data: formData,
          });
          if (response.status == 200) {
            resultMessage = 'Success! Congratulations on registering for your new account, you can now login!';
          }
          else {
            resultMessage = 'Something went wrong when trying to set up your account. Please try again.'; // TODO: add contact details?
          }

        } catch (error) {
          resultMessage = 'Something went wrong when trying to set up your account. Please try again.'; // TODO: add contact details?
          reportAxiosError('Something went wrong with user registration', error);
        }
        toggleLoading(false);
        changeStep(5, resultMessage);
      }

      return (
        <View>
          { !loadingSubmission ?
          <View>
            <TouchableOpacity onPress={() => togglePhotoSourceMenu(true)} style={{justifyContent: 'center', }}>
              { photoBase64 != null ?
              <Image style={{alignSelf: 'center', borderRadius: 100, width: 200, height: 200, marginBottom: 5, marginTop: 30,}} source={{uri: 'data:image/png;base64,' + photoBase64}} /> :
              <Image style={{alignSelf: 'center', borderRadius: 100, width: 200, height: 200, marginBottom: 5, marginTop: 30,}} source={require('../../../../assets/default-pfp.png')} />
              }
              <Text style={{alignSelf: 'center', marginVertical: 20, color: 'white'}}>Choose photo</Text>
            </TouchableOpacity>
            <View style={{margin: 20}}>
              <Separator color="lightgray" />
              <PrimaryButton text="Register" onPress={register} style={{marginVertical: 20}} />
              <SecondaryButton text="Back" onPress={back} style={{marginBottom: 20}} />
            </View>
          </View>
          :
          <View>
              <ActivityIndicator style={{marginTop: 200}} size="large" animating={true} color="red"/>
          </View>}
          <PhotoPicker menuType='alert' multiple={false} photoSourceMenuOpened={photoSourceMenuOpened} cancel={() => togglePhotoSourceMenu(false)} onReceivedPhotoResult={result => setPhotoBase64(result.base64)}/>
        </View>

      )
    }

    export default RegisterImage;