浏览代码

HW<21>start_module

Gennadysht 2 年之前
父节点
当前提交
9bc18f7251
共有 3 个文件被更改,包括 122 次插入305 次删除
  1. 0 245
      js/lesson21/Gql_promis_.html
  2. 122 60
      js/lesson21/Gql_promis_ copyexperimental_prog.html
  3. 0 0
      js/lesson21_Module/getGQL.html

+ 0 - 245
js/lesson21/Gql_promis_.html

@@ -1,245 +0,0 @@
-<Header>Gql</Header>
-
-<body>
-    <script>
-        function jwtDecode(token) {                         // расщифровки токена авторизации
-            if (!token || typeof token != "string")
-                return undefined;
-            let tokenArr = token.split(".");
-            if (tokenArr.length != 3)
-                return undefined;
-            try {
-                let tokenJsonStr = atob(tokenArr[1]);
-                let tokenJson = JSON.parse(tokenJsonStr);
-                return tokenJson;
-            }
-            catch {
-                return undefined;
-            }
-        }
-        function combineReducers(reducers) {
-            function totalReducer(totalState = {}, action) {
-                const newTotalState = {} //объект, который будет хранить только новые состояния дочерних редьюсеров
-
-                //цикл + квадратные скобочки позволяют написать код, который будет работать с любыми количеством дочерных редьюсеров
-                for (const [reducerName, childReducer] of Object.entries(reducers)) {
-                    const newState = childReducer(totalState[reducerName], action) //запуск дочернего редьюсера
-                    if (newState !== totalState[reducerName]) { //если он отреагировал на action
-                        newTotalState[reducerName] = newState //добавляем его в newTotalState
-                    }
-                }
-
-                //Универсальная проверка на то, что хотя бы один дочерний редьюсер создал новый стейт:
-                if (Object.values(newTotalState).length) {
-                    return { ...totalState, ...newTotalState } //создаем новый общий стейт, накладывая новый стейты дочерних редьюсеров на старые
-                }
-
-                return totalState //если экшен не был понят ни одним из дочерних редьюсеров, возвращаем общий стейт как был.
-            }
-
-            return totalReducer
-        }
-        function promiseReducer(state = {}, action) {                   // диспетчер обработки
-            if (action) {
-                if (action.type === 'PROMISE') {
-                    let newState = { ...state };
-                    newState[action.name] = { status: action.status, payload: action.payload, error: action.error };
-                    return newState;
-                }
-            }
-            return state;
-        }
-        function authReducer(state = {}, action) {                   // диспетчер обработки login
-            if (action) {
-                if (action.type === 'AUTH_LOGIN') {
-                    let newState = { ...state };
-                    newState.token = action.token;
-                    newState.payload = jwtDecode(action.token);
-                    if (!newState.payload) {
-                        newState.token = undefined;
-                    }
-                    return newState;
-                }
-                else if (action.type === 'AUTH_LOGOUT') {
-                    let newState = { ...state };
-                    newState.token = undefined;
-                    newState.payload = undefined;
-                    return newState;
-                }
-            }
-            return state;
-        }
-        function createStore(reducer) {
-            let state = reducer(undefined, {})              //стартовая инициализация состояния, запуск редьюсера со state === undefined
-            let cbs = []                                      //массив подписчиков
-
-            const getState = () => state                   //функция, возвращающая переменную из замыкания
-            const subscribe = cb => (cbs.push(cb),            //запоминаем подписчиков в массиве
-                () => cbs = cbs.filter(c => c !== cb))      //возвращаем функцию unsubscribe, которая удаляет подписчика из списка
-
-            function dispatch(action) {
-                if (typeof action === 'function') {         //если action - не объект, а функция
-                    return action(dispatch, getState)       //запускаем эту функцию и даем ей dispatch и getState для работы
-                }
-                const newState = reducer(state, action)      //пробуем запустить редьюсер
-                if (newState !== state) {                    //проверяем, смог ли редьюсер обработать action
-                    state = newState                        //если смог, то обновляем state 
-                    for (let cb of cbs) cb()                //и запускаем подписчиков
-                }
-            }
-
-            return {
-                getState,                                   //добавление функции getState в результирующий объект
-                dispatch,
-                subscribe                                   //добавление subscribe в объект
-            }
-        }
-
-        function gql(url, query, vars) {
-            let fetchSettings =
-            {
-                method: "POST",
-                headers:
-                {
-                    "Content-Type": "application/json",
-                    "Accept": "application/json"
-                },
-                body: JSON.stringify(
-                    {
-                        query: query,
-                        variables: vars
-
-                    })
-            };
-            return fetch(url, fetchSettings).then(res => res.json());
-        }
-
-        const actionPromiseGql = (name, promise) => {
-            return actionPromiseGqlInt = async (dispatch) => {
-                dispatch(actionPending(name)) //сигнализируем redux, что промис начался
-                try {
-                    const payload = await promise //ожидаем промиса
-                    dispatch(actionFulfilled(name, payload)) //сигнализируем redux, что промис успешно выполнен
-                    return payload //в месте запуска store.dispatch с этим thunk можно так же получить результат промиса
-                }
-                catch (error) {
-                    dispatch(actionRejected(name, error)) //в случае ошибки - сигнализируем redux, что промис несложился
-                }
-            }
-        }
-        /*function actionAuthGql(promise) {
-            return async function Exec(dispatch) {
-                try {
-                    const payload = await promise           //ожидаем промиса;
-                    let result = Object.values(payload.data)[0];
-                    dispatch(actionAuthLogin(result)); //сигнализируем redux, что промис успешно выполнен
-                    return result;                               //в месте запуска store.dispatch с этим thunk можно так же получить результат промиса
-                }
-                catch (error) {
-                    dispatch(actionLogOut())           //в случае ошибки - сигнализируем redux, что промис несложился
-                }
-            };
-        }*/
-        const actionPending = (name) => ({ type: 'PROMISE', name: name, status: 'PENDING' });
-        const actionFulfilled = (name, payload) => ({ type: 'PROMISE', name: name, payload: payload, status: 'FULFILLED' });
-        const actionRejected = (name, error) => ({ type: 'PROMISE', name: name, error: error, status: 'REJECTED' });
-        const actionAuthLogin = token => ({ type: 'AUTH_LOGIN', token });
-        const actionAuthLogout = () => ({ type: 'AUTH_LOGOUT' });
-
-        ///////////////////////////////////////
-        const gqlRootCats = () => {
-            const catQuery = `query roots {
-                CategoryFind(query: "[{\\"parent\\": null }]") {
-                                        _id name
-                                    }}`;
-            return gql("http://shop-roles.node.ed.asmer.org.ua/graphql", catQuery);
-        }
-        const actionRootCats = () =>
-            actionPromiseGql('rootCats', gqlRootCats());
-        const gqlCategoryFindOne = (id) => {
-            const catQuery = `query CategoryFindOne($q: String) {
-                    CategoryFindOne(query: $q) {
-                            _id name
-                            parent { _id name }
-                            subCategories { _id name }
-                            goods { _id name price description
-                            images { url }
-                        }
-                    }
-                }`;
-            return gql("http://shop-roles.node.ed.asmer.org.ua/graphql", catQuery, { q: `[{\"_id\": \"${id}\"}]` });
-        }
-        const actionCategoryFindOne = (id) =>
-            actionPromiseGql('catFindOne', gqlCategoryFindOne(id));
-        const gqlGoodFindOne = (id) => {
-            const catQuery = `
-                        query GoodFindOne($q: String) {
-                            GoodFindOne(query: $q) {
-                                _id name  price description
-                                images {
-                                    url
-                                }
-                            }
-                        }
-                        `;
-            return gql("http://shop-roles.node.ed.asmer.org.ua/graphql", catQuery, { q: `[{\"_id\": \"${id}\"}]` });
-        }
-        const actionGoodFindOne = (id) =>
-            actionPromiseGql('goodsFindOne', gqlGoodFindOne(id));
-        //////////////////////////////////
-        const actionLogin = (login, password) => {
-            const upsertQuery = `query login($login:String, $password:String){
-                            	login(login:$login, password:$password)
-                        }`;
-
-            return gql("http://shop-roles.node.ed.asmer.org.ua/graphql", upsertQuery, { login: login, password: password });
-        }
-        const actionFullLogin = (login, password) => {
-            return gqlFullLogin = async (dispatch) => {
-                //dispatch возвращает то, что вернул thunk, возвращаемый actionLogin, а там промис, 
-                //так как actionPromise возвращает асинхронную функцию
-                let promiseResult = dispatch((dispatch) => actionLogin(login, password));
-                let res = await promiseResult;
-                if (res && res.data) {
-                    let token = Object.values(res.data)[0];
-                    if (token && typeof token == 'string')
-                        return dispatch(actionAuthLogin(token));
-                }
-                //проверьте что token - строка и отдайте его в actionAuthLogin
-            }
-        }
-        ////////////////////////////////////////
-        const actionUpsert = (login, password) => {
-            const loginQuery = `mutation UserRegistration($login: String, $password: String) {
-                                    UserUpsert(user: {login: $login, password: $password}) {
-                                        _id createdAt
-                                    }
-                                }`;
-
-            return gql("http://shop-roles.node.ed.asmer.org.ua/graphql", loginQuery, { login: login, password: password });
-        }
-        const actionFullUpsert = (login, password) => {
-            return gqlFullUpsert = async (dispatch) => {
-                //dispatch возвращает то, что вернул thunk, возвращаемый actionLogin, а там промис, 
-                //так как actionPromise возвращает асинхронную функцию
-                let promiseResult = dispatch((dispatch) => actionUpsert(login, password));
-                let res = await promiseResult;
-                dispatch(actionFullLogin(login, password));
-                //проверьте что token - строка и отдайте его в actionAuthLogin
-            }
-        }
-        ////////////////////////////////////////
-        const store = createStore(combineReducers({ promiseReducer, authReducer }));
-
-        store.subscribe(() => {
-            console.log(store.getState())
-        });
-        //store.dispatch(actionRootCats());
-        //store.dispatch(actionCategoryFindOne("6262ca7dbf8b206433f5b3d1"));
-        //store.dispatch(actionGoodFindOne("62d3099ab74e1f5f2ec1a125"));
-        //store.dispatch(actionFullLogin("Berg", "123456789"));
-        //store.dispatch(actionFullUpsert("Berg1", "12345678911"));
-
-
-    </script>
-</body>

+ 122 - 60
js/lesson21/Gql_promis_ copyexperimental_prog.html

@@ -1,6 +1,27 @@
 <Header>Gql</Header>
 
 <body>
+    <header>
+        <div id='cartIcon'></div>
+    </header>
+    <div id='mainContainer'>
+        <aside id='aside'>
+            Категории
+            Сюда надо воткнуть список корневых категорий интернет-магазина
+            <a href="#/people/1">Luke</a>
+            <a href="#/people/2">C-3PO</a>
+            <a href="#/people/3">R2-D2</a>
+            <a href="#/people/4">Dart Vader</a>
+
+            <a href="#/films/4">new hope</a>
+            <a href="#/films/5">пятая часть</a>
+            <a href="#/films/3">шестая часть</a>
+        </aside>
+        <main id='main'>
+            Контент
+        </main>
+    </div>
+
     <script>
         function jwtDecode(token) {                         // расщифровки токена авторизации
             if (!token || typeof token != "string")
@@ -114,17 +135,19 @@
                     if (!newState.payload) {
                         newState.token = undefined;
                     }
-                    window.localStorage.authToken = newState.token;
+                    if (newState.token)
+                        localStorage.authToken = newState.token;
+                    else
+                        delete localStorage.authToken;
                     return newState;
                 }
                 else if (action.type === 'AUTH_LOGOUT') {
                     let newState = { ...state };
                     newState.token = undefined;
                     newState.payload = undefined;
+                    delete localStorage.authToken;
                     return newState;
                 }
-                else
-                    localStorage.authToken = undefined;
             }
             return state;
         }
@@ -170,8 +193,9 @@
                             variables: vars
                         })
                 };
-                if (window.localStorage.authToken) {
-                    fetchSettings.headers["Authorization"] = `Bearer ${window.localStorage.authToken}`;
+                let authToken = window.localStorage.authToken;
+                if (authToken) {
+                    fetchSettings.headers["Authorization"] = `Bearer ${authToken}`;
                 }
                 return fetch(url, fetchSettings)
                     .then(res => {
@@ -182,30 +206,14 @@
                     });
             }
         }
-        function gql(url, query, vars) {
-            let fetchSettings =
-            {
-                method: "POST",
-                headers:
-                {
-                    "Content-Type": "application/json",
-                    "Accept": "application/json"
-                },
-                body: JSON.stringify(
-                    {
-                        query: query,
-                        variables: vars
-
-                    })
-            };
-            return fetch(url, fetchSettings).then(res => res.json());
-        }
-
-        const actionPromiseGql = (name, promise) => {
-            return actionPromiseGqlInt = async (dispatch) => {
+        const gql = getGql("http://shop-roles.node.ed.asmer.org.ua/graphql");
+        const actionPromise = (name, promise) => {
+            return actionPromiseInt = async (dispatch) => {
                 dispatch(actionPending(name)) //сигнализируем redux, что промис начался
                 try {
-                    const payload = await promise //ожидаем промиса
+                    let payload = await promise //ожидаем промиса
+                    if (payload && payload.data)
+                        payload = Object.values(payload.data)[0];
                     dispatch(actionFulfilled(name, payload)) //сигнализируем redux, что промис успешно выполнен
                     return payload //в месте запуска store.dispatch с этим thunk можно так же получить результат промиса
                 }
@@ -214,19 +222,7 @@
                 }
             }
         }
-        /*function actionAuthGql(promise) {
-            return async function Exec(dispatch) {
-                try {
-                    const payload = await promise           //ожидаем промиса;
-                    let result = Object.values(payload.data)[0];
-                    dispatch(actionAuthLogin(result)); //сигнализируем redux, что промис успешно выполнен
-                    return result;                               //в месте запуска store.dispatch с этим thunk можно так же получить результат промиса
-                }
-                catch (error) {
-                    dispatch(actionLogOut())           //в случае ошибки - сигнализируем redux, что промис несложился
-                }
-            };
-        }*/
+
         const actionPending = (name) => ({ type: 'PROMISE', name: name, status: 'PENDING' });
         const actionFulfilled = (name, payload) => ({ type: 'PROMISE', name: name, payload: payload, status: 'FULFILLED' });
         const actionRejected = (name, error) => ({ type: 'PROMISE', name: name, error: error, status: 'REJECTED' });
@@ -244,10 +240,10 @@
                 CategoryFind(query: "[{\\"parent\\": null }]") {
                                         _id name
                                     }}`;
-            return gql("http://shop-roles.node.ed.asmer.org.ua/graphql", catQuery);
+            return gql(catQuery);
         }
         const actionRootCats = () =>
-            actionPromiseGql('rootCats', gqlRootCats());
+            actionPromise('rootCats', gqlRootCats());
         const gqlCategoryFindOne = (id) => {
             const catQuery = `query CategoryFindOne($q: String) {
                     CategoryFindOne(query: $q) {
@@ -259,10 +255,10 @@
                         }
                     }
                 }`;
-            return gql("http://shop-roles.node.ed.asmer.org.ua/graphql", catQuery, { q: `[{\"_id\": \"${id}\"}]` });
+            return gql(catQuery, { q: `[{\"_id\": \"${id}\"}]` });
         }
         const actionCategoryFindOne = (id) =>
-            actionPromiseGql('catFindOne', gqlCategoryFindOne(id));
+            actionPromise('catFindOne', gqlCategoryFindOne(id));
         const gqlGoodFindOne = (id) => {
             const catQuery = `
                         query GoodFindOne($q: String) {
@@ -274,17 +270,17 @@
                             }
                         }
                         `;
-            return gql("http://shop-roles.node.ed.asmer.org.ua/graphql", catQuery, { q: `[{\"_id\": \"${id}\"}]` });
+            return gql(catQuery, { q: `[{\"_id\": \"${id}\"}]` });
         }
         const actionGoodFindOne = (id) =>
-            actionPromiseGql('goodsFindOne', gqlGoodFindOne(id));
+            actionPromise('goodsFindOne', gqlGoodFindOne(id));
         //////////////////////////////////
         const actionLogin = (login, password) => {
             const upsertQuery = `query login($login:String, $password:String){
                             	login(login:$login, password:$password)
                         }`;
 
-            return gql("http://shop-roles.node.ed.asmer.org.ua/graphql", upsertQuery, { login: login, password: password });
+            return gql(upsertQuery, { login: login, password: password });
         }
         const actionFullLogin = (login, password) => {
             return gqlFullLogin = async (dispatch) => {
@@ -308,7 +304,7 @@
                                     }
                                 }`;
 
-            return gql("http://shop-roles.node.ed.asmer.org.ua/graphql", loginQuery, { login: login, password: password });
+            return gql(loginQuery, { login: login, password: password });
         }
         const actionFullAuthUpsert = (login, password) => {
             return gqlFullAuthUpsert = async (dispatch) => {
@@ -327,8 +323,7 @@
                                         _id
                                     }
                                 }`;
-            let gqlFunc = getGql("http://shop-roles.node.ed.asmer.org.ua/graphql");
-            return gqlFunc(orderUpsertQuery, { order: { "_id": id, "orderGoods": order } });
+            return gql(orderUpsertQuery, { order: { "_id": id, "orderGoods": order } });
         }
         const orderFullUpsert = () => {
             return gqlFullOrderUpsert = async (dispatch, getState) => {
@@ -363,10 +358,10 @@
                                         }
                                     }
                                     }`;
-            return getGql("http://shop-roles.node.ed.asmer.org.ua/graphql")(findOrdersQuery);
+            return gql(findOrdersQuery);
         }
         const actionFindOrders = () =>
-            actionPromiseGql('orders', gqlFindOrders());
+            actionPromise('orders', gqlFindOrders());
         ///////////////////////////////////////////////////
 
         const store = createStore(combineReducers({ promiseReducer, authReducer, cartReducer: localStoredReducer(cartReducer, 'cart') }));
@@ -375,20 +370,87 @@
             ok(ms);
         }, ms));
         store.subscribe(() => {
-            console.log(store.getState());
+            console.log({ state: store.getState() });
         });
         //////////////////////////////////////////////
+        store.subscribe(() => {
+            console.log(store.getState());
+        });
+
+        const fillRootCategories = (categories) => {
+            aside.innerText = '';
+            if (!categories)
+                return;
+            for (category of categories) {
+                let el = document.createElement('a');
+                el.innerText = `${category.name}`;
+                el.href = `"#/category/${category._id}`;
+                aside.appendChild(el);
+            }
+        }
+
+        store.subscribe(() => {
+            let state = store.getState();
+            let rootCatsPromisRes = state.promiseReducer?.rootCats;
+            if (rootCatsPromisRes?.status == "FULFILLED") {
+                let rootCats = rootCatsPromisRes.payload;
+                fillRootCategories(rootCats);
+            }
+            else
+                fillRootCategories(undefined);
+        });
+        /*
+                window.onhashchange = () => {
+                    const [, route, _id] = location.hash.split('/')
+        
+                    const routes = {
+                        people() {
+                            console.log('People', _id)
+                            store.dispatch(actionGetPeople(_id))
+                        },
+                        films() {
+                            store.dispatch(actionGetFilm(_id))
+                        },
+                        //category() {
+                        //store.dispatch(actionCategoryById(_id))
+                        //},
+                        //good(){
+                        ////тут был store.dispatch goodById
+                        //console.log('good', _id)
+                        //},
+                        login() {
+                            console.log('А ТУТ ЩА ДОЛЖНА БЫТЬ ФОРМА ЛОГИНА')
+                            //нарисовать форму логина, которая по нажатию кнопки Login делает store.dispatch(actionFullLogin(login, password))
+                        },
+                        //register(){
+                        ////нарисовать форму регистрации, которая по нажатию кнопки Login делает store.dispatch(actionFullRegister(login, password))
+                        //},
+                    }
+        
+                    if (route in routes) {
+                        routes[route]()
+                    }
+                }
+        
+                window.onhashchange()
+        */
+
+
+
 
-        //store.dispatch(actionRootCats());
-        //store.dispatch(actionCategoryFindOne("6262ca7dbf8b206433f5b3d1"));
-        //store.dispatch(actionGoodFindOne("62d3099ab74e1f5f2ec1a125"));
-        //store.dispatch(actionFullLogin("Berg", "123456789"));
+        store.dispatch(actionRootCats());
+        /*store.dispatch(actionCategoryFindOne("6262ca7dbf8b206433f5b3d1"));
+        store.dispatch(actionGoodFindOne("62d3099ab74e1f5f2ec1a125"));
+        store.dispatch(actionFullLogin("Berg", "123456789"));
         //store.dispatch(actionFullAuthUpsert("Berg1", "12345678911"));
-        //store.dispatch(actionCartAdd({ _id: '62d30938b74e1f5f2ec1a124', price: 50 }));
+        store.dispatch(actionCartAdd({ _id: '62d30938b74e1f5f2ec1a124', price: 50 }));
 
-        //delay(3000, ()=>store.dispatch(orderFullUpsert()));
+        delay(3000, () => {
+            store.dispatch(orderFullUpsert());
+            store.dispatch(actionFindOrders());
+        });*/
 
-        delay(3000, () => store.dispatch(actionFindOrders()));
+        //delay(500, () => store.dispatch(actionFindOrders()));
 
     </script>
 </body>

js/lesson21/getGQL.html → js/lesson21_Module/getGQL.html