123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849 |
- {//все готово до выполнения модуля
- // // delay
- // const delay = ms => new Promise(ok => setTimeout(() => ok(ms), ms))
- // // createStore
- // 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, которая удаляет подписчика из списка
- // const 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 в объект
- // }
- // }
- // // ========================================================================================================
- // // promiseReducer
- // function promiseReducer(state = {}, { type, status, payload, error, nameOfPromise }) {
- // if (type === 'PROMISE') {
- // return {
- // ...state,
- // [nameOfPromise]: { status, payload, error }
- // }
- // }
- // return state
- // }
- // // Акшоны:
- // // Соответственно, имя промиса будет передаваться в редьюсер как ключ в объекте action, а так же:
- // const actionPending = nameOfPromise => ({ nameOfPromise, type: 'PROMISE', status: 'PENDING' }) // в actionPending - единственный параметр
- // const actionFulfilled = (nameOfPromise, payload) => ({ nameOfPromise, type: 'PROMISE', status: 'FULFILLED', payload }) // как первый параметр, payload станет вторым параметром
- // const actionRejected = (nameOfPromise, error) => ({ nameOfPromise, type: 'PROMISE', status: 'REJECTED', error }) // по аналогии с actionFulfilled
- // const actionPromise = (nameOfPromise, promise) => // первый параметр, второй параметр - сам промис, который мы будем обрабатывать;
- // async dispatch => {
- // dispatch(actionPending(nameOfPromise)) //сигнализируем redux, что промис начался
- // try {
- // const payload = await promise //ожидаем промиса
- // dispatch(actionFulfilled(nameOfPromise, payload)) //сигнализируем redux, что промис успешно выполнен
- // return payload //в месте запуска store.dispatch с этим thunk можно так же получить результат промиса
- // }
- // catch (error) {
- // dispatch(actionRejected(nameOfPromise, error)) //в случае ошибки - сигнализируем redux, что промис несложился
- // }
- // }
- // //=========================================================================================================
- // // authReducer
- // const jwtDecode = function (token) {
- // try {
- // let parseData = token.split('.')[1]
- // return JSON.parse(atob(parseData))
- // }
- // catch (e) {
- // return undefined
- // }
- // }
- // function authReducer(state = {}, { type, token }) {
- // if (type === 'AUTH_LOGIN') {
- // let payload = jwtDecode(token)
- // return state = {
- // token,
- // payload
- // }
- // }
- // if (type === 'AUTH_LOGOUT') {
- // return {}
- // }
- // return state
- // }
- // // проверка (и экшенкриейторы бонусом):
- // const actionAuthLogin = token => ({ type: 'AUTH_LOGIN', token })
- // const actionAuthLogout = () => ({ type: 'AUTH_LOGOUT' })
- // // const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOnsiaWQiOiI2Mzc3ZTEzM2I3NGUxZjVmMmVjMWMxMjUiLCJsb2dpbiI6InRlc3Q1IiwiYWNsIjpbIjYzNzdlMTMzYjc0ZTFmNWYyZWMxYzEyNSIsInVzZXIiXX0sImlhdCI6MTY2ODgxMjQ1OH0.t1eQlRwkcP7v9JxUPMo3dcGKprH-uy8ujukNI7xE3A0"
- // //=========================================================================================================
- // // cartReducer
- // function cartReducer(state = {}, { type, count, good }) {
- // if (type === 'CART_ADD') {
- // return {
- // ...state,
- // [good._id]: {
- // good,
- // count: (state[good._id] ? state[good._id].count + count : count)
- // }
- // }
- // }
- // if (type === 'CART_SUB') {
- // if (state[good._id]) {
- // let newCount = state[good._id].count - count
- // if (newCount > 0) {
- // return {
- // ...state,
- // [good._id]: {
- // good,
- // count: newCount
- // }
- // }
- // } else {
- // delete state[good._id]
- // return { ...state }
- // }
- // } else {
- // return undefined
- // }
- // }
- // if (type === 'CART_DEL') {
- // delete state[good._id]
- // return { ...state }
- // }
- // if (type === 'CART_SET') {
- // if (count > 0) {
- // return {
- // ...state,
- // [good._id]: {
- // good,
- // count
- // }
- // }
- // } else {
- // delete state[good._id]
- // return { ...state }
- // }
- // }
- // if (type === 'CART_CLEAR') {
- // return state = {}
- // }
- // return state
- // }
- // // экшоны:
- // // Добавление товара.Должен добавлять новый ключ в state, или обновлять, если ключа в state ранее не было, увеличивая количество
- // const actionCartAdd = (good, count = 1) => ({ type: 'CART_ADD', count, good })
- // // Уменьшение количества товара.Должен уменьшать количество товара в state, или удалять его если количество будет 0 или отрицательным
- // const actionCartSub = (good, count = 1) => ({ type: 'CART_SUB', count, good })
- // // Удаление товара.Должен удалять ключ из state
- // const actionCartDel = (good) => ({ type: 'CART_DEL', good })
- // // Задание количества товара.В отличие от добавления и уменьшения, не учитывает того количества, которое уже было в корзине, а тупо назначает количество поверху(или создает новый ключ, если в корзине товара не было).Если count 0 или отрицательное число - удаляем ключ из корзины;
- // const actionCartSet = (good, count = 1) => ({ type: 'CART_SET', count, good })
- // // Очистка корзины.state должен стать пустым объектом { }
- // const actionCartClear = () => ({ type: 'CART_CLEAR' })
- // //=========================================================================================================
- // // ========================================================================================================
- // // GraphQL запросы
- // // Запрос на список корневых категорий
- // const findCategory = `query baseCategory($searchVariablesCategory: String){
- // CategoryFind(query: $searchVariablesCategory){
- // _id name parent {
- // _id
- // name
- // }
- // }
- // }`
- // const findCategoryVar = {
- // searchVariablesCategory: JSON.stringify([{ parent: null }])
- // }
- // const actionCategoryFind = () => actionPromise('CategoryFind', gql(findCategory, findCategoryVar))
- // //=========================================================================================================
- // // Запрос для получения одной категории с товарами и картинками
- // const findOneCategory = `query categoryFindOne($searchVariablesCategoryOne: String,) {
- // CategoryFindOne(query: $searchVariablesCategoryOne){
- // _id name parent{
- // _id name
- // }
- // goods{
- // _id name description price
- // images{
- // url
- // }
- // }
- // subCategories{
- // _id name
- // }
- // }
- // }`
- // const findOneCategoryVar = {
- // searchVariablesCategoryOne: JSON.stringify([{ _id: "6262ca7dbf8b206433f5b3d1" }])
- // }
- // const actionCategoryFindOne = () => actionPromise('CategoryFindOne', gql(findOneCategory, findOneCategoryVar))
- // //=========================================================================================================
- // // Запрос на получение товара с описанием и картинками
- // const findGoodWithImage = `query oneGoodWithImages($searchVariablesGoodOne: String) {
- // GoodFindOne(query: $searchVariablesGoodOne){
- // _id name price description images {
- // url
- // }
- // }
- // }
- // `
- // const findGoodWithImageVar = {
- // searchVariablesGoodOne: JSON.stringify([{ _id: "62c9472cb74e1f5f2ec1a0d3" }])
- // }
- // const actionGoodFindOne = () => actionPromise('GoodFindOne', gql(findGoodWithImage, findGoodWithImageVar))
- // //=========================================================================================================
- // // Запрос на регистрацию - работает, если не залогинен пользователь
- // const registration = `mutation registration($loginReg:String,$passwordReg:String ){
- // UserUpsert(user:{
- // login:$loginReg, password:$passwordReg
- // }){
- // _id createdAt
- // }
- // }`
- // const registrationVar = {
- // loginReg: "abababa", // вот тут нужно в параметры запихнуть переменную, которую будем получать
- // passwordReg: "123123" // вот тут нужно в параметры запихнуть переменную, которую будем получать
- // }
- // const actionUserUpsert = () => actionPromise('UserUpsert', gql(registration, registrationVar))
- // //=========================================================================================================
- // // Запрос на логин
- // const checkLogin = `query login($login: String, $password: String){
- // login(login: $login, password: $password)
- // }
- // `
- // const checkLoginVar = {
- // login: "abababa", // вот тут нужно в параметры запихнуть переменную, которую будем получать
- // password: "123123" // вот тут нужно в параметры запихнуть переменную, которую будем получать
- // }
- // const actionLogin = () => actionPromise('login', gql(checkLogin, checkLoginVar))
- // //=========================================================================================================
- // // Запрос истории заказов - нужно учитывать, что работает только, если вместе с заголовком отправить JWT-token от пользователя
- // const orderFind = `query order ($order: String){
- // OrderFind(query: $order){
- // _id total orderGoods{
- // good {
- // _id
- // name
- // price
- // }
- // }
- // }
- // }
- // `
- // const orderFindVar = {
- // order: JSON.stringify([{}])
- // }
- // const actionOrderFind = () => actionPromise('login', gql(orderFind, orderFindVar))
- // //=========================================================================================================
- // // Запрос оформления заказа - нужно добить: После успешного оформления заказа на бэке задиспатчить экшон очистки корзины
- // const orderCreate = `mutation myOrder($createOrder: OrderInput){
- // OrderUpsert(order: $createOrder) {
- // orderGoods{
- // count good{
- // _id
- // }
- // }
- // }
- // }`
- // const orderCreateVar = {
- // createOrder: JSON.stringify({ orderGoods: { count: 2, good: { _id: "62c9472cb74e1f5f2ec1a0d2" } } }) // вот тут нужно в параметры запихнуть переменную, которую будем получать
- // }
- // const actionOrderUpsert = () => actionPromise('login', gql(orderCreate, orderCreateVar))
- // // ========================================================================================================
- // // ========================================================================================================
- // // Вспомогательные функции
- // // getGql - переделка из HW18 функции gql (делаем запрос на бэк)
- // function getGql(endpoint) {
- // let headers = {
- // 'Content-Type': 'application/json;charset=utf-8',
- // 'Accept': 'application/json',
- // }
- // if ('authToken' in localStorage) {
- // headers.Authorization = 'Bearer ' + localStorage.authToken
- // }
- // return async function gql(query, variables = {}) {
- // let result = await fetch(endpoint, {
- // method: 'POST',
- // headers,
- // body: JSON.stringify({
- // query,
- // variables
- // })
- // }).then(res => res.json())
- // if (('errors' in result) && !('data' in result)) {
- // throw new Error(JSON.stringify(result.errors))
- // }
- // result = Object.values(result.data)[0]
- // return result
- // }
- // }
- // //=========================================================================================================
- // // localStoredReducer
- // function localStoredReducer(originalReducer, localStorageKey) {
- // function wrapper(state, action) {
- // if (!state) {
- // try {
- // return JSON.parse(localStorage[localStorageKey])
- // }
- // catch (error) {
- // }
- // }
- // const newState = originalReducer(state, action)
- // localStorage[localStoredReducer] = JSON.stringify(newState)
- // return newState
- // }
- // return wrapper
- // }
- // //=========================================================================================================
- // // Модуль
- }
- // createStore
- 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, которая удаляет подписчика из списка
- const 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 combineReducers(reducers) {
- function totalReducer(state = {}, action) {
- const newTotalState = {}
- for (const [reducerName, reducer] of Object.entries(reducers)) {
- const newSubState = reducer(state[reducerName], action)
- if (newSubState !== state[reducerName]) {
- newTotalState[reducerName] = newSubState
- }
- }
- if (Object.keys(newTotalState).length) {
- return { ...state, ...newTotalState }
- }
- return state
- }
- return totalReducer
- }
- // создаем объект с редьюсерами
- const reducers = {
- promise: promiseReducer, //допилить много имен для многих промисо
- auth: authReducer, //часть предыдущего ДЗ
- cart: cartReducer, //часть предыдущего ДЗ
- }
- // скармливаем объект с редьюсерами в компайн-редьюсер
- const totalReducer = combineReducers(reducers)
- // ========================================================================================================
- // promiseReducer
- function promiseReducer(state = {}, { type, status, payload, error, nameOfPromise }) {
- if (type === 'PROMISE') {
- return {
- ...state,
- [nameOfPromise]: { status, payload, error }
- }
- }
- return state
- }
- // Акшоны:
- // Соответственно, имя промиса будет передаваться в редьюсер как ключ в объекте action, а так же:
- const actionPending = nameOfPromise => ({ nameOfPromise, type: 'PROMISE', status: 'PENDING' }) // в actionPending - единственный параметр
- const actionFulfilled = (nameOfPromise, payload) => ({ nameOfPromise, type: 'PROMISE', status: 'FULFILLED', payload }) // как первый параметр, payload станет вторым параметром
- const actionRejected = (nameOfPromise, error) => ({ nameOfPromise, type: 'PROMISE', status: 'REJECTED', error }) // по аналогии с actionFulfilled
- const actionPromise = (nameOfPromise, promise) => // первый параметр, второй параметр - сам промис, который мы будем обрабатывать;
- async dispatch => {
- dispatch(actionPending(nameOfPromise)) //сигнализируем redux, что промис начался
- try {
- const payload = await promise //ожидаем промиса
- dispatch(actionFulfilled(nameOfPromise, payload)) //сигнализируем redux, что промис успешно выполнен
- return payload //в месте запуска store.dispatch с этим thunk можно так же получить результат промиса
- }
- catch (error) {
- dispatch(actionRejected(nameOfPromise, error)) //в случае ошибки - сигнализируем redux, что промис несложился
- }
- }
- const store = createStore(totalReducer) // создаем магаз с редюсером
- store.subscribe(() => console.log(store.getState())) // для контроля выводим все изменения в магазине в консоль
- //=========================================================================================================
- // authReducer
- const jwtDecode = function (token) {
- try {
- let parseData = token.split('.')[1]
- return JSON.parse(atob(parseData))
- }
- catch (e) {
- return undefined
- }
- }
- function authReducer(state = {}, { type, token }) {
- if (type === 'AUTH_LOGIN') {
- let payload = jwtDecode(token)
- return state = {
- token,
- payload
- }
- }
- if (type === 'AUTH_LOGOUT') {
- return {}
- }
- return state
- }
- // проверка (и экшенкриейторы бонусом):
- const actionAuthLogin = token => ({ type: 'AUTH_LOGIN', token })
- const actionAuthLogout = () => ({ type: 'AUTH_LOGOUT' })
- // const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOnsiaWQiOiI2Mzc3ZTEzM2I3NGUxZjVmMmVjMWMxMjUiLCJsb2dpbiI6InRlc3Q1IiwiYWNsIjpbIjYzNzdlMTMzYjc0ZTFmNWYyZWMxYzEyNSIsInVzZXIiXX0sImlhdCI6MTY2ODgxMjQ1OH0.t1eQlRwkcP7v9JxUPMo3dcGKprH-uy8ujukNI7xE3A0"
- //=========================================================================================================
- // cartReducer
- function cartReducer(state = {}, { type, count, good }) {
- if (type === 'CART_ADD') {
- return {
- ...state,
- [good._id]: {
- good,
- count: (state[good._id] ? state[good._id].count + count : count)
- }
- }
- }
- if (type === 'CART_SUB') {
- if (state[good._id]) {
- let newCount = state[good._id].count - count
- if (newCount > 0) {
- return {
- ...state,
- [good._id]: {
- good,
- count: newCount
- }
- }
- } else {
- delete state[good._id]
- return { ...state }
- }
- } else {
- return undefined
- }
- }
- if (type === 'CART_DEL') {
- delete state[good._id]
- return { ...state }
- }
- if (type === 'CART_SET') {
- if (count > 0) {
- return {
- ...state,
- [good._id]: {
- good,
- count
- }
- }
- } else {
- delete state[good._id]
- return { ...state }
- }
- }
- if (type === 'CART_CLEAR') {
- return state = {}
- }
- return state
- }
- // экшоны:
- // Добавление товара.Должен добавлять новый ключ в state, или обновлять, если ключа в state ранее не было, увеличивая количество
- const actionCartAdd = (good, count = 1) => ({ type: 'CART_ADD', count, good })
- // Уменьшение количества товара.Должен уменьшать количество товара в state, или удалять его если количество будет 0 или отрицательным
- const actionCartSub = (good, count = 1) => ({ type: 'CART_SUB', count, good })
- // Удаление товара.Должен удалять ключ из state
- const actionCartDel = (good) => ({ type: 'CART_DEL', good })
- // Задание количества товара.В отличие от добавления и уменьшения, не учитывает того количества, которое уже было в корзине, а тупо назначает количество поверху(или создает новый ключ, если в корзине товара не было).Если count 0 или отрицательное число - удаляем ключ из корзины;
- const actionCartSet = (good, count = 1) => ({ type: 'CART_SET', count, good })
- // Очистка корзины.state должен стать пустым объектом { }
- const actionCartClear = () => ({ type: 'CART_CLEAR' })
- //=========================================================================================================
- // ========================================================================================================
- // GraphQL запросы
- // Запрос на список корневых категорий
- const findCategory = `query baseCategory($searchVariablesCategory: String){
- CategoryFind(query: $searchVariablesCategory){
- _id name parent {
- _id
- name
- }
- }
- }`
- const findCategoryVar = {
- searchVariablesCategory: JSON.stringify([{ parent: null }])
- }
- const actionCategoryFind = () => actionPromise('CategoryFind', gql(findCategory, findCategoryVar))
- //=========================================================================================================
- // Запрос для получения одной категории с товарами и картинками
- const findOneCategory = `query categoryFindOne($searchVariablesCategoryOne: String,) {
- CategoryFindOne(query: $searchVariablesCategoryOne){
- _id name parent{
- _id name
- }
- goods{
- _id name description price
- images{
- url
- }
- }
- subCategories{
- _id name
- }
- }
- }`
- const findOneCategoryVar = {
- searchVariablesCategoryOne: JSON.stringify([{ _id: "6262ca7dbf8b206433f5b3d1" }])
- }
- const actionCategoryFindOne = () => actionPromise('CategoryFindOne', gql(findOneCategory, findOneCategoryVar))
- //=========================================================================================================
- // Запрос на получение товара с описанием и картинками
- const findGoodWithImage = `query oneGoodWithImages($searchVariablesGoodOne: String) {
- GoodFindOne(query: $searchVariablesGoodOne){
- _id name price description images {
- url
- }
- }
- }
- `
- const findGoodWithImageVar = {
- searchVariablesGoodOne: JSON.stringify([{ _id: "62c9472cb74e1f5f2ec1a0d3" }])
- }
- const actionGoodFindOne = () => actionPromise('GoodFindOne', gql(findGoodWithImage, findGoodWithImageVar))
- //=========================================================================================================
- // Запрос на регистрацию - работает, если не залогинен пользователь
- const registration = `mutation registration($loginReg:String,$passwordReg:String ){
- UserUpsert(user:{
- login:$loginReg, password:$passwordReg
- }){
- _id createdAt
- }
- }`
- const registrationVar = {
- loginReg: "abababa", // вот тут нужно в параметры запихнуть переменную, которую будем получать
- passwordReg: "123123" // вот тут нужно в параметры запихнуть переменную, которую будем получать
- }
- const actionUserUpsert = () => actionPromise('UserUpsert', gql(registration, registrationVar))
- //=========================================================================================================
- // Запрос на логин
- const checkLogin = `query login($login: String, $password: String){
- login(login: $login, password: $password)
- }
- `
- const checkLoginVar = {
- login: "abababa", // вот тут нужно в параметры запихнуть переменную, которую будем получать
- password: "123123" // вот тут нужно в параметры запихнуть переменную, которую будем получать
- }
- const actionLogin = () => actionPromise('login', gql(checkLogin, checkLoginVar))
- //=========================================================================================================
- // Запрос истории заказов - нужно учитывать, что работает только, если вместе с заголовком отправить JWT-token от пользователя
- const orderFind = `query order ($order: String){
- OrderFind(query: $order){
- _id total orderGoods{
- good {
- _id
- name
- price
- }
- }
- }
- }
- `
- const orderFindVar = {
- order: JSON.stringify([{}])
- }
- const actionOrderFind = () => actionPromise('login', gql(orderFind, orderFindVar))
- //=========================================================================================================
- // Запрос оформления заказа - нужно добить: После успешного оформления заказа на бэке задиспатчить экшон очистки корзины
- const orderCreate = `mutation myOrder($createOrder: OrderInput){
- OrderUpsert(order: $createOrder) {
- orderGoods{
- count good{
- _id
- }
- }
- }
- }`
- const orderCreateVar = {
- createOrder: JSON.stringify({ orderGoods: { count: 2, good: { _id: "62c9472cb74e1f5f2ec1a0d2" } } }) // вот тут нужно в параметры запихнуть переменную, которую будем получать
- }
- const actionOrderUpsert = () => actionPromise('login', gql(orderCreate, orderCreateVar))
- // ========================================================================================================
- // ========================================================================================================
- // Вспомогательные функции
- // getGql - переделка из HW18 функции gql (делаем запрос на бэк)
- function getGql(endpoint) {
- let headers = {
- 'Content-Type': 'application/json;charset=utf-8',
- 'Accept': 'application/json',
- }
- if ('authToken' in localStorage) {
- headers.Authorization = 'Bearer ' + localStorage.authToken
- }
- return async function gql(query, variables = {}) {
- let result = await fetch(endpoint, {
- method: 'POST',
- headers,
- body: JSON.stringify({
- query,
- variables
- })
- }).then(res => res.json())
- if (('errors' in result) && !('data' in result)) {
- throw new Error(JSON.stringify(result.errors))
- }
- result = Object.values(result.data)[0]
- return result
- }
- }
- //=========================================================================================================
- // localStoredReducer
- function localStoredReducer(originalReducer, localStorageKey) {
- function wrapper(state, action) {
- if (!state) {
- try {
- return JSON.parse(localStorage[localStorageKey])
- }
- catch (error) {
- }
- }
- const newState = originalReducer(state, action)
- localStorage[localStoredReducer] = JSON.stringify(newState)
- return newState
- }
- return wrapper
- }
- //=========================================================================================================
- // Модуль
|