Skip to content

Instantly share code, notes, and snippets.

@IgorDePaula
Created July 25, 2020 17:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IgorDePaula/f859fc65e6c90826528320e816232077 to your computer and use it in GitHub Desktop.
Save IgorDePaula/f859fc65e6c90826528320e816232077 to your computer and use it in GitHub Desktop.
import React, {Component, Context, useState, useContext} from 'react';
import {
ActivityIndicator,
KeyboardAvoidingView,
ScrollView,
StyleSheet,
Text,
View,
} from 'react-native';
import {Button, TextInput} from 'react-native-paper';
import {Formik} from 'formik';
import {AuthContext} from '../../Context';
import * as Yup from 'yup';
import {post} from '../../http';
import {CardContext} from '../../Context/card';
const onlyNumbers = value => value.replace(/\D/g, '');
const formataCartao = value => {
return value
? onlyNumbers(value)
.replace(/(\d{4})(\d)/, '$1 $2')
.replace(/(\d{4})(\d)/, '$1 $2')
.replace(/(\d{4})(\d)/, '$1 $2')
.replace(/(\d{4})\d+?$/, '$1')
: '';
};
const formataMesAno = value => {
return value
? onlyNumbers(value)
.replace(/(\d{2})(\d)/, '$1/$2')
.replace(/(\d{2})\d+?$/, '$1')
: '';
};
const LoginSchema = Yup.object().shape({
cvv: Yup.string().required('O codigo de seguranca é obrigatorio!'),
expiration_date: Yup.string().required(
'A data de vencimento é obrigatoria, no formato mm/aa!',
),
number: Yup.string().required('O numero do cartao é obrigatorio'),
holder_name: Yup.string().required('O nome impresso no cartao é obrigatorio'),
});
const AddCard = ({navigation}) => {
const [user] = useContext(AuthContext);
const [cards, setCards] = useContext(CardContext);
const [loading, setLoading] = useState(false);
/**
* 'holder_name' => $request->holder_name,
'number' => $request->number,
'expiration_date' => $date,
'cvv' => $request->cvv
*/
return (
<>
<KeyboardAvoidingView style={{flex: 1}} behavior={'padding'}>
<ScrollView
contentContainerStyle={{flexGrow: 1}}
keyboardShouldPersistTaps={'handled'}>
<Formik
initialValues={{
holder_name: '',
number: '',
cvv: '',
expiration_date: '',
}}
validationSchema={LoginSchema}
onSubmit={values => {
setLoading({loading: true});
values.client = user.id;
post('/user/create_card', values, user.api_token)
.then(res => res.json())
.then(resp => {
setLoading({loading: false});
setCards([...cards, resp])
user.cards.push(resp);
alert('Cartao adicionado com sucesso!');
console.log('add card resp', resp);
console.log('add card user cards', user.cards);
this.navigation.navigate('Payment');
})
.catch(err => {
setLoading({loading: false});
alert('Email/senha invalidos!');
});
}}>
{({
handleChange,
handleBlur,
handleSubmit,
values,
errors,
setFieldValue,
}) => (
<View style={styles.container}>
<Text style={[styles.marginBotton, styles.title]}>
Adicione um novo cartão abaixo:
</Text>
{errors && (
<Text style={[styles.marginBotton, styles.error]}>
{errors.number}
</Text>
)}
{errors && (
<Text style={[styles.marginBotton, styles.error]}>
{errors.cvv}
</Text>
)}
{errors && (
<Text style={[styles.marginBotton, styles.error]}>
{errors.holder_name}
</Text>
)}
{errors && (
<Text style={[styles.marginBotton, styles.error]}>
{errors.expiration_date}
</Text>
)}
<TextInput
mode="outlined"
onChangeText={handleChange('holder_name')}
onBlur={handleBlur('holder_name')}
value={values.holder_name}
label="Nome impresso no cartao"
style={[styles.marginBotton, styles.textInput]}
/>
<TextInput
mode="outlined"
onChangeText={value => {
let val = formataCartao(value);
setFieldValue('number', val);
}}
onBlur={handleBlur('number')}
value={values.number}
label="Numero do cartao"
style={[styles.marginBotton, styles.textInput]}
/>
<TextInput
mode="outlined"
onChangeText={value => {
let val = formataMesAno(value);
setFieldValue('expiration_date', val);
}}
onBlur={handleBlur('expiration_date')}
value={values.expiration_date}
label="Vencimento do cartao (mm/aa)"
style={[styles.marginBotton, styles.textInput]}
/>
<TextInput
mode="outlined"
onChangeText={value => {
let val = value ? onlyNumbers(value) : '';
setFieldValue('cvv', val);
}}
onBlur={handleBlur('cvv')}
value={values.cvv}
label="Codigo de seguranca"
style={[styles.marginBotton, styles.textInput]}
/>
<Button
loading={loading}
mode="contained"
style={styles.marginBotton}
onPress={handleSubmit}>
Adicionar
</Button>
</View>
)}
</Formik>
</ScrollView>
</KeyboardAvoidingView>
</>
);
};
export default AddCard;
const styles = StyleSheet.create({
container: {
paddingTop: 20,
paddingLeft: 10,
paddingRight: 10,
paddingBottom: 20,
alignItems: 'center',
},
marginBotton: {
marginBottom: 15,
},
title: {
fontSize: 24,
alignContent: 'center',
},
textInput: {
width: '100%',
},
error: {
color: 'red',
fontSize: 16,
},
});
import React, {createContext, useState} from 'react';
export const CardContext = createContext();
export const CardProvider = ({children}) => {
const [cards, setCards] = useState([]);
return (
<CardContext.Provider value={[cards, setCards]}>
{children}
</CardContext.Provider>
);
};
import React, {useContext, useEffect, useState} from 'react';
import {StyleSheet, Text, View, Image} from 'react-native';
import {AuthContext} from '../../Context';
import {get, post} from '../../http';
import {Button} from 'react-native-paper';
import {createStackNavigator} from '@react-navigation/stack';
import Login from '../../intro/Login';
import Register from '../../intro/Register';
import Forget from '../../intro/Forget';
import AppInto from '../index';
import {DrawerActions} from '@react-navigation/routers';
import AddCard from './AddCard';
import {CardContext} from '../../Context/card';
const brands = {
visa: require('../../images/visa.jpg'),
'american-express': require('../../images/ae.jpg'),
dinners: require('../../images/diners.jpg'),
elo: require('../../images/elo.jpg'),
mastercard: require('../../images/master.jpg'),
};
const Payment = ({navigation}) => {
const [user] = useContext(AuthContext);
const [loading, setLoading] = useState(false);
const [propostas, setPropostas] = useState([]);
useEffect(() => {
get('/me/proposals', null, user.api_token)
.then(res => res.json())
.then(res => console.log(res))
.catch(e => console.error(e));
});
return (
<View style={styles.container}>
{user.role_id == 2 && <PaymentDriver />}
{user.role_id == 3 && <PaymentClient navigation={navigation} />}
</View>
);
};
const PaymentClient = props => {
const [user] = useContext(AuthContext);
const [cards, setCards] = useContext(CardContext);
const [loading, setLoading] = useState(false);
setCards(user.cards);
return (
<View style={styles.container}>
{cards.length == 0 && <Text>Nenhuma Forma de pagamento cadastrada</Text>}
<Text>{JSON.stringify(cards)}</Text>
{cards.length > 0 &&
cards.map(item => (
<View key={item.id} style={styles.card}>
<Image source={brands[item.card_brand]} />
<Text style={styles.text}>{item.card_hidden_numbers}</Text>
</View>
))}
<Button
onPress={() => props.navigation.navigate('AddCard')}
mode="contained">
Adicionar cartão
</Button>
</View>
);
};
const PaymentDriver = () => {
const [user] = useContext(AuthContext);
const [propostas, setPropostas] = useState([]);
useEffect(() => {
get('/me/proposals', null, user.api_token)
.then(res => res.json())
.then(res => {
setPropostas(res);
});
}, []);
return (
<View style={styles.container}>
<Text style={styles.textDriver}>
Dia de transferencia: {user.transfer_day}
</Text>
<Text style={styles.textDriver}>Total de ganhos do mes:</Text>
<Text style={styles.textDriver}>
R${' '}
{propostas
.map(item => {
let value = (item.value * 89) / 100;
return value;
})
.reduce((total, cur) => {
total += cur;
return total;
}, 0)}
</Text>
</View>
);
};
const Stack = createStackNavigator();
const Nav = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="Payment"
options={{title: 'Pagamento'}}
component={Payment}
/>
<Stack.Screen
name="AddCard"
options={{title: 'Novo Cartão'}}
component={AddCard}
/>
</Stack.Navigator>
);
};
export default Nav;
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
},
textDriver: {
fontSize: 20,
},
text: {
fontSize: 30,
},
card: {
margin: 5,
backgroundColor: '#FFF',
width: '95%',
height: 120,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 1,
},
shadowOpacity: 0.22,
shadowRadius: 2.22,
elevation: 3,
marginBottom: 25,
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment