Skip to content

Commit

Permalink
feature: auth token
Browse files Browse the repository at this point in the history
  • Loading branch information
w-arantes committed Mar 24, 2020
1 parent 391ccc8 commit a5e50bf
Show file tree
Hide file tree
Showing 18 changed files with 432 additions and 74 deletions.
15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "gobarber-web",
"version": "0.1.0",
"private": true,
"license": "MIT",
"dependencies": {
"@rocketseat/unform": "^1.6.2",
"axios": "^0.19.2",
Expand All @@ -18,12 +19,12 @@
"react-redux": "^7.2.0",
"react-router-dom": "^5.0.1",
"react-scripts": "3.0.1",
"react-toastify": "^5.3.2",
"react-toastify": "^5.5.0",
"reactotron-react-js": "^3.3.2",
"reactotron-redux": "^3.1.2",
"reactotron-redux-saga": "^4.2.3",
"redux": "^4.0.5",
"redux-persist": "^5.10.0",
"redux-persist": "^6.0.0",
"redux-saga": "^1.1.3",
"styled-components": "^4.3.2",
"yup": "^0.28.3"
Expand Down Expand Up @@ -52,15 +53,15 @@
"devDependencies": {
"babel-plugin-root-import": "^6.2.0",
"customize-cra": "^0.2.14",
"eslint": "^5.16.0",
"eslint-config-airbnb": "^17.1.1",
"eslint": "^6.8.0",
"eslint-config-airbnb": "^18.1.0",
"eslint-config-prettier": "^6.0.0",
"eslint-import-resolver-babel-plugin-root-import": "^1.1.1",
"eslint-plugin-import": "^2.18.0",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-react": "^7.14.2",
"eslint-plugin-react-hooks": "^1.6.1",
"eslint-plugin-react": "^7.19.0",
"eslint-plugin-react-hooks": "^2.5.1",
"prettier": "^1.18.2",
"react-app-rewired": "^2.1.3"
}
Expand Down
15 changes: 10 additions & 5 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import React from 'react';
import { ToastContainer } from 'react-toastify';
import { PersistGate } from 'redux-persist/integration/react';
import { Provider } from 'react-redux';
import { Router } from 'react-router-dom';

Expand All @@ -7,17 +9,20 @@ import './config/ReactotronConfig';
import Routes from './routes';
import history from './services/history';

import store from './store';
import { store, persistor } from './store';

import GlobalStyle from './styles/global';

function App() {
return (
<Provider store={store}>
<Router history={history}>
<Routes />
<GlobalStyle />
</Router>
<PersistGate persistor={persistor}>
<Router history={history}>
<Routes />
<GlobalStyle />
<ToastContainer autoClose={3000} />
</Router>
</PersistGate>
</Provider>
);
}
Expand Down
2 changes: 2 additions & 0 deletions src/pages/Dashboard/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';
import api from '~/services/api';

// import { Container } from './styles';

export default function Dashboard() {
api.get('appointments');
return <h1>Dashboard</h1>;
}
5 changes: 3 additions & 2 deletions src/pages/SignIn/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { useDispatch } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
import { Form, Input } from '@rocketseat/unform';
import * as Yup from 'yup';
Expand All @@ -19,6 +19,7 @@ const schema = Yup.object().shape({

export default function SignIn() {
const dispatch = useDispatch();
const loading = useSelector(state => state.auth.loading);

function handleSubmit({ email, password }) {
dispatch(signInRequest(email, password));
Expand All @@ -36,7 +37,7 @@ export default function SignIn() {
placeholder="Sua senha secreta"
/>

<button type="submit">Acessar</button>
<button type="submit">{loading ? 'Carregando...' : 'Acessar'}</button>
<Link to="/register">Criar conta gratuita</Link>
</Form>
</>
Expand Down
13 changes: 9 additions & 4 deletions src/pages/SignUp/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import React from 'react';
import { useDispatch } from 'react-redux';
import { Link } from 'react-router-dom';
import { Form, Input } from '@rocketseat/unform';
import * as Yup from 'yup';

import logo from '~/assets/logo.svg';

import { signUpRequest } from '~/store/modules/auth/actions';

const schema = Yup.object().shape({
nome: Yup.string().required('O nome é obrigatório.'),
name: Yup.string().required('O nome é obrigatório.'),
email: Yup.string()
.email('Insira um e-mail válido.')
.required('O e-mail é obrigatório.'),
Expand All @@ -16,16 +19,18 @@ const schema = Yup.object().shape({
});

export default function SignUp() {
function handleSubmit(data) {
console.tron.log(data);
const dispatch = useDispatch();

function handleSubmit({ name, email, password }) {
dispatch(signUpRequest(name, email, password));
}

return (
<>
<img src={logo} alt="GoBarber" />

<Form schema={schema} onSubmit={handleSubmit}>
<Input name="nome" placeholder="Nome Completo" />
<Input name="name" type="text" placeholder="Nome Completo" />
<Input name="email" type="email" placeholder="Seu e-mail" />
<Input
name="password"
Expand Down
2 changes: 1 addition & 1 deletion src/routes/Route.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Route, Redirect } from 'react-router-dom';
import AuthLayout from '~/pages/_layouts/auth';
import DefaultLayout from '~/pages/_layouts/default';

import store from '~/store';
import { store } from '~/store';

export default function RouteWrapper({
component: Component,
Expand Down
8 changes: 6 additions & 2 deletions src/store/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { persistStore } from 'redux-persist';
import createSagaMiddleware from 'redux-saga';

import createStore from './createStore';
import persistReducers from './persistReducers';

import rootReducer from './modules/rootReducer';
import rootSaga from './modules/rootSaga';
Expand All @@ -13,8 +16,9 @@ const sagaMiddleware = createSagaMiddleware({ sagaMonitor });

const middlewares = [sagaMiddleware];

const store = createStore(rootReducer, middlewares);
const store = createStore(persistReducers(rootReducer), middlewares);
const persistor = persistStore(store);

sagaMiddleware.run(rootSaga);

export default store;
export { store, persistor };
7 changes: 7 additions & 0 deletions src/store/modules/auth/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ export function signInSuccess(token, user) {
};
}

export function signUpRequest(name, email, password) {
return {
type: '@auth/SIGN_UP_REQUEST',
payload: { name, email, password },
};
}

export function signFailure() {
return {
type: '@auth/SIGN_FAILURE',
Expand Down
25 changes: 18 additions & 7 deletions src/store/modules/auth/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,24 @@ const INITIAL_STATE = {
};

export default function auth(state = INITIAL_STATE, action) {
switch (action.type) {
case '@auth/SIGN_IN_SUCCESS':
return produce(state, draft => {
return produce(state, draft => {
switch (action.type) {
case '@auth/SIGN_IN_REQUEST': {
draft.loading = true;
break;
}
case '@auth/SIGN_IN_SUCCESS': {
draft.token = action.payload.token;
draft.signed = true;
});
default:
return state;
}
draft.loading = false;
break;
}
case '@auth/SIGN_FAILURE': {
draft.loading = false;
break;
}
default:
return state;
}
});
}
69 changes: 55 additions & 14 deletions src/store/modules/auth/sagas.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,69 @@
import { takeLatest, call, put, all } from 'redux-saga/effects';
import { toast } from 'react-toastify';

import history from '~/services/history';
import api from '~/services/api';
import history from '~/services/history';

import { signInSuccess } from './actions';
import { signInSuccess, signFailure } from './actions';

export function* signIn({ payload }) {
const { email, password } = payload;
try {
const { email, password } = payload;

const response = yield call(api.post, 'sessions', {
email,
password,
});

const { token, user } = response.data;

if (!user.provider) {
toast.error('O usuário não é prestador de serviço.');
return;
}

api.defaults.headers.Authorization = `Bearer ${token}`;

yield put(signInSuccess(token, user));

const response = yield call(api.post, 'sessions', {
email,
password,
});
history.push('/dashboard');
} catch (err) {
toast.error('Falha na autenticação, verifique seus dados de acesso.');
yield put(signFailure());
}
}

export function* signUp({ payload }) {
try {
const { name, email, password } = payload;

yield call(api.post, 'users', {
name,
email,
password,
provider: true,
});

const { token, user } = response.data;
history.push('/');
} catch (err) {
toast.error('Falha no cadastro, verifique seus dados!');

if (!user.provider) {
console.tron.error('O usuário não é prestador de serviço.');
return;
yield put(signFailure());
}
}

export function setToken({ payload }) {
if (!payload) return;

yield put(signInSuccess(token, user));
const { token } = payload.auth;

history.push('/dashboard');
if (token) {
api.defaults.headers.Authorization = `Bearer ${token}`;
}
}

export default all([takeLatest('@auth/SIGN_IN_REQUEST', signIn)]);
export default all([
takeLatest('persist/REHYDRATE', setToken),
takeLatest('@auth/SIGN_IN_REQUEST', signIn),
takeLatest('@auth/SIGN_UP_REQUEST', signUp),
]);
2 changes: 2 additions & 0 deletions src/store/modules/rootReducer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { combineReducers } from 'redux';

import auth from './auth/reducer';
import user from './user/reducer';

export default combineReducers({
auth,
user,
});
3 changes: 2 additions & 1 deletion src/store/modules/rootSaga.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { all } from 'redux-saga/effects';

import auth from './auth/sagas';
import user from './user/sagas';

export default function* rootSaga() {
return yield all([auth]);
return yield all([auth, user]);
}
Empty file.
16 changes: 16 additions & 0 deletions src/store/modules/user/reducer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import produce from 'immer';

const INITIAL_STATE = {
profile: null,
};

export default function user(state = INITIAL_STATE, action) {
switch (action.type) {
case '@auth/SIGN_IN_SUCCESS':
return produce(state, draft => {
draft.profile = action.payload.user;
});
default:
return state;
}
}
3 changes: 3 additions & 0 deletions src/store/modules/user/sagas.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { all } from 'redux-saga/effects';

export default all([]);
15 changes: 15 additions & 0 deletions src/store/persistReducers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import storage from 'redux-persist/lib/storage';
import { persistReducer } from 'redux-persist';

export default reducers => {
const persistedReducer = persistReducer(
{
key: 'gobarber',
storage,
whitelist: ['auth', 'user'],
},
reducers
);

return persistedReducer;
};
2 changes: 2 additions & 0 deletions src/styles/global.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { createGlobalStyle } from 'styled-components';

import 'react-toastify/dist/ReactToastify.css';

export default createGlobalStyle`
@import url('https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap');
Expand Down
Loading

0 comments on commit a5e50bf

Please sign in to comment.