From 308c64932527266111e0528f79799018d1552671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaume=20Sol=C3=ADs?= Date: Wed, 6 Mar 2024 18:16:03 +0100 Subject: [PATCH] C --- .vscode/settings.json | 11 +- api/.env.example | 6 +- api/controller/Contact/contact.controller.js | 22 + .../Delivery/delivery.controller.js | 13 + api/controller/Payment/payment.controller.js | 23 + api/controller/Payment/payment.services.js | 113 + api/controller/Payment/paypal.providers.js | 59 + api/controller/Payment/redsys-easy.text | 39 + api/controller/Payment/redsys-pos.text | 34 + api/controller/Payment/redsys.providers.js | 33 + .../{ => Product}/product.controller.js | 23 +- .../Provinces/provinces.controller.js | 23 + api/controller/products.json | 1974 ----------------- api/db/db.js | 54 +- api/index.js | 33 +- api/package.json | 5 +- index.html | 4 + package-lock.json | 673 +++--- package.json | 11 +- quasar.config.js | 18 +- src/boot/VueCountryFlag.js | 6 + src/boot/VueTelInput.js | 16 + src/boot/axios.js | 7 +- src/components/@inputs/Calendar.vue | 80 +- src/components/@inputs/Example/CalendarEx.vue | 62 - .../@inputs/Example/PostalCodeEx.vue | 62 - src/components/@inputs/PostalCode.vue | 123 +- src/components/@inputs/PriceRange.vue | 33 +- src/components/@inputs/SortSelect.vue | 2 +- src/components/footer/FooterComponent.vue | 28 +- src/components/header/HeaderPrimary.vue | 4 +- src/components/header/HeaderSecondary.vue | 4 +- src/components/header/UserArea.vue | 18 +- src/components/icons/IconInfo.vue | 75 + .../carousel/VerticalCarouselImgs.vue | 77 +- src/components/sections/QuestionSection.vue | 14 +- .../stripe/StripeCheckoutComponent.vue | 65 - src/components/swiper/Swiper.vue | 4 - src/components/ui/Card.vue | 7 +- src/components/ui/Chat.vue | 4 +- src/components/ui/MobileNav.vue | 1 - src/components/ui/Modal.vue | 77 +- src/components/ui/QuestionForm.vue | 132 +- src/constants/index.js | 2 + src/constants/objValitation.js | 15 + src/css/app.scss | 64 +- src/css/components/calendar-postalcode.scss | 4 +- src/functions/quasarNotify.js | 27 +- src/hooks/useCheckoutForm.js | 340 ++- src/hooks/useLocalStorage.js | 25 +- src/hooks/usePostalCalendar.js | 373 +++- src/hooks/useProductPage.js | 51 - src/hooks/useQuestionForm.js | 113 + src/hooks/useVerticalCarouselImgs.js | 25 + src/pages/CategoryPage.vue | 152 +- src/pages/CheckoutErrorPage.vue | 28 + src/pages/CheckoutPage.vue | 735 +++--- src/pages/CheckoutSuccessPage.vue | 321 +++ src/pages/ExamplePage.vue | 21 - src/pages/HomePage.vue | 8 +- src/pages/ProductPage.vue | 121 +- src/router/routes.js | 23 +- src/stores/cart.js | 259 +-- src/stores/forms.js | 15 +- src/stores/modalStore.js | 3 +- src/stores/rangePrice.js | 1 - src/utils/zod/functions.js | 34 +- src/utils/zod/messages.js | 6 +- src/utils/zod/regex.js | 9 +- src/utils/zod/schemas/checkoutSchema.js | 28 +- src/utils/zod/schemas/questionSchema.js | 12 +- src/utils/zod/schemas/rangePriceSchema.js | 4 +- 72 files changed, 3234 insertions(+), 3657 deletions(-) create mode 100644 api/controller/Contact/contact.controller.js create mode 100644 api/controller/Delivery/delivery.controller.js create mode 100644 api/controller/Payment/payment.controller.js create mode 100644 api/controller/Payment/payment.services.js create mode 100644 api/controller/Payment/paypal.providers.js create mode 100644 api/controller/Payment/redsys-easy.text create mode 100644 api/controller/Payment/redsys-pos.text create mode 100644 api/controller/Payment/redsys.providers.js rename api/controller/{ => Product}/product.controller.js (82%) create mode 100644 api/controller/Provinces/provinces.controller.js delete mode 100644 api/controller/products.json create mode 100644 src/boot/VueCountryFlag.js create mode 100644 src/boot/VueTelInput.js delete mode 100644 src/components/@inputs/Example/CalendarEx.vue delete mode 100644 src/components/@inputs/Example/PostalCodeEx.vue create mode 100644 src/components/icons/IconInfo.vue delete mode 100644 src/components/stripe/StripeCheckoutComponent.vue create mode 100644 src/constants/index.js create mode 100644 src/constants/objValitation.js delete mode 100644 src/hooks/useProductPage.js create mode 100644 src/hooks/useQuestionForm.js create mode 100644 src/hooks/useVerticalCarouselImgs.js create mode 100644 src/pages/CheckoutErrorPage.vue create mode 100644 src/pages/CheckoutSuccessPage.vue delete mode 100644 src/pages/ExamplePage.vue diff --git a/.vscode/settings.json b/.vscode/settings.json index 2c9288b..f6fae2a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -23,7 +23,6 @@ "source.fixAll.eslint", "source.fixAll.stylelint" ], - "files.exclude": { "**/.git": true, "**/.svn": true, @@ -61,11 +60,6 @@ "terminal.integrated.enableImages": true, "figma.autocompleteBlocks": true, "figma.assetExportDirectory": "src/assets", - "editor.codeActionsOnSave": [ - "source.addMissingImports", - "source.organizeImports", - "source.fixAll.eslint" - ], "gitlens.gitCommands.skipConfirmations": ["fetch:command", "switch:command"], "diffEditor.ignoreTrimWhitespace": false, "svg.preview.mode": "svg", @@ -78,8 +72,5 @@ "workbench.tree.indent": 16, "window.zoomLevel": -1, "git.ignoreRebaseWarning": true, - "editor.largeFileOptimizations": false, - "[javascript]": { - "editor.defaultFormatter": "vscode.typescript-language-features" - } + "editor.largeFileOptimizations": false } diff --git a/api/.env.example b/api/.env.example index 5418d4b..a6af16c 100644 --- a/api/.env.example +++ b/api/.env.example @@ -2,4 +2,8 @@ HOST="127.0.0.1" DB_USER="root" DB_PASSWORD="root" PORT ="3306" -DATABASE="floranet" \ No newline at end of file +DATABASE="floranet" +BASE_URL =http://localhost:9100 + +CLIENT_ID="Ab5vEddhdvdJhLUkXtTiS2pe43W6PD1JNKns7XMnlw8FvC31H2VYakyVEHvuFBi2b543QIHiPh8j4FLF" +SECRET_KEY="EAxLf05kp08cvbLgZrqjwdx-NXnhQtnP4Y0B4LHAM_7T9-HOh4RaNTirinWfTV8GR6DJWg9djry5yHfO" \ No newline at end of file diff --git a/api/controller/Contact/contact.controller.js b/api/controller/Contact/contact.controller.js new file mode 100644 index 0000000..84aa1fb --- /dev/null +++ b/api/controller/Contact/contact.controller.js @@ -0,0 +1,22 @@ +const db = require("../../db/db"); + +class ContactController { + async Create(req, res) { + try { + const { name, phone, email, message } = req.body; + console.log(name, phone, email, message); + const contact = await db.contact_Request(name, phone, email, message); + + return res.status(200).send({ + data: contact[0] + }) + } catch (error) { + console.log(error); + return res.status(422).send({ + message: "error al guardar contacto" + }) + } + } +} + +module.exports = new ContactController(); diff --git a/api/controller/Delivery/delivery.controller.js b/api/controller/Delivery/delivery.controller.js new file mode 100644 index 0000000..c043584 --- /dev/null +++ b/api/controller/Delivery/delivery.controller.js @@ -0,0 +1,13 @@ +const db = require("../../db/db"); + +class DeliveryController { + async findByPostalCode(req, res) { + const { postalCode } = req.query; + const dates = await db.deliveryDate_get(postalCode); + return res.status(200).send({ + data: dates[0] + }) + } +} + +module.exports = new DeliveryController(); diff --git a/api/controller/Payment/payment.controller.js b/api/controller/Payment/payment.controller.js new file mode 100644 index 0000000..cdc2129 --- /dev/null +++ b/api/controller/Payment/payment.controller.js @@ -0,0 +1,23 @@ +const db = require("../../db/db"); +const paypal = require('paypal-rest-sdk'); +const paymentServices = require('./payment.services') + +class PaymentController { + async Create(req, res) { + return await paymentServices.Create(req, res) + } + + async Success(req, res) { + return await paymentServices.Success(req, res) + } + + Cancel(req, res) { + return res.status(200).send({ + data: { + menssage: "cancelado" + } + }) + } +} + +module.exports = new PaymentController(); diff --git a/api/controller/Payment/payment.services.js b/api/controller/Payment/payment.services.js new file mode 100644 index 0000000..f0db6d0 --- /dev/null +++ b/api/controller/Payment/payment.services.js @@ -0,0 +1,113 @@ +const db = require("../../db/db"); +const payPalProviders = require('./paypal.providers') +const redsysProviders = require('./redsys.providers') + +class PaymentServices { + async Create(req, res) { + try { + //parâmetros para retornar os produtos que serão comprados + const { products, dateExpired, postalCode, customer, type } = req.body + const _products = await db.getProducts(dateExpired, postalCode) + + const productsFilter = _products[0].filter((item) => { + if (products.includes(item.id)) { + return item + } + }); + + if (productsFilter.length !== products.length) { + return res.status(422).send({ + data: { + message: "Uno de los productos no existe." + } + }) + } + + let priceIntial = 0 + let price = productsFilter.reduce((accumulator, curValue) => accumulator + Number(curValue.price), priceIntial) + + let productsIds = '' + for (let i = 0; i < products.length; i++) { + productsIds += `${products[i]}${i === products.length - 1 ? '' : '-'}` + } + + //Create new order + const jsonOrderData = JSON.stringify({ + "customer": { + customerData: { + ...customer.customerData, + type: type, + products: productsFilter + } + }, + }) + const order = await db.orderData_put(jsonOrderData); + const orderFk = order[0][0].orderFk + + if (type === "paypal") { + const data = await payPalProviders.New(orderFk, price) + return res.status(200).send({ + data: { ...data, orderId: orderFk } + }) + } + if (type === "redsys") { + const data = await redsysProviders.New(orderFk, price) + return res.status(200).send({ + data: { ...data, orderId: orderFk } + }) + } + /* if (newOrder) { + return res.status(200).send({ + data: { link: newOrder.links, orderId: orderFk } + }) + } */ + } catch (error) { + console.log(error); + return res.status(422).send({ + data: { + message: "Error al iniciar el pago" + } + }) + } + } + + async Success(req, res) { + try { + //Parameters payment + const { paymentId, PayerID, orderId } = req.body + const payerId = { 'payer_id': PayerID }; + + //API validation payent and confirnm order + paypal.payment.execute(paymentId, payerId, async function (error, payment) { + if (error) { + return res.status(422).send({ + data: { + message: "payment not successful" + } + }) + } else { + if (payment.state == 'approved') { + await db.order_confirm(orderId) + return res.status(200).send({ + data: { + id: payment.id, + message: "payment completed successfully", + } + }) + } else { + return res.status(422).send({ + data: { + message: "payment not successful" + } + }) + } + } + }); + + } catch (error) { + throw error; + } + } +} + +module.exports = new PaymentServices(); diff --git a/api/controller/Payment/paypal.providers.js b/api/controller/Payment/paypal.providers.js new file mode 100644 index 0000000..d1c3edf --- /dev/null +++ b/api/controller/Payment/paypal.providers.js @@ -0,0 +1,59 @@ +const paypal = require('paypal-rest-sdk'); + +class PayPalProviders { + async New(orderFk, price) { + try { + const payReq = JSON.stringify({ + 'intent': 'sale', + 'redirect_urls': { + 'return_url': `${process.env.BASE_URL}/checkout/success?orderId=${orderFk}`, + 'cancel_url': `${process.env.BASE_URL}/checkout/error` + }, + 'payer': { + 'payment_method': 'paypal' + }, + 'transactions': [{ + 'amount': { + 'total': 0.0000000001, + 'currency': 'EUR' + }, + 'description': 'This is the payment transaction description.' + }] + }); + + //Starting checkout process and returning sandbox url + const newOrder = await new Promise(async (resolve, reject) => { + paypal.payment.create(payReq, function (error, payment) { + if (error) { + reject(error) + } else { + //capture HATEOAS links + var links = {}; + payment.links.forEach(function (linkObj) { + links[linkObj.rel] = { + 'href': linkObj.href, + 'method': linkObj.method + }; + }) + //if redirect url present, redirect user + if (links.hasOwnProperty('approval_url')) { + resolve( + { + id: payment.id, + link: links['approval_url'].href, + } + ) + } else { + console.error('no redirect URI present'); + } + } + }); + }).then(res => res) + return newOrder + } catch (error) { + throw error; + } + } +} + +module.exports = new PayPalProviders(); \ No newline at end of file diff --git a/api/controller/Payment/redsys-easy.text b/api/controller/Payment/redsys-easy.text new file mode 100644 index 0000000..b24064d --- /dev/null +++ b/api/controller/Payment/redsys-easy.text @@ -0,0 +1,39 @@ +const Redsys = require('redsys-easy'); +const { + SANDBOX_URLS, + PRODUCTION_URLS, + TRANSACTION_TYPES +} = Redsys + +class RedsysProviders { + async New(orderFk, price) { + console.log("Chama"); + try { + const redsys = new Redsys({ + secretKey: 'sq7HjrUOBfKmC576ILgskD5srU870gJ7', + urls: SANDBOX_URLS, // Also PRODUCTION_URLS + }); + const obj = { + amount: price, + currency: 'EUR', + order: orderFk, + merchantName: 'Floraner', + merchantCode: '999008881', + transactionType: TRANSACTION_TYPES.AUTHORIZATION, // '0' + terminal: '001', + merchantURL: `${process.env.BASE_URL}/payments/redsys/notification`, + successURL: `${process.env.BASE_URL}/checkout/success?orderId=${orderFk}`, + errorURL: `${process.env.BASE_URL}/checkout/error` + } + + const form = redsys.redirectPetition(obj) + + console.log(form); + return true + } catch (error) { + throw error; + } + } +} + +module.exports = new RedsysProviders(); \ No newline at end of file diff --git a/api/controller/Payment/redsys-pos.text b/api/controller/Payment/redsys-pos.text new file mode 100644 index 0000000..59dd6c7 --- /dev/null +++ b/api/controller/Payment/redsys-pos.text @@ -0,0 +1,34 @@ +const RedsysPos = require('redsys-pos'); +const { + CURRENCIES, TRANSACTION_TYPES +} = RedsysPos; + +class RedsysProviders { + async New(orderFk, price) { + console.log("Chama"); + try { + const MERCHANT_KEY = "sq7HjrUOBfKmC576ILgskD5srU870gJ7"; + const redsys = new RedsysPos(MERCHANT_KEY); + const obj = JSON.stringify({ + amount: 100, // 100 euros + orderReference: orderFk, + merchantName: "Floranet", + merchantCode: "999008881", + currency: CURRENCIES.EUR, + transactionType: TRANSACTION_TYPES.AUTHORIZATION, // '0' + terminal: "001", + merchantURL: `${process.env.BASE_URL}/payments/redsys/notification`, + successURL: `${process.env.BASE_URL}/checkout/success?orderId=${orderFk}`, + errorURL: `${process.env.BASE_URL}/checkout/error` + }); + + console.log(obj); + const result = redsys.makePaymentParameters(obj); + return "" + } catch (error) { + throw error; + } + } +} + +module.exports = new RedsysProviders(); \ No newline at end of file diff --git a/api/controller/Payment/redsys.providers.js b/api/controller/Payment/redsys.providers.js new file mode 100644 index 0000000..bab2fa8 --- /dev/null +++ b/api/controller/Payment/redsys.providers.js @@ -0,0 +1,33 @@ +const RedsysPos = require('redsys-pos'); +const { + CURRENCIES, TRANSACTION_TYPES +} = RedsysPos; + +class RedsysProviders { + async New(orderFk, price) { + try { + const MERCHANT_KEY = "sq7HjrUOBfKmC576ILgskD5srU870gJ7"; + const redsys = new RedsysPos(MERCHANT_KEY); + const obj = { + amount: String(price), + orderReference: String(orderFk), + merchantName: "Floranet", + merchantCode: "999008881", + currency: CURRENCIES.EUR, + transactionType: TRANSACTION_TYPES.AUTHORIZATION, // '0' + terminal: "001", + merchantURL: `${process.env.BASE_URL}/payments/redsys/notification`, + successURL: `${process.env.BASE_URL}/checkout/success?orderId=${orderFk}`, + errorURL: `${process.env.BASE_URL}/checkout/error` + }; + + const result = redsys.makePaymentParameters(obj); + console.log(result); + return result + } catch (error) { + throw error; + } + } +} + +module.exports = new RedsysProviders(); \ No newline at end of file diff --git a/api/controller/product.controller.js b/api/controller/Product/product.controller.js similarity index 82% rename from api/controller/product.controller.js rename to api/controller/Product/product.controller.js index 69a9b67..477a1e1 100644 --- a/api/controller/product.controller.js +++ b/api/controller/Product/product.controller.js @@ -1,34 +1,18 @@ -const db = require("../db/db"); - -const productsJson = require("./products.json") +const db = require("../../db/db"); class ProductController { async findAll(req, res) { const params = req.query; const _products = await db.getProducts(params.dateExpired, params.postalCode); - let productsFilter = _products[0]; + let productsFilter = _products[0] if (Number(params.recommend)) { - productsFilter = productsFilter.filter(item => item.recommend == Number(params.recommend)) + productsFilter = productsFilter.filter(item => item.recommend == params.recommend) } if (params.type) { productsFilter = productsFilter.filter(item => item.type === params.type) } - /*if (params.postalCode) { - productsFilter = productsFilter.filter(item => item.postalCode === params.postalCode) - } - if (params.dateExpired) { - const dateSearch = new Date(params.dateExpired); - productsFilter = productsFilter.filter(item => { - const dateProduct = new Date(item.dateExpired); - if (dateProduct >= dateSearch) { - return item - } - }) - }*/ - console.log(productsFilter.length); - if (params.minPrice && !params.maxPrice) { productsFilter = productsFilter.filter(item => { @@ -105,6 +89,7 @@ class ProductController { products: products }) */ + return res.status(200).send({ data: productsFilter }) diff --git a/api/controller/Provinces/provinces.controller.js b/api/controller/Provinces/provinces.controller.js new file mode 100644 index 0000000..d4b6f00 --- /dev/null +++ b/api/controller/Provinces/provinces.controller.js @@ -0,0 +1,23 @@ +const db = require("../../db/db"); + +class ProvincesController { + async findAll(req, res) { + const params = req.query; + const tmpProvinces = await db.getProvinces(); + + let provinces = []; + + tmpProvinces.forEach(element => { + provinces = [...provinces,{ + code: element.id, + name: element.name + }]; + }) + + return res.status(200).send({ + data: provinces + }) + } +} + +module.exports = new ProvincesController(); diff --git a/api/controller/products.json b/api/controller/products.json deleted file mode 100644 index 3840e9b..0000000 --- a/api/controller/products.json +++ /dev/null @@ -1,1974 +0,0 @@ -[ - { - "id": 1, - "name": "Increible Metal Gorro", - "description": "Andy shoes are designed to keeping in mind durability as well as trends, the most stylish range of shoes & sandals", - "price": "€200", - "specialPrice": "€54", - "isNew": false, - "slug": "978-1-348-64648-8", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/efCSfe/640/480", - "https://picsum.photos/seed/cJ5zEC/640/480" - ], - "featured": 1 - }, - { - "id": 2, - "name": "Inteligente Ladrillo Atún", - "description": "Ergonomic executive chair upholstered in bonded black leather and PVC padded seat and back for all-day comfort and support", - "price": "€59", - "specialPrice": "€36", - "isNew": true, - "slug": "978-0-8481-8892-4", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/aqCUrLS/640/480", - "https://picsum.photos/seed/AyGVwTCkAI/640/480", - "https://picsum.photos/seed/N0kuFal/640/480" - ], - "featured": 0, - "position": 2 - }, - { - "id": 3, - "name": "Sabroso Madera Camiseta", - "description": "The automobile layout consists of a front-engine design, with transaxle-type transmissions mounted at the rear of the engine and four wheel drive", - "price": "€67", - "specialPrice": "€25", - "isNew": true, - "slug": "978-0-319-77499-1", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/hLvGjJ/640/480", - "https://picsum.photos/seed/NcOmpIJw/640/480" - ], - "featured": 1, - "position": 3 - }, - { - "id": 4, - "name": "Genérico Algodón Coche", - "description": "The Apollotech B340 is an affordable wireless mouse with reliable connectivity, 12 months battery life and modern design", - "price": "€128", - "specialPrice": "€34", - "isNew": false, - "slug": "978-0-431-46161-8", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/knVoCgN/640/480", - "https://picsum.photos/seed/5yGO2h/640/480" - ], - "featured": 1, - "position": 4, - "discount": "5" - }, - { - "id": 5, - "name": "Ergonómico Algodón Pantalones", - "description": "The Nagasaki Lander is the trademarked name of several series of Nagasaki sport bikes, that started with the 1984 ABC800J", - "price": "€193", - "specialPrice": "€54", - "isNew": false, - "slug": "978-1-342-63425-2", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/YD3k3/640/480", - "https://picsum.photos/seed/jkGhjeZ00/640/480", - "https://picsum.photos/seed/gSNZGN/640/480", - "https://picsum.photos/seed/AEJnS/640/480" - ], - "featured": 1, - "discount": "14" - }, - { - "id": 6, - "name": "Increible Hormigon Sopa", - "description": "Andy shoes are designed to keeping in mind durability as well as trends, the most stylish range of shoes & sandals", - "price": "€77", - "specialPrice": "€40", - "isNew": true, - "slug": "978-1-268-28760-0", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/xntRUHQ/640/480", - "https://picsum.photos/seed/Hu4oY/640/480", - "https://picsum.photos/seed/590BcM/640/480", - "https://picsum.photos/seed/HsVfl/640/480" - ], - "featured": 1 - }, - { - "id": 7, - "name": "Sorprendente Metal Teclado", - "description": "The Apollotech B340 is an affordable wireless mouse with reliable connectivity, 12 months battery life and modern design", - "price": "€84", - "specialPrice": "€42", - "isNew": true, - "slug": "978-0-7079-1378-0", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/oVPFFWAPa/640/480", - "https://picsum.photos/seed/DAsBOLDk/640/480", - "https://picsum.photos/seed/WyZIkkU999/640/480", - "https://picsum.photos/seed/qQ5llz2/640/480", - "https://picsum.photos/seed/Neug42/640/480" - ], - "featured": 1, - "position": 7, - "discount": "8" - }, - { - "id": 8, - "name": "Práctico Plástico Patatas fritas", - "description": "The Football Is Good For Training And Recreational Purposes", - "price": "€91", - "specialPrice": "€44", - "isNew": false, - "slug": "978-1-295-54883-5", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/6enb1U/640/480", - "https://picsum.photos/seed/wLiKA/640/480", - "https://picsum.photos/seed/7BHZ8KnK0J/640/480", - "https://picsum.photos/seed/ZswFH/640/480" - ], - "featured": 1, - "position": 8, - "discount": "12" - }, - { - "id": 9, - "name": "Sabroso Ladrillo Pollo", - "description": "Carbonite web goalkeeper gloves are ergonomically designed to give easy fit", - "price": "€179", - "specialPrice": "€48", - "isNew": false, - "slug": "978-1-63125-580-9", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/rtWLLUs/640/480", - "https://picsum.photos/seed/84YmSjI/640/480", - "https://picsum.photos/seed/8mfl0k/640/480", - "https://picsum.photos/seed/FXbll/640/480" - ], - "featured": 0, - "discount": "12" - }, - { - "id": 10, - "name": "Genérico Plástico Gorro", - "description": "The Nagasaki Lander is the trademarked name of several series of Nagasaki sport bikes, that started with the 1984 ABC800J", - "price": "€50", - "specialPrice": "€32", - "isNew": true, - "slug": "978-1-76312-403-5", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/FB6ThP/640/480", - "https://picsum.photos/seed/9KZh5I/640/480" - ], - "featured": 0, - "position": 10, - "discount": "15" - }, - { - "id": 11, - "name": "Ergonómico Plástico Raton", - "description": "Boston's most advanced compression wear technology increases muscle oxygenation, stabilizes active muscles", - "price": "€108", - "specialPrice": "€54", - "isNew": true, - "slug": "978-1-82301-801-4", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/AQBLZ/640/480", - "https://picsum.photos/seed/luBRfDE3N/640/480", - "https://picsum.photos/seed/lDgqkF7FZ/640/480", - "https://picsum.photos/seed/hZC5b3hFzC/640/480", - "https://picsum.photos/seed/LdmTkN/640/480", - "https://picsum.photos/seed/1vhVw/640/480" - ], - "featured": 0 - }, - { - "id": 12, - "name": "Guapo Acero Mesa", - "description": "New ABC 13 9370, 13.3, 5th Gen CoreA5-8250U, 8GB RAM, 256GB SSD, power UHD Graphics, OS 10 Home, OS Office A & J 2016", - "price": "€56", - "specialPrice": "€28", - "isNew": false, - "slug": "978-1-965192-91-7", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/j1ViMIl/640/480", - "https://picsum.photos/seed/GlmDi/640/480", - "https://picsum.photos/seed/fYbvd6t/640/480" - ], - "featured": 1, - "position": 12 - }, - { - "id": 13, - "name": "Genérico Ladrillo Pizza", - "description": "The automobile layout consists of a front-engine design, with transaxle-type transmissions mounted at the rear of the engine and four wheel drive", - "price": "€130", - "specialPrice": "€50", - "isNew": false, - "slug": "978-0-87287-519-7", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/MeJEmW0/640/480", - "https://picsum.photos/seed/HzpbywR2D/640/480", - "https://picsum.photos/seed/tJBVf/640/480", - "https://picsum.photos/seed/pMCEmn38/640/480", - "https://picsum.photos/seed/oLjn2o/640/480" - ], - "featured": 1, - "discount": "7" - }, - { - "id": 14, - "name": "Refinado Madera Teclado", - "description": "Ergonomic executive chair upholstered in bonded black leather and PVC padded seat and back for all-day comfort and support", - "price": "€95", - "specialPrice": "€31", - "isNew": true, - "slug": "978-1-7991-7993-1", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/jake6b/640/480", - "https://picsum.photos/seed/Bv3GD/640/480", - "https://picsum.photos/seed/NjEk2s/640/480" - ], - "featured": 0 - }, - { - "id": 15, - "name": "Ergonómico Granito Gorro", - "description": "The beautiful range of Apple Naturalé that has an exciting mix of natural ingredients. With the Goodness of 100% Natural Ingredients", - "price": "€178", - "specialPrice": "€58", - "isNew": true, - "slug": "978-1-236-05968-0", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/NUjeWD/640/480", - "https://picsum.photos/seed/FXcWKarPgR/640/480", - "https://picsum.photos/seed/teETy/640/480", - "https://picsum.photos/seed/xU40Wwc/640/480", - "https://picsum.photos/seed/nYXPBqk/640/480", - "https://picsum.photos/seed/8MIPl/640/480" - ], - "featured": 0, - "discount": "11" - }, - { - "id": 16, - "name": "Inteligente Algodón Toallas", - "description": "Andy shoes are designed to keeping in mind durability as well as trends, the most stylish range of shoes & sandals", - "price": "€88", - "specialPrice": "€30", - "isNew": false, - "slug": "978-1-06-472991-5", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/3QgBNrISB/640/480", - "https://picsum.photos/seed/w26O8t4dU/640/480", - "https://picsum.photos/seed/LcunJq/640/480", - "https://picsum.photos/seed/wsxF0MFH/640/480", - "https://picsum.photos/seed/qCaawO/640/480" - ], - "featured": 0, - "discount": "7" - }, - { - "id": 17, - "name": "Sabroso Granito Atún", - "description": "The Apollotech B340 is an affordable wireless mouse with reliable connectivity, 12 months battery life and modern design", - "price": "€21", - "specialPrice": "€60", - "isNew": false, - "slug": "978-1-57118-965-3", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/SN0IW/640/480", - "https://picsum.photos/seed/Ajbvmw3/640/480", - "https://picsum.photos/seed/ZNquT4J50/640/480" - ], - "featured": 0, - "position": 17, - "discount": "11" - }, - { - "id": 18, - "name": "Genérico Plástico Camiseta", - "description": "Carbonite web goalkeeper gloves are ergonomically designed to give easy fit", - "price": "€149", - "specialPrice": "€40", - "isNew": false, - "slug": "978-1-932110-67-8", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/Ib02oSlkv/640/480", - "https://picsum.photos/seed/j7IHn0WcKp/640/480", - "https://picsum.photos/seed/T8heZoClH/640/480", - "https://picsum.photos/seed/oAzVU/640/480", - "https://picsum.photos/seed/lf0N4j/640/480" - ], - "featured": 0 - }, - { - "id": 19, - "name": "Genérico Metal Queso", - "description": "The Nagasaki Lander is the trademarked name of several series of Nagasaki sport bikes, that started with the 1984 ABC800J", - "price": "€27", - "specialPrice": "€26", - "isNew": true, - "slug": "978-1-324-94811-7", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/H9uB5/640/480", - "https://picsum.photos/seed/SoANcSxyac/640/480", - "https://picsum.photos/seed/KLSOpBF9kh/640/480", - "https://picsum.photos/seed/pLNNSDd/640/480", - "https://picsum.photos/seed/6ogPVwRn/640/480" - ], - "featured": 0, - "position": 19 - }, - { - "id": 20, - "name": "Hecho a mano Plástico Salchichas", - "description": "Ergonomic executive chair upholstered in bonded black leather and PVC padded seat and back for all-day comfort and support", - "price": "€152", - "specialPrice": "€32", - "isNew": false, - "slug": "978-1-310-91779-0", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/FEfDF6tnF/640/480", - "https://picsum.photos/seed/eTmq5a/640/480", - "https://picsum.photos/seed/SMULME/640/480", - "https://picsum.photos/seed/t11SEBl6/640/480" - ], - "featured": 0 - }, - { - "id": 21, - "name": "Inteligente Algodón Atún", - "description": "Carbonite web goalkeeper gloves are ergonomically designed to give easy fit", - "price": "€21", - "specialPrice": "€50", - "isNew": true, - "slug": "978-0-7133-9383-5", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/hW3tkRcqCI/640/480", - "https://picsum.photos/seed/t7NHO/640/480", - "https://picsum.photos/seed/V3gdDgxD0/640/480", - "https://picsum.photos/seed/cqgpbHa/640/480", - "https://picsum.photos/seed/jNZ62FSKc/640/480" - ], - "featured": 1, - "position": 21, - "discount": "14" - }, - { - "id": 22, - "name": "Sabroso Algodón Pollo", - "description": "Carbonite web goalkeeper gloves are ergonomically designed to give easy fit", - "price": "€102", - "specialPrice": "€36", - "isNew": false, - "slug": "978-0-288-35801-7", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/z7odxwHu/640/480", - "https://picsum.photos/seed/RaGAjX8R/640/480", - "https://picsum.photos/seed/Hmj1KFPpO/640/480", - "https://picsum.photos/seed/uianxlSxSf/640/480", - "https://picsum.photos/seed/zYhooqjS/640/480" - ], - "featured": 1, - "position": 22 - }, - { - "id": 23, - "name": "Refinado Granito Coche", - "description": "The Apollotech B340 is an affordable wireless mouse with reliable connectivity, 12 months battery life and modern design", - "price": "€81", - "specialPrice": "€26", - "isNew": true, - "slug": "978-0-8275-2208-4", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/XFcxz0YY/640/480", - "https://picsum.photos/seed/bRx77e/640/480", - "https://picsum.photos/seed/eMxcy371u/640/480" - ], - "featured": 1, - "position": 23 - }, - { - "id": 24, - "name": "Increible Metal Pizza", - "description": "The beautiful range of Apple Naturalé that has an exciting mix of natural ingredients. With the Goodness of 100% Natural Ingredients", - "price": "€188", - "specialPrice": "€56", - "isNew": true, - "slug": "978-1-55027-664-0", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/qMu6FQzt/640/480", - "https://picsum.photos/seed/cslc2/640/480", - "https://picsum.photos/seed/F4wKdsI51V/640/480" - ], - "featured": 0, - "position": 24, - "discount": "8" - }, - { - "id": 25, - "name": "Fantástico Metal Teclado", - "description": "The Nagasaki Lander is the trademarked name of several series of Nagasaki sport bikes, that started with the 1984 ABC800J", - "price": "€89", - "specialPrice": "€22", - "isNew": true, - "slug": "978-1-140-19874-1", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/61xoHbbj3/640/480", - "https://picsum.photos/seed/jvlNP/640/480", - "https://picsum.photos/seed/xciRM7qd3B/640/480", - "https://picsum.photos/seed/rmfcz75sV/640/480" - ], - "featured": 0, - "position": 25 - }, - { - "id": 26, - "name": "Increible Plástico Pelota", - "description": "Andy shoes are designed to keeping in mind durability as well as trends, the most stylish range of shoes & sandals", - "price": "€59", - "specialPrice": "€45", - "isNew": false, - "slug": "978-1-048-57120-2", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/Kv2pHL/640/480", - "https://picsum.photos/seed/8nMjd6TU2/640/480", - "https://picsum.photos/seed/Spcwv/640/480", - "https://picsum.photos/seed/OTyjd/640/480", - "https://picsum.photos/seed/YVbDFheA/640/480" - ], - "featured": 1, - "position": 26, - "discount": "15" - }, - { - "id": 27, - "name": "Genérico Acero Coche", - "description": "Andy shoes are designed to keeping in mind durability as well as trends, the most stylish range of shoes & sandals", - "price": "€59", - "specialPrice": "€44", - "isNew": true, - "slug": "978-0-15-326573-0", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/WSkuyujFa/640/480", - "https://picsum.photos/seed/WmuRvQx/640/480", - "https://picsum.photos/seed/kb0vcOf/640/480", - "https://picsum.photos/seed/uH0xXb/640/480", - "https://picsum.photos/seed/4MzyV3/640/480" - ], - "featured": 1, - "position": 27 - }, - { - "id": 28, - "name": "Hecho a mano Hormigon Zapatos", - "description": "The Football Is Good For Training And Recreational Purposes", - "price": "€45", - "specialPrice": "€45", - "isNew": true, - "slug": "978-0-7563-2842-9", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/cYKbw/640/480", - "https://picsum.photos/seed/IYFq9N/640/480", - "https://picsum.photos/seed/UvSVZ78/640/480", - "https://picsum.photos/seed/INrOs/640/480", - "https://picsum.photos/seed/dEhAEZrv/640/480", - "https://picsum.photos/seed/cMjA3Z/640/480" - ], - "featured": 1, - "position": 28 - }, - { - "id": 29, - "name": "Refinado Granito Pollo", - "description": "Carbonite web goalkeeper gloves are ergonomically designed to give easy fit", - "price": "€191", - "specialPrice": "€44", - "isNew": true, - "slug": "978-1-3988-7301-8", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/qePoXP6K/640/480", - "https://picsum.photos/seed/h3p0l6/640/480", - "https://picsum.photos/seed/G2EpUubO/640/480" - ], - "featured": 1 - }, - { - "id": 30, - "name": "Inteligente Madera Salchichas", - "description": "Ergonomic executive chair upholstered in bonded black leather and PVC padded seat and back for all-day comfort and support", - "price": "€126", - "specialPrice": "€20", - "isNew": true, - "slug": "978-1-331-75743-6", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/dBTrE/640/480", - "https://picsum.photos/seed/JA4Cw/640/480", - "https://picsum.photos/seed/2q5if/640/480", - "https://picsum.photos/seed/2ih0CRO/640/480", - "https://picsum.photos/seed/8fCncPfW/640/480" - ], - "featured": 0, - "discount": "5" - }, - { - "id": 31, - "name": "Rústico Hormigon Bicicleta", - "description": "Andy shoes are designed to keeping in mind durability as well as trends, the most stylish range of shoes & sandals", - "price": "€63", - "specialPrice": "€40", - "isNew": true, - "slug": "978-0-11-989468-4", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/EwzFjj8/640/480", - "https://picsum.photos/seed/Ne0GuwEU6/640/480" - ], - "featured": 1 - }, - { - "id": 32, - "name": "Genérico Algodón Raton", - "description": "The Apollotech B340 is an affordable wireless mouse with reliable connectivity, 12 months battery life and modern design", - "price": "€95", - "specialPrice": "€20", - "isNew": false, - "slug": "978-1-4452-7592-5", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/JzEKDZ/640/480", - "https://picsum.photos/seed/ofYhP4/640/480", - "https://picsum.photos/seed/psUTjl0o/640/480" - ], - "featured": 1 - }, - { - "id": 33, - "name": "Guapa Ladrillo Teclado", - "description": "Ergonomic executive chair upholstered in bonded black leather and PVC padded seat and back for all-day comfort and support", - "price": "€168", - "specialPrice": "€28", - "isNew": false, - "slug": "978-1-8380507-5-7", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/MvlUAg/640/480", - "https://picsum.photos/seed/kJ6aZe/640/480", - "https://picsum.photos/seed/vG2qiqZrI/640/480" - ], - "featured": 1, - "discount": "14" - }, - { - "id": 34, - "name": "Guapa Acero Ensalada", - "description": "Boston's most advanced compression wear technology increases muscle oxygenation, stabilizes active muscles", - "price": "€199", - "specialPrice": "€51", - "isNew": false, - "slug": "978-0-515-08362-0", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/ktlHFZa7T/640/480", - "https://picsum.photos/seed/zGj5G1f/640/480", - "https://picsum.photos/seed/cGn3F/640/480" - ], - "featured": 1 - }, - { - "id": 35, - "name": "Hecho a mano Algodón Pelota", - "description": "Andy shoes are designed to keeping in mind durability as well as trends, the most stylish range of shoes & sandals", - "price": "€164", - "specialPrice": "€49", - "isNew": true, - "slug": "978-1-377-81139-0", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/jTkM6B/640/480", - "https://picsum.photos/seed/1bMD1mgLJ/640/480", - "https://picsum.photos/seed/Ho4E1yc/640/480", - "https://picsum.photos/seed/rFUM8gZxsK/640/480", - "https://picsum.photos/seed/9PQ51cFnX/640/480" - ], - "featured": 0, - "discount": "9" - }, - { - "id": 36, - "name": "Guapo Metal Pescado", - "description": "New range of formal shirts are designed keeping you in mind. With fits and styling that will make you stand apart", - "price": "€187", - "specialPrice": "€51", - "isNew": false, - "slug": "978-0-314-22100-1", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/mcSNVcAt/640/480", - "https://picsum.photos/seed/YgXJEOkF/640/480", - "https://picsum.photos/seed/e3fkI67F/640/480" - ], - "featured": 1, - "position": 36 - }, - { - "id": 37, - "name": "Fantástico Madera Pollo", - "description": "The Nagasaki Lander is the trademarked name of several series of Nagasaki sport bikes, that started with the 1984 ABC800J", - "price": "€195", - "specialPrice": "€39", - "isNew": true, - "slug": "978-1-84460-628-3", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/PuObBpl/640/480", - "https://picsum.photos/seed/D6XW1XMhuR/640/480", - "https://picsum.photos/seed/XaZsN/640/480" - ], - "featured": 0, - "discount": "11" - }, - { - "id": 38, - "name": "Rústico Algodón Queso", - "description": "The Apollotech B340 is an affordable wireless mouse with reliable connectivity, 12 months battery life and modern design", - "price": "€124", - "specialPrice": "€26", - "isNew": true, - "slug": "978-1-309-55513-2", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/8g9ga6K/640/480", - "https://picsum.photos/seed/er1R20/640/480", - "https://picsum.photos/seed/W05nMAmO/640/480", - "https://picsum.photos/seed/NGjAmte4C/640/480" - ], - "featured": 0, - "discount": "10" - }, - { - "id": 39, - "name": "Sorprendente Ladrillo Mesa", - "description": "Boston's most advanced compression wear technology increases muscle oxygenation, stabilizes active muscles", - "price": "€103", - "specialPrice": "€53", - "isNew": true, - "slug": "978-1-6599-5199-8", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/Kbdw1/640/480", - "https://picsum.photos/seed/pEemudoDJ/640/480", - "https://picsum.photos/seed/R9F4r1E/640/480" - ], - "featured": 0 - }, - { - "id": 40, - "name": "Genérico Madera Teclado", - "description": "New ABC 13 9370, 13.3, 5th Gen CoreA5-8250U, 8GB RAM, 256GB SSD, power UHD Graphics, OS 10 Home, OS Office A & J 2016", - "price": "€27", - "specialPrice": "€44", - "isNew": true, - "slug": "978-0-00-710592-2", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/qsKyfaxQ4g/640/480", - "https://picsum.photos/seed/RbYRZBXlm/640/480", - "https://picsum.photos/seed/ZNVJ25dE0X/640/480", - "https://picsum.photos/seed/Mc0Sc/640/480", - "https://picsum.photos/seed/KwPFis3Jh/640/480", - "https://picsum.photos/seed/rShUr0Fxp/640/480" - ], - "featured": 1, - "discount": "14" - }, - { - "id": 41, - "name": "Genérico Granito Pantalones", - "description": "The slim & simple Maple Gaming Keyboard from Dev Byte comes with a sleek body and 7- Color RGB LED Back-lighting for smart functionality", - "price": "€38", - "specialPrice": "€48", - "isNew": false, - "slug": "978-1-4176-3485-9", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/zLjAl3/640/480", - "https://picsum.photos/seed/t7lzKsc/640/480", - "https://picsum.photos/seed/EdEpBs2n3/640/480" - ], - "featured": 0 - }, - { - "id": 42, - "name": "Guapo Madera Raton", - "description": "The automobile layout consists of a front-engine design, with transaxle-type transmissions mounted at the rear of the engine and four wheel drive", - "price": "€160", - "specialPrice": "€22", - "isNew": true, - "slug": "978-0-940197-17-6", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/bB5fh/640/480", - "https://picsum.photos/seed/4z8LC3hXF/640/480", - "https://picsum.photos/seed/KhHhYT/640/480", - "https://picsum.photos/seed/Fg8pI/640/480", - "https://picsum.photos/seed/Uj5w7I3V/640/480" - ], - "featured": 1, - "position": 42, - "discount": "7" - }, - { - "id": 43, - "name": "Artesanal Plástico Gorro", - "description": "Carbonite web goalkeeper gloves are ergonomically designed to give easy fit", - "price": "€154", - "specialPrice": "€56", - "isNew": true, - "slug": "978-1-318-64981-5", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/QVRhLvAY7/640/480", - "https://picsum.photos/seed/JAM43Cq3qz/640/480", - "https://picsum.photos/seed/g1CG1BOr/640/480", - "https://picsum.photos/seed/g5Gpd/640/480" - ], - "featured": 1, - "position": 43 - }, - { - "id": 44, - "name": "Refinado Algodón Camiseta", - "description": "The Football Is Good For Training And Recreational Purposes", - "price": "€32", - "specialPrice": "€28", - "isNew": false, - "slug": "978-0-89872-374-8", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/l97X5/640/480", - "https://picsum.photos/seed/e5a8U/640/480", - "https://picsum.photos/seed/3ID5gT/640/480", - "https://picsum.photos/seed/Fv91Wp2/640/480" - ], - "featured": 1, - "discount": "14" - }, - { - "id": 45, - "name": "Refinado Plástico Zapatos", - "description": "The Football Is Good For Training And Recreational Purposes", - "price": "€106", - "specialPrice": "€34", - "isNew": true, - "slug": "978-0-217-22380-5", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/cSzf4H/640/480", - "https://picsum.photos/seed/yuUm9XD8o/640/480", - "https://picsum.photos/seed/zRg0Tof/640/480" - ], - "featured": 1 - }, - { - "id": 46, - "name": "Increible Madera Ordenador", - "description": "Carbonite web goalkeeper gloves are ergonomically designed to give easy fit", - "price": "€111", - "specialPrice": "€35", - "isNew": true, - "slug": "978-0-909996-40-6", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/8CNBVztO/640/480", - "https://picsum.photos/seed/Xrp987/640/480", - "https://picsum.photos/seed/8uaxkeTHO/640/480" - ], - "featured": 1 - }, - { - "id": 47, - "name": "Fantástico Acero Queso", - "description": "The Nagasaki Lander is the trademarked name of several series of Nagasaki sport bikes, that started with the 1984 ABC800J", - "price": "€123", - "specialPrice": "€23", - "isNew": false, - "slug": "978-1-64697-271-5", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/wCp2KM/640/480", - "https://picsum.photos/seed/nnBEvn/640/480", - "https://picsum.photos/seed/t5y9qSOx/640/480", - "https://picsum.photos/seed/IwucQ3tPf/640/480", - "https://picsum.photos/seed/Jb0yX4/640/480", - "https://picsum.photos/seed/6e7xniBLbp/640/480" - ], - "featured": 1, - "position": 47 - }, - { - "id": 48, - "name": "Rústico Plástico Teclado", - "description": "Carbonite web goalkeeper gloves are ergonomically designed to give easy fit", - "price": "€72", - "specialPrice": "€48", - "isNew": true, - "slug": "978-0-937555-33-0", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/hg9HMXJ4l/640/480", - "https://picsum.photos/seed/PCA1uHX/640/480", - "https://picsum.photos/seed/JFRCbMQO/640/480", - "https://picsum.photos/seed/j5oP44i/640/480", - "https://picsum.photos/seed/8ltyUC/640/480", - "https://picsum.photos/seed/rJMEG/640/480" - ], - "featured": 1 - }, - { - "id": 49, - "name": "Guapa Acero Gorro", - "description": "The slim & simple Maple Gaming Keyboard from Dev Byte comes with a sleek body and 7- Color RGB LED Back-lighting for smart functionality", - "price": "€41", - "specialPrice": "€35", - "isNew": false, - "slug": "978-1-238-68808-6", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/mWU235G/640/480", - "https://picsum.photos/seed/ZCinUiiwZ/640/480", - "https://picsum.photos/seed/yJo5MOPK/640/480", - "https://picsum.photos/seed/29OaIyJ/640/480" - ], - "featured": 0, - "discount": "15" - }, - { - "id": 50, - "name": "Genérico Algodón Bicicleta", - "description": "The Apollotech B340 is an affordable wireless mouse with reliable connectivity, 12 months battery life and modern design", - "price": "€190", - "specialPrice": "€20", - "isNew": false, - "slug": "978-1-56675-720-1", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/EaDjCiqk/640/480", - "https://picsum.photos/seed/nGNbbNc/640/480" - ], - "featured": 1, - "discount": "15" - }, - { - "id": 51, - "name": "Refinado Metal Pollo", - "description": "The Nagasaki Lander is the trademarked name of several series of Nagasaki sport bikes, that started with the 1984 ABC800J", - "price": "€20", - "specialPrice": "€56", - "isNew": true, - "slug": "978-1-257-37902-6", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/s8zjP0/640/480", - "https://picsum.photos/seed/9zEZt/640/480", - "https://picsum.photos/seed/V7zVU/640/480" - ], - "featured": 0, - "discount": "13" - }, - { - "id": 52, - "name": "Fantástico Plástico Ensalada", - "description": "New ABC 13 9370, 13.3, 5th Gen CoreA5-8250U, 8GB RAM, 256GB SSD, power UHD Graphics, OS 10 Home, OS Office A & J 2016", - "price": "€194", - "specialPrice": "€38", - "isNew": true, - "slug": "978-1-933903-90-3", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/HTev9LlW/640/480", - "https://picsum.photos/seed/SUxtP5cT/640/480", - "https://picsum.photos/seed/T4487xS9DG/640/480" - ], - "featured": 0, - "position": 52 - }, - { - "id": 53, - "name": "Artesanal Madera Ordenador", - "description": "New ABC 13 9370, 13.3, 5th Gen CoreA5-8250U, 8GB RAM, 256GB SSD, power UHD Graphics, OS 10 Home, OS Office A & J 2016", - "price": "€29", - "specialPrice": "€34", - "isNew": false, - "slug": "978-0-7736-7108-9", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/B6rfb/640/480", - "https://picsum.photos/seed/k3JYiBQRx/640/480", - "https://picsum.photos/seed/gnntwG1BX/640/480", - "https://picsum.photos/seed/A9Wd3/640/480", - "https://picsum.photos/seed/bptxrVNRiz/640/480", - "https://picsum.photos/seed/HbLRfW/640/480" - ], - "featured": 1 - }, - { - "id": 54, - "name": "Pequeño Metal Ordenador", - "description": "The automobile layout consists of a front-engine design, with transaxle-type transmissions mounted at the rear of the engine and four wheel drive", - "price": "€51", - "specialPrice": "€32", - "isNew": true, - "slug": "978-0-675-04894-1", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/DD2MtGS8/640/480", - "https://picsum.photos/seed/vERlc/640/480", - "https://picsum.photos/seed/ljRUIx1/640/480", - "https://picsum.photos/seed/1lYn2Xcr1g/640/480", - "https://picsum.photos/seed/od7uZ0Hy/640/480", - "https://picsum.photos/seed/eotkUn/640/480" - ], - "featured": 1, - "position": 54 - }, - { - "id": 55, - "name": "Sabroso Ladrillo Pizza", - "description": "The automobile layout consists of a front-engine design, with transaxle-type transmissions mounted at the rear of the engine and four wheel drive", - "price": "€104", - "specialPrice": "€50", - "isNew": false, - "slug": "978-0-7105-6291-3", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/9N7ink7krJ/640/480", - "https://picsum.photos/seed/7s4aYaneZg/640/480", - "https://picsum.photos/seed/2nhD8DhqKq/640/480" - ], - "featured": 0, - "position": 55, - "discount": "5" - }, - { - "id": 56, - "name": "Artesanal Metal Toallas", - "description": "The beautiful range of Apple Naturalé that has an exciting mix of natural ingredients. With the Goodness of 100% Natural Ingredients", - "price": "€117", - "specialPrice": "€53", - "isNew": false, - "slug": "978-0-18-757443-3", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/wNA60wdyxq/640/480", - "https://picsum.photos/seed/86jeF/640/480", - "https://picsum.photos/seed/2Ix8CKO0/640/480", - "https://picsum.photos/seed/08QHc5F/640/480" - ], - "featured": 1 - }, - { - "id": 57, - "name": "Ergonómico Acero Pescado", - "description": "The Nagasaki Lander is the trademarked name of several series of Nagasaki sport bikes, that started with the 1984 ABC800J", - "price": "€176", - "specialPrice": "€58", - "isNew": true, - "slug": "978-0-538-86677-4", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/vFAtUVdhTQ/640/480", - "https://picsum.photos/seed/27vewh/640/480" - ], - "featured": 0 - }, - { - "id": 58, - "name": "Inteligente Granito Guantes", - "description": "The slim & simple Maple Gaming Keyboard from Dev Byte comes with a sleek body and 7- Color RGB LED Back-lighting for smart functionality", - "price": "€151", - "specialPrice": "€33", - "isNew": false, - "slug": "978-1-61481-833-5", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/4MsN1O/640/480", - "https://picsum.photos/seed/UdYQ9p/640/480" - ], - "featured": 1 - }, - { - "id": 59, - "name": "Ergonómico Algodón Pizza", - "description": "Carbonite web goalkeeper gloves are ergonomically designed to give easy fit", - "price": "€87", - "specialPrice": "€45", - "isNew": false, - "slug": "978-1-716-77358-7", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/YXrh4TJhn/640/480", - "https://picsum.photos/seed/qJ3IS/640/480", - "https://picsum.photos/seed/vZTLJBiSs/640/480", - "https://picsum.photos/seed/yWwpqd9uRR/640/480", - "https://picsum.photos/seed/1oPusQ9Q3/640/480", - "https://picsum.photos/seed/Q6kSK6/640/480" - ], - "featured": 0, - "position": 59 - }, - { - "id": 60, - "name": "Sorprendente Acero Salchichas", - "description": "New ABC 13 9370, 13.3, 5th Gen CoreA5-8250U, 8GB RAM, 256GB SSD, power UHD Graphics, OS 10 Home, OS Office A & J 2016", - "price": "€59", - "specialPrice": "€60", - "isNew": false, - "slug": "978-0-7694-2909-0", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/98Nx8Mi/640/480", - "https://picsum.photos/seed/BwjmGy6VB/640/480" - ], - "featured": 0, - "discount": "6" - }, - { - "id": 61, - "name": "Increible Hormigon Pollo", - "description": "Ergonomic executive chair upholstered in bonded black leather and PVC padded seat and back for all-day comfort and support", - "price": "€57", - "specialPrice": "€50", - "isNew": true, - "slug": "978-0-619-91892-7", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/kxRaIrj5/640/480", - "https://picsum.photos/seed/QAIRpl/640/480" - ], - "featured": 1, - "position": 61, - "discount": "5" - }, - { - "id": 62, - "name": "Guapa Plástico Pizza", - "description": "The automobile layout consists of a front-engine design, with transaxle-type transmissions mounted at the rear of the engine and four wheel drive", - "price": "€194", - "specialPrice": "€33", - "isNew": false, - "slug": "978-1-377-08792-4", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/t70NVE/640/480", - "https://picsum.photos/seed/WCDGPADT7M/640/480" - ], - "featured": 0 - }, - { - "id": 63, - "name": "Guapo Plástico Patatas fritas", - "description": "The Nagasaki Lander is the trademarked name of several series of Nagasaki sport bikes, that started with the 1984 ABC800J", - "price": "€140", - "specialPrice": "€31", - "isNew": false, - "slug": "978-0-7734-2463-0", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/ibhRMBMJ/640/480", - "https://picsum.photos/seed/7fNck/640/480", - "https://picsum.photos/seed/esXzS36A2/640/480", - "https://picsum.photos/seed/Zyx0R/640/480", - "https://picsum.photos/seed/gyUEYTFw/640/480" - ], - "featured": 1 - }, - { - "id": 64, - "name": "Genérico Algodón Coche", - "description": "New ABC 13 9370, 13.3, 5th Gen CoreA5-8250U, 8GB RAM, 256GB SSD, power UHD Graphics, OS 10 Home, OS Office A & J 2016", - "price": "€137", - "specialPrice": "€47", - "isNew": false, - "slug": "978-1-77867-791-5", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/AsMDYHf3/640/480", - "https://picsum.photos/seed/tCkf3/640/480", - "https://picsum.photos/seed/8ZnlYxm/640/480", - "https://picsum.photos/seed/a4eViqq8y0/640/480", - "https://picsum.photos/seed/VowNo/640/480" - ], - "featured": 1, - "position": 64 - }, - { - "id": 65, - "name": "Inteligente Hormigon Atún", - "description": "Boston's most advanced compression wear technology increases muscle oxygenation, stabilizes active muscles", - "price": "€39", - "specialPrice": "€44", - "isNew": true, - "slug": "978-1-926748-33-7", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/vzOKt7Ss/640/480", - "https://picsum.photos/seed/cvHL8wo/640/480", - "https://picsum.photos/seed/SSNTk/640/480", - "https://picsum.photos/seed/DXRIbXn/640/480", - "https://picsum.photos/seed/eBegt2U/640/480", - "https://picsum.photos/seed/WTaw713G/640/480" - ], - "featured": 0 - }, - { - "id": 66, - "name": "Inteligente Metal Pizza", - "description": "Carbonite web goalkeeper gloves are ergonomically designed to give easy fit", - "price": "€177", - "specialPrice": "€31", - "isNew": false, - "slug": "978-1-229-86164-1", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/6EIye/640/480", - "https://picsum.photos/seed/mKRPxDHnqH/640/480" - ], - "featured": 1 - }, - { - "id": 67, - "name": "Fantástico Algodón Pizza", - "description": "Andy shoes are designed to keeping in mind durability as well as trends, the most stylish range of shoes & sandals", - "price": "€25", - "specialPrice": "€36", - "isNew": false, - "slug": "978-0-299-87026-3", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/iGfs1/640/480", - "https://picsum.photos/seed/mxA3uTj/640/480", - "https://picsum.photos/seed/f3Y9Y/640/480" - ], - "featured": 0, - "position": 67 - }, - { - "id": 68, - "name": "Práctico Plástico Mesa", - "description": "Ergonomic executive chair upholstered in bonded black leather and PVC padded seat and back for all-day comfort and support", - "price": "€28", - "specialPrice": "€32", - "isNew": true, - "slug": "978-0-8453-9085-6", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/pZHuRWv1V/640/480", - "https://picsum.photos/seed/P22AtCz7/640/480", - "https://picsum.photos/seed/wKO6C6VO/640/480", - "https://picsum.photos/seed/z86STX25O/640/480" - ], - "featured": 1, - "position": 68 - }, - { - "id": 69, - "name": "Refinado Granito Queso", - "description": "The Football Is Good For Training And Recreational Purposes", - "price": "€173", - "specialPrice": "€45", - "isNew": true, - "slug": "978-0-19-050936-1", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/CQ84sbVM/640/480", - "https://picsum.photos/seed/XOEr59/640/480" - ], - "featured": 1, - "discount": "15" - }, - { - "id": 70, - "name": "Hecho a mano Granito Pescado", - "description": "New range of formal shirts are designed keeping you in mind. With fits and styling that will make you stand apart", - "price": "€57", - "specialPrice": "€40", - "isNew": false, - "slug": "978-0-533-86437-9", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/oUdfbU/640/480", - "https://picsum.photos/seed/53aGSoCV/640/480", - "https://picsum.photos/seed/TAj3bbm/640/480" - ], - "featured": 1, - "discount": "7" - }, - { - "id": 71, - "name": "Práctico Madera Zapatos", - "description": "Carbonite web goalkeeper gloves are ergonomically designed to give easy fit", - "price": "€26", - "specialPrice": "€34", - "isNew": false, - "slug": "978-1-959637-80-6", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/n5HnJveOa/640/480", - "https://picsum.photos/seed/74riXk3/640/480", - "https://picsum.photos/seed/qVXXnHpTSJ/640/480", - "https://picsum.photos/seed/Pka9uIQyEL/640/480", - "https://picsum.photos/seed/LcQaJud/640/480" - ], - "featured": 1 - }, - { - "id": 72, - "name": "Guapo Granito Pelota", - "description": "Andy shoes are designed to keeping in mind durability as well as trends, the most stylish range of shoes & sandals", - "price": "€116", - "specialPrice": "€42", - "isNew": true, - "slug": "978-1-57149-992-9", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/jEUBH4QZke/640/480", - "https://picsum.photos/seed/erI72LXH/640/480", - "https://picsum.photos/seed/23TyWqZQ/640/480", - "https://picsum.photos/seed/b4GfqzlUKx/640/480" - ], - "featured": 0, - "discount": "15" - }, - { - "id": 73, - "name": "Hecho a mano Ladrillo Ordenador", - "description": "Carbonite web goalkeeper gloves are ergonomically designed to give easy fit", - "price": "€53", - "specialPrice": "€24", - "isNew": true, - "slug": "978-1-249-08425-9", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/mBopp/640/480", - "https://picsum.photos/seed/kFK1V/640/480" - ], - "featured": 1 - }, - { - "id": 74, - "name": "Genérico Algodón Atún", - "description": "Carbonite web goalkeeper gloves are ergonomically designed to give easy fit", - "price": "€157", - "specialPrice": "€23", - "isNew": true, - "slug": "978-0-447-47968-3", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/cLwQaL/640/480", - "https://picsum.photos/seed/cgRbBDr2K/640/480", - "https://picsum.photos/seed/e2AkbcrrbQ/640/480", - "https://picsum.photos/seed/WHu0N5/640/480", - "https://picsum.photos/seed/NY7Yv/640/480" - ], - "featured": 0 - }, - { - "id": 75, - "name": "Guapa Plástico Pizza", - "description": "Ergonomic executive chair upholstered in bonded black leather and PVC padded seat and back for all-day comfort and support", - "price": "€109", - "specialPrice": "€30", - "isNew": false, - "slug": "978-0-927854-44-3", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/SKOcqLfbL/640/480", - "https://picsum.photos/seed/3wqPKL9P/640/480", - "https://picsum.photos/seed/A0UPk/640/480" - ], - "featured": 0, - "position": 75, - "discount": "10" - }, - { - "id": 76, - "name": "Ergonómico Metal Ordenador", - "description": "The beautiful range of Apple Naturalé that has an exciting mix of natural ingredients. With the Goodness of 100% Natural Ingredients", - "price": "€81", - "specialPrice": "€40", - "isNew": true, - "slug": "978-0-448-94113-4", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/aVQJJ/640/480", - "https://picsum.photos/seed/AT7nQkM45Z/640/480", - "https://picsum.photos/seed/FBgbD60/640/480", - "https://picsum.photos/seed/CV2zoRUDiA/640/480", - "https://picsum.photos/seed/TBWP8RW/640/480" - ], - "featured": 1 - }, - { - "id": 77, - "name": "Increible Acero Mesa", - "description": "The automobile layout consists of a front-engine design, with transaxle-type transmissions mounted at the rear of the engine and four wheel drive", - "price": "€148", - "specialPrice": "€25", - "isNew": true, - "slug": "978-0-251-50209-6", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/4PCEsZUNV8/640/480", - "https://picsum.photos/seed/BLIbPNoqbc/640/480", - "https://picsum.photos/seed/nhtFOy0L/640/480", - "https://picsum.photos/seed/uIOse8YZV/640/480", - "https://picsum.photos/seed/alDhaxN/640/480" - ], - "featured": 1, - "position": 77, - "discount": "10" - }, - { - "id": 78, - "name": "Sorprendente Madera Bicicleta", - "description": "The automobile layout consists of a front-engine design, with transaxle-type transmissions mounted at the rear of the engine and four wheel drive", - "price": "€93", - "specialPrice": "€59", - "isNew": true, - "slug": "978-0-346-58774-8", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/zJ0aWOHm/640/480", - "https://picsum.photos/seed/xZ3Cb/640/480" - ], - "featured": 0, - "position": 78 - }, - { - "id": 79, - "name": "Sorprendente Metal Atún", - "description": "Andy shoes are designed to keeping in mind durability as well as trends, the most stylish range of shoes & sandals", - "price": "€126", - "specialPrice": "€48", - "isNew": false, - "slug": "978-0-7900-3519-2", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/DuYVyZ4V/640/480", - "https://picsum.photos/seed/C1MqeUSve/640/480", - "https://picsum.photos/seed/HSxWo4kxAH/640/480", - "https://picsum.photos/seed/oyfF2q/640/480" - ], - "featured": 0, - "discount": "5" - }, - { - "id": 80, - "name": "Rústico Granito Ensalada", - "description": "The Football Is Good For Training And Recreational Purposes", - "price": "€192", - "specialPrice": "€44", - "isNew": false, - "slug": "978-0-7068-0264-1", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/TDHd4l5/640/480", - "https://picsum.photos/seed/AlODLgF/640/480", - "https://picsum.photos/seed/xIqLgU/640/480", - "https://picsum.photos/seed/vfsbUDfC/640/480" - ], - "featured": 0, - "position": 80, - "discount": "12" - }, - { - "id": 81, - "name": "Refinado Hormigon Silla", - "description": "The slim & simple Maple Gaming Keyboard from Dev Byte comes with a sleek body and 7- Color RGB LED Back-lighting for smart functionality", - "price": "€124", - "specialPrice": "€22", - "isNew": true, - "slug": "978-1-82028-222-7", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/7rQSVsud9y/640/480", - "https://picsum.photos/seed/v503sK/640/480", - "https://picsum.photos/seed/9Yzs3A3x/640/480", - "https://picsum.photos/seed/JeLrcZtW/640/480" - ], - "featured": 1, - "position": 81, - "discount": "9" - }, - { - "id": 82, - "name": "Artesanal Madera Pelota", - "description": "The Nagasaki Lander is the trademarked name of several series of Nagasaki sport bikes, that started with the 1984 ABC800J", - "price": "€63", - "specialPrice": "€33", - "isNew": false, - "slug": "978-0-8045-0032-6", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/apkynsM/640/480", - "https://picsum.photos/seed/x8TxsLqWq/640/480", - "https://picsum.photos/seed/QCvTJm2Vw/640/480", - "https://picsum.photos/seed/Lc2uPnFVd/640/480", - "https://picsum.photos/seed/ZzPt5jVh/640/480" - ], - "featured": 0 - }, - { - "id": 83, - "name": "Ergonómico Algodón Bacon", - "description": "Carbonite web goalkeeper gloves are ergonomically designed to give easy fit", - "price": "€64", - "specialPrice": "€46", - "isNew": false, - "slug": "978-0-06-018240-3", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/zY0e2vmO9O/640/480", - "https://picsum.photos/seed/wSoCzSaP/640/480", - "https://picsum.photos/seed/hx6X2MM/640/480", - "https://picsum.photos/seed/RKj2y/640/480" - ], - "featured": 1, - "position": 83, - "discount": "15" - }, - { - "id": 84, - "name": "Rústico Hormigon Bicicleta", - "description": "Ergonomic executive chair upholstered in bonded black leather and PVC padded seat and back for all-day comfort and support", - "price": "€150", - "specialPrice": "€24", - "isNew": true, - "slug": "978-0-503-25299-1", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/7GgcI3O/640/480", - "https://picsum.photos/seed/QJd06EZD/640/480", - "https://picsum.photos/seed/UUZtuR0/640/480", - "https://picsum.photos/seed/uNnFeax/640/480" - ], - "featured": 0, - "discount": "11" - }, - { - "id": 85, - "name": "Práctico Acero Ensalada", - "description": "Andy shoes are designed to keeping in mind durability as well as trends, the most stylish range of shoes & sandals", - "price": "€140", - "specialPrice": "€59", - "isNew": true, - "slug": "978-1-83978-799-7", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/gghO9FeS/640/480", - "https://picsum.photos/seed/spn5I6R/640/480", - "https://picsum.photos/seed/zgqFt9/640/480", - "https://picsum.photos/seed/MA9RK/640/480" - ], - "featured": 1 - }, - { - "id": 86, - "name": "Hecho a mano Plástico Teclado", - "description": "The beautiful range of Apple Naturalé that has an exciting mix of natural ingredients. With the Goodness of 100% Natural Ingredients", - "price": "€184", - "specialPrice": "€35", - "isNew": true, - "slug": "978-0-609-43686-8", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/JbXS1/640/480", - "https://picsum.photos/seed/0nBtkn8/640/480", - "https://picsum.photos/seed/JNyR9bbz/640/480", - "https://picsum.photos/seed/SjGh0AlcFr/640/480", - "https://picsum.photos/seed/KDUniZvZQ/640/480" - ], - "featured": 0, - "discount": "13" - }, - { - "id": 87, - "name": "Ergonómico Metal Salchichas", - "description": "The automobile layout consists of a front-engine design, with transaxle-type transmissions mounted at the rear of the engine and four wheel drive", - "price": "€71", - "specialPrice": "€45", - "isNew": false, - "slug": "978-0-527-38222-3", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/kqMq4IbI/640/480", - "https://picsum.photos/seed/V5kJzsX4Qq/640/480" - ], - "featured": 0, - "position": 87 - }, - { - "id": 88, - "name": "Artesanal Acero Toallas", - "description": "New range of formal shirts are designed keeping you in mind. With fits and styling that will make you stand apart", - "price": "€20", - "specialPrice": "€36", - "isNew": false, - "slug": "978-1-106-45123-1", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/ZAUKGmZoH8/640/480", - "https://picsum.photos/seed/b4E2a/640/480" - ], - "featured": 1, - "position": 88 - }, - { - "id": 89, - "name": "Inteligente Plástico Ensalada", - "description": "Carbonite web goalkeeper gloves are ergonomically designed to give easy fit", - "price": "€186", - "specialPrice": "€23", - "isNew": true, - "slug": "978-0-09-262953-2", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/yi0wdYVFd/640/480", - "https://picsum.photos/seed/N6x8TCI37/640/480", - "https://picsum.photos/seed/LdnWmnU/640/480", - "https://picsum.photos/seed/ZvJVU7yIs0/640/480", - "https://picsum.photos/seed/CuJshkx/640/480", - "https://picsum.photos/seed/K4BYL/640/480" - ], - "featured": 0, - "position": 89 - }, - { - "id": 90, - "name": "Ergonómico Ladrillo Guantes", - "description": "Boston's most advanced compression wear technology increases muscle oxygenation, stabilizes active muscles", - "price": "€144", - "specialPrice": "€26", - "isNew": false, - "slug": "978-0-08-218659-5", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/r3f9zy6s/640/480", - "https://picsum.photos/seed/geSHZ/640/480", - "https://picsum.photos/seed/0BzdL5/640/480", - "https://picsum.photos/seed/wmspiYqEs/640/480" - ], - "featured": 1, - "position": 90, - "discount": "5" - }, - { - "id": 91, - "name": "Sorprendente Madera Zapatos", - "description": "Ergonomic executive chair upholstered in bonded black leather and PVC padded seat and back for all-day comfort and support", - "price": "€146", - "specialPrice": "€33", - "isNew": false, - "slug": "978-1-0925-8381-7", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/uFgCLHRlu/640/480", - "https://picsum.photos/seed/09IFrW/640/480", - "https://picsum.photos/seed/9lYlf4bME/640/480", - "https://picsum.photos/seed/dXedo8jO/640/480", - "https://picsum.photos/seed/1mnxTIVfpl/640/480" - ], - "featured": 0, - "discount": "12" - }, - { - "id": 92, - "name": "Increible Hormigon Pizza", - "description": "The Football Is Good For Training And Recreational Purposes", - "price": "€123", - "specialPrice": "€20", - "isNew": false, - "slug": "978-1-6760-4609-7", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/q5RDIKF/640/480", - "https://picsum.photos/seed/gftwcvjbrE/640/480" - ], - "featured": 1, - "position": 92 - }, - { - "id": 93, - "name": "Genérico Algodón Teclado", - "description": "The Apollotech B340 is an affordable wireless mouse with reliable connectivity, 12 months battery life and modern design", - "price": "€119", - "specialPrice": "€38", - "isNew": false, - "slug": "978-1-4015-3538-4", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/Gc2nBOYHS/640/480", - "https://picsum.photos/seed/7MZtu75Zc/640/480", - "https://picsum.photos/seed/SDqw9obku/640/480", - "https://picsum.photos/seed/xAdLYxsae/640/480", - "https://picsum.photos/seed/epyeMo/640/480", - "https://picsum.photos/seed/g2Ub09a8/640/480" - ], - "featured": 0, - "discount": "5" - }, - { - "id": 94, - "name": "Artesanal Metal Bacon", - "description": "Carbonite web goalkeeper gloves are ergonomically designed to give easy fit", - "price": "€89", - "specialPrice": "€47", - "isNew": true, - "slug": "978-1-043-52433-3", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/lSX3wnBP/640/480", - "https://picsum.photos/seed/LUOu8/640/480" - ], - "featured": 1, - "position": 94, - "discount": "11" - }, - { - "id": 95, - "name": "Genérico Metal Sopa", - "description": "Andy shoes are designed to keeping in mind durability as well as trends, the most stylish range of shoes & sandals", - "price": "€110", - "specialPrice": "€51", - "isNew": false, - "slug": "978-1-006-62105-5", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/JD4XtJf/640/480", - "https://picsum.photos/seed/KE0iL/640/480", - "https://picsum.photos/seed/x0wxQjAyB/640/480", - "https://picsum.photos/seed/3uWlXw9Oa9/640/480", - "https://picsum.photos/seed/NSuo2fRTJ/640/480" - ], - "featured": 0, - "position": 95, - "discount": "6" - }, - { - "id": 96, - "name": "Hecho a mano Ladrillo Zapatos", - "description": "The automobile layout consists of a front-engine design, with transaxle-type transmissions mounted at the rear of the engine and four wheel drive", - "price": "€76", - "specialPrice": "€47", - "isNew": true, - "slug": "978-0-553-62311-6", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/tY5Oe7H6T/640/480", - "https://picsum.photos/seed/IFg1o/640/480", - "https://picsum.photos/seed/b3WiU7yw/640/480" - ], - "featured": 0 - }, - { - "id": 97, - "name": "Guapo Granito Toallas", - "description": "Boston's most advanced compression wear technology increases muscle oxygenation, stabilizes active muscles", - "price": "€178", - "specialPrice": "€31", - "isNew": false, - "slug": "978-0-270-99429-2", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/SKaIE/640/480", - "https://picsum.photos/seed/U4Dl1e/640/480" - ], - "featured": 1, - "position": 97 - }, - { - "id": 98, - "name": "Ergonómico Ladrillo Pizza", - "description": "The Nagasaki Lander is the trademarked name of several series of Nagasaki sport bikes, that started with the 1984 ABC800J", - "price": "€32", - "specialPrice": "€58", - "isNew": false, - "slug": "978-0-316-30967-7", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/I55ldG/640/480", - "https://picsum.photos/seed/BLzJ5HyqJf/640/480", - "https://picsum.photos/seed/df7KM/640/480", - "https://picsum.photos/seed/wdjnNMXiAS/640/480", - "https://picsum.photos/seed/zVNn3S/640/480" - ], - "featured": 0, - "position": 98 - }, - { - "id": 99, - "name": "Sabroso Metal Ensalada", - "description": "The beautiful range of Apple Naturalé that has an exciting mix of natural ingredients. With the Goodness of 100% Natural Ingredients", - "price": "€188", - "specialPrice": "€59", - "isNew": true, - "slug": "978-0-212-16286-4", - "category": 2, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/V8MtVycBt/640/480", - "https://picsum.photos/seed/Tu33LX/640/480", - "https://picsum.photos/seed/uGXR6B5VgF/640/480" - ], - "featured": 0, - "discount": "11" - }, - { - "id": 100, - "name": "Sorprendente Ladrillo Pizza", - "description": "The Football Is Good For Training And Recreational Purposes", - "price": "€20", - "specialPrice": "€53", - "isNew": true, - "slug": "978-1-9793-4598-9", - "category": 1, - "postalCode": "12345", - "dateExpired": "30/01/2024", - "images": [ - "https://picsum.photos/seed/Q5rFD/640/480", - "https://picsum.photos/seed/gObhsXJgT/640/480", - "https://picsum.photos/seed/eD2kNo/640/480" - ], - "featured": 0, - "position": 100, - "discount": "8" - } -] diff --git a/api/db/db.js b/api/db/db.js index 5801e03..733d2e9 100644 --- a/api/db/db.js +++ b/api/db/db.js @@ -12,17 +12,65 @@ async function connect() { const mysql = require("mysql2/promise"); const connection = await mysql.createConnection("mysql://" + user + ":" + password + "@" + host + ":" + port + "/" + database + ""); - console.log("Connected to MySQL!"); global.connection = connection; return connection; } +//Procedure for get products async function getProducts(dateExpired, postalCode) { - console.log("Query in table MySQL!"); const conn = await connect(); const [rows] = await conn.query(`CALL catalogue_get("${dateExpired}", "${postalCode}")`); return rows; } +//Procedure for create transactions, do not carry out any manipulation at the bank +async function orderData_put(jsonOrderData) { + const conn = await connect(); + const [rows] = await conn.query(`CALL orderData_put(?)`, [jsonOrderData], (err, results) => { + if (err) { + console.error(err); + } else { + console.log('Result:', results); + } + }); + return rows; +} +async function order_confirm(orderFk) { + const conn = await connect(); + const [rows] = await conn.query(`CALL order_confirm(${orderFk})`); + return rows; +} -module.exports = { getProducts } \ No newline at end of file + +//Procedure for get transactions, do not carry out any manipulation at the bank +async function orderData_get() { + const conn = await connect(); + const [rows] = await conn.query(`CALL orderData_get()`); + return rows; +} + + +async function getProvinces() { + const conn = await connect(); + const [rows] = await conn.query(`SELECT p.id, p.name, c.code, c.country + FROM vn.province p + JOIN vn.country c ON c.id = p.countryFk + WHERE c.country IN('España', 'Francia', 'Portugal')`); + return rows; +} + + +async function deliveryDate_get(postalCode) { + const conn = await connect(); + const [rows] = await conn.query(`CALL deliveryDate_get("${postalCode}")`); + return rows; +} + +async function contact_Request(name, phone, email, message) { + const conn = await connect(); + const [rows] = await conn.query(`CALL contact_Request("${name}", "${phone}", "${email}", "${message}")`); + return rows; +} + + +module.exports = { getProducts, orderData_get, orderData_put, getProvinces, deliveryDate_get, contact_Request, order_confirm } \ No newline at end of file diff --git a/api/index.js b/api/index.js index 40bcdd9..a65219e 100644 --- a/api/index.js +++ b/api/index.js @@ -1,18 +1,37 @@ const cors = require('cors'); const express = require('express'); const path = require('path'); -const productController = require('./controller/product.controller'); +const paypal = require('paypal-rest-sdk'); +const productController = require('./controller/Product/product.controller'); +const paymengtController = require('./controller/Payment/payment.controller'); +const provincesController = require('./controller/Provinces/provinces.controller'); +const deliveryController = require('./controller/Delivery/delivery.controller'); +const contactController = require('./controller/Contact/contact.controller'); + +paypal.configure({ + 'mode': 'sandbox', + 'client_id': process.env.CLIENT_ID, + 'client_secret': process.env.SECRET_KEY +}); const app = express(); const port = 9999; -const allowedOrigins = ['http://localhost:9100', 'https://floranet.onecommerce.dev/']; +const allowedOrigins = ['http://localhost:9100', 'https://floranet.onecommerce.dev','http://49.13.85.117','http://floranet.onecommerce.dev']; const corsOptions = { origin: allowedOrigins, optionsSuccessStatus: 200, }; + app.use(cors(corsOptions)); +app.use(express.json()); +app.use( + express.urlencoded({ + extended: true, + }), +); + app.get('/', (req, res) => { const indexPath = path.join(__dirname, './', 'index.html'); res.sendFile(indexPath); @@ -21,7 +40,15 @@ app.get('/', (req, res) => { //Products app.get('/api/products', productController.findAll); app.get('/api/products/:id', productController.findById); +app.post('/api/payment/', paymengtController.Create) +app.post('/api/payment/success', paymengtController.Success) +app.get('/api/payment/cancel', paymengtController.Cancel) +app.get('/api/provinces', provincesController.findAll) +app.get('/api/delivery/dates', deliveryController.findByPostalCode) +app.post('/api/contact/save', contactController.Create) + + app.listen(port, () => { console.log(`Server listening at http://localhost:${port}`); -}); \ No newline at end of file +}); diff --git a/api/package.json b/api/package.json index 879cd23..447daea 100644 --- a/api/package.json +++ b/api/package.json @@ -8,8 +8,5 @@ }, "keywords": [], "author": "", - "license": "ISC", - "dependencies": { - "express": "^4.18.2" - } + "license": "ISC" } diff --git a/index.html b/index.html index 9329f89..62cf7e4 100644 --- a/index.html +++ b/index.html @@ -39,6 +39,10 @@ + =6.14.13" } }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, + "node_modules/@floating-ui/vue": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@floating-ui/vue/-/vue-1.0.6.tgz", + "integrity": "sha512-EdrOljjkpkkqZnrpqUcPoz9NvHxuTjUtSInh6GMv3+Mcy+giY2cE2pHh9rpacRcZ2eMSCxel9jWkWXTjLmY55w==", + "dependencies": { + "@floating-ui/dom": "^1.6.1", + "@floating-ui/utils": "^0.2.1", + "vue-demi": ">=0.13.0" + } + }, + "node_modules/@floating-ui/vue/node_modules/vue-demi": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { @@ -176,9 +238,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, "node_modules/@intlify/bundle-utils": { @@ -206,12 +268,12 @@ } }, "node_modules/@intlify/core-base": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.9.0.tgz", - "integrity": "sha512-C7UXPymDIOlMGSNjAhNLtKgzITc/8BjINK5gNKXg8GiWCTwL6n3MWr55czksxn8RM5wTMz0qcLOFT+adtaVQaA==", + "version": "9.9.1", + "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.9.1.tgz", + "integrity": "sha512-qsV15dg7jNX2faBRyKMgZS8UcFJViWEUPLdzZ9UR0kQZpFVeIpc0AG7ZOfeP7pX2T9SQ5jSiorq/tii9nkkafA==", "dependencies": { - "@intlify/message-compiler": "9.9.0", - "@intlify/shared": "9.9.0" + "@intlify/message-compiler": "9.9.1", + "@intlify/shared": "9.9.1" }, "engines": { "node": ">= 16" @@ -221,11 +283,11 @@ } }, "node_modules/@intlify/message-compiler": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.9.0.tgz", - "integrity": "sha512-yDU/jdUm9KuhEzYfS+wuyja209yXgdl1XFhMlKtXEgSFTxz4COZQCRXXbbH8JrAjMsaJ7bdoPSLsKlY6mXG2iA==", + "version": "9.9.1", + "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.9.1.tgz", + "integrity": "sha512-zTvP6X6HeumHOXuAE1CMMsV6tTX+opKMOxO1OHTCg5N5Sm/F7d8o2jdT6W6L5oHUsJ/vvkGefHIs7Q3hfowmsA==", "dependencies": { - "@intlify/shared": "9.9.0", + "@intlify/shared": "9.9.1", "source-map-js": "^1.0.2" }, "engines": { @@ -236,9 +298,9 @@ } }, "node_modules/@intlify/shared": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.9.0.tgz", - "integrity": "sha512-1ECUyAHRrzOJbOizyGufYP2yukqGrWXtkmTu4PcswVnWbkcjzk3YQGmJ0bLkM7JZ0ZYAaohLGdYvBYnTOGYJ9g==", + "version": "9.9.1", + "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.9.1.tgz", + "integrity": "sha512-b3Pta1nwkz5rGq434v0psHwEwHGy1pYCttfcM22IE//K9owbpkEvFptx9VcuRAxjQdrO2If249cmDDjBu5wMDA==", "engines": { "node": ">= 16" }, @@ -277,9 +339,9 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "engines": { "node": ">=6.0.0" @@ -336,9 +398,9 @@ } }, "node_modules/@quasar/app-vite": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@quasar/app-vite/-/app-vite-1.7.1.tgz", - "integrity": "sha512-cs3ix7w8f7884JiTp3EW6auZ9R+Fg4qoPxEZ7VRGOrSsUg5oQtR/i91jeQk4Z96J/JUOqtcKqdqbzN4fzaFyIg==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@quasar/app-vite/-/app-vite-1.7.3.tgz", + "integrity": "sha512-pnDInCFP9M1d7lJzS8UkiFq8bGWdekLz8Gu+NLI9UAxruIM9QVlSD4hUmWptTQXaVEvYlDnqfW3LOr57B8eVtw==", "dev": true, "dependencies": { "@quasar/render-ssr-error": "^1.0.3", @@ -579,9 +641,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.41", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", - "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "version": "4.17.43", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", + "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", "dev": true, "dependencies": { "@types/node": "*", @@ -600,9 +662,9 @@ } }, "node_modules/@types/filewriter": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.32.tgz", - "integrity": "sha512-Kpi2GXQyYJdjL8mFclL1eDgihn1SIzorMZjD94kdPZh9E4VxGOeyjPxi5LpsM4Zku7P0reqegZTt2GxhmA9VBg==", + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.33.tgz", + "integrity": "sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==", "dev": true }, "node_modules/@types/har-format": { @@ -624,9 +686,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.10.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.8.tgz", - "integrity": "sha512-f8nQs3cLxbAFc00vEU59yf9UyGUftkPaLGfvbVOIDdx2i1b8epBqj2aNGyP19fiyXWvlmZ7qC1XLjAzw/OKIeA==", + "version": "20.11.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", + "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -677,12 +739,12 @@ "dev": true }, "node_modules/@vee-validate/zod": { - "version": "4.12.4", - "resolved": "https://registry.npmjs.org/@vee-validate/zod/-/zod-4.12.4.tgz", - "integrity": "sha512-iNFhkBfGkre2b+eBXgBpNlNVStxDrI59sJUbzBr01EjyTkFOUgc/0wPJrhY/kBp+0pnGzNi04jklJaKfNK2ibg==", + "version": "4.12.5", + "resolved": "https://registry.npmjs.org/@vee-validate/zod/-/zod-4.12.5.tgz", + "integrity": "sha512-hUjvXaa4HHvlZeosucViIDOUikQmyKaXXuL6P8LR1ETOUrBV6ntTsafJGvRYtwhXosoLYuolUD6Km737okK4Gg==", "dependencies": { "type-fest": "^4.8.3", - "vee-validate": "4.12.4", + "vee-validate": "4.12.5", "zod": "^3.22.4" } }, @@ -709,108 +771,108 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.7.tgz", - "integrity": "sha512-hhCaE3pTMrlIJK7M/o3Xf7HV8+JoNTGOQ/coWS+V+pH6QFFyqtoXqQzpqsNp7UK17xYKua/MBiKj4e1vgZOBYw==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.19.tgz", + "integrity": "sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w==", "dependencies": { - "@babel/parser": "^7.23.6", - "@vue/shared": "3.4.7", + "@babel/parser": "^7.23.9", + "@vue/shared": "3.4.19", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.0.2" } }, "node_modules/@vue/compiler-dom": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.7.tgz", - "integrity": "sha512-qDKBAIurCTub4n/6jDYkXwgsFuriqqmmLrIq1N2QDfYJA/mwiwvxi09OGn28g+uDdERX9NaKDLji0oTjE3sScg==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.19.tgz", + "integrity": "sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==", "dependencies": { - "@vue/compiler-core": "3.4.7", - "@vue/shared": "3.4.7" + "@vue/compiler-core": "3.4.19", + "@vue/shared": "3.4.19" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.7.tgz", - "integrity": "sha512-Gec6CLkReVswDYjQFq79O5rktri4R7TsD/VPCiUoJw40JhNNxaNJJa8mrQrWoJluW4ETy6QN0NUyC/JO77OCOw==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.19.tgz", + "integrity": "sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg==", "dependencies": { - "@babel/parser": "^7.23.6", - "@vue/compiler-core": "3.4.7", - "@vue/compiler-dom": "3.4.7", - "@vue/compiler-ssr": "3.4.7", - "@vue/shared": "3.4.7", + "@babel/parser": "^7.23.9", + "@vue/compiler-core": "3.4.19", + "@vue/compiler-dom": "3.4.19", + "@vue/compiler-ssr": "3.4.19", + "@vue/shared": "3.4.19", "estree-walker": "^2.0.2", - "magic-string": "^0.30.5", - "postcss": "^8.4.32", + "magic-string": "^0.30.6", + "postcss": "^8.4.33", "source-map-js": "^1.0.2" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.7.tgz", - "integrity": "sha512-PvYeSOvnCkST5mGS0TLwEn5w+4GavtEn6adcq8AspbHaIr+mId5hp7cG3ASy3iy8b+LuXEG2/QaV/nj5BQ/Aww==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.19.tgz", + "integrity": "sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==", "dependencies": { - "@vue/compiler-dom": "3.4.7", - "@vue/shared": "3.4.7" + "@vue/compiler-dom": "3.4.19", + "@vue/shared": "3.4.19" } }, "node_modules/@vue/devtools-api": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.1.tgz", - "integrity": "sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==" + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.1.tgz", + "integrity": "sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==" }, "node_modules/@vue/reactivity": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.7.tgz", - "integrity": "sha512-F539DO0ogH0+L8F9Pnw7cjqibcmSOh5UTk16u5f4MKQ8fraqepI9zdh+sozPX6VmEHOcjo8qw3Or9ZcFFw4SZA==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.19.tgz", + "integrity": "sha512-+VcwrQvLZgEclGZRHx4O2XhyEEcKaBi50WbxdVItEezUf4fqRh838Ix6amWTdX0CNb/b6t3Gkz3eOebfcSt+UA==", "dependencies": { - "@vue/shared": "3.4.7" + "@vue/shared": "3.4.19" } }, "node_modules/@vue/runtime-core": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.7.tgz", - "integrity": "sha512-QMMsWRQaD3BpGyjjChthpl4Mji4Fjx1qfdufsXlDkKU3HV+hWNor2z+29F+E1MmVcP0ZfRZUfqYgtsQoL7IGwQ==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.19.tgz", + "integrity": "sha512-/Z3tFwOrerJB/oyutmJGoYbuoadphDcJAd5jOuJE86THNZji9pYjZroQ2NFsZkTxOq0GJbb+s2kxTYToDiyZzw==", "dependencies": { - "@vue/reactivity": "3.4.7", - "@vue/shared": "3.4.7" + "@vue/reactivity": "3.4.19", + "@vue/shared": "3.4.19" } }, "node_modules/@vue/runtime-dom": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.7.tgz", - "integrity": "sha512-XwegyUY1rw8zxsX1Z36vwYcqo+uOgih5ti7y9vx+pPFhNdSQmN4LqK2RmSeAJG1oKV8NqSUmjpv92f/x6h0SeQ==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.19.tgz", + "integrity": "sha512-IyZzIDqfNCF0OyZOauL+F4yzjMPN2rPd8nhqPP2N1lBn3kYqJpPHHru+83Rkvo2lHz5mW+rEeIMEF9qY3PB94g==", "dependencies": { - "@vue/runtime-core": "3.4.7", - "@vue/shared": "3.4.7", + "@vue/runtime-core": "3.4.19", + "@vue/shared": "3.4.19", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.7.tgz", - "integrity": "sha512-3bWnYLEkLLhkDWqvNk7IvbQD4UcxvFKxELBiOO2iG3m6AniFIsBWfHOO5tLVQnjdWkODu4rq0GipmfEenVAK5Q==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.19.tgz", + "integrity": "sha512-eAj2p0c429RZyyhtMRnttjcSToch+kTWxFPHlzGMkR28ZbF1PDlTcmGmlDxccBuqNd9iOQ7xPRPAGgPVj+YpQw==", "dependencies": { - "@vue/compiler-ssr": "3.4.7", - "@vue/shared": "3.4.7" + "@vue/compiler-ssr": "3.4.19", + "@vue/shared": "3.4.19" }, "peerDependencies": { - "vue": "3.4.7" + "vue": "3.4.19" } }, "node_modules/@vue/shared": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.7.tgz", - "integrity": "sha512-G+i4glX1dMJk88sbJEcQEGWRQnVm9eIY7CcQbO5dpdsD9SF8jka3Mr5OqZYGjczGN1+D6EUwdu6phcmcx9iuPA==" + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.19.tgz", + "integrity": "sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw==" }, "node_modules/@vueuse/core": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.7.1.tgz", - "integrity": "sha512-74mWHlaesJSWGp1ihg76vAnfVq9NTv1YT0SYhAQ6zwFNdBkkP+CKKJmVOEHcdSnLXCXYiL5e7MaewblfiYLP7g==", + "version": "10.7.2", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.7.2.tgz", + "integrity": "sha512-AOyAL2rK0By62Hm+iqQn6Rbu8bfmbgaIMXcE3TSr7BdQ42wnSFlwIdPjInO62onYsEMK/yDMU8C6oGfDAtZ2qQ==", "dependencies": { "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "10.7.1", - "@vueuse/shared": "10.7.1", + "@vueuse/metadata": "10.7.2", + "@vueuse/shared": "10.7.2", "vue-demi": ">=0.14.6" }, "funding": { @@ -818,9 +880,9 @@ } }, "node_modules/@vueuse/core/node_modules/vue-demi": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", - "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", "hasInstallScript": true, "bin": { "vue-demi-fix": "bin/vue-demi-fix.js", @@ -843,17 +905,17 @@ } }, "node_modules/@vueuse/metadata": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.7.1.tgz", - "integrity": "sha512-jX8MbX5UX067DYVsbtrmKn6eG6KMcXxLRLlurGkZku5ZYT3vxgBjui2zajvUZ18QLIjrgBkFRsu7CqTAg18QFw==", + "version": "10.7.2", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.7.2.tgz", + "integrity": "sha512-kCWPb4J2KGrwLtn1eJwaJD742u1k5h6v/St5wFe8Quih90+k2a0JP8BS4Zp34XUuJqS2AxFYMb1wjUL8HfhWsQ==", "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/shared": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.7.1.tgz", - "integrity": "sha512-v0jbRR31LSgRY/C5i5X279A/WQjD6/JsMzGa+eqt658oJ75IvQXAeONmwvEMrvJQKnRElq/frzBR7fhmWY5uLw==", + "version": "10.7.2", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.7.2.tgz", + "integrity": "sha512-qFbXoxS44pi2FkgFjPvF4h7c9oMDutpyBdcJdMYIMg9XyXli2meFMuaKn+UMgsClo//Th6+beeCgqweT/79BVA==", "dependencies": { "vue-demi": ">=0.14.6" }, @@ -862,9 +924,9 @@ } }, "node_modules/@vueuse/shared/node_modules/vue-demi": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", - "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", "hasInstallScript": true, "bin": { "vue-demi-fix": "bin/vue-demi-fix.js", @@ -920,9 +982,9 @@ } }, "node_modules/acorn-walk": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", - "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true, "engines": { "node": ">=0.4.0" @@ -1109,9 +1171,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/autoprefixer": { - "version": "10.4.16", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", - "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==", + "version": "10.4.17", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz", + "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==", "dev": true, "funding": [ { @@ -1128,9 +1190,9 @@ } ], "dependencies": { - "browserslist": "^4.21.10", - "caniuse-lite": "^1.0.30001538", - "fraction.js": "^4.3.6", + "browserslist": "^4.22.2", + "caniuse-lite": "^1.0.30001578", + "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", "postcss-value-parser": "^4.2.0" @@ -1146,9 +1208,9 @@ } }, "node_modules/axios": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", - "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "dependencies": { "follow-redirects": "^1.15.4", "form-data": "^4.0.0", @@ -1286,9 +1348,9 @@ } }, "node_modules/browserslist": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "dev": true, "funding": [ { @@ -1305,8 +1367,8 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" }, @@ -1345,7 +1407,6 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, "engines": { "node": "*" } @@ -1360,13 +1421,18 @@ } }, "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1392,9 +1458,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001576", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001576.tgz", - "integrity": "sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==", + "version": "1.0.30001587", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001587.tgz", + "integrity": "sha512-HMFNotUmLXn71BQxg8cijvqxnIAofforZOwGsxyXJ0qugTdspUF4sPSJ2vhgprHCB996tIDzEq1ubumPDV8ULA==", "dev": true, "funding": [ { @@ -1434,16 +1500,10 @@ "dev": true }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -1456,6 +1516,9 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } @@ -1852,16 +1915,19 @@ } }, "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-lazy-prop": { @@ -1948,9 +2014,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.625", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.625.tgz", - "integrity": "sha512-DENMhh3MFgaPDoXWrVIqSPInQoLImywfCwrSmVl3cf9QHzoZSiutHwGaB/Ql3VkqcQV30rzgdM+BjKqBAJxo5Q==", + "version": "1.4.670", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.670.tgz", + "integrity": "sha512-hcijYOWjOtjKrKPtNA6tuLlA/bTLO3heFG8pQA6mLpq7dRydSWicXova5lyxDzp1iVJaYhK7J2OQlGE52KYn7A==", "dev": true }, "node_modules/elementtree": { @@ -2012,6 +2078,25 @@ "node": ">= 0.8" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.14.51", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.51.tgz", @@ -2368,9 +2453,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, "engines": { "node": ">=6" @@ -2461,9 +2546,9 @@ } }, "node_modules/eslint-plugin-vue": { - "version": "9.19.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.19.2.tgz", - "integrity": "sha512-CPDqTOG2K4Ni2o4J5wixkLVNwgctKXFu6oBpVJlpNq7f38lh9I80pRTouZSJ2MAebPJlINU/KTFSXyQfBUlymA==", + "version": "9.21.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.21.1.tgz", + "integrity": "sha512-XVtI7z39yOVBFJyi8Ljbn7kY9yHzznKXL02qQYn+ta63Iy4A9JFBw6o4OSB9hyD2++tVT+su9kQqetUyCCwhjw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", @@ -2471,7 +2556,7 @@ "nth-check": "^2.1.1", "postcss-selector-parser": "^6.0.13", "semver": "^7.5.4", - "vue-eslint-parser": "^9.3.1", + "vue-eslint-parser": "^9.4.2", "xml-name-validator": "^4.0.0" }, "engines": { @@ -2764,9 +2849,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", - "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -2896,9 +2981,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "funding": [ { "type": "individual", @@ -2956,6 +3041,11 @@ "node": ">= 0.6" } }, + "node_modules/fs": { + "version": "0.0.1-security", + "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", + "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==" + }, "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -3022,15 +3112,19 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dependencies": { + "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3127,11 +3221,11 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3160,9 +3254,9 @@ } }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", "dependencies": { "function-bind": "^1.1.2" }, @@ -3247,18 +3341,18 @@ ] }, "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" } }, "node_modules/immutable": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", - "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz", + "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==", "dev": true }, "node_modules/import-fresh": { @@ -3494,12 +3588,12 @@ "dev": true }, "node_modules/isbinaryfile": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.0.tgz", - "integrity": "sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.2.tgz", + "integrity": "sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==", "dev": true, "engines": { - "node": ">= 14.0.0" + "node": ">= 18.0.0" }, "funding": { "url": "https://github.com/sponsors/gjtorikian/" @@ -3743,6 +3837,11 @@ "node": ">= 0.8.0" } }, + "node_modules/libphonenumber-js": { + "version": "1.10.56", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.56.tgz", + "integrity": "sha512-d0GdKshNnyfl5gM7kZ9rXjGiAbxT/zCXp0k+EAzh8H4zrb2R7GXtMCrULrX7UQxtfx6CLy/vz/lomvW79FAFdA==" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -3859,21 +3958,17 @@ "dev": true }, "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", + "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", "engines": { - "node": ">=10" + "node": ">=16.14" } }, "node_modules/magic-string": { - "version": "0.30.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", - "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", + "version": "0.30.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz", + "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, @@ -4076,9 +4171,9 @@ "dev": true }, "node_modules/mysql2": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.7.0.tgz", - "integrity": "sha512-c45jA3Jc1X8yJKzrWu1GpplBKGwv/wIV6ITZTlCSY7npF2YfJR+6nMP5e+NTQhUeJPSyOQAbGDCGEHbAl8HN9w==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.1.tgz", + "integrity": "sha512-3njoWAAhGBYy0tWBabqUQcLtczZUxrmmtc2vszQUekg3kTJyZ5/IeLC3Fo04u6y6Iy5Sba7pIIa2P/gs8D3ZeQ==", "dependencies": { "denque": "^2.1.0", "generate-function": "^2.3.1", @@ -4104,14 +4199,6 @@ "node": ">=0.10.0" } }, - "node_modules/mysql2/node_modules/lru-cache": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", - "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", - "engines": { - "node": ">=16.14" - } - }, "node_modules/named-placeholders": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", @@ -4431,6 +4518,26 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, + "node_modules/paypal-rest-sdk": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/paypal-rest-sdk/-/paypal-rest-sdk-1.8.1.tgz", + "integrity": "sha512-Trj2GuPn10GqpICAxQh5wjxuDT7rq7DMOkvyatz05wI5xPGmqXN7UC0WfDSF9WSBs4YdcWZP0g+nY+sOdaFggw==", + "dependencies": { + "buffer-crc32": "^0.2.3", + "semver": "^5.0.3" + }, + "engines": { + "node": ">= v0.6.0" + } + }, + "node_modules/paypal-rest-sdk/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -4483,9 +4590,9 @@ } }, "node_modules/pinia/node_modules/vue-demi": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", - "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", "hasInstallScript": true, "bin": { "vue-demi-fix": "bin/vue-demi-fix.js", @@ -4526,9 +4633,9 @@ } }, "node_modules/postcss": { - "version": "8.4.33", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", - "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==", + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", "funding": [ { "type": "opencollective", @@ -4642,9 +4749,9 @@ } }, "node_modules/quasar": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/quasar/-/quasar-2.14.2.tgz", - "integrity": "sha512-f5KliWtM5BEuFsDU4yvuP+dlVIWZNrGu5VpWFsxzjpoykcP4B2HIOUiCl3mx2NCqERHd4Ts0aeioRkt9TTeExA==", + "version": "2.14.4", + "resolved": "https://registry.npmjs.org/quasar/-/quasar-2.14.4.tgz", + "integrity": "sha512-l+bSGVMcesVydX1IeWyAAjqCRfigwaonIDqxodvNjZwkifZF29YdCMh9bief2l9k9r23kMl7P5Oqs6EA5ja4ag==", "engines": { "node": ">= 10.18.1", "npm": ">= 6.13.4", @@ -4970,9 +5077,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sass": { - "version": "1.69.7", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.7.tgz", - "integrity": "sha512-rzj2soDeZ8wtE2egyLXgOOHQvaC2iosZrkF6v3EUG+tBwEvhqUCzm0VP3k9gHF9LXbSrRhT5SksoI56Iw8NPnQ==", + "version": "1.70.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.70.0.tgz", + "integrity": "sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -4993,9 +5100,9 @@ "dev": true }, "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -5013,6 +5120,18 @@ "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", "dev": true }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -5089,14 +5208,16 @@ "dev": true }, "node_modules/set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", "dependencies": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -5141,13 +5262,17 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", + "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5478,9 +5603,9 @@ } }, "node_modules/type-fest": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.9.0.tgz", - "integrity": "sha512-KS/6lh/ynPGiHD/LnAobrEFq3Ad4pBzOlJ1wAnJx9N4EYoqFhMfLIBjUT2UEx4wg5ZE+cC1ob6DCSpppVo+rtg==", + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.10.2.tgz", + "integrity": "sha512-anpAG63wSpdEbLwOqH8L84urkL6PiVIov3EMmgIhhThevh9aiMQov+6Btx0wldNcvm4wV+e2/Rt1QdDwKHFbHw==", "engines": { "node": ">=16" }, @@ -5622,9 +5747,9 @@ } }, "node_modules/vee-validate": { - "version": "4.12.4", - "resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-4.12.4.tgz", - "integrity": "sha512-rqSjMdl0l/RiGKywKhkXttUKwDlQOoxTxe31uMQiMlwK4Hbtlvr3OcQvpREp/qPTARxNKudKWCUVW/mfzuxUVQ==", + "version": "4.12.5", + "resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-4.12.5.tgz", + "integrity": "sha512-rvaDfLPSLwTk+mf016XWE4drB8yXzOsKXiKHTb9gNXNLTtQSZ0Ww26O0/xbIFQe+n3+u8Wv1Y8uO/aLDX4fxOg==", "dependencies": { "@vue/devtools-api": "^6.5.1", "type-fest": "^4.8.3" @@ -5634,9 +5759,9 @@ } }, "node_modules/vite": { - "version": "2.9.16", - "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.16.tgz", - "integrity": "sha512-X+6q8KPyeuBvTQV8AVSnKDvXoBMnTx8zxh54sOwmmuOdxkjMmEJXH2UEchA+vTMps1xw9vL64uwJOWryULg7nA==", + "version": "2.9.17", + "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.17.tgz", + "integrity": "sha512-XxcRzra6d7xrKXH66jZUgb+srThoPu+TLJc06GifUyKq9JmjHkc1Numc8ra0h56rju2jfVWw3B3fs5l3OFMvUw==", "dev": true, "dependencies": { "esbuild": "^0.14.27", @@ -5671,15 +5796,15 @@ } }, "node_modules/vue": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.7.tgz", - "integrity": "sha512-4urmkWpudekq0CPNMO7p6mBGa9qmTXwJMO2r6CT4EzIJVG7WoSReiysiNb7OSi/WI113oX0Srn9Rz1k/DCXKFQ==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.19.tgz", + "integrity": "sha512-W/7Fc9KUkajFU8dBeDluM4sRGc/aa4YJnOYck8dkjgZoXtVsn3OeTGni66FV1l3+nvPA7VBFYtPioaGKUmEADw==", "dependencies": { - "@vue/compiler-dom": "3.4.7", - "@vue/compiler-sfc": "3.4.7", - "@vue/runtime-dom": "3.4.7", - "@vue/server-renderer": "3.4.7", - "@vue/shared": "3.4.7" + "@vue/compiler-dom": "3.4.19", + "@vue/compiler-sfc": "3.4.19", + "@vue/runtime-dom": "3.4.19", + "@vue/server-renderer": "3.4.19", + "@vue/shared": "3.4.19" }, "peerDependencies": { "typescript": "*" @@ -5695,10 +5820,21 @@ "resolved": "https://registry.npmjs.org/vue-coerce-props/-/vue-coerce-props-1.0.0.tgz", "integrity": "sha512-4fdRMXO6FHzmE7H4soAph6QmPg3sL/RiGdd+axuxuU07f02LNMns0jMM88fmt1bvSbN+2Wyd8raho6p6nXUzag==" }, + "node_modules/vue-country-flag-next": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/vue-country-flag-next/-/vue-country-flag-next-2.3.2.tgz", + "integrity": "sha512-Lv12L1VTwlBgizpZ3xPEPO3zuIETaJmeSiPuLOWLLgu2EakwU/o72iKYiKcdZ6BXiSkfss+Ski5fDzjuxZ1DcA==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, "node_modules/vue-eslint-parser": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.0.tgz", - "integrity": "sha512-7KsNBb6gHFA75BtneJsoK/dbZ281whUIwFYdQxA68QrCrGMXYzUMbPDHGcOQ0OocIVKrWSKWXZ4mL7tonCXoUw==", + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz", + "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==", "dev": true, "dependencies": { "debug": "^4.3.4", @@ -5720,12 +5856,12 @@ } }, "node_modules/vue-i18n": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.9.0.tgz", - "integrity": "sha512-xQ5SxszUAqK5n84N+uUyHH/PiQl9xZ24FOxyAaNonmOQgXeN+rD9z/6DStOpOxNFQn4Cgcquot05gZc+CdOujA==", + "version": "9.9.1", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.9.1.tgz", + "integrity": "sha512-xyQ4VspLdNSPTKBFBPWa1tvtj+9HuockZwgFeD2OhxxXuC2CWeNvV4seu2o9+vbQOyQbhAM5Ez56oxUrrnTWdw==", "dependencies": { - "@intlify/core-base": "9.9.0", - "@intlify/shared": "9.9.0", + "@intlify/core-base": "9.9.1", + "@intlify/shared": "9.9.1", "@vue/devtools-api": "^6.5.0" }, "engines": { @@ -5760,6 +5896,15 @@ "vue": "^3.2.0" } }, + "node_modules/vue-tel-input": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/vue-tel-input/-/vue-tel-input-8.3.1.tgz", + "integrity": "sha512-+YMFf1Dq/H9xJ2QQ0dDtPrCRNdfWCMCZ78/29qV9BJ9cf7BAFv4jpBPNQU4DyOqoOd0BEujVw9SRJ+fcXPO21Q==", + "dependencies": { + "libphonenumber-js": "^1.10.51", + "vue": "^3.3.9" + } + }, "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", diff --git a/package.json b/package.json index 57dd062..a88e171 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "floranet", "version": "0.0.1", "description": "A floranet app", - "productName": "Floranet App", + "productName": "Floranet", "author": "user", "private": true, "scripts": { @@ -16,20 +16,29 @@ "backend": "json-server -p 3000 -d 600 -w src/services/json-server/db.json --routes src/services/json-server/routes.json" }, "dependencies": { + "@floating-ui/vue": "^1.0.6", "@quasar/extras": "^1.16.4", "@vee-validate/zod": "^4.12.2", "@vue-stripe/vue-stripe": "^4.5.0", "@vueuse/core": "^10.7.0", "axios": "^1.2.1", "express": "^4.18.2", + "fs": "^0.0.1-security", "mysql2": "^3.7.0", + "node-redsys-api": "^0.0.5", + "paypal-rest-sdk": "^1.8.1", "pinia": "^2.0.11", "quasar": "^2.6.0", + "redsys-easy": "^5.2.3", + "redsys-pay": "^1.2.0", + "redsys-pos": "^1.0.2", "vee-validate": "^4.12.2", "vue": "^3.0.0", + "vue-country-flag-next": "^2.3.2", "vue-i18n": "^9.0.0", "vue-image-zoomer": "^2.2.3", "vue-router": "^4.0.0", + "vue-tel-input": "^8.3.1", "zod": "^3.22.4" }, "devDependencies": { diff --git a/quasar.config.js b/quasar.config.js index 7a6fab8..1f8b723 100644 --- a/quasar.config.js +++ b/quasar.config.js @@ -11,7 +11,7 @@ const { configure } = require("quasar/wrappers"); const path = require("path"); -module.exports = configure(function (/* ctx */) { +module.exports = configure(function (ctx) { return { eslint: { // fix: true, @@ -28,7 +28,15 @@ module.exports = configure(function (/* ctx */) { // app boot file (/src/boot) // --> boot files are part of "main.js" // https://v2.quasar.dev/quasar-cli-vite/boot-files - boot: ["i18n", "axios" /* , { path: "stripe", server: false } */], + boot: [ + "i18n", + "axios", + { + path: "VueCountryFlag", + server: false, + }, + { path: "VueTelInput", server: false }, + ], // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css css: ["app.scss"], @@ -49,6 +57,12 @@ module.exports = configure(function (/* ctx */) { // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build build: { + env: { + API: ctx.dev + ? "http://localhost:9999/api/" + : "https://floranet-back.onecommerce.dev/api/", + }, + target: { browser: ["es2019", "edge88", "firefox78", "chrome87", "safari13.1"], node: "node16", diff --git a/src/boot/VueCountryFlag.js b/src/boot/VueCountryFlag.js new file mode 100644 index 0000000..5c3e77d --- /dev/null +++ b/src/boot/VueCountryFlag.js @@ -0,0 +1,6 @@ +import { boot } from "quasar/wrappers"; +import CountryFlag from "vue-country-flag-next"; + +export default boot(({ app }) => { + app.use(CountryFlag); +}); diff --git a/src/boot/VueTelInput.js b/src/boot/VueTelInput.js new file mode 100644 index 0000000..be4ed8e --- /dev/null +++ b/src/boot/VueTelInput.js @@ -0,0 +1,16 @@ +import { boot } from "quasar/wrappers"; +import VueTelInput from "vue-tel-input"; + +export default boot(({ app }) => { + const options = { + mode: "auto", + dropdownOptions: { + showDialCodeInSelection: true, + showFlags: true, + showDialCodeInList: true, + }, + autoFormat: true, + }; + + app.use(VueTelInput, options); +}); diff --git a/src/boot/axios.js b/src/boot/axios.js index b1d4769..28c01e7 100644 --- a/src/boot/axios.js +++ b/src/boot/axios.js @@ -7,8 +7,8 @@ import { boot } from "quasar/wrappers"; // good idea to move this instance creation inside of the // "export default () => {}" function below (which runs individually // for each client) -const api = axios.create({ baseURL: "http://localhost:3000/jsonServer/" }); -const apiBack = axios.create({ baseURL: "http://localhost:9999/api/" }); + +const apiBack = axios.create({ baseURL: process.env.API }); export default boot(({ app }) => { // for use inside Vue files (Options API) through this.$axios and this.$api @@ -17,10 +17,9 @@ export default boot(({ app }) => { // ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form) // so you won't necessarily have to import axios in each vue file - app.config.globalProperties.$api = api; app.config.globalProperties.$apiBack = apiBack; // ^ ^ ^ this will allow you to use this.$api (for Vue Options API form) // so you can easily perform requests against your app's API }); -export { api, apiBack }; +export { apiBack }; diff --git a/src/components/@inputs/Calendar.vue b/src/components/@inputs/Calendar.vue index a262502..e5f9ffe 100644 --- a/src/components/@inputs/Calendar.vue +++ b/src/components/@inputs/Calendar.vue @@ -1,45 +1,65 @@ - - diff --git a/src/components/@inputs/Example/PostalCodeEx.vue b/src/components/@inputs/Example/PostalCodeEx.vue deleted file mode 100644 index 2f99696..0000000 --- a/src/components/@inputs/Example/PostalCodeEx.vue +++ /dev/null @@ -1,62 +0,0 @@ - - - diff --git a/src/components/@inputs/PostalCode.vue b/src/components/@inputs/PostalCode.vue index 25919ab..91b1743 100644 --- a/src/components/@inputs/PostalCode.vue +++ b/src/components/@inputs/PostalCode.vue @@ -1,47 +1,75 @@ @@ -51,20 +79,35 @@ export default defineComponent({
-

¿Dónde?

+

+ ¿Dónde? + +

- - + @blur="onBlur" + />
+ + diff --git a/src/components/@inputs/PriceRange.vue b/src/components/@inputs/PriceRange.vue index c420066..37f9749 100644 --- a/src/components/@inputs/PriceRange.vue +++ b/src/components/@inputs/PriceRange.vue @@ -11,16 +11,36 @@ export default defineComponent({ default: 0, required: true, }, + minDefault: { + type: Number, + default: 0, + required: true, + }, max: { type: Number, default: 200, required: true, }, + maxDefault: { + type: Number, + default: 200, + required: true, + }, + modelValue: { + type: String, + }, + bindValue: { + type: Object, + }, }, - setup() { + setup(props, { emit }) { const rangePriceStore = useRangePriceStore(); - return { rangePriceStore }; + const updateModel = (value) => { + emit("update:modelValue", value); + }; + + return { rangePriceStore, updateModel }; }, }); @@ -29,7 +49,14 @@ export default defineComponent({

Precio

- +

diff --git a/src/components/@inputs/SortSelect.vue b/src/components/@inputs/SortSelect.vue index 288b368..1fd470c 100644 --- a/src/components/@inputs/SortSelect.vue +++ b/src/components/@inputs/SortSelect.vue @@ -10,7 +10,7 @@ export default defineComponent({ const formStore = useFormStore(); const { sortProductFilters } = storeToRefs(formStore); - async function handleOrder(order) { + function handleOrder(order) { sortProductFilters.value.order = order; sortProductFilters.value.isOpenOrderFilter = false; } diff --git a/src/components/footer/FooterComponent.vue b/src/components/footer/FooterComponent.vue index 50d07d4..f76f966 100644 --- a/src/components/footer/FooterComponent.vue +++ b/src/components/footer/FooterComponent.vue @@ -33,8 +33,7 @@ export default defineComponent({

@@ -44,7 +43,7 @@ export default defineComponent({ Plantas
- Contacta + Contacta
@@ -123,31 +128,17 @@ export default defineComponent({ v-if="modalItem === 'isOpenAvailability'" class="modal-body-availability" > - - - + - - - +
@@ -159,23 +150,11 @@ export default defineComponent({ align="center" class="modal-footer" form="filters-form" + :disabled="modalItem === 'isOpenFilters' && isPostalCalendarEmpty" > -

ver disponibilidad

- @@ -238,6 +217,10 @@ export default defineComponent({ margin-bottom: 29px; &.availability { gap: 65px; + + @media only screen and (max-width: $med-md) { + gap: 10px; + } } & .modal-body-paragraph { diff --git a/src/components/ui/QuestionForm.vue b/src/components/ui/QuestionForm.vue index 3786bb2..0dc400d 100644 --- a/src/components/ui/QuestionForm.vue +++ b/src/components/ui/QuestionForm.vue @@ -1,49 +1,37 @@ + + + + diff --git a/src/pages/CheckoutPage.vue b/src/pages/CheckoutPage.vue index 9793ca3..645376d 100644 --- a/src/pages/CheckoutPage.vue +++ b/src/pages/CheckoutPage.vue @@ -20,7 +20,20 @@ export default defineComponent({ checkoutBlock, cart, totalPrice, - formState: { errors, meta, onSubmit, submitLoading }, + isError, + onError, + redsysData, + tooltip: { + postalCode: { + postalCodeRef, + postalCodeTooltip, + floatingStyles, + isHidden, + hideTooltip, + showTooltip, + }, + }, + formState: { errors, meta, onSubmit, isLoadingSubmit }, fields: { name, nameAttrs, @@ -51,21 +64,31 @@ export default defineComponent({ terms, termsAttrs, }, + phoneInputRef, + phoneSenderInputRef, + redsysFormRef, } = useCheckoutForm(); onBeforeMount(() => { if (cart.length === 0) return push("/"); }); - const isError = ref(false); - const onError = () => { - isError.value = true; - }; - return { handleClickStep, onSubmit, onError, + redsysData, + + phoneInputRef, + phoneSenderInputRef, + redsysFormRef, + + postalCodeRef, + postalCodeTooltip, + floatingStyles, + isHidden, + hideTooltip, + showTooltip, checkoutBlock, stepsFormated, @@ -74,7 +97,7 @@ export default defineComponent({ stepList, cart, step: ref(1), - submitLoading, + isLoadingSubmit, successURL: ref(""), cancelURL: ref(""), meta, @@ -117,21 +140,12 @@ export default defineComponent({ - + Ver todos los diseños @@ -97,8 +96,7 @@ export default defineComponent({ Nuestra selección de plantas para el verano -

-

+

diff --git a/src/pages/ProductPage.vue b/src/pages/ProductPage.vue index c1a8e79..da7acb8 100644 --- a/src/pages/ProductPage.vue +++ b/src/pages/ProductPage.vue @@ -1,7 +1,7 @@