App.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import {createStore, combineReducers, applyMiddleware} from 'redux';
  2. import thunk from 'redux-thunk';
  3. import {Provider} from 'react-redux';
  4. import {Router, Route} from 'react-router-dom';
  5. import React from 'react';
  6. import './App.scss';
  7. import SignIn from './components/signIn';
  8. import SignUp from './components/signup';
  9. import Profile from './components/myprofile';
  10. import CreateAdConnect from './components/add';
  11. import GoodUser from './components/good';
  12. import MainList from './components/goods'
  13. import AllProductsUser from './components/productsUser';
  14. import HeaderConnect from './components/header'
  15. import Messages from './components/message'
  16. import ChangeAdConnect from './components/changeAd'
  17. const history = require("history").createBrowserHistory()
  18. const getGQL = url =>
  19. (query, variables= {}) =>
  20. fetch(url, {
  21. method: 'POST',
  22. headers: checkToken(),
  23. body:JSON.stringify({query, variables})
  24. }).then(res => res.json())
  25. .then(data => {
  26. try {
  27. if(!data.data && data.errors) {
  28. throw new SyntaxError(`SyntaxError - ${JSON.stringify(Object.values(data.errors)[0])}`);
  29. }
  30. return Object.values(data.data)[0];
  31. } catch (e) {
  32. console.error(e);
  33. }
  34. });
  35. const checkToken = () => {
  36. const headers = {
  37. "Content-Type": "application/json",
  38. "Accept": "application/json",
  39. }
  40. if(localStorage.getItem('authToken')) {
  41. return {
  42. ...headers,
  43. "Authorization": `Bearer ${localStorage.getItem('authToken')}`
  44. }
  45. } else {
  46. return headers;
  47. }
  48. }
  49. const defaultAvatar = "http://marketplace.node.ed.asmer.org.ua/images/744eed7a2030edd908ef3c59cc9405ce"
  50. const origUrl = "http://marketplace.node.ed.asmer.org.ua/"
  51. const gql = getGQL(origUrl + 'graphql')
  52. const actionPromise = (namePromise,promise) =>
  53. async dispatch => {
  54. dispatch(actionPending(namePromise))
  55. try{
  56. const payload = await promise
  57. dispatch(actionFulfilled(namePromise,payload))
  58. return payload
  59. }
  60. catch (error){
  61. dispatch(actionRejected(namePromise,error))
  62. }
  63. }
  64. const actionPending = (namePromise) => ({type: 'PROMISE', status: 'PENDING',namePromise})
  65. const actionFulfilled = (namePromise,payload) => ({type: 'PROMISE', status: 'FULFILLED',namePromise, payload})
  66. const actionRejected = (namePromise,error) => ({type: 'PROMISE', status: 'REJECTED', namePromise, error})
  67. function promiseReducer(state={}, {type, status, payload, error,namePromise}){
  68. if (type === 'PROMISE'){
  69. return {
  70. ...state,
  71. [namePromise] : {status, payload, error}
  72. }
  73. }
  74. return state
  75. }
  76. const store = createStore(combineReducers({auth: authReducer, promise:localStoredReducer(promiseReducer, 'promise')}), applyMiddleware(thunk))
  77. store.subscribe(() => console.log(store.getState()))
  78. function jwtDecode(token){
  79. try {
  80. return JSON.parse(atob(token.split('.')[1]))
  81. }
  82. catch(e){
  83. }
  84. }
  85. function localStoredReducer(reducer, localStorageKey){
  86. function wrapper(state, action){
  87. if (state === undefined){
  88. try {
  89. return JSON.parse(localStorage[localStorageKey])
  90. }
  91. catch(e){ }
  92. }
  93. const newState = reducer(state, action)
  94. localStorage.setItem(localStorageKey, JSON.stringify(newState))
  95. return newState
  96. }
  97. return wrapper
  98. }
  99. function authReducer(state={}, {type, token}){
  100. if (type === 'AUTH_LOGIN'){
  101. const payload = jwtDecode(token)
  102. try{
  103. if (payload){
  104. return {
  105. token,
  106. payload
  107. }
  108. }
  109. }
  110. catch (e) {}
  111. }
  112. if (type === 'AUTH_LOGOUT'){
  113. return {}
  114. }
  115. return state
  116. }
  117. const actionAuthLogout = () =>
  118. () => {
  119. store.dispatch({type: 'AUTH_LOGOUT'});
  120. localStorage.removeItem('authToken');
  121. localStorage.clear()
  122. }
  123. const actionAuthLogin = (token) =>
  124. () => {
  125. const oldState = store.getState()
  126. store.dispatch({type: 'AUTH_LOGIN', token})
  127. const newState = store.getState()
  128. if (oldState !== newState)
  129. localStorage.setItem('authToken', token)
  130. }
  131. const defaultImg = "https://www.lionstroy.ru/published/publicdata/U70619SHOP/attachments/SC/products_pictures/nophoto.png"
  132. store.dispatch(actionAuthLogin(localStorage.authToken))
  133. !store.getState().auth.token&&history.push("/sign_in")
  134. function App() {
  135. return (
  136. <Router history = {history}>
  137. <Provider store={store}>
  138. <HeaderConnect/>
  139. <Route path="/sign_in" component={SignIn} exact/>
  140. <Route path="/sign_up" component={SignUp} exact/>
  141. <Route path="/my_profile" component={Profile} exact/>
  142. <Route path="/create_ad" component={CreateAdConnect} exact/>
  143. <Route path="/change/:_id" component={ChangeAdConnect} exact/>
  144. <Route path="/page/:_id" component={MainList} exact/>
  145. <Route path="/message" component={Messages} exact/>
  146. <Route path="/all_products_user" component={AllProductsUser} exact/>
  147. <Route path="/page/:page/good/:_id" component={GoodUser} exact/>
  148. <Route path="/good/:_id" component={GoodUser} exact/>
  149. </Provider>
  150. </Router>
  151. );
  152. }
  153. export {
  154. store,
  155. defaultAvatar,
  156. origUrl,
  157. defaultImg,
  158. actionAuthLogout,
  159. actionAuthLogin,
  160. history,
  161. jwtDecode,
  162. actionPromise,
  163. gql
  164. }
  165. export default App;