Skip to content

Commit

Permalink
autenticação e cores nos inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
savio777 committed Apr 8, 2021
1 parent 8b83e52 commit c5d27f3
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 17 deletions.
5 changes: 4 additions & 1 deletion gobarberApp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"@react-navigation/stack": "^5.14.3",
"@unform/core": "^2.1.6",
"@unform/mobile": "^2.1.6",
"axios": "^0.21.1",
"react": "17.0.1",
"react-native": "0.64.0",
"react-native-gesture-handler": "^1.10.3",
Expand All @@ -23,7 +24,8 @@
"react-native-safe-area-context": "^3.2.0",
"react-native-screens": "^2.18.1",
"react-native-vector-icons": "^8.1.0",
"styled-components": "^5.2.1"
"styled-components": "^5.2.1",
"yup": "^0.32.9"
},
"devDependencies": {
"@babel/core": "^7.12.9",
Expand All @@ -33,6 +35,7 @@
"@types/react-native-vector-icons": "^6.4.6",
"@types/styled-components": "^5.1.9",
"@types/styled-components-react-native": "^5.1.1",
"@types/yup": "^0.29.11",
"@typescript-eslint/eslint-plugin": "^4.20.0",
"@typescript-eslint/parser": "^4.20.0",
"babel-jest": "^26.6.3",
Expand Down
33 changes: 30 additions & 3 deletions gobarberApp/src/components/Input/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ import React, {
useRef,
useImperativeHandle,
forwardRef,
useState,
useCallback,
} from 'react';

import { TextInputProps } from 'react-native';
import Icon from 'react-native-vector-icons/Feather';

import { useField } from '@unform/core';

import { Container, TextInput, Icon } from './styles';
import { Container, TextInput } from './styles';

interface InputProps extends TextInputProps {
name: string;
Expand All @@ -27,11 +31,24 @@ const Input: React.ForwardRefRenderFunction<InputRef, InputProps> = (
{ icon, name, ...rest },
ref,
) => {
const [isFocused, setIsFocused] = useState(false);
const [isFilled, setIsFilled] = useState(false);

const { registerField, defaultValue = '', fieldName, error } = useField(name);

const inputValueRef = useRef<InputValueReference>({ value: defaultValue });
const inputElementRef = useRef<any>(null);

const handleInputFocus = useCallback(() => {
setIsFocused(true);
}, []);

const handleInputBlur = useCallback(() => {
setIsFocused(false);

setIsFilled(!!inputValueRef.current.value);
}, []);

// passar informação do componente filho para o componente pai
useImperativeHandle(ref, () => ({
focus() {
Expand All @@ -58,8 +75,14 @@ const Input: React.ForwardRefRenderFunction<InputRef, InputProps> = (
}, [registerField, fieldName]);

return (
<Container>
{icon && <Icon name={icon} size={20} color="#666360" />}
<Container isFocused={isFocused} isErrored={!!error}>
{icon && (
<Icon
name={icon}
size={20}
color={isFocused || isFilled ? '#ff9000' : '#666360'}
/>
)}

<TextInput
ref={inputElementRef}
Expand All @@ -68,8 +91,12 @@ const Input: React.ForwardRefRenderFunction<InputRef, InputProps> = (
onChangeText={value => {
inputValueRef.current.value = value;
}}
onBlur={handleInputBlur}
onFocus={handleInputFocus}
{...rest}
/>

{error && <Icon name="alert-circle" size={20} color="#c53030" />}
</Container>
);
};
Expand Down
27 changes: 20 additions & 7 deletions gobarberApp/src/components/Input/styles.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
import styled from 'styled-components/native';
import styled, { css } from 'styled-components/native';

import FeatherIcon from 'react-native-vector-icons/Feather';
interface ContainerProps {
isFocused: boolean;
isErrored: boolean;
}

export const Container = styled.View`
export const Container = styled.View<ContainerProps>`
width: 100%;
height: 60px;
padding: 0 16px;
background: #232129;
border-radius: 10px;
margin-bottom: 8px;
border-width: 2px;
border-color: #232129;
flex-direction: row;
align-items: center;
${props =>
props.isErrored &&
css`
border-color: #c53030;
`}
${props =>
props.isFocused &&
css`
border-color: #ff9000;
`}
`;

export const TextInput = styled.TextInput`
flex: 1;
color: #fff;
font-size: 16px;
font-family: 'RobotoSlab-Regular';
`;

export const Icon = styled(FeatherIcon)`
margin-right: 16px;
margin-left: 16px;
`;
45 changes: 43 additions & 2 deletions gobarberApp/src/screens/SignIn/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ import {
KeyboardAvoidingView,
Platform,
TextInput,
Alert,
} from 'react-native';
import Icon from 'react-native-vector-icons/Feather';
import { useNavigation } from '@react-navigation/native';
import { Form } from '@unform/mobile';
import { FormHandles } from '@unform/core';
import * as Yup from 'yup';

import getValidationErrors from '../../utils/getValidationError';

import Input from '../../components/Input';
import Button from '../../components/Button';
Expand All @@ -27,13 +31,50 @@ import {

import logo from '../../assets/logo.png';

interface SignInFormData {
email: string;
password: string;
}

const SignIn: React.FC = () => {
const navigation = useNavigation();
const formRef = useRef<FormHandles>(null);
const passwordInputRef = useRef<TextInput>(null);

const handleSignin = useCallback((data: object) => {
console.log(data);
const handleSignin = useCallback(async (data: SignInFormData) => {
try {
formRef.current?.setErrors({});

const schema = Yup.object().shape({
email: Yup.string()
.required('Email obrigatório')
.email('Digite um email válido'),
password: Yup.string().required('Senha obrigatória'),
});

await schema.validate(data, { abortEarly: false });

// await signIn({ email: data.email, password: data.password });

//navigation.navigate('')
} catch (error) {
if (error instanceof Yup.ValidationError) {
const errors = getValidationErrors(error);
formRef.current?.setErrors(errors);
return;
}

Alert.alert(
'Erro na autenticação',
'Ocorreu um erro ao fazer login, cheque suas credenciais.',
);
/*addToast({
type: 'error',
title: 'Erro na autenticação',
description:
'Ocorreu um erro ao fazer login, cheque suas credenciais.',
});*/
}
}, []);

return (
Expand Down
54 changes: 52 additions & 2 deletions gobarberApp/src/screens/SignUp/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ import {
KeyboardAvoidingView,
Platform,
TextInput,
Alert,
} from 'react-native';
import Icon from 'react-native-vector-icons/Feather';
import { useNavigation } from '@react-navigation/native';
import { Form } from '@unform/mobile';
import { FormHandles } from '@unform/core';
import * as Yup from 'yup';

import api from '../../services/api';
import getValidationErrors from '../../utils/getValidationError';

import Input from '../../components/Input';
import Button from '../../components/Button';
Expand All @@ -25,15 +30,60 @@ import {

import logo from '../../assets/logo.png';

interface SignUpFormData {
name: string;
email: string;
password: string;
}

const SignUp: React.FC = () => {
const navigation = useNavigation();
const formRef = useRef<FormHandles>();

const emailRef = useRef<TextInput>(null);
const passwordRef = useRef<TextInput>(null);

const handleSignUp = useCallback((data: object) => {
console.log(data);
const handleSignUp = useCallback(async (data: SignUpFormData) => {
try {
formRef.current?.setErrors({});

const schema = Yup.object().shape({
name: Yup.string().required('Nome obrigatório'),
email: Yup.string()
.required('Email obrigatório')
.email('Digite um email válido'),
password: Yup.string().min(6, 'No mínimo 6 dígitos'),
});

await schema.validate(data, { abortEarly: false });

await api.post('/users', data);

Alert.alert('Cadastro realizado', 'Você já pode fazer o seu login');
/*addToast({
type: 'success',
title: 'Cadastro realizado',
description: 'Você já pode fazer o seu login',
});*/

navigation.goBack();
} catch (error) {
if (error instanceof Yup.ValidationError) {
const errors = getValidationErrors(error);
formRef.current?.setErrors(errors);
return;
}

Alert.alert(
'Erro no cadastro',
'Ocorreu um erro ao fazer cadastro, tente novamente',
);
/*addToast({
type: 'error',
title: 'Erro no cadastro',
description: 'Ocorreu um erro ao fazer cadastro, tente novamente',
});*/
}
}, []);

return (
Expand Down
5 changes: 5 additions & 0 deletions gobarberApp/src/services/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import axios from 'axios';

const api = axios.create({ baseURL: 'http://localhost:3333' });

export default api;
17 changes: 17 additions & 0 deletions gobarberApp/src/utils/getValidationError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ValidationError } from 'yup';

interface Errors {
[key: string]: string;
}

export default function getValidationErrors(error: ValidationError): Errors {
const valodationErrors: Errors = {};

// path: nome do campo do input
// message: erro da mensagem
error.inner.forEach(err => {
if (err.path) valodationErrors[err?.path] = err.message;
});

return valodationErrors;
}
Loading

0 comments on commit c5d27f3

Please sign in to comment.