|
@@ -1,4 +1,7 @@
|
|
|
import './App.css';
|
|
|
+import * as action from './actions'
|
|
|
+import * as reducer from './reducers'
|
|
|
+
|
|
|
import thunk from 'redux-thunk';
|
|
|
import { useEffect, useState } from 'react';
|
|
|
import { createStore, combineReducers, applyMiddleware } from 'redux';
|
|
@@ -6,184 +9,56 @@ import { Provider, connect } from 'react-redux';
|
|
|
import { Link, Route, Router, Switch, Redirect } from 'react-router-dom';
|
|
|
import createHistory from 'history/createBrowserHistory'
|
|
|
|
|
|
-const actionPending = name => ({ type: 'PROMISE', status: 'PENDING', name })
|
|
|
-const actionResolved = (name, payload) => ({ type: 'PROMISE', status: 'RESOLVED', name, payload })
|
|
|
-const actionRejected = (name, error) => ({ type: 'PROMISE', status: 'REJECTED', name, error })
|
|
|
-
|
|
|
-const actionPromise = (name, promise) =>
|
|
|
- async dispatch => {
|
|
|
- dispatch(actionPending(name))
|
|
|
- try {
|
|
|
- let payload = await promise
|
|
|
- dispatch(actionResolved(name, payload))
|
|
|
- return payload
|
|
|
- }
|
|
|
- catch (error) {
|
|
|
- dispatch(actionRejected(name, error))
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-const getGQL = url =>
|
|
|
+export const getGQL = url =>
|
|
|
(query, variables = {}) =>
|
|
|
fetch(url, {
|
|
|
method: 'POST',
|
|
|
headers: {
|
|
|
"Content-Type": "application/json",
|
|
|
- ...(localStorage.authToken ? { "Authorization": "Bearer " + localStorage.authToken } :
|
|
|
- {})
|
|
|
+ ...(localStorage.authToken ? { "Authorization": "Bearer " + localStorage.authToken } : {})
|
|
|
},
|
|
|
body: JSON.stringify({ query, variables })
|
|
|
})
|
|
|
.then(res => res.json())
|
|
|
.then(data => {
|
|
|
- if (data.errors && !data.data)
|
|
|
- throw new Error(JSON.stringify(data.errors))
|
|
|
+ if (data.errors && !data.data) throw new Error(JSON.stringify(data.errors))
|
|
|
return data.data[Object.keys(data.data)[0]]
|
|
|
})
|
|
|
|
|
|
-const backendURL = "http://player.asmer.fs.a-level.com.ua"
|
|
|
-const gql = getGQL(backendURL + '/graphql')
|
|
|
const history = createHistory()
|
|
|
-
|
|
|
-
|
|
|
-function jwtDecode(token) {
|
|
|
- try {
|
|
|
- let decoded = token.split('.')
|
|
|
- decoded = decoded[1]
|
|
|
- decoded = atob(decoded)
|
|
|
- decoded = JSON.parse(decoded)
|
|
|
- return decoded
|
|
|
-
|
|
|
- } catch (e) {
|
|
|
- return;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-function authReducer(state, { type, token }) {
|
|
|
- if (!state) {
|
|
|
- if (localStorage.authToken) {
|
|
|
- type = 'AUTH_LOGIN'
|
|
|
- token = localStorage.authToken
|
|
|
- } else {
|
|
|
- return {}
|
|
|
- }
|
|
|
- }
|
|
|
- if (type === 'AUTH_LOGIN') {
|
|
|
- let auth = jwtDecode(token)
|
|
|
- if (auth) {
|
|
|
- localStorage.authToken = token
|
|
|
- return { token, payload: auth }
|
|
|
- }
|
|
|
- }
|
|
|
- if (type === 'AUTH_LOGOUT') {
|
|
|
- localStorage.authToken = ''
|
|
|
- return {}
|
|
|
- }
|
|
|
-
|
|
|
- return state
|
|
|
-}
|
|
|
-
|
|
|
-function promiseReducer(state = {}, { type, name, status, payload, error }) {
|
|
|
- if (type === 'PROMISE') {
|
|
|
-
|
|
|
- return {
|
|
|
- ...state,
|
|
|
- [name]: { status, payload: (state === 'PENDING' && state[name] && state[name].payload) || payload, error }
|
|
|
- }
|
|
|
- }
|
|
|
- return state
|
|
|
-}
|
|
|
-
|
|
|
-const localStoreReducer = (reducer, localStorageName) => {
|
|
|
- return (
|
|
|
- (state, action) => {
|
|
|
- let newState
|
|
|
- if(!state && localStorage.getItem(localStorageName)) {
|
|
|
- newState = JSON.parse(localStorage.getItem(localStorageName))
|
|
|
- console.log(newState)
|
|
|
- } else {
|
|
|
- newState = reducer(state, action)
|
|
|
- localStorage.setItem(localStorageName, JSON.stringify(newState))
|
|
|
- }
|
|
|
- return newState
|
|
|
- }
|
|
|
- )
|
|
|
-}
|
|
|
-
|
|
|
-const actionAuthLogin = (token) => ({ type: 'AUTH_LOGIN', token })
|
|
|
-const actionAuthLogout = () => ({ type: 'AUTH_LOGOUT' })
|
|
|
-
|
|
|
-const actionLogin = (login, password) =>
|
|
|
- actionPromise('login', gql(`
|
|
|
- query log($login:String!, $password:String!) {
|
|
|
- login(login: $login, password: $password)
|
|
|
- }`, { login, password }))
|
|
|
-
|
|
|
-const actionFullLogin = (login = 'tst', password = '123') =>
|
|
|
- async dispatch => {
|
|
|
- let token = await dispatch(actionLogin(login, password))
|
|
|
- if (token) {
|
|
|
- await dispatch(actionAuthLogin(token))
|
|
|
- dispatch(actionGetUserData())
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-const actionRegister = (login, password) =>
|
|
|
- actionPromise('registration', gql(`
|
|
|
- mutation register($login:String!, $password:String!) {
|
|
|
- createUser(login: $login, password: $password) {
|
|
|
- login, _id
|
|
|
- }
|
|
|
- }
|
|
|
- `, { login, password }))
|
|
|
-
|
|
|
-const actionFullRegister = (login = 'tst', password = '123') =>
|
|
|
- async dispatch => {
|
|
|
- await dispatch(actionRegister(login, password))
|
|
|
- await dispatch(actionFullLogin(login, password))
|
|
|
- }
|
|
|
-
|
|
|
-const actionGetPlaylists = (userId = "5fe35e1ce926687ee86b0a3f") => {
|
|
|
- actionPromise('getPlaylists', gql(`
|
|
|
- query getPlaylistByOwnerId($ownerId:String!) {
|
|
|
- PlaylistFind(query: $ownerId) {
|
|
|
- _id, name
|
|
|
- }
|
|
|
- }
|
|
|
- `, { ownerId: JSON.stringify([{ ___owner: userId }]) }))
|
|
|
-}
|
|
|
-
|
|
|
-const actionGetUserData = () => {
|
|
|
- let _id = jwtDecode(localStorage.authToken).sub.id
|
|
|
- return (
|
|
|
- actionPromise('userData', gql(`
|
|
|
- query($userId: String!) {
|
|
|
- UserFindOne(query: $userId){
|
|
|
- login, _id, avatar {_id, url, originalFileName}
|
|
|
- }
|
|
|
- }
|
|
|
- `, { userId: JSON.stringify([{_id}]) }))
|
|
|
-
|
|
|
- )
|
|
|
-}
|
|
|
+const backendURL = "http://player.asmer.fs.a-level.com.ua"
|
|
|
+export const gql = getGQL(backendURL + '/graphql')
|
|
|
|
|
|
const store = createStore(
|
|
|
combineReducers(
|
|
|
{
|
|
|
- promise: promiseReducer,
|
|
|
- auth: authReducer,
|
|
|
+ promise: reducer.promiseReducer,
|
|
|
+ auth: reducer.authReducer,
|
|
|
//local: localStoreReducer(promiseReducer, 'locale')
|
|
|
}
|
|
|
), applyMiddleware(thunk)
|
|
|
)
|
|
|
+
|
|
|
store.subscribe(() => console.log(store.getState()))
|
|
|
if(store.getState().auth?.token) {
|
|
|
//history.push('/player')
|
|
|
- store.dispatch(actionGetUserData())
|
|
|
+ store.dispatch(action.actionGetUserData())
|
|
|
} else {
|
|
|
history.push('/login')
|
|
|
}
|
|
|
|
|
|
+export function jwtDecode(token) {
|
|
|
+ try {
|
|
|
+ let decoded = token.split('.')
|
|
|
+ decoded = decoded[1]
|
|
|
+ decoded = atob(decoded)
|
|
|
+ decoded = JSON.parse(decoded)
|
|
|
+ return decoded
|
|
|
+
|
|
|
+ } catch (e) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
const LoginForm = ({ loged, onLogin }) => {
|
|
|
let [login, setLogin] = useState()
|
|
@@ -217,7 +92,7 @@ const LoginForm = ({ loged, onLogin }) => {
|
|
|
)
|
|
|
}
|
|
|
|
|
|
-const LoginFormConnect = connect(state => ({ loged: state.promise.login || {} }), { onLogin: actionFullLogin })(LoginForm)
|
|
|
+const LoginFormConnect = connect(state => ({ loged: state.promise.login || {} }), { onLogin: action.actionFullLogin })(LoginForm)
|
|
|
|
|
|
const RegisterForm = ({ onRegister }) => {
|
|
|
let [login, setLogin] = useState()
|
|
@@ -244,14 +119,12 @@ const RegisterForm = ({ onRegister }) => {
|
|
|
</>
|
|
|
)
|
|
|
}
|
|
|
-const RegisterFormConnect = connect(null, { onRegister: actionFullRegister })(RegisterForm)
|
|
|
+const RegisterFormConnect = connect(null, { onRegister: action.actionRegister })(RegisterForm)
|
|
|
|
|
|
const Player = ({ user, getUserData, onLogout }) => {
|
|
|
let [userInfo, setUserInfo] = useState(user.payload)
|
|
|
useEffect(()=> {
|
|
|
- //setUserInfo(userData.payload)
|
|
|
setUserInfo(user.payload)
|
|
|
- //console.log('data & info', user.payload, userInfo)
|
|
|
},[user, userInfo])
|
|
|
|
|
|
return (
|
|
@@ -305,19 +178,18 @@ const Player = ({ user, getUserData, onLogout }) => {
|
|
|
|
|
|
const PlayerConnect = connect(
|
|
|
state => ({
|
|
|
- //playlists: state.promise.getPlaylists || {},
|
|
|
- user: state.promise.userData || {}
|
|
|
+ user: state.promise.userData || {}
|
|
|
+ //playlists: state.promise.getPlaylists || {}
|
|
|
}),
|
|
|
{
|
|
|
- onLogout: actionAuthLogout,
|
|
|
- getUserData: actionGetUserData,
|
|
|
+ onLogout: action.actionAuthLogout,
|
|
|
+ getUserData: action.actionGetUserData,
|
|
|
//getPlaylists: actionGetPlaylists
|
|
|
}
|
|
|
)(Player)
|
|
|
|
|
|
|
|
|
function App() {
|
|
|
- //if(store.getState().auth?.token) history.push('/player')
|
|
|
return (
|
|
|
<Router history={history}>
|
|
|
<Provider store={store}>
|
|
@@ -333,5 +205,4 @@ function App() {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
-export default App;
|
|
|
-
|
|
|
+export default App;
|