Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
6.1 kB
2
Indexable
Never
import {Input} from '@components/common/inputs';
import PrimaryButton from '@components/common/PrimaryButton';
import PaywallDesc from '@components/screens/Paywall/PaywallDesc';
import PaywallHeader from '@components/screens/Paywall/PaywallHeader';
import {useNavigation, useRoute} from '@react-navigation/native';
import {updateUser} from '@reduxs/reducers/auth-reducer';
import paywallApi from '@services/api/paywall-api';
import {CardField, useStripe} from '@stripe/stripe-react-native';
import {Colors, Typography} from '@themes';
import Dimension from '@utils/Dimension';
import {FormikProvider, useFormik} from 'formik';
import _ from 'lodash';
import React, {useRef, useState} from 'react';
import {
  Alert,
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import {useDispatch} from 'react-redux';
import * as Yup from 'yup';

const paywallScheme = Yup.object().shape({
  name: Yup.string().required('Please fill this field'),
});

const PaywallDetails = () => {
  const {createToken, createPaymentMethod} = useStripe();
  const [cardDetails, setCardDetails] = useState(null);
  const buttonRef = useRef(null);
  const dispatch = useDispatch();
  const {params} = useRoute();
  const {goBack} = useNavigation();

  const paywallFormik = useFormik({
    initialValues: {
      name: '',
    },
    onSubmit: async values => {
      buttonRef.current?.setProcess(true);
      const response = await createToken({
        type: 'Card',
        name: values?.name,
      });
      if (response?.error) {
        buttonRef.current?.setProcess(false);
        Alert.alert('Error', response?.error.message);
        return;
      }
      const res = await createPaymentMethod({
        paymentMethodType: 'Card',
        paymentMethodData: {
          token: response.token?.id,
          billingDetails: {
            name: values?.name,
          },
        },
      });
      if (res?.errorPayment) {
        buttonRef.current?.setProcess(false);
        Alert.alert('Error', res?.errorPayment.message);
        return;
      }
      paywallApi.createSubscription(
        {
          name: params.plan?.name,
          payment_method: res?.paymentMethod?.id,
          plan_id: params.plan?.plan_id,
          _token: response.token?.id,
        },
        result => {
          let status = _.get(result, 'data.stripe_status', null);
          buttonRef.current?.setProcess(false);

          if (status) {
            Alert.alert('Success', 'Payment Successfully', [
              {
                text: 'Confirm',
                onPress: () => {
                  dispatch(
                    updateUser({
                      status,
                    }),
                  );
                },
              },
            ]);
          }
        },
        e => {
          Alert.alert('Error', e?.message || 'Payment Failed');
          buttonRef.current?.setProcess(false);
        },
      );
    },
    validationSchema: paywallScheme,
    validateOnMount: true,
    enableReinitialize: true,
  });

  const onCardChange = cardDetails => {
    setCardDetails(cardDetails);
  };

  const {top} = useSafeAreaInsets();
  const disabled =
    _.isEmpty(paywallFormik.errors) &&
    cardDetails?.validCVC === 'Valid' &&
    cardDetails?.validExpiryDate === 'Valid' &&
    cardDetails?.validNumber === 'Valid';

  return (
    <FormikProvider value={paywallFormik}>
      <ScrollView
        style={{flex: 1, backgroundColor: Colors.white}}
        contentContainerStyle={{paddingTop: top, paddingBottom: 60}}>
        <PaywallHeader />
        <Text style={styles.title}>
          PAYMENT <Text style={{color: Colors.brand2}}>DETAILS</Text>
        </Text>
        <View style={styles.formView}>
          <Input
            fieldName={'name'}
            title={'Cardholder Name'}
            formikGetProps={paywallFormik.getFieldProps('name')}
            style={styles.inputStyle}
          />

          <Text style={styles.titleText}>Card Number</Text>
          <CardField
            postalCodeEnabled={false}
            style={styles.cardField}
            cardStyle={styles.cardStyle}
            onCardChange={onCardChange}
          />
          <View style={styles.buttonView}>
            <TouchableOpacity onPress={goBack} style={styles.cancelButton}>
              <Text style={styles.textCancel}>Cancel</Text>
            </TouchableOpacity>
            <PrimaryButton
              ref={buttonRef}
              title="Continue"
              style={styles.buttonContinue}
              labelStyle={{fontWeight: '400'}}
              onPress={paywallFormik.handleSubmit}
              disabled={!disabled}
              isShowProcess
            />
          </View>
        </View>

        <PaywallDesc />
      </ScrollView>
    </FormikProvider>
  );
};

export default PaywallDetails;

const styles = StyleSheet.create({
  title: {
    ...Typography.essonnes.regular,
    fontSize: 26,
    alignSelf: 'center',
    textAlign: 'center',
    lineHeight: 30,
    marginTop: 24,
  },
  inputStyle: {
    marginBottom: 8,
  },
  titleText: {
    ...Typography.lato.regular,
    color: Colors.greyScale2,
    fontSize: 14,
    lineHeight: 16,
  },
  formView: {
    marginHorizontal: 20,
    borderWidth: 1,
    paddingHorizontal: 24,
    paddingTop: 16,
    paddingBottom: 28,
    borderRadius: 3,
    borderColor: Colors.greyScale4,
    marginTop: Dimension.verticalScale(24),
  },
  cardField: {
    marginTop: 8,
    height: 50,
    width: '100%',
  },
  cardStyle: {
    backgroundColor: Colors.greyScale6,
    borderWidth: 1,
    textColor: Colors.greyScale1,
  },
  buttonView: {
    flexDirection: 'row',
    justifyContent: 'flex-end',
    marginTop: 24,
  },
  cancelButton: {
    height: 40,
    justifyContent: 'center',
    paddingHorizontal: 20,
    marginRight: 12,
  },
  textCancel: {
    ...Typography.lato.regular,
    fontSize: 14,
  },
  buttonContinue: {
    height: 40,
    width: 100,
    justifyContent: 'center',
    alignItems: 'center',
  },
});