Source

src/components/Auth/Registration/RegisterMain.tsx

import React, { useEffect, useState } from 'react';
import { Alert, Dimensions, StyleSheet, View } from 'react-native';
import 'react-native-get-random-values';
import { Text } from 'react-native-paper';
import { useRegistrationFormState } from '../../../contexts/RegisterContext';
import { AuthStackNavigationProp } from '../../../navigation/UnauthorizedNavigator';
import UnauthorizedLayout from '../AuthLayout';
import RegisterCredentials from './RegisterCredential';
import RegisterImage from './RegisterImage';
import RegisterMeasurements from './RegisterMeasurements';
import RegisterPassword from './RegisterPassword';
import RegisterResult from './RegistrationResult';

/**
 * {@link RegisterMain} component props.
 */
export interface RegisterProps {
  /**The navigation object used to interact with the {@link Auth} navigator.*/
  navigation: AuthStackNavigationProp
}

export interface RegisterStepProps {
  changeStep: (stepNumber: number, stepSubtitleText: string) => void;
  setFormValues: (formValues: RegisterFormValues) => void
  formValues: RegisterFormValues
}

export interface RegisterFormValues {
  username?: string;
  email?: string;
  password?: string;
  confirmPassword?: string;
  sagitta?: false
  height?: string;
  weight?: string;
}

/**
 * The main registration component. Acts as a backdrop for all intermediate registration steps.
 * @category Unauthorized
 * @subcategory Registration
 * @component
 */
export const RegisterMain : React.FC<RegisterProps> = ({navigation}) => {
  
  /**Holds an integer value that maps to a step in the registration process. 
   * The mapping is as follows:
   * - 1 -> Username and Email 
   * - 2 -> Password
   * - 3 -> Sagitta and Measurements
   * - 4 -> Profile picture and submission
   * - 5 -> Result
   */
  const stepState = 1;
  const [step, setStep] = useState(stepState);
  /**
   * Holds the current subtitle text.
   */
  const subTitleState = "Let's start with some basic account information.";
  const [subtitle, setSubtitle] = useState<string>(subTitleState);
  const [formValues, setFormValues] = useState<RegisterFormValues>({}); 

  useEffect(() => {
      /**
       * Handler that intercepts a request to leave the registration screen and asks the user to confirm that they want to leave.
       * If they confirm they want to leave, all registration state will reset and the user will be directed back to {@link Intro}.
       * @memberOf RegisterMain
       */
      const preventExitFromRegistration = navigation.addListener('beforeRemove', (e) => {
        if (step != 5) {    
        e.preventDefault();
        
        Alert.alert(
          'Going so soon?',
          'Are you sure you want to cancel registration?',
          [
            { text: "Don't leave", style: 'cancel', onPress: () => {} },
            {
              text: 'Discard',
              style: 'destructive',
              onPress: () => {
                setFormValues({});
                navigation.dispatch(e.data.action)
              },
            },
          ]
        );
      }})
      return preventExitFromRegistration;
    }, [navigation, step]);

  /**
   * Changes the registration step to the given value.
   */
  const changeStep = (step: any, subtitle: any) => {
    setStep(step);
    setSubtitle(subtitle);
  }

  /**
   * Returns to the intro screen.
   */
  const finish = () => {
    navigation.pop();
  }

  return (
    <UnauthorizedLayout>
      <View style={styles.brandContainer}>
        {step != 5 ?
        <Text style={styles.title} >Welcome!</Text> : null}
        <Text style={styles.subtitle}>{subtitle}</Text>
      </View>
      <View>
        {step == 1 ? <RegisterCredentials setFormValues={setFormValues} formValues={formValues} changeStep={changeStep}/> : 
          step == 2 ? <RegisterPassword setFormValues={setFormValues} formValues={formValues} changeStep={changeStep}/> : 
          step == 3 ? <RegisterMeasurements setFormValues={setFormValues} formValues={formValues} changeStep={changeStep}/> : 
          step == 4 ? <RegisterImage setFormValues={setFormValues} formValues={formValues} changeStep={changeStep} /> :
          step == 5 ? <RegisterResult finish={finish}/> : null}
      </View>
    </UnauthorizedLayout>
  )
}

const styles = StyleSheet.create({
  container: {
    position: 'absolute',
    width: Dimensions.get('window').width,
    height: Dimensions.get('window').height,
    flex: 1,
    justifyContent: 'flex-start',
    resizeMode: 'cover',
  },
  brandContainer: {
    marginTop: 60,  
    marginHorizontal: 25,
    flexDirection: 'column',
    justifyContent: 'space-evenly'
  },
  title: {
    color: 'white',
    fontSize: 20
  },

  subtitle: {
    color: 'white',
    fontSize: 15,
    marginTop: 20
  },
});