script.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. function createStore(reducer){
  2. let state = reducer(undefined, {})
  3. let cbs = []
  4. const getState = () => state
  5. const subscribe = cb => (cbs.push(cb),
  6. () => cbs = cbs.filter(c => c !== cb))
  7. const dispatch = action => {
  8. if (typeof action === 'function'){
  9. return action(dispatch, getState)
  10. }
  11. const newState = reducer(state, action)
  12. if (newState !== state){
  13. state = newState
  14. for (let cb of cbs) cb()
  15. }
  16. }
  17. return {
  18. getState,
  19. dispatch,
  20. subscribe
  21. }
  22. }
  23. const getGQL = url =>
  24. (query, variables) => fetch(url, {
  25. method: 'POST',
  26. headers: {
  27. "Content-Type": "application/json",
  28. // 'Accept' : 'application/json',
  29. ...(localStorage.authToken ? {"Authorization": "Bearer " + localStorage.authToken} : {})
  30. },
  31. body: JSON.stringify({query, variables})
  32. }).then(res => res.json())
  33. .then(data => {
  34. if (data.data){
  35. return Object.values(data.data)[0]
  36. }
  37. else throw new Error(JSON.stringify(data.errors))
  38. })
  39. const backendURL = 'http://shop-roles.asmer.fs.a-level.com.ua'
  40. const gql = getGQL(backendURL + '/graphql');
  41. const jwtDecode = token => {
  42. try{
  43. return JSON.parse(atob(token.split('.')[1]));
  44. }
  45. catch(e){
  46. console.log(e.name, e.message);
  47. }
  48. }
  49. function authReducer(state, {type, token}){
  50. if (state === undefined){
  51. if(localStorage.authToken){
  52. type = 'AUTH_LOGIN';
  53. token = localStorage.authToken
  54. }
  55. }
  56. if(type === 'AUTH_LOGIN'){
  57. let payload = jwtDecode(token);
  58. if (payload){
  59. localStorage.authToken = token
  60. return {token, payload}
  61. }
  62. }
  63. if(type === 'AUTH_LOGOUT'){
  64. localStorage.removeItem("authToken")
  65. return {}
  66. }
  67. return state || {}
  68. }
  69. function promiseReducer(state={}, {type, name, status, payload, error}){
  70. if (type === 'PROMISE'){
  71. return {
  72. ...state,
  73. [name]:{status, payload, error}
  74. }
  75. }
  76. return state
  77. }
  78. const combineReducers = (reducers) => (state={}, action) => {
  79. let newState = {}
  80. for (const [reducerName, reducer] of Object.entries(reducers)){
  81. let subNewState = reducer(state[reducerName],action)
  82. if(subNewState !== state[reducerName]){
  83. newState = {
  84. ...newState, [reducerName] : subNewState
  85. }
  86. }
  87. }
  88. if(Object.keys(newState).length > 0){
  89. return {
  90. ...state,...newState
  91. }
  92. }
  93. return state
  94. }
  95. const actionAuthLogin = (token) => ({type: 'AUTH_LOGIN', token});
  96. const actionAuthLogout = () => ({type: 'AUTH_LOGOUT'});
  97. const actionPending = name => ({type:'PROMISE',name, status: 'PENDING'})
  98. const actionFulfilled = (name,payload) => ({type:'PROMISE',name, status: 'FULFILLED', payload})
  99. const actionRejected = (name,error) => ({type:'PROMISE',name, status: 'REJECTED', error})
  100. const delay = ms => new Promise(ok => setTimeout(() => ok(ms), ms))
  101. const store = createStore(combineReducers({promise: promiseReducer, auth: authReducer}));
  102. store.subscribe(() => console.log(store.getState()))
  103. const actionPromise = (name, promise) =>
  104. async dispatch => {
  105. dispatch(actionPending(name))
  106. try {
  107. let payload = await promise
  108. dispatch(actionFulfilled(name, payload))
  109. return payload
  110. }
  111. catch(error){
  112. dispatch(actionRejected(name, error))
  113. }
  114. }
  115. const actionFullRegister = (log, pass) =>
  116. async dispatch => {
  117. let user = await dispatch(
  118. actionPromise('register', gql( `mutation register($login: String, $password: String) {
  119. UserUpsert(user: {login: $login, password: $password}) {
  120. _id
  121. login
  122. }
  123. }`, {login : log, password : pass}))
  124. )
  125. if(user){
  126. dispatch(actionFullLogin(log, pass));
  127. }
  128. }
  129. const actionFullLogin = (log, pass) =>
  130. async dispatch => {
  131. let token = await dispatch(
  132. actionPromise('login', gql(`query login($login: String, $password: String) {
  133. login(login: $login, password: $password)
  134. }`, {login: log, password: pass}))
  135. )
  136. if(token){
  137. dispatch(actionAuthLogin(token))
  138. }
  139. }
  140. store.dispatch(actionFullRegister('bd2404', '2404'))
  141. // store.dispatch(actionAuthLogout());
  142. const actionLuke = () => actionPromise('luke',
  143. fetch('https://swapi.dev/api/people/1')
  144. .then(res => res.json()))
  145. store.dispatch(actionLuke())
  146. const actionCategoryById = (_id) =>
  147. actionPromise('catById', gql(`query catById($q: String){
  148. CategoryFindOne(query: $q){
  149. _id name goods {
  150. _id name price images {
  151. url
  152. }
  153. }
  154. }
  155. }`, {q: JSON.stringify([{_id}])}));
  156. store.dispatch(actionCategoryById("5dc458985df9d670df48cc47"));
  157. const actionGoodById = (_id) =>
  158. actionPromise('goodById', gql(`query goodByid($goodId: String) {
  159. GoodFindOne(query: $goodId) {
  160. name
  161. price
  162. description
  163. images {
  164. url
  165. }
  166. }
  167. }`, {goodId: JSON.stringify([{_id}])}))
  168. store.dispatch(actionGoodById("5dc4a3e15df9d670df48cc6b"));
  169. const actionRootCategories = () =>
  170. actionPromise('rootCats', gql(`query {
  171. CategoryFind(query: "[{\\"parent\\":null}]"){
  172. _id name
  173. }
  174. }`))
  175. store.dispatch(actionRootCategories());
  176. const actionNewOrder = (order) =>
  177. actionPromise('newOrder', gql( `mutation newOrder($order: OrderInput) {
  178. OrderUpsert(order: $order) {
  179. _id
  180. total
  181. }
  182. }`, {order : order}
  183. )
  184. )
  185. let order = {
  186. orderGoods: [
  187. {count: 2, good: {_id: "5dcac57d6d09c45440d14cfc"}},
  188. {count: 2, good: {_id: "5dcac9ba6d09c45440d14d02"}},
  189. {count: 1, good: {_id: "5dc8844e0e36db246e3049bd"}},
  190. ]
  191. }
  192. // store.dispatch(actionNewOrder(order));
  193. const actionOrders = () =>
  194. actionPromise('allOrders', gql(`query findOrder($q: String) {
  195. OrderFind(query: $q) {
  196. _id
  197. total
  198. orderGoods {
  199. count
  200. good {
  201. name
  202. price
  203. }
  204. }
  205. }
  206. }`, {q: JSON.stringify([{}])}))
  207. // store.dispatch(actionOrders())