|
@@ -0,0 +1,568 @@
|
|
|
|
+<!DOCTYPE html>
|
|
|
|
+<html lang="en">
|
|
|
|
+
|
|
|
|
+<head>
|
|
|
|
+ <meta charset="UTF-8">
|
|
|
|
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
+ <title>Magaz</title>
|
|
|
|
+
|
|
|
|
+ <style>
|
|
|
|
+ * *,
|
|
|
|
+ *::before,
|
|
|
|
+ *::after {
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
+ margin: 0;
|
|
|
|
+ padding: 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #page-wrapper {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+ min-height: 100vh;
|
|
|
|
+ margin: 0 auto;
|
|
|
|
+ max-width: 1170px;
|
|
|
|
+ width: 100%;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #mainContainer {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-grow: 1;
|
|
|
|
+ margin: 20px 0;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #header {
|
|
|
|
+ height: 50px;
|
|
|
|
+ background-color: #FF5319;
|
|
|
|
+ border: 1px solid gray;
|
|
|
|
+ padding: 10px 5px;
|
|
|
|
+ font-size: 26px;
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #userAuth li {
|
|
|
|
+ list-style-type: none;
|
|
|
|
+ display: inline-block;
|
|
|
|
+ font-size: 18px;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ a {
|
|
|
|
+ text-decoration: none;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #aside {
|
|
|
|
+ min-width: 25%;
|
|
|
|
+ font-size: 20px;
|
|
|
|
+ padding: 0 20px 0px 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #aside>a {
|
|
|
|
+ display: block;
|
|
|
|
+ color: black;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #aside>a:hover {
|
|
|
|
+ color: tomato;
|
|
|
|
+ font-size: 24px;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #main {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
+ width: 100%;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #footer {
|
|
|
|
+ text-align: center;
|
|
|
|
+ background-color: #FF5319;
|
|
|
|
+ border: 1px solid gray;
|
|
|
|
+ height: 40px;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #cartImg {
|
|
|
|
+ height: 30px;
|
|
|
|
+ width: 30px;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #nav {
|
|
|
|
+ display: flex;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ </style>
|
|
|
|
+
|
|
|
|
+</head>
|
|
|
|
+
|
|
|
|
+<body>
|
|
|
|
+
|
|
|
|
+ <div id="page-wrapper">
|
|
|
|
+ <header id="header">
|
|
|
|
+ <div id="logo">Larek</div>
|
|
|
|
+
|
|
|
|
+ <nav id="nav">
|
|
|
|
+ <ul id="userAuth">
|
|
|
|
+ <li>войти</li>
|
|
|
|
+ <li>регистрация</li>
|
|
|
|
+ </ul>
|
|
|
|
+ <div id="cart">
|
|
|
|
+ <a id="cartLink"><img id="cartImg"
|
|
|
|
+ src="https://i.pinimg.com/originals/15/4f/df/154fdf2f2759676a96e9aed653082276.png"
|
|
|
|
+ alt=""></a>
|
|
|
|
+ </div>
|
|
|
|
+ </nav>
|
|
|
|
+ </header>
|
|
|
|
+
|
|
|
|
+ <div id='mainContainer'>
|
|
|
|
+ <aside id='aside'>
|
|
|
|
+ Категории
|
|
|
|
+ </aside>
|
|
|
|
+ <main id='main'>
|
|
|
|
+ Контент
|
|
|
|
+ </main>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <footer id="footer">КУДА Я ПОПАЛ?2</footer>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <script>
|
|
|
|
+ // debugger;
|
|
|
|
+ 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 reducer(state = {}, { type, status, payload, error, name }) {
|
|
|
|
+ // if (type === 'PROMISE') {
|
|
|
|
+ // return {
|
|
|
|
+ // ...state,
|
|
|
|
+ // [name]: { status, payload, error }
|
|
|
|
+ // }
|
|
|
|
+ // }
|
|
|
|
+ // return state
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /////
|
|
|
|
+ function promiseReducer(state = {}, { type, status, payload, error, name }) {
|
|
|
|
+ if (type === 'PROMISE') {
|
|
|
|
+ return {
|
|
|
|
+ ...state,
|
|
|
|
+ [name]: { status, payload, error }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return state
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function cardReducer(state = {}, { type, count = 1, good }) {
|
|
|
|
+ //придумать типы CART_ADD, CART_CLEAR, CART_SET, CART_DELETE
|
|
|
|
+ //{ _id1: {count: 2, good: {....}},
|
|
|
|
+ // _id2: 10,}
|
|
|
|
+ //
|
|
|
|
+ if (type === 'CART_ADD') { ///где то тут проеб
|
|
|
|
+ console.log("+1")
|
|
|
|
+ const _id = good._id
|
|
|
|
+ return {
|
|
|
|
+ ...state,
|
|
|
|
+ [_id]: { count: (state[_id]?.count || 0) + count, good }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (type === 'CART_DELETE') {
|
|
|
|
+ console.log("-1")
|
|
|
|
+ const _id = good._id
|
|
|
|
+ return {
|
|
|
|
+ ...state,
|
|
|
|
+ [_id]: { count: (state[_id]?.count || 0) - count, good }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return state
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const actionCartAdd = (good, count = 1) => ({ type: 'CART_ADD', count, good })
|
|
|
|
+ // const actionCartDelete = (good, count = 1) => ({ type: 'CART_DELETE', count, good })
|
|
|
|
+
|
|
|
|
+ //под товаром сделать кнопку "купить"
|
|
|
|
+ // buy.onclick = () => {
|
|
|
|
+ // //debugger;
|
|
|
|
+ // store.dispatch(actionCartAdd(good))
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ //отрисовка количество где-то в хидере (на всех страницах)
|
|
|
|
+ // store.subscribe(() => {
|
|
|
|
+ // const cart = store.getState().cart
|
|
|
|
+ // смочь в цикл/reduce по подсчету суммы количеств товаров и вывести куда-то в дом
|
|
|
|
+ //(заготовка под кошик с количеством)
|
|
|
|
+ // })
|
|
|
|
+
|
|
|
|
+ function authReducer(state = { name: "Токен и все такое" }, action) { // { type, token }
|
|
|
|
+ if (state === undefined) {
|
|
|
|
+ //добавить в action token из localStorage, и проимитировать LOGIN (action.type = 'LOGIN')
|
|
|
|
+ return {}
|
|
|
|
+ }
|
|
|
|
+ if (action.type === 'LOGIN') {
|
|
|
|
+ console.log('ЛОГИН', action)
|
|
|
|
+ //+localStorage
|
|
|
|
+ //jwt_decode:
|
|
|
|
+ //достать среднюю часть из токена (между точками)
|
|
|
|
+ //atob
|
|
|
|
+ //JSON.parse
|
|
|
|
+ // return {token: action.token, payload: jwt_decode(action.jwt)}
|
|
|
|
+ }
|
|
|
|
+ if (action.type === 'LOGOUT') {
|
|
|
|
+ console.log('ЛОГАУТ')
|
|
|
|
+ //-localStorage
|
|
|
|
+ //removeItem или clear
|
|
|
|
+ //вернуть пустой объект
|
|
|
|
+ return {}
|
|
|
|
+ }
|
|
|
|
+ return state
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const reducers = {
|
|
|
|
+ promise: promiseReducer,
|
|
|
|
+ cart: cardReducer,
|
|
|
|
+ auth: authReducer
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const combineReducers = reducers => {
|
|
|
|
+ return (state = {}, action) => {
|
|
|
|
+ const newState = {}
|
|
|
|
+ for (const [name, reducer] of Object.entries(reducers)) {
|
|
|
|
+ // console.log(name, reducer)
|
|
|
|
+ const newSubState = reducer(state[name], action)
|
|
|
|
+ if (newSubState !== state[name]) {
|
|
|
|
+ newState[name] = newSubState
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (Object.keys(newState).length === 0) {
|
|
|
|
+ return state
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // {
|
|
|
|
+ // ...
|
|
|
|
+ // promise: state.promise,
|
|
|
|
+ // cart: state.cart,
|
|
|
|
+ // auth: state.auth,
|
|
|
|
+ // promise: newState.promise
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ return { ...state, ...newState }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const store = createStore(combineReducers(reducers))
|
|
|
|
+ ////
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ //const store = createStore(reducer)
|
|
|
|
+ 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))
|
|
|
|
+
|
|
|
|
+ //store.dispatch(actionPending('delay1000'))
|
|
|
|
+ //delay(1000).then(payload => store.dispatch(actionResolved('delay1000', payload)),
|
|
|
|
+ //error => store.dispatch(actionRejected('delay1000', error)))
|
|
|
|
+
|
|
|
|
+ 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 =>
|
|
|
|
+ (query, variables = {}) => fetch(url, {
|
|
|
|
+ method: 'POST',
|
|
|
|
+ headers: {
|
|
|
|
+ // Accept: "application/json",
|
|
|
|
+ "Content-Type": "application/json"
|
|
|
|
+ //якщо в localStorage.authToken шото есть, то наверное это надо отправить с заголовком Authorization
|
|
|
|
+ },
|
|
|
|
+ body: JSON.stringify({ query, variables })
|
|
|
|
+ }).then(res => res.json())
|
|
|
|
+
|
|
|
|
+ let shopGQL = getGQL('http://shop-roles.asmer.fs.a-level.com.ua/graphql')
|
|
|
|
+
|
|
|
|
+ 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 }]) }))
|
|
|
|
+
|
|
|
|
+ const actionGoodById = (_id) =>
|
|
|
|
+ actionPromise('goodById', shopGQL(`query goodById($query:String){
|
|
|
|
+ GoodFindOne(query:$query){
|
|
|
|
+ _id name price description images {
|
|
|
|
+ url
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }`, { query: JSON.stringify([{ _id }]) }))
|
|
|
|
+
|
|
|
|
+ const actionGetToken = (login, password) =>
|
|
|
|
+ actionPromise('getToken', shopGQL(`query login($login:String, $password:String){
|
|
|
|
+ login(login: $login, password: $password)
|
|
|
|
+ }`, { login, password }))
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // const actionGetOrders = () =>
|
|
|
|
+ // actionPromise('orders', shopGQL(`query orders{
|
|
|
|
+ // OrderFind(query:"[{}]"){
|
|
|
|
+ // _id total orderGoods{
|
|
|
|
+ // count good{
|
|
|
|
+ // name
|
|
|
|
+ // }
|
|
|
|
+ // }
|
|
|
|
+ // }
|
|
|
|
+ // }`))
|
|
|
|
+
|
|
|
|
+ const actionAuthLogin = token => ({ type: 'LOGIN', token })
|
|
|
|
+
|
|
|
|
+ const actionFullLogin = (login, password) =>
|
|
|
|
+ async dispatch => {
|
|
|
|
+ let payload = await dispatch(actionGetToken(login, password))
|
|
|
|
+ if (payload.data.login) {
|
|
|
|
+ dispatch(actionAuthLogin(payload.data.login))
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ //НАПИЛИТЬ actionFullRegister:
|
|
|
|
+ // - actionRegister, который actionPromise
|
|
|
|
+ // - если удачно, делаете сразу же actionFullLogin
|
|
|
|
+
|
|
|
|
+ store.dispatch(actionRootCategories())
|
|
|
|
+ store.dispatch(actionFullLogin('tst123', '123123'))
|
|
|
|
+
|
|
|
|
+ function drawCart() {
|
|
|
|
+ //цикл по отрисовке с картинками и редактирование количества/удалением товара
|
|
|
|
+ //
|
|
|
|
+
|
|
|
|
+ const cart = store.getState().cart
|
|
|
|
+
|
|
|
|
+ // if (cart) {
|
|
|
|
+ // main.innerText = ''
|
|
|
|
+ // for (let {})
|
|
|
|
+ // }
|
|
|
|
+ // main.innerHTML = `<pre>${JSON.stringify(cart, null, 4)}</pre>`
|
|
|
|
+ console.log("kart", cart)
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function loadAnimationFunc() {
|
|
|
|
+ main.innerHTML = ""
|
|
|
|
+ let loadAnimationContainer = document.createElement('div')
|
|
|
|
+ loadAnimationContainer.setAttribute('style', "width: 100%; height: 100%; display: flex; justify-content: center; align-items: center;")
|
|
|
|
+ main.append(loadAnimationContainer)
|
|
|
|
+
|
|
|
|
+ let loadAnimation = document.createElement('img')
|
|
|
|
+ loadAnimation.src = "https://image.flaticon.com/icons/png/512/2492/2492765.png"
|
|
|
|
+ loadAnimation.setAttribute("style", "width: 50px; height: 50px; animation: load 1s linear infinite;")
|
|
|
|
+ loadAnimation.animate([{ transform: 'rotate(360deg)' }], { duration: 1000, iterations: Infinity })
|
|
|
|
+ loadAnimationContainer.append(loadAnimation)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ window.onhashchange = () => {
|
|
|
|
+ let { 1: route, 2: id } = location.hash.split('/')
|
|
|
|
+ if (route === 'categories') {
|
|
|
|
+ loadAnimationFunc()
|
|
|
|
+ store.dispatch(actionCategoryById(id))
|
|
|
|
+ }
|
|
|
|
+ if (route === 'good') {
|
|
|
|
+ loadAnimationFunc()
|
|
|
|
+ store.dispatch(actionGoodById(id))
|
|
|
|
+ }
|
|
|
|
+ if (route === 'login') {
|
|
|
|
+ // нарисовать форму логина, которая по OK делает
|
|
|
|
+ // store.dispatch(actionFullLogin(login, password))
|
|
|
|
+ }
|
|
|
|
+ if (route === 'register') {
|
|
|
|
+ // нарисовать форму регистрации, которая по OK делает
|
|
|
|
+ // store.dispatch(actionFullRegister(login, password))
|
|
|
|
+ }
|
|
|
|
+ if (route === 'cart') {
|
|
|
|
+ loadAnimationFunc()
|
|
|
|
+ // store.dispatch(actionGetOrders())
|
|
|
|
+ console.log("страница корзины")
|
|
|
|
+ drawCart()
|
|
|
|
+
|
|
|
|
+ //#/cart/
|
|
|
|
+ // //нарисовать корзину с кнопочками добавления/удаления товаров
|
|
|
|
+ // main.innerHTML = ""
|
|
|
|
+ // //const cart = store.getState().cart
|
|
|
|
+ // //смочь в цикл / reduce по подсчету суммы количеств товаров и вывести куда - то в дом
|
|
|
|
+ // //(заготовка под кошик с количеством)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function drawMainMenu() {
|
|
|
|
+ //debugger;
|
|
|
|
+ let cats = store.getState().promise.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
|
|
|
|
+
|
|
|
|
+ console.log("cart")
|
|
|
|
+ cartLink.href = `#/cart/`
|
|
|
|
+
|
|
|
|
+ aside.append(catA)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ store.subscribe(drawMainMenu)
|
|
|
|
+
|
|
|
|
+ store.subscribe(() => {
|
|
|
|
+ //debugger;
|
|
|
|
+ const { 1: route, 2: id } = location.hash.split('/')
|
|
|
|
+ if (route === 'categories') {
|
|
|
|
+ const catById = store.getState().promise.catById?.payload
|
|
|
|
+ if (catById) {
|
|
|
|
+ main.innerText = ""
|
|
|
|
+ // Вывести категорию(название)
|
|
|
|
+ let h1 = document.createElement('h1')
|
|
|
|
+ h1.setAttribute('style', 'width: 100%;')
|
|
|
|
+ h1.innerText = catById.data.CategoryFindOne.name
|
|
|
|
+ main.append(h1)
|
|
|
|
+ // Вывести циклом товары со ссылками вида # / good / АЙДИШНИК
|
|
|
|
+ for (let { _id, name, description, price, images } of catById.data.CategoryFindOne.goods) { //тута
|
|
|
|
+
|
|
|
|
+ let divGoodA = document.createElement('div')
|
|
|
|
+ divGoodA.setAttribute('style', "margin: 0 10px 10px 0; padding: 20px; width: 400px; border: 2px solid gray; display: flex; flex-direction: column; align-content: stretch ")
|
|
|
|
+ divGoodA.onmousemove = () => divGoodA.style.borderColor = "#FF7373"
|
|
|
|
+ divGoodA.onmouseout = () => divGoodA.style.borderColor = "gray"
|
|
|
|
+ //background - color: #FF5319;
|
|
|
|
+ let goodImg = document.createElement('img')
|
|
|
|
+ goodImg.src = `http://shop-roles.asmer.fs.a-level.com.ua/${images[0].url}`
|
|
|
|
+
|
|
|
|
+ let goodLink = document.createElement('a')
|
|
|
|
+ goodLink.setAttribute('style', "flex: 1 1 auto; text-align: center; font-size: 22px")
|
|
|
|
+ goodLink.href = `#/good/${_id}`
|
|
|
|
+ goodLink.innerHTML = name
|
|
|
|
+
|
|
|
|
+ let goodPrice = document.createElement('div')
|
|
|
|
+ goodPrice.setAttribute('style', "font-size: 20px; font-weight: bold; text-align: center;")
|
|
|
|
+ goodPrice.innerText = `Цена: ${price} грн`
|
|
|
|
+
|
|
|
|
+ let goodButton = document.createElement('button')
|
|
|
|
+ goodButton.setAttribute('style', "height: 50px; font-weight: bold; margin: 10px 0 0 0; border-radius: 30px; background-color: white;")
|
|
|
|
+ goodButton.innerText = "Купить"
|
|
|
|
+ goodButton.onclick = () => window.location.href = `#/good/${_id}`
|
|
|
|
+ goodButton.onmousemove = () => goodButton.style.backgroundColor = "#FF5319"
|
|
|
|
+ goodButton.onmouseout = () => goodButton.style.backgroundColor = "white"
|
|
|
|
+
|
|
|
|
+ divGoodA.append(goodImg)
|
|
|
|
+ divGoodA.append(goodLink)
|
|
|
|
+ //divGoodA.append(goodDescription)
|
|
|
|
+ divGoodA.append(goodPrice)
|
|
|
|
+ divGoodA.append(goodButton)
|
|
|
|
+ main.append(divGoodA)
|
|
|
|
+ }
|
|
|
|
+ // main.innerHTML = `<pre>${JSON.stringify(catById, null, 4)}</pre>`
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (route === 'cart') {
|
|
|
|
+ // нарисовать корзину с кнопочками добавления/удаления товаров
|
|
|
|
+ //
|
|
|
|
+ //const cart = store.getState().cart
|
|
|
|
+ drawCart()
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ store.subscribe(() => {
|
|
|
|
+ // debugger;
|
|
|
|
+ //когда появится actionGoodById и ссылки на товары это заработает
|
|
|
|
+ const { 1: route, 2: id } = location.hash.split('/')
|
|
|
|
+ if (route === 'good') {
|
|
|
|
+ const goodById = store.getState().promise.goodById?.payload
|
|
|
|
+ if (goodById) {
|
|
|
|
+ let main = document.getElementById('main')
|
|
|
|
+ main.innerHTML = ""
|
|
|
|
+
|
|
|
|
+ let divGoodB = document.createElement('div')
|
|
|
|
+ divGoodB.setAttribute('style', "margin: 0 10px 10px 25px; padding: 20px; display: flex; flex-direction: column;")
|
|
|
|
+
|
|
|
|
+ let goodImg1 = document.createElement('img')
|
|
|
|
+ goodImg1.src = `http://shop-roles.asmer.fs.a-level.com.ua/${goodById.data.GoodFindOne.images[0].url}`
|
|
|
|
+
|
|
|
|
+ let goodLink1 = document.createElement('h1')
|
|
|
|
+ goodLink1.setAttribute('style', "text-align: center; font-size: 22px")
|
|
|
|
+ goodLink1.innerHTML = goodById.data.GoodFindOne.name
|
|
|
|
+
|
|
|
|
+ let goodDescription1 = document.createElement('div')
|
|
|
|
+ goodDescription1.setAttribute('style', "margin: 20px; ")
|
|
|
|
+ goodDescription1.innerText = goodById.data.GoodFindOne.description
|
|
|
|
+
|
|
|
|
+ let goodPrice1 = document.createElement('h1')
|
|
|
|
+ goodPrice1.setAttribute('style', "font-size: 20px; font-weight: bold; text-align: center;")
|
|
|
|
+ goodPrice1.innerText = `Цена: ${goodById.data.GoodFindOne.price} грн`
|
|
|
|
+
|
|
|
|
+ let goodButton1 = document.createElement('button')
|
|
|
|
+ goodButton1.setAttribute('style', "height: 50px; font-weight: bold; margin: 10px 0 0 0; border-radius: 30px; background-color: white;")
|
|
|
|
+ goodButton1.innerText = "Купить"
|
|
|
|
+ goodButton1.onmousemove = () => goodButton1.style.backgroundColor = "#FF5319"
|
|
|
|
+ goodButton1.onmouseout = () => goodButton1.style.backgroundColor = "white"
|
|
|
|
+ goodButton1.onclick = () => { store.dispatch(actionCartAdd(goodById.data.GoodFindOne)) }
|
|
|
|
+
|
|
|
|
+ divGoodB.append(goodImg1)
|
|
|
|
+ divGoodB.append(goodLink1)
|
|
|
|
+ divGoodB.append(goodDescription1)
|
|
|
|
+ divGoodB.append(goodPrice1)
|
|
|
|
+ divGoodB.append(goodButton1)
|
|
|
|
+ main.append(divGoodB)
|
|
|
|
+ // вывести в main страницу товаров
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ </script>
|
|
|
|
+
|
|
|
|
+</body>
|
|
|
|
+
|
|
|
|
+</html>
|