Browse Source

в процессе

Varvara Huza 3 years ago
parent
commit
8970fe89cf
2 changed files with 263 additions and 0 deletions
  1. 60 0
      Homework_17/index.html
  2. 203 0
      Homework_17/main.js

+ 60 - 0
Homework_17/index.html

@@ -0,0 +1,60 @@
+<!DOCTYPE HTML>
+<html>
+    <head>
+        <title>GQL</title>
+        <meta charset='utf8' />
+        <style>
+            body {
+                margin: 0;
+                padding: 0;
+            }
+
+            a {
+                color: #23217c;
+                text-decoration: none;
+            }
+
+            a:hover {
+                color: #1916dd;
+            }
+
+            header {
+                background-color: #23217c;
+                color: #fff;
+                font-weight: bold;
+                padding: 10px 25px;
+            }
+
+            #mainContainer {
+                display: flex;
+                padding: 15px 0;
+            }
+
+            #aside {
+                width: 30%;
+                padding: 0 25px;
+            }
+
+            #aside > a{
+                display: block;
+            }
+
+            #main > a {
+                display: block;
+                margin: 15px 0 5px 0;
+            }
+        </style>
+    </head>
+    <body>
+        <header>КУДА Я ПОПАЛ?</header>
+        <div id='mainContainer'>
+            <aside id='aside'>
+                Категории
+            </aside>
+            <main id='main'>
+                Выберите категорию пожалуйста будьте так любезны 
+            </main>
+        </div>
+        <script src='main.js'></script>
+    </body>
+</html>

+ 203 - 0
Homework_17/main.js

@@ -0,0 +1,203 @@
+function createStore(reducer){
+    let state = reducer(undefined, {})
+    let cbs   = []
+    function dispatch(action){
+        if (typeof action === 'function'){
+            return action(dispatch)
+        }
+        const newState = reducer(state, action)
+        if (state !== newState){
+            state = newState
+            cbs.forEach(cb => cb())
+        }
+    }
+    return {
+        dispatch,
+        subscribe(cb){
+            cbs.push(cb)
+            return () =>  cbs = cbs.filter(c => c !== cb)
+        },
+        getState(){
+            return state
+        }
+    }
+}
+
+function promiseReducer(state={}, {type, status, payload, error, name}){
+    if (type === 'PROMISE'){
+        return {
+            ...state,
+            [name]:{status, payload, error}
+        }
+    }
+    return state
+}
+
+
+//под товаром сделать кнопку "купить"
+
+const store = createStore(promiseReducer)
+const unsubscribe1 = store.subscribe(() => console.log(store.getState()))
+
+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 delay = ms => new Promise(ok => setTimeout(() => ok(ms), ms))
+
+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 => {
+        return function(query, variables={}) {
+            return fetch(url, 
+            {
+                method: "POST",
+                headers: 
+                {"Content-Type": "application/json",
+                ...(localStorage.authToken ? {Authorization: localStorage.authToken} : {})
+                },
+                body: JSON.stringify({query, variables})
+            }).then(resp => resp.json())
+            // .then(data => {
+            //     if ("errors" in data) {
+            //         throw new Error('ашипка, угадывай што не так')
+            //     }
+            //     else {
+            //         return data.data[Object.keys(variables)[0]]
+            //     }
+            // })
+        }
+    }
+
+let shopGQL = getGQL('http://shop-roles.asmer.fs.a-level.com.ua/graphql')
+
+const goodById = goodId => {
+    let id = `[{"_id":"${goodId}"}]`
+    return shopGQL(`
+    query good($id:String){
+        GoodFindOne(query: $id) {
+          name description price images {
+            _id text url
+          }
+          categories {
+            _id name
+          }
+        }
+    }`, { id })
+}
+
+const actionGoodById = id => 
+    actionPromise('goodById', goodById(id))
+
+const actionRootCategories = () =>
+    actionPromise('rootCategories', shopGQL(`
+            query cats($query:String){
+              CategoryFind(query:$query){
+                _id name 
+              }
+            }
+        `, {query: JSON.stringify([{parent:null}])}))
+
+const actionCategoryById = (_id) => 
+    actionPromise('catById', shopGQL(`query catById($query:String){
+                                          CategoryFindOne(query:$query){
+                                            _id name goods{
+                                              _id name price description images{
+                                                url
+                                              }
+                                            }
+                                          }
+                                        }`, {query: JSON.stringify([{_id}])}))
+
+
+store.dispatch(actionRootCategories())
+
+window.onhashchange = () => {
+    let {1: route, 2:id} = location.hash.split('/')
+    if (route === 'categories'){
+        store.dispatch(actionCategoryById(id))
+    }
+
+    if (route === 'good'){
+        store.dispatch(actionGoodById(id))
+    }
+}
+
+function drawMainMenu(){
+    let cats = store.getState().rootCategories.payload
+    if (cats){ //каждый раз дорисовываются в body
+        aside.innerText = ''
+        for (let {_id, name} of cats.data.CategoryFind){
+            let catA = document.createElement('a')
+            catA.href = `#/categories/${_id}`
+            catA.innerText = name
+            aside.append(catA)
+        }
+    }
+}
+
+store.subscribe(drawMainMenu)
+
+
+
+store.subscribe(() => {
+    const {1: route, 2:id} = location.hash.split('/')
+    if (route === 'categories'){
+        const catById = store.getState().catById?.payload
+        if (catById){
+            main.innerText = ''
+            let categoryName = document.createElement('div')
+            categoryName.innerText = catById.data.CategoryFindOne.name
+            categoryName.style.fontSize = '25px'
+            categoryName.style.fontWeight = 'bold'
+            main.append(categoryName)
+            for (let {_id, name} of catById.data.CategoryFindOne.goods){
+                let good = document.createElement('a')
+                    good.href = `#/good/${_id}`
+                    good.innerText = name
+
+                let btn = document.createElement('button')
+                    btn.style.cursor = 'pointer'
+                    btn.innerText = 'купыть'
+                main.append(good, btn)
+            }
+        }
+    }
+    if (route === 'good'){
+        const goodById = store.getState().goodById?.payload
+        if (goodById){
+            main.innerText = ''
+            let {name, description, price} = goodById.data.GoodFindOne
+            let goodName = document.createElement('div')
+                goodName.innerText = name
+                goodName.style.fontSize = '35px'
+                goodName.style.fontWeight = 'bold'
+                goodName.style.marginBottom = '25px'
+
+            let goodDescription = document.createElement('div')
+                goodDescription.innerText = description
+                goodDescription.style.marginBottom = '25px'
+
+            let goodPrice = document.createElement('div')
+                goodPrice.innerText = 'Цена: ' + price
+                goodPrice.style.marginBottom = '5px'
+
+            let btn = document.createElement('button')
+                btn.style.cursor = 'pointer'
+                btn.innerText = 'купыть'
+
+            main.append(goodName, goodDescription, goodPrice, btn)
+        }
+    }
+})