Bladeren bron

HWJS17 (authReducer, combineReducers, actionFullRegister) done

DimaBondarenko 3 jaren geleden
bovenliggende
commit
6c2293abcf
5 gewijzigde bestanden met toevoegingen van 270 en 0 verwijderingen
  1. 2 0
      HWJS17/css/style.min.css
  2. 9 0
      HWJS17/css/style.min.css.map
  3. 14 0
      HWJS17/index.html
  4. 240 0
      HWJS17/js/script.js
  5. 5 0
      HWJS17/sass/style.scss

+ 2 - 0
HWJS17/css/style.min.css

@@ -0,0 +1,2 @@
+*{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0}
+/*# sourceMappingURL=style.min.css.map */

+ 9 - 0
HWJS17/css/style.min.css.map

@@ -0,0 +1,9 @@
+{
+    "version": 3,
+    "mappings": "AAAA,AAAA,CAAC,AAAA,CACG,UAAU,CAAE,UAAU,CACtB,MAAM,CAAE,CAAC,CACZ",
+    "sources": [
+        "../sass/style.scss"
+    ],
+    "names": [],
+    "file": "style.min.css"
+}

+ 14 - 0
HWJS17/index.html

@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Document</title>
+    <link rel="stylesheet" href="css/style.min.css">
+</head>
+<body>
+    
+    <script src="js/script.js"></script>
+</body>
+</html>

+ 240 - 0
HWJS17/js/script.js

@@ -0,0 +1,240 @@
+function createStore(reducer){                                     
+    let state       = reducer(undefined, {}) 
+    let cbs         = []                     
+    
+    const getState  = () => state           
+    const subscribe = cb => (cbs.push(cb),  
+                             () => cbs = cbs.filter(c => c !== cb)) 
+                             
+    const dispatch  = action => { 
+        if (typeof action === 'function'){ 
+            return action(dispatch, getState) 
+        }
+        const newState = reducer(state, action) 
+        if (newState !== state){ 
+            state = newState 
+            for (let cb of cbs)  cb() 
+        }
+    }
+    
+    return {
+        getState,
+        dispatch,
+        subscribe 
+    }
+}
+
+const getGQL = url =>
+    (query, variables) => fetch(url, {
+        method: 'POST',
+        headers: {
+            "Content-Type": "application/json",
+            // 'Accept' : 'application/json',
+            ...(localStorage.authToken ? {"Authorization": "Bearer " + localStorage.authToken} : {})
+        },
+        body: JSON.stringify({query, variables})
+    }).then(res => res.json())
+        .then(data => {
+            if (data.data){
+                return Object.values(data.data)[0] 
+            } 
+            else throw new Error(JSON.stringify(data.errors))
+        })
+const backendURL = 'http://shop-roles.asmer.fs.a-level.com.ua'
+const gql = getGQL(backendURL + '/graphql');
+
+const jwtDecode = token => {
+    try{
+        return JSON.parse(atob(token.split('.')[1]));
+        
+    }
+    catch(e){
+        console.log(e.name, e.message);
+    }
+}
+
+function authReducer(state, {type, token}){                                 
+    if (state === undefined){
+        if(localStorage.authToken){
+            type = 'AUTH_LOGIN';
+            token = localStorage.authToken
+        }
+    }
+    if(type === 'AUTH_LOGIN'){
+        let payload = jwtDecode(token);
+        if (payload){
+            localStorage.authToken = token
+             return {token, payload}
+        }       
+    } 
+    if(type === 'AUTH_LOGOUT'){
+        localStorage.removeItem("authToken")
+        return {}
+    } 
+    return state || {}
+}
+
+function promiseReducer(state={}, {type, name, status, payload, error}){
+    if (type === 'PROMISE'){
+        return {
+            ...state,
+            [name]:{status, payload, error}
+        }
+    }
+    return state
+}
+
+const combineReducers = (reducers) => (state={}, action) => {
+    let newState = {}
+    for (const [reducerName, reducer] of Object.entries(reducers)){
+            let subNewState = reducer(state[reducerName],action)
+            if(subNewState !== state[reducerName]){
+                newState = {
+                    ...newState, [reducerName] : subNewState
+                }
+            }        
+    }
+    if(Object.keys(newState).length > 0){
+            return {
+                ...state,...newState
+            }
+    }
+    return state
+}
+
+const actionAuthLogin = (token) => ({type: 'AUTH_LOGIN', token});
+const actionAuthLogout = () => ({type: 'AUTH_LOGOUT'});
+
+const actionPending             = name => ({type:'PROMISE',name, status: 'PENDING'})
+const actionFulfilled = (name,payload) => ({type:'PROMISE',name, status: 'FULFILLED', payload})
+const actionRejected  = (name,error)   => ({type:'PROMISE',name, status: 'REJECTED', error})
+
+const delay = ms => new Promise(ok => setTimeout(() => ok(ms), ms))
+
+const store = createStore(combineReducers({promise: promiseReducer, auth: authReducer}));
+store.subscribe(() => console.log(store.getState()))
+
+
+const actionPromise = (name, promise) =>
+async dispatch => {
+    dispatch(actionPending(name))
+    try {
+        let payload = await promise
+        dispatch(actionFulfilled(name, payload))
+        return payload
+    }
+    catch(error){
+        dispatch(actionRejected(name, error))
+    }
+}
+
+const actionFullRegister = (log,  pass) => 
+    async dispatch => {
+        let user = await dispatch(
+            actionPromise('register', gql( `mutation register($login: String, $password: String) {
+                UserUpsert(user: {login: $login, password: $password}) {
+                   _id
+                   login
+                 }
+               }`, {login : log, password : pass}))
+        )
+        if(user){
+            dispatch(actionFullLogin(log, pass));
+        }
+    }
+
+const actionFullLogin = (log, pass) => 
+      async dispatch => {
+          let token = await dispatch(
+            actionPromise('login', gql(`query login($login: String, $password: String) {
+            login(login: $login, password: $password)
+            }`, {login: log, password: pass}))
+        )
+        if(token){
+            dispatch(actionAuthLogin(token))
+        }
+      }
+
+
+store.dispatch(actionFullRegister('bd2404', '2404'))
+// store.dispatch(actionAuthLogout());      
+
+
+const actionLuke = () => actionPromise('luke', 
+                                        fetch('https://swapi.dev/api/people/1')
+                                                .then(res => res.json()))
+store.dispatch(actionLuke())
+
+
+const actionCategoryById = (_id) => 
+    actionPromise('catById', gql(`query catById($q: String){
+        CategoryFindOne(query: $q){
+            _id name goods {
+                _id name price images {
+                    url
+                }
+            }
+        }
+    }`, {q: JSON.stringify([{_id}])}));
+
+store.dispatch(actionCategoryById("5dc458985df9d670df48cc47"));
+
+const actionGoodById = (_id) =>
+    actionPromise('goodById', gql(`query goodByid($goodId: String) {
+        GoodFindOne(query: $goodId) {
+        name
+        price
+        description
+        images {
+            url
+        }
+        }
+    }`, {goodId: JSON.stringify([{_id}])}))
+
+store.dispatch(actionGoodById("5dc4a3e15df9d670df48cc6b"));
+
+const actionRootCategories = () => 
+    actionPromise('rootCats', gql(`query {
+        CategoryFind(query: "[{\\"parent\\":null}]"){
+            _id name
+        }
+    }`))
+
+store.dispatch(actionRootCategories());
+
+const actionNewOrder = (order) => 
+    actionPromise('newOrder', gql( `mutation newOrder($order: OrderInput) {
+        OrderUpsert(order: $order) {
+          _id
+          total
+        }
+      }`, {order : order}
+    )
+
+    )
+let order = {
+    orderGoods: [
+            {count: 2, good: {_id: "5dcac57d6d09c45440d14cfc"}},
+            {count: 2, good: {_id: "5dcac9ba6d09c45440d14d02"}},
+            {count: 1, good: {_id: "5dc8844e0e36db246e3049bd"}},
+    ]
+}
+
+// store.dispatch(actionNewOrder(order));
+
+const actionOrders = () => 
+    actionPromise('allOrders', gql(`query findOrder($q: String) {
+        OrderFind(query: $q) {
+          _id
+          total
+          orderGoods {
+            count
+            good {
+              name
+              price
+            }
+          }
+        }
+      }`, {q: JSON.stringify([{}])}))
+
+// store.dispatch(actionOrders())

+ 5 - 0
HWJS17/sass/style.scss

@@ -0,0 +1,5 @@
+*{
+    box-sizing: border-box;
+    margin: 0;
+}
+