123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911 |
- <!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;
- }
- 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;
- }
- .larekBtn {
- height: 50px;
- font-weight: bold;
- margin: 10px 0 0 0;
- border-radius: 30px;
- background-color: white;
- color: black;
- }
- .larekBtn:hover {
- background-color: tomato;
- }
- </style>
- </head>
- <body>
- <div id="page-wrapper">
- <header id="header">
- <div id="logo">Larek</div>
- <nav id="nav">
- <ul id="userAuth"></ul>
- <div id="cart">
- <a href="#/cart/" 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"></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 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 }) {
- if (type === "CART_ADD") {
- console.log("+1");
- const _id = good._id;
- return {
- ...state,
- [_id]: { count: (state[_id]?.count || 0) + count, good },
- };
- }
- if (type === "CART_CLEAR") {
- return {};
- }
- if (type === "CART_SET") {
- const _id = good._id;
- if (count == 0) {
- delete state[_id];
- } else {
- return {
- ...state,
- [_id]: { count, good },
- };
- }
- }
- if (type === "CART_DELETE") {
- const _id = good._id;
- if (state[_id].count - 1 === 0) {
- delete state[_id];
- return state;
- } else {
- return {
- ...state,
- [_id]: { count: state[_id]?.count - count, good },
- };
- }
- }
- return state;
- }
- function authReducer(state, action) {
- // { type, token }
- if (state === undefined) {
- if (localStorage.token) {
- //добавить в action token из localStorage,
- action.token = localStorage.token; //и проимитировать LOGIN (action.type = 'LOGIN')
- action.type = "LOGIN";
- } else {
- return {};
- }
- }
- if (action.type === "LOGIN") {
- localStorage.token = action.token; //+localStorage
- let { 1: tokenAverage } = action.token.split("."); //достать среднюю часть из токена (между точками)
- let decodedToken = atob(tokenAverage); //jwt_decode: //atob
- let parsedToken = JSON.parse(decodedToken); //JSON.parse
- return { token: action.token, payload: parsedToken }; //return {token: action.token, payload: jwt_decode(action.jwt)}
- }
- if (action.type === "LOGOUT") {
- console.log("ЛОГАУТ");
- localStorage.removeItem("token"); //-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;
- // }
- return { ...state, ...newState };
- };
- };
- const store = createStore(combineReducers(reducers));
- 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 = {}) => {
- let headers;
- if (localStorage.token) {
- //якщо в localStorage.authToken шото есть, то наверное это надо отправить с заголовком Authorization
- headers = {
- // Accept: "application/json",
- "Content-Type": "application/json",
- Authorization: "Bearer " + localStorage.token,
- };
- } else {
- headers = {
- "Content-Type": "application/json",
- };
- }
- return fetch(url, {
- method: "POST",
- headers,
- 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 }]) }
- )
- );
- //auth************************
- const actionGetToken = (login, password) =>
- actionPromise(
- "getToken",
- shopGQL(
- `query login($login:String, $password:String){
- login(login: $login, password: $password)
- }`,
- { login, password }
- )
- );
- 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));
- }
- };
- //registration****************
- const actionRegister = (login, password) =>
- actionPromise(
- "register",
- shopGQL(
- `mutation reg($query:UserInput){
- UserUpsert(user:$query){
- _id login
- }
- }`,
- { query: { login, password } }
- )
- );
- const actionFullRegister = (login, password) => async (dispatch) => {
- let payload = await dispatch(actionRegister(login, password)); //actionRegister, который actionPromise
- if (payload.data.UserUpsert != null) {
- await dispatch(actionFullLogin(login, password)); //если удачно, делаете сразу же actionFullLogin
- }
- };
- //order
- const actionCreateOrder = (_id, count) =>
- actionPromise(
- "createdOrder",
- shopGQL(
- `mutation createOrder($order:OrderInput){
- OrderUpsert(order:$order){
- _id
- }
- }`,
- {
- order: {
- orderGoods: [{ count: count, good: { _id: _id } }],
- },
- }
- )
- );
- const actionCartAdd = (good, count = 1) => ({
- type: "CART_ADD",
- count,
- good,
- });
- const actionCartDelete = (good, count = 1) => ({
- type: "CART_DELETE",
- count,
- good,
- });
- const actionCartClear = (good, count = 1) => ({
- type: "CART_CLEAR",
- count,
- good,
- });
- store.dispatch(actionRootCategories());
- //store.dispatch(actionFullLogin("tst123", "123123"));
- function drawCart() {
- //цикл по отрисовке с картинками и редактирование количества/удалением товара
- //
- const cart = store.getState().cart;
- console.log("kart", cart);
- }
- 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 делает
- drawLogin();
- }
- if (route === "register") {
- // нарисовать форму регистрации, которая по OK делает
- // store.dispatch(actionFullRegister(login, password))
- drawRegister();
- }
- if (route === "cart") {
- loadAnimationFunc();
- drawCart();
- //#/cart/
- // //нарисовать корзину с кнопочками добавления/удаления товаров
- // main.innerHTML = ""
- // //const cart = store.getState().cart
- // //смочь в цикл / reduce по подсчету суммы количеств товаров и вывести куда - то в дом
- // //(заготовка под кошик с количеством)
- }
- };
- store.subscribe(drawMainMenu);
- store.subscribe(drawCategories);
- store.subscribe(drawGood);
- //store.subscribe(drawLogin);
- // store.subscribe(drawRegistration);
- //store.subscribe(drawCart);
- store.subscribe(loggedIn);
- function loggedIn() {
- const loggedIn = store.getState().auth.token;
- if (loggedIn) {
- userAuth.innerText = "";
- let logout = document.createElement("button");
- logout.innerText = "выйти";
- logout.onclick = () => {
- store.dispatch({ type: "LOGOUT" });
- };
- userAuth.appendChild(logout);
- } else {
- userAuth.innerText = "";
- let loginButton = document.createElement("a");
- loginButton.setAttribute("style", "margin-right: 10px; color:black;");
- loginButton.innerText = "войти";
- loginButton.href = "#/login/";
- userAuth.appendChild(loginButton);
- let registerButton = document.createElement("a");
- registerButton.setAttribute(
- "style",
- "margin-left: 10px; color:black;"
- );
- registerButton.innerText = "регистрация";
- registerButton.href = "#/register/";
- userAuth.appendChild(registerButton);
- }
- }
- function drawCart() {
- //цикл по отрисовке с картинками и редактирование количества/удалением товара
- //
- const cart = store.getState().cart;
- main.innerHTML = "";
- let divWrapper = document.createElement("div");
- divWrapper.setAttribute("style", "width: 100%;");
- let header1 = document.createElement("h1");
- header1.innerText = "Корзина";
- divWrapper.append(header1);
- let buttonClear = document.createElement("button");
- buttonClear.setAttribute(
- "style",
- "height: 30px; font-weight: bold; margin: 0 auto; border-radius: 30px; background-color: white;"
- );
- buttonClear.innerText = "Очистить";
- buttonClear.onclick = () => {
- store.dispatch(actionCartClear());
- };
- divWrapper.append(buttonClear);
- main.append(divWrapper);
- for (let key in cart) {
- let divCartA = document.createElement("div");
- divCartA.setAttribute(
- "style",
- "margin: 0 10px 10px 0; padding: 20px; width: 400px; border: 2px solid gray; display: flex; flex-direction: column; align-content: stretch "
- );
- let cartImg = document.createElement("img");
- cartImg.src = `http://shop-roles.asmer.fs.a-level.com.ua/${
- cart[`${key}`].good.images[0].url
- }`;
- let cartButtons = document.createElement("div");
- cartButtons.setAttribute(
- "style",
- "text-align: center; margin: 10px;"
- );
- let cartButtonAdd = document.createElement("button");
- let cartButtonMinus = document.createElement("button");
- cartButtonAdd.innerText = "+";
- cartButtonAdd.setAttribute(
- "style",
- "text-align: center; font-size: 22px; padding: 5px"
- );
- cartButtonMinus.innerText = "-";
- cartButtonMinus.setAttribute(
- "style",
- "text-align: center; font-size: 22px; padding: 5px"
- );
- cartButtonAdd.onclick = () => {
- store.dispatch(actionCartAdd(cart[key].good, 1));
- };
- cartButtonMinus.onclick = () => {
- store.dispatch(actionCartDelete(cart[key]?.good, 1));
- };
- cartButtons.append(cartButtonAdd);
- cartButtons.append(cartButtonMinus);
- let cartText = document.createElement("p");
- cartText.setAttribute(
- "style",
- "flex: 1 1 auto; text-align: center; font-size: 22px"
- );
- cartText.innerHTML = cart[`${key}`].good.name;
- let cartCountPrice = document.createElement("div");
- cartCountPrice.setAttribute(
- "style",
- "font-size: 20px; font-weight: bold; text-align: center;"
- );
- cartCountPrice.innerText = `Кол-во: ${cart[`${key}`].count} Цена: ${
- cart[`${key}`].good.price * cart[`${key}`].count
- } грн`;
- let cartButton = document.createElement("button");
- cartButton.classList = "larekBtn";
- cartButton.onclick = () => {
- store.dispatch(
- actionCreateOrder(cart[key].good._id, cart[key].count)
- );
- };
- cartButton.innerText = "Оплатить";
- divCartA.append(cartImg);
- divCartA.append(cartText);
- divCartA.append(cartCountPrice);
- divCartA.append(cartButtons);
- divCartA.append(cartButton);
- main.append(divCartA);
- }
- }
- function drawRegister() {
- main.innerText = "";
- let divLoginHolder = document.createElement("div");
- divLoginHolder.setAttribute("style", "margin: 0 auto;");
- let divLogin = document.createElement("div");
- divLogin.setAttribute(
- "style",
- "margin: 0 auto; padding: 20px; width: 400px; display: flex; flex-direction: column;"
- );
- let textLogin = document.createElement("p");
- let loginInput = document.createElement("input");
- textLogin.innerText = "Login";
- let textPassword = document.createElement("p");
- let passwordInput = document.createElement("input");
- textPassword.innerText = "Password";
- let authButton = document.createElement("button");
- authButton.innerText = "Зарегистрироваться";
- authButton.classList = "larekBtn";
- let authHeading = document.createElement("h1");
- authHeading.innerText = "Регистрация";
- divLogin.append(authHeading);
- divLogin.append(textLogin);
- divLogin.append(loginInput);
- divLogin.append(textPassword);
- divLogin.append(passwordInput);
- divLogin.append(authButton);
- authButton.onclick = async () => {
- if (loginInput.value && passwordInput.value) {
- payload = await store.dispatch(
- actionFullRegister(loginInput.value, passwordInput.value)
- );
- if (store.getState().auth.token) {
- divLogin.innerText = "";
- authHeading.innerText = "Welcome";
- authHeading.style.fontSize = "30px";
- divLogin.append(authHeading);
- divLoginHolder.append(divLogin);
- main.append(divLoginHolder);
- } else {
- let error = document.createElement("p");
- error.innerText = "Такой логин уже занят";
- divLogin.append(error);
- }
- }
- };
- divLoginHolder.append(divLogin);
- main.append(divLoginHolder);
- }
- function drawLogin() {
- main.innerText = "";
- let divLoginHolder = document.createElement("div");
- divLoginHolder.setAttribute("style", "margin: 0 auto;");
- let divLogin = document.createElement("div");
- divLogin.setAttribute(
- "style",
- "margin: 0 auto; padding: 20px; width: 400px; display: flex; flex-direction: column;"
- );
- let textLogin = document.createElement("p");
- let loginInput = document.createElement("input");
- textLogin.innerText = "Login";
- let textPassword = document.createElement("p");
- let passwordInput = document.createElement("input");
- textPassword.innerText = "Password";
- let authButton = document.createElement("button");
- authButton.innerText = "Войти";
- authButton.classList = "larekBtn";
- let authHeading = document.createElement("h1");
- authHeading.innerText = "Авторизация";
- divLogin.append(authHeading);
- divLogin.append(textLogin);
- divLogin.append(loginInput);
- divLogin.append(textPassword);
- divLogin.append(passwordInput);
- divLogin.append(authButton);
- authButton.onclick = async () => {
- if (loginInput.value && passwordInput.value) {
- payload = await store.dispatch(
- actionFullLogin(loginInput.value, passwordInput.value)
- );
- if (store.getState().auth.token) {
- divLogin.innerText = "";
- authHeading.innerText = "Welcome";
- authHeading.style.fontSize = "30px";
- divLogin.append(authHeading);
- divLoginHolder.append(divLogin);
- main.append(divLoginHolder);
- } else {
- let error = document.createElement("p");
- error.innerText = "Неверный логин или пароль";
- divLogin.append(error);
- }
- }
- };
- divLoginHolder.append(divLogin);
- main.append(divLoginHolder);
- }
- 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;
- aside.append(catA);
- }
- }
- }
- function drawCategories() {
- //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.classList = "larekBtn";
- goodButton.innerText = "Купить";
- goodButton.onclick = () =>
- (window.location.href = `#/good/${_id}`);
- divGoodA.append(goodImg);
- divGoodA.append(goodLink);
- 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();
- }
- }
- function drawGood() {
- // 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.classList = "larekBtn";
- goodButton1.innerText = "Купить";
- 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 страницу товаров
- }
- }
- }
- 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);
- }
- </script>
- </body>
- </html>
|