import { useEffect, useState } from 'react';
import logo from './logo.svg';
import './App.scss';
import thunk from 'redux-thunk';
import {createStore, combineReducers, applyMiddleware} from 'redux';
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)) // 1. {delay1000: {status: 'PENDING'}}
try{
let payload = await promise
dispatch(actionResolved(name, payload))
return payload
}
catch(error){
dispatch(actionRejected(name, error))
}
}
const getGQL = url =>
(query, variables = {}) =>
fetch(url, {
method: 'POST',
headers: {
"Content-Type": "application/json",
...(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))
return data.data[Object.keys(data.data)[0]]
})
const backendURL = "http://shop-roles.asmer.fs.a-level.com.ua"
const gql = getGQL(backendURL + '/graphql')
function jwtDecode(token) {
try {
let decoded = token.split('.')
decoded = decoded[1]
decoded = atob(decoded)
decoded = JSON.parse(decoded)
return decoded
} catch (e) {
return;
}
}
const actionRootCats = () =>
actionPromise('rootCats', gql(`query {
CategoryFind(query: "[{\\"parent\\":null}]"){
_id name
}
}`))
const actionCartAdd = (good, count = 1) => ({ type: 'CART_ADD', good, count })
const actionCartRemove = (good, count = 1) => ({ type: 'CART_REMOVE', good, count })
const actionCartChange = (good, count = 1) => ({ type: 'CART_CHANGE', good, count })
const actionCartClear = (good, count = 1) => ({ type: 'CART_CLEAR', good, count })
function cartReducer(state = {}, { type, good={}, count=1}){
const {_id } = good
const types = {
CART_ADD() {
return {
...state,
[_id]: { good, count: count + (state[_id]?.count || 0)}
}
},
CART_REMOVE(){
let newState = { ...state }
delete newState[_id]
return {
...newState
}
},
CART_CHANGE(){
return {
...state,
[_id]:{good, count}
}
},
CART_CLEAR(){
return {}
},
}
if (type in types)
return types[type]()
return state
}
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, error}
}
}
return state
}
const actionAuthLogin = (token) => ({ type: 'AUTH_LOGIN', token })
const actionAuthLogout = () => ({ type: 'AUTH_LOGOUT' })
const actionLogin = (login = 'tst', password = '123') =>
actionPromise('login', gql(`query ($login:String, $password:String){ login(login:$login, password:$password)}`, { 'login': login, 'password': password }))
const actionFullLogin = (login = 'tst', password = '123') =>
async dispatch => {
let token = await dispatch(actionLogin(login, password))
if (token) {
dispatch(actionAuthLogin(token))
}
}
const actionRegister = (login = 'tst', password = '123') =>
actionPromise('login', gql(`mutation reg($login:String, $password:String) {
UserUpsert(user:{login:$login, password:$password, nick:$login}){
_id login
}
}`, { 'login': login, 'password': password }))
const actionFullRegister = (login = 'tst', password = '123') =>
async dispatch => {
await dispatch(actionRegister(login, password))
await dispatch(actionFullLogin(login, password))
}
const actionCatById = (_id) =>
actionPromise('catById', gql(`query ($q: String){
CategoryFindOne(query: $q){
_id name goods {
_id name price images {
url
}
}
subCategories {
_id name
}
}
}`, { q: JSON.stringify([{ _id }]) }))
const actionGoodById = (_id) =>
actionPromise('goodById', gql(`query ($good:String) {
GoodFindOne(query:$good) {
_id name price images {
url
}
}
}`, { good: JSON.stringify([{ _id }]) }))
const store = createStore(combineReducers({promise: promiseReducer,
auth: authReducer,
cart: cartReducer}), applyMiddleware(thunk))
store.subscribe(() => console.log(store.getState()))
store.dispatch(actionRootCats())
//store.dispatch(actionCatById('5dc458985df9d670df48cc47'))
const Logo = () =>
const Header = () =>