index.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>My</title>
  5. <meta charset='utf8' />
  6. <style>
  7. #mainContainer {
  8. display: flex;
  9. }
  10. #aside {
  11. width: 30%;
  12. }
  13. #aside > a {
  14. text-decoration: none;
  15. display: block;
  16. }
  17. img{
  18. width:250px;
  19. }
  20. #main a{
  21. text-decoration: none;
  22. border-bottom: 3px solid pink;
  23. padding-bottom: 1px
  24. }
  25. .link {
  26. display: block;
  27. }
  28. .good_item {
  29. text-align: center;
  30. }
  31. .description {
  32. text-align: right;
  33. }
  34. #i{
  35. margin-bottom: 30px;
  36. width: 50px;
  37. }
  38. </style>
  39. </head>
  40. <body>
  41. <header id="he">
  42. <a href="#/" id="cartIcon" ><img src="data:image/png;base64,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" id="i"></a>
  43. </header>
  44. <div id='mainContainer'>
  45. <aside id='aside'>
  46. Категории
  47. </aside>
  48. <main id='main'>
  49. Контент
  50. </main>
  51. </div>
  52. <script>
  53. function createStore(reducer) {
  54. let state = reducer(undefined, {})
  55. let cbs = []
  56. const getState = () => state
  57. const subscribe = cb => (cbs.push(cb),
  58. () => cbs = cbs.filter(c => c !== cb))
  59. const dispatch = action => {
  60. if (typeof action === 'function') {
  61. return action(dispatch, getState)
  62. }
  63. const newState = reducer(state, action)
  64. if (newState !== state) {
  65. state = newState
  66. for (let cb of cbs) cb()
  67. }
  68. }
  69. return {
  70. getState,
  71. dispatch,
  72. subscribe
  73. }
  74. }
  75. function promiseReducer(state = {}, { type, name, status, payload, error }) {
  76. //{
  77. // login: {status, payload, error}
  78. // catById: {status, payload, error}
  79. //}
  80. if (type === 'PROMISE') {
  81. return {
  82. ...state,
  83. [name]: { status, payload, error }
  84. }
  85. }
  86. return state
  87. }
  88. const actionPending = name => ({ type: 'PROMISE', status: 'PENDING', name })
  89. const actionResolved = (name, payload) => ({ type: 'PROMISE', status: 'RESOLVED', name, payload })
  90. const actionRejected = (name, error) => ({ type: 'PROMISE', status: 'REJECTED', name, error })
  91. const actionPromise = (name, promise) =>
  92. async dispatch => {
  93. dispatch(actionPending(name))
  94. try {
  95. let payload = await promise
  96. dispatch(actionResolved(name, payload))
  97. return payload
  98. }
  99. catch (error) {
  100. dispatch(actionRejected(name, error))
  101. }
  102. }
  103. const store = createStore(promiseReducer)
  104. store.subscribe(() => console.log(store.getState()))
  105. const getGQL = url =>
  106. (query, variables = {}) =>
  107. fetch(url, {
  108. method: 'POST',
  109. headers: {
  110. "Content-Type": "application/json",
  111. ...(localStorage.authToken ? { "Authorization": "Bearer " + localStorage.authToken } : {})
  112. },
  113. body: JSON.stringify({ query, variables })
  114. })
  115. .then(res => res.json())
  116. .then(data => {
  117. if (data.errors && !data.data)
  118. throw new Error(JSON.stringify(data.errors))
  119. return data.data[Object.keys(data.data)[0]]
  120. })
  121. const backURL = 'http://shop-roles.asmer.fs.a-level.com.ua'
  122. const gql = getGQL(backURL + '/graphql')
  123. const actionRootCats = () =>
  124. actionPromise('rootCats', gql(`query {
  125. CategoryFind(query: "[{\\"parent\\":null}]"){
  126. _id name
  127. }
  128. }`))
  129. const actionCatById = (_id) =>
  130. actionPromise('catById', gql(`query catById($q: String){
  131. CategoryFindOne(query: $q) {
  132. _id name goods{
  133. _id name price description images {
  134. url
  135. }
  136. }
  137. subCategories {
  138. name _id goods {
  139. _id name description
  140. }
  141. }
  142. }
  143. }`, { q: JSON.stringify([{ _id }]) }))
  144. const actionGoodById = (_id) =>
  145. actionPromise('goodById', gql(`query goodById($q: String){
  146. GoodFindOne(query: $q){
  147. _id name description price images{
  148. url
  149. }
  150. }
  151. }`, { q: JSON.stringify([{ _id }]) }))
  152. store.dispatch(actionRootCats())
  153. store.subscribe(() => {
  154. const { rootCats } = store.getState()
  155. if (rootCats?.payload) {
  156. aside.innerHTML = ''
  157. for (const { _id, name } of rootCats?.payload) {
  158. const link = document.createElement('a')
  159. link.href = `#/category/${_id}`
  160. link.innerText = name
  161. aside.append(link)
  162. }
  163. }
  164. })
  165. window.onhashchange = () => {
  166. const [, route, _id] = location.hash.split('/')
  167. const routes = {
  168. category() {
  169. store.dispatch(actionCatById(_id))
  170. },
  171. good() {
  172. store.dispatch(actionGoodById(_id))
  173. console.log('ТОВАРОСТРАНИЦА')
  174. },
  175. }
  176. if (route in routes)
  177. routes[route]()
  178. }
  179. window.onhashchange()
  180. /*store.subscribe(() => {
  181. const {catById} = store.getState()
  182. const [,route, _id] = location.hash.split('/')
  183. if (catById?.payload && route === 'category'){
  184. const {name} = catById.payload
  185. main.innerHTML = `<h1>${name}</h1>`
  186. for (const good of catById.payload.goods){
  187. const{_id, name, price, images}=good;
  188. const card = document.createElement('div')
  189. card.innerHTML = `<h2>${name}</h2>
  190. <img src="${backURL}/${images[0].url}" />
  191. <strong>${price}</strong>
  192. `
  193. main.append(card);
  194. }
  195. }
  196. })*/
  197. store.subscribe(() => {
  198. const { catById } = store.getState()
  199. const [, route, _id] = location.hash.split('/')
  200. if (catById?.payload && route === 'category') {
  201. const { name } = catById.payload
  202. main.innerHTML = `<h1>${name}</h1>`
  203. if (catById.payload.subCategories) {
  204. for (let { _id, name } of catById.payload.subCategories) {
  205. const link = document.createElement('a')
  206. link.className = 'link'
  207. link.href = `#/category/${_id}`
  208. link.textContent = name
  209. main.append(link)
  210. }
  211. }
  212. for (const { _id, name, price, images } of catById.payload.goods) {
  213. const card = document.createElement('div')
  214. card.innerHTML = `<h2>${name}</h2>
  215. <img src="${backURL}/${images[0].url}"/>
  216. <div>
  217. <strong>Стоимость: <i>${price} UAH</i></strong><br>
  218. <p><a href=#/good/${_id}>Страница товара</a>
  219. </p>
  220. </div>`
  221. let btn=document.createElement('input');
  222. btn.value='Купить';
  223. btn.type='submit';
  224. btn.style.marginLeft=230+'px';
  225. btn.style.marginTop=5+'px';
  226. btn.onclick=()=>console.log('hello')
  227. main.append(card,btn)
  228. }
  229. }
  230. })
  231. store.subscribe(() => {
  232. const { goodById } = store.getState()
  233. const [, route, _id] = location.hash.split('/')
  234. if (goodById?.payload && route === 'good' && location.href.includes(`#/good/${_id}`)) {
  235. main.innerHTML = ``
  236. let { _id, name, price, images, description } = goodById.payload
  237. let goodItem = document.createElement('div')
  238. goodItem.className = 'good_item'
  239. goodItem.innerHTML = `
  240. <h2>${name}</h2>
  241. <img src="${backURL}/${images[0].url}"/>
  242. <div>
  243. <p><strong>Стоимость: <i>${price} UAH</i></strong></p>
  244. <p><strong>Описание:</strong> <i>${description}</i></p>
  245. </div>
  246. `
  247. main.append(goodItem)
  248. }
  249. })
  250. </script>
  251. </body>
  252. </html>