From 55c02761a4d05543f1299e0445d8873a12ea5692 Mon Sep 17 00:00:00 2001 From: Stepan Usatiuk Date: Sat, 9 Jun 2018 16:05:26 +0300 Subject: [PATCH] use redux-offline --- react/package-lock.json | 19 ++++++++++ react/package.json | 1 + react/src/actions/lists.js | 19 ++-------- react/src/actions/todos.js | 10 ++--- react/src/actions/user.js | 19 +++------- react/src/actions/util.js | 13 ++++--- react/src/components/Header.js | 6 +-- react/src/components/UserHeader.js | 15 ++++++++ react/src/components/user/UserErrors.js | 2 +- react/src/containers/FetchButton.js | 41 +++++++++++++++++++++ react/src/containers/LogoutLink.js | 2 - react/src/containers/Status.js | 34 +++++++++++++++++ react/src/containers/UserHeaderContainer.js | 10 +++++ react/src/index.js | 32 ++++++++++++---- 14 files changed, 170 insertions(+), 53 deletions(-) create mode 100644 react/src/components/UserHeader.js create mode 100644 react/src/containers/FetchButton.js create mode 100644 react/src/containers/Status.js create mode 100644 react/src/containers/UserHeaderContainer.js diff --git a/react/package-lock.json b/react/package-lock.json index 8157833..6e6774f 100644 --- a/react/package-lock.json +++ b/react/package-lock.json @@ -61,6 +61,15 @@ "recompose": "^0.26.0 || ^0.27.0" } }, + "@redux-offline/redux-offline": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@redux-offline/redux-offline/-/redux-offline-2.3.3.tgz", + "integrity": "sha512-uv0DW9ZAFzL+lc7WzjQoDoWydReJiZe+Rpz6suGCS5ux+ZJWkr3jpRzeWlTW149uo+OrEk1BchNAE7FCTakXjQ==", + "requires": { + "babel-runtime": "^6.26.0", + "redux-persist": "^4.5.0" + } + }, "@types/jss": { "version": "9.5.3", "resolved": "https://registry.npmjs.org/@types/jss/-/jss-9.5.3.tgz", @@ -9752,6 +9761,16 @@ "prop-types": "^15.6.1" } }, + "redux-persist": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-4.10.2.tgz", + "integrity": "sha512-U+e0ieMGC69Zr72929iJW40dEld7Mflh6mu0eJtVMLGfMq/aJqjxUM1hzyUWMR1VUyAEEdPHuQmeq5ti9krIgg==", + "requires": { + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.4", + "lodash-es": "^4.17.4" + } + }, "redux-thunk": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz", diff --git a/react/package.json b/react/package.json index dffd590..f71e5f7 100644 --- a/react/package.json +++ b/react/package.json @@ -5,6 +5,7 @@ "dependencies": { "@material-ui/core": "^1.1.0", "@material-ui/icons": "^1.1.0", + "@redux-offline/redux-offline": "^2.3.3", "localforage": "^1.7.1", "prop-types": "^15.6.1", "react": "^16.4.0", diff --git a/react/src/actions/lists.js b/react/src/actions/lists.js index 26c557a..72c1f49 100644 --- a/react/src/actions/lists.js +++ b/react/src/actions/lists.js @@ -1,4 +1,3 @@ -import localforage from 'localforage'; import { API_ROOT, getToken } from './util'; import { RECIEVE_TODOS } from './todos'; @@ -51,7 +50,7 @@ export function addList(name) { const response = await fetch(`${API_ROOT}/lists`, { body: JSON.stringify({ name }), headers: { - Authorization: `Bearer ${await getToken()}`, + Authorization: `Bearer ${getToken()}`, 'content-type': 'application/json', }, method: 'POST', @@ -71,7 +70,7 @@ export function removeList() { dispatch(invalidateLists()); const response = await fetch(`${API_ROOT}/lists/${list}`, { headers: { - Authorization: `Bearer ${await getToken()}`, + Authorization: `Bearer ${getToken()}`, 'content-type': 'application/json', }, method: 'DELETE', @@ -96,7 +95,7 @@ export function editList(name) { const response = await fetch(`${API_ROOT}/lists/${list}`, { body: JSON.stringify({ name }), headers: { - Authorization: `Bearer ${await getToken()}`, + Authorization: `Bearer ${getToken()}`, 'content-type': 'application/json', }, method: 'PATCH', @@ -127,7 +126,7 @@ export function fetchLists() { dispatch(requestLists()); const response = await fetch(`${API_ROOT}/lists`, { headers: { - Authorization: `Bearer ${await getToken()}`, + Authorization: `Bearer ${getToken()}`, }, }); const json = await response.json(); @@ -149,22 +148,12 @@ export function fetchLists() { if (lists.length !== 0) { dispatch(changeList(listsObj[Object.keys(listsObj)[0]].id)); } - await localforage.setItem('lists', listsObj); - await localforage.setItem('todos', normalizeTodos(lists)); }; } export function loadLists() { return async dispatch => { dispatch(requestLists()); - - const lists = await localforage.getItem('lists'); - const todos = await localforage.getItem('todos'); - dispatch(recieveLists(lists)); - dispatch({ type: RECIEVE_TODOS, todos }); - if (lists && Object.keys(lists).length) { - dispatch(changeList(lists[Object.keys(lists)[0]].id)); - } dispatch(fetchLists()); }; } diff --git a/react/src/actions/todos.js b/react/src/actions/todos.js index c86c366..43a6e9d 100644 --- a/react/src/actions/todos.js +++ b/react/src/actions/todos.js @@ -33,7 +33,7 @@ export function fetchTodos() { dispatch({ type: REQUEST_TODOS }); const response = await fetch(`${API_ROOT}/todos`, { headers: { - Authorization: `Bearer ${await getToken()}`, + Authorization: `Bearer ${getToken()}`, }, }); const json = await response.json(); @@ -51,7 +51,7 @@ export function addTodo(text) { const response = await fetch(`${API_ROOT}/lists/${list}/todos`, { body: JSON.stringify({ text }), headers: { - Authorization: `Bearer ${await getToken()}`, + Authorization: `Bearer ${getToken()}`, 'content-type': 'application/json', }, method: 'POST', @@ -73,7 +73,7 @@ export function removeTodo(id) { dispatch(invalidateTodos()); const response = await fetch(`${API_ROOT}/todos/${id}`, { headers: { - Authorization: `Bearer ${await getToken()}`, + Authorization: `Bearer ${getToken()}`, 'content-type': 'application/json', }, method: 'DELETE', @@ -97,7 +97,7 @@ export function toggleTodo(id) { const response = await fetch(`${API_ROOT}/todos/${id}`, { body: JSON.stringify({ completed }), headers: { - Authorization: `Bearer ${await getToken()}`, + Authorization: `Bearer ${getToken()}`, 'content-type': 'application/json', }, method: 'PATCH', @@ -118,7 +118,7 @@ export function editTodo(id, text) { const response = await fetch(`${API_ROOT}/todos/${id}`, { body: JSON.stringify({ text }), headers: { - Authorization: `Bearer ${await getToken()}`, + Authorization: `Bearer ${getToken()}`, 'content-type': 'application/json', }, method: 'PATCH', diff --git a/react/src/actions/user.js b/react/src/actions/user.js index b919e61..aec1b56 100644 --- a/react/src/actions/user.js +++ b/react/src/actions/user.js @@ -1,5 +1,4 @@ -import localforage from 'localforage'; -import { API_ROOT, getToken } from './util'; +import { API_ROOT, getToken, setToken } from './util'; import { loadLists } from './lists'; export const LOGIN_SUCCESS = 'LOGIN_SUCCESS'; @@ -30,21 +29,16 @@ function validateUser() { export function loadUser() { return async dispatch => { - if (await getToken()) { - const user = await localforage.getItem('user'); - dispatch(loginSuccess(user)); - dispatch(loadLists()); - + if (getToken()) { const response = await fetch(`${API_ROOT}/users/user`, { headers: { - Authorization: `Bearer ${await getToken()}`, + Authorization: `Bearer ${getToken()}`, 'content-type': 'application/json', }, method: 'GET', }); const json = await response.json(); if (json.success) { - await localforage.setItem('user', json.data); dispatch(loginSuccess(json.data)); dispatch(loadLists()); } else { @@ -68,7 +62,7 @@ export function login(user) { }); const json = await response.json(); if (json.success) { - await localforage.setItem('user', json.data); + setToken(json.data.jwt); dispatch(loginSuccess(json.data)); dispatch(loadLists()); } else { @@ -97,7 +91,7 @@ export function signup(user) { }); const json = await response.json(); if (json.success) { - await await localforage.setItem('user', json.data); + setToken(json.data.jwt); dispatch(signupSuccess(json.data)); dispatch(loadLists()); } else { @@ -112,9 +106,6 @@ export function reset() { export function logout() { return async dispatch => { - await localforage.removeItem('user'); - await localforage.removeItem('lists'); - await localforage.removeItem('items'); dispatch({ type: LOGOUT }); }; } diff --git a/react/src/actions/util.js b/react/src/actions/util.js index 637e739..46b55c8 100644 --- a/react/src/actions/util.js +++ b/react/src/actions/util.js @@ -1,8 +1,11 @@ -import localforage from 'localforage'; - export const API_ROOT = '/api'; -export async function getToken() { - const user = await localforage.getItem('user'); - return user ? user.jwt : null; +let token = null; + +export function setToken(_token) { + token = _token; +} + +export function getToken() { + return token; } diff --git a/react/src/components/Header.js b/react/src/components/Header.js index 216dd0c..521ba57 100644 --- a/react/src/components/Header.js +++ b/react/src/components/Header.js @@ -1,15 +1,13 @@ import React from 'react'; import FilterLink from '../containers/FilterLink'; -import LogoutLink from '../containers/LogoutLink'; +import UserHeaderContainer from '../containers/UserHeaderContainer'; import { VisibilityFilters } from '../actions/todos'; import ListsContainer from '../containers/ListsContainer'; export default function Header() { return (