develop #8
|
@ -23,7 +23,6 @@
|
||||||
"source.fixAll.eslint",
|
"source.fixAll.eslint",
|
||||||
"source.fixAll.stylelint"
|
"source.fixAll.stylelint"
|
||||||
],
|
],
|
||||||
|
|
||||||
"files.exclude": {
|
"files.exclude": {
|
||||||
"**/.git": true,
|
"**/.git": true,
|
||||||
"**/.svn": true,
|
"**/.svn": true,
|
||||||
|
@ -61,11 +60,6 @@
|
||||||
"terminal.integrated.enableImages": true,
|
"terminal.integrated.enableImages": true,
|
||||||
"figma.autocompleteBlocks": true,
|
"figma.autocompleteBlocks": true,
|
||||||
"figma.assetExportDirectory": "src/assets",
|
"figma.assetExportDirectory": "src/assets",
|
||||||
"editor.codeActionsOnSave": [
|
|
||||||
"source.addMissingImports",
|
|
||||||
"source.organizeImports",
|
|
||||||
"source.fixAll.eslint"
|
|
||||||
],
|
|
||||||
"gitlens.gitCommands.skipConfirmations": ["fetch:command", "switch:command"],
|
"gitlens.gitCommands.skipConfirmations": ["fetch:command", "switch:command"],
|
||||||
"diffEditor.ignoreTrimWhitespace": false,
|
"diffEditor.ignoreTrimWhitespace": false,
|
||||||
"svg.preview.mode": "svg",
|
"svg.preview.mode": "svg",
|
||||||
|
@ -78,8 +72,5 @@
|
||||||
"workbench.tree.indent": 16,
|
"workbench.tree.indent": 16,
|
||||||
"window.zoomLevel": -1,
|
"window.zoomLevel": -1,
|
||||||
"git.ignoreRebaseWarning": true,
|
"git.ignoreRebaseWarning": true,
|
||||||
"editor.largeFileOptimizations": false,
|
"editor.largeFileOptimizations": false
|
||||||
"[javascript]": {
|
|
||||||
"editor.defaultFormatter": "vscode.typescript-language-features"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,3 +3,7 @@ DB_USER="root"
|
||||||
DB_PASSWORD="root"
|
DB_PASSWORD="root"
|
||||||
PORT ="3306"
|
PORT ="3306"
|
||||||
DATABASE="floranet"
|
DATABASE="floranet"
|
||||||
|
BASE_URL =http://localhost:9100
|
||||||
|
|
||||||
|
CLIENT_ID="Ab5vEddhdvdJhLUkXtTiS2pe43W6PD1JNKns7XMnlw8FvC31H2VYakyVEHvuFBi2b543QIHiPh8j4FLF"
|
||||||
|
SECRET_KEY="EAxLf05kp08cvbLgZrqjwdx-NXnhQtnP4Y0B4LHAM_7T9-HOh4RaNTirinWfTV8GR6DJWg9djry5yHfO"
|
|
@ -0,0 +1,146 @@
|
||||||
|
const db = require("../../db/db");
|
||||||
|
const paypal = require('paypal-rest-sdk');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
class PaymentController {
|
||||||
|
async Create(req, res) {
|
||||||
|
|
||||||
|
//parâmetros para retornar os produtos que serão comprados
|
||||||
|
const products = req.body.products
|
||||||
|
//parameters to return price
|
||||||
|
const price = req.body.price
|
||||||
|
let productsIds = ''
|
||||||
|
for (let i = 0; i < products.length; i++) {
|
||||||
|
productsIds += `${products[i]}${i === products.length - 1 ? '' : '-'}`
|
||||||
|
}
|
||||||
|
|
||||||
|
//json for checkout
|
||||||
|
var payReq = JSON.stringify({
|
||||||
|
'intent': 'sale',
|
||||||
|
'redirect_urls': {
|
||||||
|
'return_url': `${process.env.BASE_URL}/checkout/success?productsIds=${productsIds}`,
|
||||||
|
'cancel_url': `${process.env.BASE_URL}/checkout/error`
|
||||||
|
},
|
||||||
|
'payer': {
|
||||||
|
'payment_method': 'paypal'
|
||||||
|
},
|
||||||
|
'transactions': [{
|
||||||
|
'amount': {
|
||||||
|
'total': price,
|
||||||
|
'currency': 'EUR'
|
||||||
|
},
|
||||||
|
'description': 'This is the payment transaction description.'
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
//Starting checkout process and returning sandbox url
|
||||||
|
try {
|
||||||
|
let urlRedirect
|
||||||
|
urlRedirect = 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(links['approval_url'].href)
|
||||||
|
} else {
|
||||||
|
console.error('no redirect URI present');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).then(res => res)
|
||||||
|
if (urlRedirect) {
|
||||||
|
return res.status(200).send({
|
||||||
|
data: urlRedirect
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return res.status(422).send({
|
||||||
|
data: {
|
||||||
|
message: "Error when starting payment"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async Success(req, res) {
|
||||||
|
//Parameters for validating payment and purchased products
|
||||||
|
const paramns = JSON.parse(req.body.data)
|
||||||
|
const custumer = paramns.custumer
|
||||||
|
const productsIds = paramns.productsIds
|
||||||
|
const productsArray = productsIds.split('-')
|
||||||
|
const products = productsArray.map(Number)
|
||||||
|
const _products = await db.getProducts();
|
||||||
|
const productsFilter = _products[0].filter((item) => {
|
||||||
|
if (products.includes(item.id)) {
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const paymentId = paramns.paymentId;
|
||||||
|
const payerId = { 'payer_id': paramns.PayerID };
|
||||||
|
|
||||||
|
const jsonOrderData = JSON.stringify({
|
||||||
|
"paymentId": paymentId,
|
||||||
|
"custumer": custumer,
|
||||||
|
"products": productsFilter
|
||||||
|
})
|
||||||
|
|
||||||
|
fs.writeFileSync('order.json', jsonOrderData, 'utf-8')
|
||||||
|
const contentOrder = fs.readFileSync('order.json', 'utf-8');
|
||||||
|
//API validation and data
|
||||||
|
paypal.payment.execute(paymentId, payerId, async function (error, payment) {
|
||||||
|
if (error) {
|
||||||
|
console.log(error);
|
||||||
|
return res.status(422).send({
|
||||||
|
data: {
|
||||||
|
message: "payment not successful"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
if (payment.state == 'approved') {
|
||||||
|
await db.orderData_put(contentOrder);
|
||||||
|
return res.status(200).send({
|
||||||
|
data: {
|
||||||
|
id: payment.id,
|
||||||
|
email: payment.payer.payer_info.email,
|
||||||
|
message: "payment completed successfully",
|
||||||
|
products: productsFilter
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return res.status(422).send({
|
||||||
|
data: {
|
||||||
|
message: "payment not successful"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/* return res.status(200).send({
|
||||||
|
data: {
|
||||||
|
menssage: "sucesso"
|
||||||
|
}
|
||||||
|
}) */
|
||||||
|
}
|
||||||
|
|
||||||
|
Cancel(req, res) {
|
||||||
|
return res.status(200).send({
|
||||||
|
data: {
|
||||||
|
menssage: "cancelado"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = new PaymentController();
|
|
@ -1,4 +1,4 @@
|
||||||
const db = require("../db/db");
|
const db = require("../../db/db");
|
||||||
|
|
||||||
const productsJson = require("./products.json")
|
const productsJson = require("./products.json")
|
||||||
|
|
||||||
|
@ -7,28 +7,14 @@ class ProductController {
|
||||||
|
|
||||||
const params = req.query;
|
const params = req.query;
|
||||||
const _products = await db.getProducts(params.dateExpired, params.postalCode);
|
const _products = await db.getProducts(params.dateExpired, params.postalCode);
|
||||||
let productsFilter = _products[0];
|
let productsFilter = _products[0]
|
||||||
|
|
||||||
if (Number(params.recommend)) {
|
if (Number(params.recommend)) {
|
||||||
productsFilter = productsFilter.filter(item => item.recommend == Number(params.recommend))
|
productsFilter = productsFilter.filter(item => item.recommend == params.recommend)
|
||||||
}
|
}
|
||||||
if (params.type) {
|
if (params.type) {
|
||||||
productsFilter = productsFilter.filter(item => item.type === 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) {
|
if (params.minPrice && !params.maxPrice) {
|
||||||
productsFilter = productsFilter.filter(item => {
|
productsFilter = productsFilter.filter(item => {
|
||||||
|
@ -105,6 +91,7 @@ class ProductController {
|
||||||
products: products
|
products: products
|
||||||
}) */
|
}) */
|
||||||
|
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
data: productsFilter
|
data: productsFilter
|
||||||
})
|
})
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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();
|
36
api/db/db.js
36
api/db/db.js
|
@ -12,17 +12,47 @@ async function connect() {
|
||||||
|
|
||||||
const mysql = require("mysql2/promise");
|
const mysql = require("mysql2/promise");
|
||||||
const connection = await mysql.createConnection("mysql://" + user + ":" + password + "@" + host + ":" + port + "/" + database + "");
|
const connection = await mysql.createConnection("mysql://" + user + ":" + password + "@" + host + ":" + port + "/" + database + "");
|
||||||
console.log("Connected to MySQL!");
|
|
||||||
global.connection = connection;
|
global.connection = connection;
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Procedure for get products
|
||||||
async function getProducts(dateExpired, postalCode) {
|
async function getProducts(dateExpired, postalCode) {
|
||||||
console.log("Query in table MySQL!");
|
|
||||||
const conn = await connect();
|
const conn = await connect();
|
||||||
const [rows] = await conn.query(`CALL catalogue_get("${dateExpired}", "${postalCode}")`);
|
const [rows] = await conn.query(`CALL catalogue_get("${dateExpired}", "${postalCode}")`);
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Procedure for create transactions, do not carry out any manipulation at the bank
|
||||||
|
async function orderData_put(jsonOrderData) {
|
||||||
|
const conn = await connect();
|
||||||
|
console.log(jsonOrderData);
|
||||||
|
const [rows] = await conn.query(`CALL orderData_put(?)`, [jsonOrderData], (err, results) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
} else {
|
||||||
|
console.log('Result:', results);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = { getProducts }
|
//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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = { getProducts, orderData_get, orderData_put, getProvinces }
|
23
api/index.js
23
api/index.js
|
@ -1,7 +1,16 @@
|
||||||
const cors = require('cors');
|
const cors = require('cors');
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const path = require('path');
|
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');
|
||||||
|
|
||||||
|
paypal.configure({
|
||||||
|
'mode': 'sandbox',
|
||||||
|
'client_id': process.env.CLIENT_ID,
|
||||||
|
'client_secret': process.env.SECRET_KEY
|
||||||
|
});
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
const port = 9999;
|
const port = 9999;
|
||||||
|
@ -11,8 +20,16 @@ const corsOptions = {
|
||||||
origin: allowedOrigins,
|
origin: allowedOrigins,
|
||||||
optionsSuccessStatus: 200,
|
optionsSuccessStatus: 200,
|
||||||
};
|
};
|
||||||
|
|
||||||
app.use(cors(corsOptions));
|
app.use(cors(corsOptions));
|
||||||
|
|
||||||
|
app.use(express.json());
|
||||||
|
app.use(
|
||||||
|
express.urlencoded({
|
||||||
|
extended: true,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
app.get('/', (req, res) => {
|
app.get('/', (req, res) => {
|
||||||
const indexPath = path.join(__dirname, './', 'index.html');
|
const indexPath = path.join(__dirname, './', 'index.html');
|
||||||
res.sendFile(indexPath);
|
res.sendFile(indexPath);
|
||||||
|
@ -21,6 +38,10 @@ app.get('/', (req, res) => {
|
||||||
//Products
|
//Products
|
||||||
app.get('/api/products', productController.findAll);
|
app.get('/api/products', productController.findAll);
|
||||||
app.get('/api/products/:id', productController.findById);
|
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.listen(port, () => {
|
app.listen(port, () => {
|
||||||
console.log(`Server listening at http://localhost:${port}`);
|
console.log(`Server listening at http://localhost:${port}`);
|
||||||
|
|
|
@ -8,8 +8,5 @@
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC"
|
||||||
"dependencies": {
|
|
||||||
"express": "^4.18.2"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,9 @@
|
||||||
"@vueuse/core": "^10.7.0",
|
"@vueuse/core": "^10.7.0",
|
||||||
"axios": "^1.2.1",
|
"axios": "^1.2.1",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
|
"fs": "^0.0.1-security",
|
||||||
"mysql2": "^3.7.0",
|
"mysql2": "^3.7.0",
|
||||||
|
"paypal-rest-sdk": "^1.8.1",
|
||||||
"pinia": "^2.0.11",
|
"pinia": "^2.0.11",
|
||||||
"quasar": "^2.6.0",
|
"quasar": "^2.6.0",
|
||||||
"vee-validate": "^4.12.2",
|
"vee-validate": "^4.12.2",
|
||||||
|
@ -54,9 +56,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/parser": {
|
"node_modules/@babel/parser": {
|
||||||
"version": "7.23.6",
|
"version": "7.23.9",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz",
|
||||||
"integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
|
"integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"parser": "bin/babel-parser.js"
|
"parser": "bin/babel-parser.js"
|
||||||
},
|
},
|
||||||
|
@ -133,9 +135,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@faker-js/faker": {
|
"node_modules/@faker-js/faker": {
|
||||||
"version": "8.3.1",
|
"version": "8.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-8.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-8.4.0.tgz",
|
||||||
"integrity": "sha512-FdgpFxY6V6rLZE9mmIBb9hM0xpfvQOSNOLnzolzKwsE1DH+gC7lEKV1p1IbR0lAYyvYd5a4u3qWJzowUkw1bIw==",
|
"integrity": "sha512-htW87352wzUCdX1jyUQocUcmAaFqcR/w082EC8iP/gtkF0K+aKcBp0hR5Arb7dzR8tQ1TrhE9DNa5EbJELm84w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -149,13 +151,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@humanwhocodes/config-array": {
|
"node_modules/@humanwhocodes/config-array": {
|
||||||
"version": "0.11.13",
|
"version": "0.11.14",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
||||||
"integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==",
|
"integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@humanwhocodes/object-schema": "^2.0.1",
|
"@humanwhocodes/object-schema": "^2.0.2",
|
||||||
"debug": "^4.1.1",
|
"debug": "^4.3.1",
|
||||||
"minimatch": "^3.0.5"
|
"minimatch": "^3.0.5"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -176,9 +178,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@humanwhocodes/object-schema": {
|
"node_modules/@humanwhocodes/object-schema": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz",
|
||||||
"integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==",
|
"integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@intlify/bundle-utils": {
|
"node_modules/@intlify/bundle-utils": {
|
||||||
|
@ -206,12 +208,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@intlify/core-base": {
|
"node_modules/@intlify/core-base": {
|
||||||
"version": "9.9.0",
|
"version": "9.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.9.1.tgz",
|
||||||
"integrity": "sha512-C7UXPymDIOlMGSNjAhNLtKgzITc/8BjINK5gNKXg8GiWCTwL6n3MWr55czksxn8RM5wTMz0qcLOFT+adtaVQaA==",
|
"integrity": "sha512-qsV15dg7jNX2faBRyKMgZS8UcFJViWEUPLdzZ9UR0kQZpFVeIpc0AG7ZOfeP7pX2T9SQ5jSiorq/tii9nkkafA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@intlify/message-compiler": "9.9.0",
|
"@intlify/message-compiler": "9.9.1",
|
||||||
"@intlify/shared": "9.9.0"
|
"@intlify/shared": "9.9.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16"
|
||||||
|
@ -221,11 +223,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@intlify/message-compiler": {
|
"node_modules/@intlify/message-compiler": {
|
||||||
"version": "9.9.0",
|
"version": "9.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.9.1.tgz",
|
||||||
"integrity": "sha512-yDU/jdUm9KuhEzYfS+wuyja209yXgdl1XFhMlKtXEgSFTxz4COZQCRXXbbH8JrAjMsaJ7bdoPSLsKlY6mXG2iA==",
|
"integrity": "sha512-zTvP6X6HeumHOXuAE1CMMsV6tTX+opKMOxO1OHTCg5N5Sm/F7d8o2jdT6W6L5oHUsJ/vvkGefHIs7Q3hfowmsA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@intlify/shared": "9.9.0",
|
"@intlify/shared": "9.9.1",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -236,9 +238,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@intlify/shared": {
|
"node_modules/@intlify/shared": {
|
||||||
"version": "9.9.0",
|
"version": "9.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.9.1.tgz",
|
||||||
"integrity": "sha512-1ECUyAHRrzOJbOizyGufYP2yukqGrWXtkmTu4PcswVnWbkcjzk3YQGmJ0bLkM7JZ0ZYAaohLGdYvBYnTOGYJ9g==",
|
"integrity": "sha512-b3Pta1nwkz5rGq434v0psHwEwHGy1pYCttfcM22IE//K9owbpkEvFptx9VcuRAxjQdrO2If249cmDDjBu5wMDA==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16"
|
||||||
},
|
},
|
||||||
|
@ -336,9 +338,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@quasar/app-vite": {
|
"node_modules/@quasar/app-vite": {
|
||||||
"version": "1.7.1",
|
"version": "1.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/@quasar/app-vite/-/app-vite-1.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/@quasar/app-vite/-/app-vite-1.7.3.tgz",
|
||||||
"integrity": "sha512-cs3ix7w8f7884JiTp3EW6auZ9R+Fg4qoPxEZ7VRGOrSsUg5oQtR/i91jeQk4Z96J/JUOqtcKqdqbzN4fzaFyIg==",
|
"integrity": "sha512-pnDInCFP9M1d7lJzS8UkiFq8bGWdekLz8Gu+NLI9UAxruIM9QVlSD4hUmWptTQXaVEvYlDnqfW3LOr57B8eVtw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@quasar/render-ssr-error": "^1.0.3",
|
"@quasar/render-ssr-error": "^1.0.3",
|
||||||
|
@ -579,9 +581,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/express-serve-static-core": {
|
"node_modules/@types/express-serve-static-core": {
|
||||||
"version": "4.17.41",
|
"version": "4.17.42",
|
||||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz",
|
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.42.tgz",
|
||||||
"integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==",
|
"integrity": "sha512-ckM3jm2bf/MfB3+spLPWYPUH573plBFwpOhqQ2WottxYV85j1HQFlxmnTq57X1yHY9awZPig06hL/cLMgNWHIQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
|
@ -600,9 +602,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/filewriter": {
|
"node_modules/@types/filewriter": {
|
||||||
"version": "0.0.32",
|
"version": "0.0.33",
|
||||||
"resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.32.tgz",
|
"resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.33.tgz",
|
||||||
"integrity": "sha512-Kpi2GXQyYJdjL8mFclL1eDgihn1SIzorMZjD94kdPZh9E4VxGOeyjPxi5LpsM4Zku7P0reqegZTt2GxhmA9VBg==",
|
"integrity": "sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/har-format": {
|
"node_modules/@types/har-format": {
|
||||||
|
@ -624,9 +626,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "20.10.8",
|
"version": "20.11.13",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.13.tgz",
|
||||||
"integrity": "sha512-f8nQs3cLxbAFc00vEU59yf9UyGUftkPaLGfvbVOIDdx2i1b8epBqj2aNGyP19fiyXWvlmZ7qC1XLjAzw/OKIeA==",
|
"integrity": "sha512-5G4zQwdiQBSWYTDAH1ctw2eidqdhMJaNsiIDKHFr55ihz5Trl2qqR8fdrT732yPBho5gkNxXm67OxWFBqX9aPg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~5.26.4"
|
"undici-types": "~5.26.4"
|
||||||
|
@ -677,12 +679,12 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@vee-validate/zod": {
|
"node_modules/@vee-validate/zod": {
|
||||||
"version": "4.12.4",
|
"version": "4.12.5",
|
||||||
"resolved": "https://registry.npmjs.org/@vee-validate/zod/-/zod-4.12.4.tgz",
|
"resolved": "https://registry.npmjs.org/@vee-validate/zod/-/zod-4.12.5.tgz",
|
||||||
"integrity": "sha512-iNFhkBfGkre2b+eBXgBpNlNVStxDrI59sJUbzBr01EjyTkFOUgc/0wPJrhY/kBp+0pnGzNi04jklJaKfNK2ibg==",
|
"integrity": "sha512-hUjvXaa4HHvlZeosucViIDOUikQmyKaXXuL6P8LR1ETOUrBV6ntTsafJGvRYtwhXosoLYuolUD6Km737okK4Gg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"type-fest": "^4.8.3",
|
"type-fest": "^4.8.3",
|
||||||
"vee-validate": "4.12.4",
|
"vee-validate": "4.12.5",
|
||||||
"zod": "^3.22.4"
|
"zod": "^3.22.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -709,49 +711,49 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-core": {
|
"node_modules/@vue/compiler-core": {
|
||||||
"version": "3.4.7",
|
"version": "3.4.15",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.7.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.15.tgz",
|
||||||
"integrity": "sha512-hhCaE3pTMrlIJK7M/o3Xf7HV8+JoNTGOQ/coWS+V+pH6QFFyqtoXqQzpqsNp7UK17xYKua/MBiKj4e1vgZOBYw==",
|
"integrity": "sha512-XcJQVOaxTKCnth1vCxEChteGuwG6wqnUHxAm1DO3gCz0+uXKaJNx8/digSz4dLALCy8n2lKq24jSUs8segoqIw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.23.6",
|
"@babel/parser": "^7.23.6",
|
||||||
"@vue/shared": "3.4.7",
|
"@vue/shared": "3.4.15",
|
||||||
"entities": "^4.5.0",
|
"entities": "^4.5.0",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-dom": {
|
"node_modules/@vue/compiler-dom": {
|
||||||
"version": "3.4.7",
|
"version": "3.4.15",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.7.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.15.tgz",
|
||||||
"integrity": "sha512-qDKBAIurCTub4n/6jDYkXwgsFuriqqmmLrIq1N2QDfYJA/mwiwvxi09OGn28g+uDdERX9NaKDLji0oTjE3sScg==",
|
"integrity": "sha512-wox0aasVV74zoXyblarOM3AZQz/Z+OunYcIHe1OsGclCHt8RsRm04DObjefaI82u6XDzv+qGWZ24tIsRAIi5MQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-core": "3.4.7",
|
"@vue/compiler-core": "3.4.15",
|
||||||
"@vue/shared": "3.4.7"
|
"@vue/shared": "3.4.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-sfc": {
|
"node_modules/@vue/compiler-sfc": {
|
||||||
"version": "3.4.7",
|
"version": "3.4.15",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.7.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.15.tgz",
|
||||||
"integrity": "sha512-Gec6CLkReVswDYjQFq79O5rktri4R7TsD/VPCiUoJw40JhNNxaNJJa8mrQrWoJluW4ETy6QN0NUyC/JO77OCOw==",
|
"integrity": "sha512-LCn5M6QpkpFsh3GQvs2mJUOAlBQcCco8D60Bcqmf3O3w5a+KWS5GvYbrrJBkgvL1BDnTp+e8q0lXCLgHhKguBA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.23.6",
|
"@babel/parser": "^7.23.6",
|
||||||
"@vue/compiler-core": "3.4.7",
|
"@vue/compiler-core": "3.4.15",
|
||||||
"@vue/compiler-dom": "3.4.7",
|
"@vue/compiler-dom": "3.4.15",
|
||||||
"@vue/compiler-ssr": "3.4.7",
|
"@vue/compiler-ssr": "3.4.15",
|
||||||
"@vue/shared": "3.4.7",
|
"@vue/shared": "3.4.15",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"magic-string": "^0.30.5",
|
"magic-string": "^0.30.5",
|
||||||
"postcss": "^8.4.32",
|
"postcss": "^8.4.33",
|
||||||
"source-map-js": "^1.0.2"
|
"source-map-js": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-ssr": {
|
"node_modules/@vue/compiler-ssr": {
|
||||||
"version": "3.4.7",
|
"version": "3.4.15",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.7.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.15.tgz",
|
||||||
"integrity": "sha512-PvYeSOvnCkST5mGS0TLwEn5w+4GavtEn6adcq8AspbHaIr+mId5hp7cG3ASy3iy8b+LuXEG2/QaV/nj5BQ/Aww==",
|
"integrity": "sha512-1jdeQyiGznr8gjFDadVmOJqZiLNSsMa5ZgqavkPZ8O2wjHv0tVuAEsw5hTdUoUW4232vpBbL/wJhzVW/JwY1Uw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.4.7",
|
"@vue/compiler-dom": "3.4.15",
|
||||||
"@vue/shared": "3.4.7"
|
"@vue/shared": "3.4.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/devtools-api": {
|
"node_modules/@vue/devtools-api": {
|
||||||
|
@ -760,57 +762,57 @@
|
||||||
"integrity": "sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA=="
|
"integrity": "sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA=="
|
||||||
},
|
},
|
||||||
"node_modules/@vue/reactivity": {
|
"node_modules/@vue/reactivity": {
|
||||||
"version": "3.4.7",
|
"version": "3.4.15",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.7.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.15.tgz",
|
||||||
"integrity": "sha512-F539DO0ogH0+L8F9Pnw7cjqibcmSOh5UTk16u5f4MKQ8fraqepI9zdh+sozPX6VmEHOcjo8qw3Or9ZcFFw4SZA==",
|
"integrity": "sha512-55yJh2bsff20K5O84MxSvXKPHHt17I2EomHznvFiJCAZpJTNW8IuLj1xZWMLELRhBK3kkFV/1ErZGHJfah7i7w==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/shared": "3.4.7"
|
"@vue/shared": "3.4.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-core": {
|
"node_modules/@vue/runtime-core": {
|
||||||
"version": "3.4.7",
|
"version": "3.4.15",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.7.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.15.tgz",
|
||||||
"integrity": "sha512-QMMsWRQaD3BpGyjjChthpl4Mji4Fjx1qfdufsXlDkKU3HV+hWNor2z+29F+E1MmVcP0ZfRZUfqYgtsQoL7IGwQ==",
|
"integrity": "sha512-6E3by5m6v1AkW0McCeAyhHTw+3y17YCOKG0U0HDKDscV4Hs0kgNT5G+GCHak16jKgcCDHpI9xe5NKb8sdLCLdw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.4.7",
|
"@vue/reactivity": "3.4.15",
|
||||||
"@vue/shared": "3.4.7"
|
"@vue/shared": "3.4.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-dom": {
|
"node_modules/@vue/runtime-dom": {
|
||||||
"version": "3.4.7",
|
"version": "3.4.15",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.7.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.15.tgz",
|
||||||
"integrity": "sha512-XwegyUY1rw8zxsX1Z36vwYcqo+uOgih5ti7y9vx+pPFhNdSQmN4LqK2RmSeAJG1oKV8NqSUmjpv92f/x6h0SeQ==",
|
"integrity": "sha512-EVW8D6vfFVq3V/yDKNPBFkZKGMFSvZrUQmx196o/v2tHKdwWdiZjYUBS+0Ez3+ohRyF8Njwy/6FH5gYJ75liUw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/runtime-core": "3.4.7",
|
"@vue/runtime-core": "3.4.15",
|
||||||
"@vue/shared": "3.4.7",
|
"@vue/shared": "3.4.15",
|
||||||
"csstype": "^3.1.3"
|
"csstype": "^3.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/server-renderer": {
|
"node_modules/@vue/server-renderer": {
|
||||||
"version": "3.4.7",
|
"version": "3.4.15",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.7.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.15.tgz",
|
||||||
"integrity": "sha512-3bWnYLEkLLhkDWqvNk7IvbQD4UcxvFKxELBiOO2iG3m6AniFIsBWfHOO5tLVQnjdWkODu4rq0GipmfEenVAK5Q==",
|
"integrity": "sha512-3HYzaidu9cHjrT+qGUuDhFYvF/j643bHC6uUN9BgM11DVy+pM6ATsG6uPBLnkwOgs7BpJABReLmpL3ZPAsUaqw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-ssr": "3.4.7",
|
"@vue/compiler-ssr": "3.4.15",
|
||||||
"@vue/shared": "3.4.7"
|
"@vue/shared": "3.4.15"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vue": "3.4.7"
|
"vue": "3.4.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/shared": {
|
"node_modules/@vue/shared": {
|
||||||
"version": "3.4.7",
|
"version": "3.4.15",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.7.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.15.tgz",
|
||||||
"integrity": "sha512-G+i4glX1dMJk88sbJEcQEGWRQnVm9eIY7CcQbO5dpdsD9SF8jka3Mr5OqZYGjczGN1+D6EUwdu6phcmcx9iuPA=="
|
"integrity": "sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g=="
|
||||||
},
|
},
|
||||||
"node_modules/@vueuse/core": {
|
"node_modules/@vueuse/core": {
|
||||||
"version": "10.7.1",
|
"version": "10.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.7.2.tgz",
|
||||||
"integrity": "sha512-74mWHlaesJSWGp1ihg76vAnfVq9NTv1YT0SYhAQ6zwFNdBkkP+CKKJmVOEHcdSnLXCXYiL5e7MaewblfiYLP7g==",
|
"integrity": "sha512-AOyAL2rK0By62Hm+iqQn6Rbu8bfmbgaIMXcE3TSr7BdQ42wnSFlwIdPjInO62onYsEMK/yDMU8C6oGfDAtZ2qQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/web-bluetooth": "^0.0.20",
|
"@types/web-bluetooth": "^0.0.20",
|
||||||
"@vueuse/metadata": "10.7.1",
|
"@vueuse/metadata": "10.7.2",
|
||||||
"@vueuse/shared": "10.7.1",
|
"@vueuse/shared": "10.7.2",
|
||||||
"vue-demi": ">=0.14.6"
|
"vue-demi": ">=0.14.6"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
|
@ -843,17 +845,17 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vueuse/metadata": {
|
"node_modules/@vueuse/metadata": {
|
||||||
"version": "10.7.1",
|
"version": "10.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.7.2.tgz",
|
||||||
"integrity": "sha512-jX8MbX5UX067DYVsbtrmKn6eG6KMcXxLRLlurGkZku5ZYT3vxgBjui2zajvUZ18QLIjrgBkFRsu7CqTAg18QFw==",
|
"integrity": "sha512-kCWPb4J2KGrwLtn1eJwaJD742u1k5h6v/St5wFe8Quih90+k2a0JP8BS4Zp34XUuJqS2AxFYMb1wjUL8HfhWsQ==",
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/antfu"
|
"url": "https://github.com/sponsors/antfu"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vueuse/shared": {
|
"node_modules/@vueuse/shared": {
|
||||||
"version": "10.7.1",
|
"version": "10.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.7.2.tgz",
|
||||||
"integrity": "sha512-v0jbRR31LSgRY/C5i5X279A/WQjD6/JsMzGa+eqt658oJ75IvQXAeONmwvEMrvJQKnRElq/frzBR7fhmWY5uLw==",
|
"integrity": "sha512-qFbXoxS44pi2FkgFjPvF4h7c9oMDutpyBdcJdMYIMg9XyXli2meFMuaKn+UMgsClo//Th6+beeCgqweT/79BVA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"vue-demi": ">=0.14.6"
|
"vue-demi": ">=0.14.6"
|
||||||
},
|
},
|
||||||
|
@ -920,9 +922,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/acorn-walk": {
|
"node_modules/acorn-walk": {
|
||||||
"version": "8.3.1",
|
"version": "8.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz",
|
||||||
"integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==",
|
"integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
|
@ -1109,9 +1111,9 @@
|
||||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||||
},
|
},
|
||||||
"node_modules/autoprefixer": {
|
"node_modules/autoprefixer": {
|
||||||
"version": "10.4.16",
|
"version": "10.4.17",
|
||||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz",
|
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz",
|
||||||
"integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==",
|
"integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -1128,9 +1130,9 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"browserslist": "^4.21.10",
|
"browserslist": "^4.22.2",
|
||||||
"caniuse-lite": "^1.0.30001538",
|
"caniuse-lite": "^1.0.30001578",
|
||||||
"fraction.js": "^4.3.6",
|
"fraction.js": "^4.3.7",
|
||||||
"normalize-range": "^0.1.2",
|
"normalize-range": "^0.1.2",
|
||||||
"picocolors": "^1.0.0",
|
"picocolors": "^1.0.0",
|
||||||
"postcss-value-parser": "^4.2.0"
|
"postcss-value-parser": "^4.2.0"
|
||||||
|
@ -1146,9 +1148,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.6.5",
|
"version": "1.6.7",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz",
|
||||||
"integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==",
|
"integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.4",
|
"follow-redirects": "^1.15.4",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
|
@ -1286,9 +1288,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/browserslist": {
|
"node_modules/browserslist": {
|
||||||
"version": "4.22.2",
|
"version": "4.22.3",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.3.tgz",
|
||||||
"integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
|
"integrity": "sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -1305,8 +1307,8 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"caniuse-lite": "^1.0.30001565",
|
"caniuse-lite": "^1.0.30001580",
|
||||||
"electron-to-chromium": "^1.4.601",
|
"electron-to-chromium": "^1.4.648",
|
||||||
"node-releases": "^2.0.14",
|
"node-releases": "^2.0.14",
|
||||||
"update-browserslist-db": "^1.0.13"
|
"update-browserslist-db": "^1.0.13"
|
||||||
},
|
},
|
||||||
|
@ -1345,7 +1347,6 @@
|
||||||
"version": "0.2.13",
|
"version": "0.2.13",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||||
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
|
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
|
@ -1392,9 +1393,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001576",
|
"version": "1.0.30001581",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001576.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001581.tgz",
|
||||||
"integrity": "sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==",
|
"integrity": "sha512-whlTkwhqV2tUmP3oYhtNfaWGYHDdS3JYFQBKXxcUR9qqPWsRhFHhoISO2Xnl/g0xyKzht9mI1LZpiNWfMzHixQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -1948,9 +1949,9 @@
|
||||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.4.625",
|
"version": "1.4.651",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.625.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.651.tgz",
|
||||||
"integrity": "sha512-DENMhh3MFgaPDoXWrVIqSPInQoLImywfCwrSmVl3cf9QHzoZSiutHwGaB/Ql3VkqcQV30rzgdM+BjKqBAJxo5Q==",
|
"integrity": "sha512-jjks7Xx+4I7dslwsbaFocSwqBbGHQmuXBJUK9QBZTIrzPq3pzn6Uf2szFSP728FtLYE3ldiccmlkOM/zhGKCpA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/elementtree": {
|
"node_modules/elementtree": {
|
||||||
|
@ -2461,9 +2462,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-vue": {
|
"node_modules/eslint-plugin-vue": {
|
||||||
"version": "9.19.2",
|
"version": "9.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.19.2.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.21.0.tgz",
|
||||||
"integrity": "sha512-CPDqTOG2K4Ni2o4J5wixkLVNwgctKXFu6oBpVJlpNq7f38lh9I80pRTouZSJ2MAebPJlINU/KTFSXyQfBUlymA==",
|
"integrity": "sha512-B3NgZRtbi9kSl7M0x/PqhSMk7ULJUwWxQpTvM8b2Z6gNTORK0YSt5v1vzwY84oMs/2+3BWH5XmTepaQebcJwfA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.4.0",
|
"@eslint-community/eslint-utils": "^4.4.0",
|
||||||
|
@ -2471,7 +2472,7 @@
|
||||||
"nth-check": "^2.1.1",
|
"nth-check": "^2.1.1",
|
||||||
"postcss-selector-parser": "^6.0.13",
|
"postcss-selector-parser": "^6.0.13",
|
||||||
"semver": "^7.5.4",
|
"semver": "^7.5.4",
|
||||||
"vue-eslint-parser": "^9.3.1",
|
"vue-eslint-parser": "^9.4.2",
|
||||||
"xml-name-validator": "^4.0.0"
|
"xml-name-validator": "^4.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -2764,9 +2765,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/fastq": {
|
"node_modules/fastq": {
|
||||||
"version": "1.16.0",
|
"version": "1.17.0",
|
||||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.0.tgz",
|
||||||
"integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==",
|
"integrity": "sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"reusify": "^1.0.4"
|
"reusify": "^1.0.4"
|
||||||
|
@ -2896,9 +2897,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/follow-redirects": {
|
"node_modules/follow-redirects": {
|
||||||
"version": "1.15.4",
|
"version": "1.15.5",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
|
||||||
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
|
"integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
|
@ -2956,6 +2957,11 @@
|
||||||
"node": ">= 0.6"
|
"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": {
|
"node_modules/fs-constants": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
||||||
|
@ -3256,9 +3262,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/immutable": {
|
"node_modules/immutable": {
|
||||||
"version": "4.3.4",
|
"version": "4.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz",
|
||||||
"integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==",
|
"integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/import-fresh": {
|
"node_modules/import-fresh": {
|
||||||
|
@ -3859,15 +3865,11 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/lru-cache": {
|
"node_modules/lru-cache": {
|
||||||
"version": "6.0.0",
|
"version": "8.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz",
|
||||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
"integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"yallist": "^4.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=16.14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/magic-string": {
|
"node_modules/magic-string": {
|
||||||
|
@ -4076,9 +4078,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/mysql2": {
|
"node_modules/mysql2": {
|
||||||
"version": "3.7.0",
|
"version": "3.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.1.tgz",
|
||||||
"integrity": "sha512-c45jA3Jc1X8yJKzrWu1GpplBKGwv/wIV6ITZTlCSY7npF2YfJR+6nMP5e+NTQhUeJPSyOQAbGDCGEHbAl8HN9w==",
|
"integrity": "sha512-3njoWAAhGBYy0tWBabqUQcLtczZUxrmmtc2vszQUekg3kTJyZ5/IeLC3Fo04u6y6Iy5Sba7pIIa2P/gs8D3ZeQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"denque": "^2.1.0",
|
"denque": "^2.1.0",
|
||||||
"generate-function": "^2.3.1",
|
"generate-function": "^2.3.1",
|
||||||
|
@ -4104,14 +4106,6 @@
|
||||||
"node": ">=0.10.0"
|
"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": {
|
"node_modules/named-placeholders": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz",
|
||||||
|
@ -4431,6 +4425,26 @@
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||||
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
|
"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": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||||
|
@ -4642,9 +4656,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/quasar": {
|
"node_modules/quasar": {
|
||||||
"version": "2.14.2",
|
"version": "2.14.3",
|
||||||
"resolved": "https://registry.npmjs.org/quasar/-/quasar-2.14.2.tgz",
|
"resolved": "https://registry.npmjs.org/quasar/-/quasar-2.14.3.tgz",
|
||||||
"integrity": "sha512-f5KliWtM5BEuFsDU4yvuP+dlVIWZNrGu5VpWFsxzjpoykcP4B2HIOUiCl3mx2NCqERHd4Ts0aeioRkt9TTeExA==",
|
"integrity": "sha512-7WzbtZxykLn2ic5oNpepZ2ZjDVpmxyVD4KC9rWe+Ia+4Er61svGr4jOuttN+Ok7IerLSCmKIRyjQMgasF60rFA==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 10.18.1",
|
"node": ">= 10.18.1",
|
||||||
"npm": ">= 6.13.4",
|
"npm": ">= 6.13.4",
|
||||||
|
@ -4970,9 +4984,9 @@
|
||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||||
},
|
},
|
||||||
"node_modules/sass": {
|
"node_modules/sass": {
|
||||||
"version": "1.69.7",
|
"version": "1.70.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.69.7.tgz",
|
"resolved": "https://registry.npmjs.org/sass/-/sass-1.70.0.tgz",
|
||||||
"integrity": "sha512-rzj2soDeZ8wtE2egyLXgOOHQvaC2iosZrkF6v3EUG+tBwEvhqUCzm0VP3k9gHF9LXbSrRhT5SksoI56Iw8NPnQ==",
|
"integrity": "sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chokidar": ">=3.0.0 <4.0.0",
|
"chokidar": ">=3.0.0 <4.0.0",
|
||||||
|
@ -5013,6 +5027,18 @@
|
||||||
"integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
|
"integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
|
||||||
"dev": true
|
"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": {
|
"node_modules/send": {
|
||||||
"version": "0.18.0",
|
"version": "0.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
|
||||||
|
@ -5089,14 +5115,15 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/set-function-length": {
|
"node_modules/set-function-length": {
|
||||||
"version": "1.1.1",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz",
|
||||||
"integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==",
|
"integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"define-data-property": "^1.1.1",
|
"define-data-property": "^1.1.1",
|
||||||
"get-intrinsic": "^1.2.1",
|
"function-bind": "^1.1.2",
|
||||||
|
"get-intrinsic": "^1.2.2",
|
||||||
"gopd": "^1.0.1",
|
"gopd": "^1.0.1",
|
||||||
"has-property-descriptors": "^1.0.0"
|
"has-property-descriptors": "^1.0.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
|
@ -5478,9 +5505,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/type-fest": {
|
"node_modules/type-fest": {
|
||||||
"version": "4.9.0",
|
"version": "4.10.2",
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.10.2.tgz",
|
||||||
"integrity": "sha512-KS/6lh/ynPGiHD/LnAobrEFq3Ad4pBzOlJ1wAnJx9N4EYoqFhMfLIBjUT2UEx4wg5ZE+cC1ob6DCSpppVo+rtg==",
|
"integrity": "sha512-anpAG63wSpdEbLwOqH8L84urkL6PiVIov3EMmgIhhThevh9aiMQov+6Btx0wldNcvm4wV+e2/Rt1QdDwKHFbHw==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16"
|
"node": ">=16"
|
||||||
},
|
},
|
||||||
|
@ -5622,9 +5649,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vee-validate": {
|
"node_modules/vee-validate": {
|
||||||
"version": "4.12.4",
|
"version": "4.12.5",
|
||||||
"resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-4.12.4.tgz",
|
"resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-4.12.5.tgz",
|
||||||
"integrity": "sha512-rqSjMdl0l/RiGKywKhkXttUKwDlQOoxTxe31uMQiMlwK4Hbtlvr3OcQvpREp/qPTARxNKudKWCUVW/mfzuxUVQ==",
|
"integrity": "sha512-rvaDfLPSLwTk+mf016XWE4drB8yXzOsKXiKHTb9gNXNLTtQSZ0Ww26O0/xbIFQe+n3+u8Wv1Y8uO/aLDX4fxOg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/devtools-api": "^6.5.1",
|
"@vue/devtools-api": "^6.5.1",
|
||||||
"type-fest": "^4.8.3"
|
"type-fest": "^4.8.3"
|
||||||
|
@ -5634,9 +5661,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "2.9.16",
|
"version": "2.9.17",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-2.9.16.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-2.9.17.tgz",
|
||||||
"integrity": "sha512-X+6q8KPyeuBvTQV8AVSnKDvXoBMnTx8zxh54sOwmmuOdxkjMmEJXH2UEchA+vTMps1xw9vL64uwJOWryULg7nA==",
|
"integrity": "sha512-XxcRzra6d7xrKXH66jZUgb+srThoPu+TLJc06GifUyKq9JmjHkc1Numc8ra0h56rju2jfVWw3B3fs5l3OFMvUw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.14.27",
|
"esbuild": "^0.14.27",
|
||||||
|
@ -5671,15 +5698,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vue": {
|
"node_modules/vue": {
|
||||||
"version": "3.4.7",
|
"version": "3.4.15",
|
||||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.7.tgz",
|
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.15.tgz",
|
||||||
"integrity": "sha512-4urmkWpudekq0CPNMO7p6mBGa9qmTXwJMO2r6CT4EzIJVG7WoSReiysiNb7OSi/WI113oX0Srn9Rz1k/DCXKFQ==",
|
"integrity": "sha512-jC0GH4KkWLWJOEQjOpkqU1bQsBwf4R1rsFtw5GQJbjHVKWDzO6P0nWWBTmjp1xSemAioDFj1jdaK1qa3DnMQoQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.4.7",
|
"@vue/compiler-dom": "3.4.15",
|
||||||
"@vue/compiler-sfc": "3.4.7",
|
"@vue/compiler-sfc": "3.4.15",
|
||||||
"@vue/runtime-dom": "3.4.7",
|
"@vue/runtime-dom": "3.4.15",
|
||||||
"@vue/server-renderer": "3.4.7",
|
"@vue/server-renderer": "3.4.15",
|
||||||
"@vue/shared": "3.4.7"
|
"@vue/shared": "3.4.15"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "*"
|
"typescript": "*"
|
||||||
|
@ -5696,9 +5723,9 @@
|
||||||
"integrity": "sha512-4fdRMXO6FHzmE7H4soAph6QmPg3sL/RiGdd+axuxuU07f02LNMns0jMM88fmt1bvSbN+2Wyd8raho6p6nXUzag=="
|
"integrity": "sha512-4fdRMXO6FHzmE7H4soAph6QmPg3sL/RiGdd+axuxuU07f02LNMns0jMM88fmt1bvSbN+2Wyd8raho6p6nXUzag=="
|
||||||
},
|
},
|
||||||
"node_modules/vue-eslint-parser": {
|
"node_modules/vue-eslint-parser": {
|
||||||
"version": "9.4.0",
|
"version": "9.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
|
||||||
"integrity": "sha512-7KsNBb6gHFA75BtneJsoK/dbZ281whUIwFYdQxA68QrCrGMXYzUMbPDHGcOQ0OocIVKrWSKWXZ4mL7tonCXoUw==",
|
"integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
|
@ -5720,12 +5747,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vue-i18n": {
|
"node_modules/vue-i18n": {
|
||||||
"version": "9.9.0",
|
"version": "9.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.9.1.tgz",
|
||||||
"integrity": "sha512-xQ5SxszUAqK5n84N+uUyHH/PiQl9xZ24FOxyAaNonmOQgXeN+rD9z/6DStOpOxNFQn4Cgcquot05gZc+CdOujA==",
|
"integrity": "sha512-xyQ4VspLdNSPTKBFBPWa1tvtj+9HuockZwgFeD2OhxxXuC2CWeNvV4seu2o9+vbQOyQbhAM5Ez56oxUrrnTWdw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@intlify/core-base": "9.9.0",
|
"@intlify/core-base": "9.9.1",
|
||||||
"@intlify/shared": "9.9.0",
|
"@intlify/shared": "9.9.1",
|
||||||
"@vue/devtools-api": "^6.5.0"
|
"@vue/devtools-api": "^6.5.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"name": "floranet",
|
"name": "floranet",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"description": "A floranet app",
|
"description": "A floranet app",
|
||||||
"productName": "Floranet App",
|
"productName": "Floranet",
|
||||||
"author": "user",
|
"author": "user",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -22,7 +22,9 @@
|
||||||
"@vueuse/core": "^10.7.0",
|
"@vueuse/core": "^10.7.0",
|
||||||
"axios": "^1.2.1",
|
"axios": "^1.2.1",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
|
"fs": "^0.0.1-security",
|
||||||
"mysql2": "^3.7.0",
|
"mysql2": "^3.7.0",
|
||||||
|
"paypal-rest-sdk": "^1.8.1",
|
||||||
"pinia": "^2.0.11",
|
"pinia": "^2.0.11",
|
||||||
"quasar": "^2.6.0",
|
"quasar": "^2.6.0",
|
||||||
"vee-validate": "^4.12.2",
|
"vee-validate": "^4.12.2",
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
<script>
|
<script>
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
|
import { defineComponent, onBeforeMount, ref, watch } from "vue";
|
||||||
|
|
||||||
import { fullCurrentDate } from "src/constants/date";
|
import { fullCurrentDate } from "src/constants/date";
|
||||||
|
import { invertDate } from "src/functions/invertDate";
|
||||||
import { useFormStore } from "src/stores/forms";
|
import { useFormStore } from "src/stores/forms";
|
||||||
import { defineComponent, ref } from "vue";
|
|
||||||
import IconCalendar from "../icons/IconCalendar.vue";
|
import IconCalendar from "../icons/IconCalendar.vue";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
@ -19,27 +21,45 @@ export default defineComponent({
|
||||||
const formStore = useFormStore();
|
const formStore = useFormStore();
|
||||||
const { availability } = storeToRefs(formStore);
|
const { availability } = storeToRefs(formStore);
|
||||||
|
|
||||||
const proxyDate = ref(fullCurrentDate);
|
const [year, month, day] = fullCurrentDate.replaceAll("/", "-").split("-");
|
||||||
|
const currentDate = `${day}-${month}-${year}`;
|
||||||
|
const proxyDate = ref(invertDate(currentDate));
|
||||||
|
|
||||||
function updateProxy() {
|
function updateProxy() {
|
||||||
proxyDate.value = fullCurrentDate;
|
proxyDate.value = invertDate(currentDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
function optionsValidDates(date) {
|
function optionsValidDates(date) {
|
||||||
return date >= fullCurrentDate;
|
return date >= fullCurrentDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
function save() {
|
onBeforeMount(() => {
|
||||||
availability.value.date = proxyDate.value;
|
setValues({ date: invertDate(proxyDate.value) });
|
||||||
setValues({ date: proxyDate.value });
|
});
|
||||||
}
|
|
||||||
|
watch(proxyDate, (newProxy) => {
|
||||||
|
setValues({ date: invertDate(newProxy) });
|
||||||
|
});
|
||||||
|
|
||||||
|
const locale = {
|
||||||
|
days: "Domingo_Lunes_Martes_Miércoles_Jueves_Viernes_Sábado".split("_"),
|
||||||
|
daysShort: "Dom_Lun_Mar_Mié_Jue_Vie_Sáb".split("_"),
|
||||||
|
months:
|
||||||
|
"Enero_Febrero_Marzo_Abril_Mayo_Junio_Julio_Agosto_Septiembre_Octubre_Noviembre_Diciembre".split(
|
||||||
|
"_"
|
||||||
|
),
|
||||||
|
monthsShort: "Ene_Feb_Mar_Abr_May_Jun_Jul_Ago_Sep_Oct_Nov_Dic".split("_"),
|
||||||
|
firstDayOfWeek: 1,
|
||||||
|
format24h: false,
|
||||||
|
pluralDay: "dias",
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
availability,
|
availability,
|
||||||
proxyDate,
|
proxyDate,
|
||||||
|
locale,
|
||||||
updateProxy,
|
updateProxy,
|
||||||
optionsValidDates,
|
optionsValidDates,
|
||||||
save,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -58,19 +78,14 @@ export default defineComponent({
|
||||||
>
|
>
|
||||||
<q-date
|
<q-date
|
||||||
v-model="proxyDate"
|
v-model="proxyDate"
|
||||||
v-bind="calendarAttrs"
|
|
||||||
:options="optionsValidDates"
|
:options="optionsValidDates"
|
||||||
mask="DD-MM-YYYY"
|
:locale="locale"
|
||||||
|
today-btn
|
||||||
|
mask="YYYY-MM-DD"
|
||||||
>
|
>
|
||||||
<div class="row items-center justify-end q-gutter-sm">
|
<div class="row items-center justify-end q-gutter-sm">
|
||||||
<q-btn label="Cancel" color="primary" flat v-close-popup />
|
<q-btn label="Cancel" color="primary" flat v-close-popup />
|
||||||
<q-btn
|
<q-btn label="OK" color="primary" flat v-close-popup />
|
||||||
label="OK"
|
|
||||||
color="primary"
|
|
||||||
flat
|
|
||||||
@click="save"
|
|
||||||
v-close-popup
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</q-date>
|
</q-date>
|
||||||
</q-popup-proxy>
|
</q-popup-proxy>
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
<script>
|
|
||||||
import { toTypedSchema } from "@vee-validate/zod";
|
|
||||||
import { Field, useForm } from "vee-validate";
|
|
||||||
import { defineComponent, watch } from "vue";
|
|
||||||
|
|
||||||
import { quasarNotify } from "src/functions/quasarNotify";
|
|
||||||
import { useFormStore } from "src/stores/forms";
|
|
||||||
import { availabilitySchema } from "src/utils/zod/schemas/availabilitySchema";
|
|
||||||
import IconPostalCode from "../icons/IconPostalCode.vue";
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "PostalCodeEx",
|
|
||||||
components: { IconPostalCode, Field },
|
|
||||||
setup() {
|
|
||||||
const formStore = useFormStore();
|
|
||||||
const validationSchema = toTypedSchema(
|
|
||||||
availabilitySchema.pick({ date: true })
|
|
||||||
);
|
|
||||||
const { errors, values, handleSubmit } = useForm({
|
|
||||||
validationSchema,
|
|
||||||
initialValues: {
|
|
||||||
date: "",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(values, (newValues) => {
|
|
||||||
formStore.$patch({
|
|
||||||
availability: {
|
|
||||||
postalCode: newValues.date,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(errors, (newErrors) => {
|
|
||||||
if (newErrors.date) {
|
|
||||||
quasarNotify({ message: newErrors.date, type: "erro" });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = handleSubmit(formStore.registerAvailability);
|
|
||||||
|
|
||||||
return {
|
|
||||||
postalCode,
|
|
||||||
postalCodeAttrs,
|
|
||||||
errors,
|
|
||||||
onBlur,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="custom-input-el postal-code">
|
|
||||||
<IconPostalCode />
|
|
||||||
|
|
||||||
<div class="custom-block-content">
|
|
||||||
<p class="custom-head-paragraph">¿Dónde?</p>
|
|
||||||
<!-- <p class="custom-main-paragraph">código postal</p> -->
|
|
||||||
<Field />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
|
@ -1,62 +0,0 @@
|
||||||
<script>
|
|
||||||
import { toTypedSchema } from "@vee-validate/zod";
|
|
||||||
import { Field, useForm } from "vee-validate";
|
|
||||||
import { defineComponent, watch } from "vue";
|
|
||||||
|
|
||||||
import { quasarNotify } from "src/functions/quasarNotify";
|
|
||||||
import { useFormStore } from "src/stores/forms";
|
|
||||||
import { availabilitySchema } from "src/utils/zod/schemas/availabilitySchema";
|
|
||||||
import IconPostalCode from "../icons/IconPostalCode.vue";
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "PostalCodeEx",
|
|
||||||
components: { IconPostalCode, Field },
|
|
||||||
setup() {
|
|
||||||
const formStore = useFormStore();
|
|
||||||
const validationSchema = toTypedSchema(
|
|
||||||
availabilitySchema.pick({ postalCode: true })
|
|
||||||
);
|
|
||||||
const { errors, values, handleSubmit } = useForm({
|
|
||||||
validationSchema,
|
|
||||||
initialValues: {
|
|
||||||
postalCode: "",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(values, (newValues) => {
|
|
||||||
formStore.$patch({
|
|
||||||
availability: {
|
|
||||||
postalCode: newValues.postalCode,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(errors, (newErrors) => {
|
|
||||||
if (newErrors.postalCode) {
|
|
||||||
quasarNotify({ message: newErrors.postalCode, type: "erro" });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = handleSubmit(formStore.registerAvailability);
|
|
||||||
|
|
||||||
return {
|
|
||||||
postalCode,
|
|
||||||
postalCodeAttrs,
|
|
||||||
errors,
|
|
||||||
onBlur,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="custom-input-el postal-code">
|
|
||||||
<IconPostalCode />
|
|
||||||
|
|
||||||
<div class="custom-block-content">
|
|
||||||
<p class="custom-head-paragraph">¿Dónde?</p>
|
|
||||||
<!-- <p class="custom-main-paragraph">código postal</p> -->
|
|
||||||
<Field />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
|
@ -1,47 +1,13 @@
|
||||||
<script>
|
<script>
|
||||||
import { toTypedSchema } from "@vee-validate/zod";
|
import { defineComponent } from "vue";
|
||||||
import { storeToRefs } from "pinia";
|
|
||||||
import { useForm } from "vee-validate";
|
|
||||||
import { defineComponent, watch } from "vue";
|
|
||||||
|
|
||||||
import { quasarNotify } from "src/functions/quasarNotify";
|
|
||||||
import { useFormStore } from "src/stores/forms";
|
|
||||||
import { availabilitySchema } from "src/utils/zod/schemas/availabilitySchema";
|
|
||||||
import IconPostalCode from "../icons/IconPostalCode.vue";
|
import IconPostalCode from "../icons/IconPostalCode.vue";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "postal-code",
|
name: "postal-code",
|
||||||
components: { IconPostalCode },
|
components: { IconPostalCode },
|
||||||
setup() {
|
setup() {
|
||||||
const formStore = useFormStore();
|
return {};
|
||||||
const { availability } = storeToRefs(formStore);
|
|
||||||
const validationSchema = toTypedSchema(
|
|
||||||
availabilitySchema.pick({ postalCode: true }).partial()
|
|
||||||
);
|
|
||||||
const { errors, defineField, values } = useForm({
|
|
||||||
validationSchema,
|
|
||||||
initialValues: {
|
|
||||||
postalCode: availability.value.postalCode,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const [postalCode, postalCodeAttrs] = defineField("postalCode");
|
|
||||||
const onBlur = () => {
|
|
||||||
availability.value.postalCode = postalCode.value;
|
|
||||||
};
|
|
||||||
availability.value.postalCode = values.postalCode;
|
|
||||||
|
|
||||||
watch(errors, (newErrors) => {
|
|
||||||
if (newErrors.postalCode) {
|
|
||||||
quasarNotify({ message: newErrors.postalCode, type: "erro" });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
postalCode,
|
|
||||||
postalCodeAttrs,
|
|
||||||
errors,
|
|
||||||
onBlur,
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -54,17 +20,6 @@ export default defineComponent({
|
||||||
<p class="custom-head-paragraph">¿Dónde?</p>
|
<p class="custom-head-paragraph">¿Dónde?</p>
|
||||||
|
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
<!-- <q-input
|
|
||||||
borderless
|
|
||||||
class="custom-main-paragraph"
|
|
||||||
v-model="postalCode"
|
|
||||||
v-bind="postalCodeAttrs"
|
|
||||||
:error="!!errors.postalCode"
|
|
||||||
placeholder="código postal"
|
|
||||||
mask="#####"
|
|
||||||
@blur="onBlur"
|
|
||||||
dense
|
|
||||||
/> -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -10,7 +10,7 @@ export default defineComponent({
|
||||||
const formStore = useFormStore();
|
const formStore = useFormStore();
|
||||||
const { sortProductFilters } = storeToRefs(formStore);
|
const { sortProductFilters } = storeToRefs(formStore);
|
||||||
|
|
||||||
async function handleOrder(order) {
|
function handleOrder(order) {
|
||||||
sortProductFilters.value.order = order;
|
sortProductFilters.value.order = order;
|
||||||
sortProductFilters.value.isOpenOrderFilter = false;
|
sortProductFilters.value.isOpenOrderFilter = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,9 @@ export default defineComponent({
|
||||||
:class="isOpenNav && 'mobile-nav'"
|
:class="isOpenNav && 'mobile-nav'"
|
||||||
>
|
>
|
||||||
<send-banner
|
<send-banner
|
||||||
left-text="ENVÍO GRATIS a partir de 60€ | Compra el sábado hasta 14h y entrega el domingo"
|
left-text="ENVÍO GRATIS"
|
||||||
right-text="Envíos 24-48 h a toda España, Portugal y sur de Francia"
|
right-text="Envíos 24-48 h a toda España, Portugal y sur de Francia"
|
||||||
mobile-text="ENVÍO GRATIS a partir de 60€"
|
mobile-text="ENVÍO GRATIS"
|
||||||
v-if="!isOpenNav"
|
v-if="!isOpenNav"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,9 @@ export default defineComponent({
|
||||||
<template>
|
<template>
|
||||||
<q-header class="header-container transparent">
|
<q-header class="header-container transparent">
|
||||||
<send-banner
|
<send-banner
|
||||||
left-text="ENVÍO GRATIS a partir de 60€ | Compra el sábado hasta 14h y entrega el domingo"
|
left-text="ENVÍO GRATIS"
|
||||||
right-text="Envíos 24-48 h a toda España, Portugal y sur de Francia"
|
right-text="Envíos 24-48 h a toda España, Portugal y sur de Francia"
|
||||||
mobile-text="ENVÍO GRATIS a partir de 60€"
|
mobile-text="ENVÍO GRATIS"
|
||||||
class="remove-mobile"
|
class="remove-mobile"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent } from "vue";
|
import { computed, defineComponent } from "vue";
|
||||||
|
|
||||||
import IconCart from "components/icons/IconCart.vue";
|
import IconCart from "components/icons/IconCart.vue";
|
||||||
import IconHamburger from "components/icons/IconHamburger.vue";
|
import IconHamburger from "components/icons/IconHamburger.vue";
|
||||||
|
|
||||||
import { useLocalStorage } from "src/hooks/useLocalStorage";
|
import { storeToRefs } from "pinia";
|
||||||
|
import { useCartStore } from "src/stores/cart";
|
||||||
import { useMobileStore } from "stores/mobileNav";
|
import { useMobileStore } from "stores/mobileNav";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
@ -14,14 +15,15 @@ export default defineComponent({
|
||||||
IconHamburger,
|
IconHamburger,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const { getItem } = useLocalStorage();
|
const cartStore = useCartStore();
|
||||||
|
const { cart } = storeToRefs(cartStore);
|
||||||
|
|
||||||
const mobileStore = useMobileStore();
|
const mobileStore = useMobileStore();
|
||||||
const { handleOpenMobileNav } = mobileStore;
|
const { handleOpenMobileNav } = mobileStore;
|
||||||
|
|
||||||
const cartLength = getItem("cart").length;
|
const currentLength = computed(() => cart.value.length);
|
||||||
|
|
||||||
return { handleOpenMobileNav, cartLength };
|
return { handleOpenMobileNav, currentLength };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -38,11 +40,11 @@ export default defineComponent({
|
||||||
<RouterLink
|
<RouterLink
|
||||||
class="user-area-link cart"
|
class="user-area-link cart"
|
||||||
to="/checkout"
|
to="/checkout"
|
||||||
v-if="cartLength > 0"
|
v-if="currentLength > 0"
|
||||||
>
|
>
|
||||||
<icon-cart />
|
<icon-cart />
|
||||||
<span class="cart-count" :class="cartLength > 0 && 'active'">
|
<span class="cart-count" :class="currentLength > 0 && 'active'">
|
||||||
{{ cartLength }}
|
{{ currentLength }}
|
||||||
</span>
|
</span>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
|
|
||||||
|
|
|
@ -87,8 +87,7 @@ export default defineComponent({
|
||||||
Regala un verano lleno de flores y plantas
|
Regala un verano lleno de flores y plantas
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p class="carousel-header-paragraph">
|
<!-- <p class="carousel-header-paragraph"></p> -->
|
||||||
</p>
|
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<form @submit="onSubmit" class="carousel-content-body">
|
<form @submit="onSubmit" class="carousel-content-body">
|
||||||
|
@ -99,7 +98,7 @@ export default defineComponent({
|
||||||
class="custom-date-input"
|
class="custom-date-input"
|
||||||
v-model="calendar"
|
v-model="calendar"
|
||||||
v-bind="calendarAttrs"
|
v-bind="calendarAttrs"
|
||||||
:error="!!errors.date"
|
:error="false"
|
||||||
placeholder="Elige una fecha"
|
placeholder="Elige una fecha"
|
||||||
mask="##/##/####"
|
mask="##/##/####"
|
||||||
dense
|
dense
|
||||||
|
@ -114,7 +113,7 @@ export default defineComponent({
|
||||||
class="custom-main-paragraph"
|
class="custom-main-paragraph"
|
||||||
v-model="postalCode"
|
v-model="postalCode"
|
||||||
v-bind="postalCodeAttrs"
|
v-bind="postalCodeAttrs"
|
||||||
:error="!!errors.postalCode"
|
:error="false"
|
||||||
placeholder="código postal"
|
placeholder="código postal"
|
||||||
mask="#####"
|
mask="#####"
|
||||||
dense
|
dense
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
<template>
|
|
||||||
<StripeCheckout
|
|
||||||
ref="checkoutRef"
|
|
||||||
mode="payment"
|
|
||||||
:pk="pK"
|
|
||||||
:line-items="cartItems"
|
|
||||||
:success-url="successURL"
|
|
||||||
:cancel-url="cancelURL"
|
|
||||||
@loading="(v) => (loading = v)"
|
|
||||||
style="display: none"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<slot></slot>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { storeToRefs } from "pinia";
|
|
||||||
import { defineComponent, ref, toRefs } from "vue";
|
|
||||||
|
|
||||||
import { useCartStore } from "src/stores/cart";
|
|
||||||
import { onUpdated } from "vue";
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "StripeCheckoutComponent",
|
|
||||||
components: {},
|
|
||||||
props: {
|
|
||||||
submitLoading: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
onSubmit: {
|
|
||||||
type: Function,
|
|
||||||
default: () => {},
|
|
||||||
},
|
|
||||||
cartItems: {
|
|
||||||
type: Array,
|
|
||||||
default: () => [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
setup({ submitLoading, cartItems }) {
|
|
||||||
const cartStore = useCartStore();
|
|
||||||
const { checkoutRef } = storeToRefs(cartStore);
|
|
||||||
|
|
||||||
const loading = toRefs(submitLoading);
|
|
||||||
const pK = ref(
|
|
||||||
"pk_test_51OZaJdIK1lTlG93d2y0B81n4XrjvjQwqfIUZ7ggb9wEBa1e4h34GlYFYPwjtGl3OUT7DJZlVNX9EMXaCdOBkIC3T007mLnfvCu"
|
|
||||||
);
|
|
||||||
|
|
||||||
onUpdated(() => {
|
|
||||||
console.log(checkoutRef.value);
|
|
||||||
console.log(cartItems);
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
pK,
|
|
||||||
loading,
|
|
||||||
checkoutRef,
|
|
||||||
successURL: ref("/checkout/success"),
|
|
||||||
cancelURL: ref("/checkout/cancel"),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss"></style>
|
|
|
@ -20,8 +20,6 @@ export default defineComponent({
|
||||||
const nextSwiperBtn = ref(null);
|
const nextSwiperBtn = ref(null);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// console.log('Montado!');
|
|
||||||
|
|
||||||
swiperContainer.value =
|
swiperContainer.value =
|
||||||
document.querySelector("swiper-container").shadowRoot;
|
document.querySelector("swiper-container").shadowRoot;
|
||||||
prevSwiperBtn.value = swiperContainer.value.querySelector(
|
prevSwiperBtn.value = swiperContainer.value.querySelector(
|
||||||
|
@ -40,11 +38,9 @@ export default defineComponent({
|
||||||
return {
|
return {
|
||||||
screenWidth,
|
screenWidth,
|
||||||
handlePrev() {
|
handlePrev() {
|
||||||
// console.log('Prev click');
|
|
||||||
prevSwiperBtn.value.click();
|
prevSwiperBtn.value.click();
|
||||||
},
|
},
|
||||||
handleNext() {
|
handleNext() {
|
||||||
// console.log('Next click');
|
|
||||||
nextSwiperBtn.value.click();
|
nextSwiperBtn.value.click();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,10 +33,7 @@ export default defineComponent({
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: "",
|
||||||
},
|
},
|
||||||
isNew: {
|
isNew: String,
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
size: {
|
size: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "md-card",
|
default: "md-card",
|
||||||
|
@ -54,10 +51,8 @@ export default defineComponent({
|
||||||
const isLoaded = ref(false);
|
const isLoaded = ref(false);
|
||||||
const isError = ref(false);
|
const isError = ref(false);
|
||||||
const percent = +discount / 100;
|
const percent = +discount / 100;
|
||||||
//const priceWithoutLetter = ~~price?.replaceAll("€", "");
|
|
||||||
const priceWithoutLetter = price;
|
const priceWithoutLetter = price;
|
||||||
const finalValue = ~~(priceWithoutLetter - priceWithoutLetter * percent);
|
const finalValue = ~~(priceWithoutLetter - priceWithoutLetter * percent);
|
||||||
console.log(price);
|
|
||||||
|
|
||||||
const onLoad = () => {
|
const onLoad = () => {
|
||||||
isLoaded.value = true;
|
isLoaded.value = true;
|
||||||
|
|
|
@ -6,9 +6,7 @@ export default defineComponent({
|
||||||
name: "chat-component",
|
name: "chat-component",
|
||||||
components: { IconChat },
|
components: { IconChat },
|
||||||
setup() {
|
setup() {
|
||||||
const handleClick = () => {
|
const handleClick = () => {};
|
||||||
console.log("click");
|
|
||||||
};
|
|
||||||
return { handleClick };
|
return { handleClick };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,7 +18,6 @@ export default defineComponent({
|
||||||
|
|
||||||
function closeNav() {
|
function closeNav() {
|
||||||
isOpenNav.value = false;
|
isOpenNav.value = false;
|
||||||
console.log("foi click");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(isOpenNav, (newValue) => {
|
watch(isOpenNav, (newValue) => {
|
||||||
|
|
|
@ -129,7 +129,7 @@ export default defineComponent({
|
||||||
class="custom-date-input"
|
class="custom-date-input"
|
||||||
v-model="calendar"
|
v-model="calendar"
|
||||||
v-bind="calendarAttrs"
|
v-bind="calendarAttrs"
|
||||||
:error="!!errors.date"
|
:error="false"
|
||||||
placeholder="Elige una fecha"
|
placeholder="Elige una fecha"
|
||||||
mask="##/##/####"
|
mask="##/##/####"
|
||||||
dense
|
dense
|
||||||
|
@ -142,7 +142,7 @@ export default defineComponent({
|
||||||
class="custom-main-paragraph"
|
class="custom-main-paragraph"
|
||||||
v-model="postalCode"
|
v-model="postalCode"
|
||||||
v-bind="postalCodeAttrs"
|
v-bind="postalCodeAttrs"
|
||||||
:error="!!errors.postalCode"
|
:error="false"
|
||||||
placeholder="código postal"
|
placeholder="código postal"
|
||||||
mask="#####"
|
mask="#####"
|
||||||
dense
|
dense
|
||||||
|
|
|
@ -30,7 +30,6 @@ export default defineComponent({
|
||||||
const [terms, termsAttrs] = defineField("terms");
|
const [terms, termsAttrs] = defineField("terms");
|
||||||
|
|
||||||
const onSubmit = handleSubmit((values) => {
|
const onSubmit = handleSubmit((values) => {
|
||||||
console.log(values);
|
|
||||||
handleQuestionData(values);
|
handleQuestionData(values);
|
||||||
handleReset();
|
handleReset();
|
||||||
if (!terms.value) {
|
if (!terms.value) {
|
||||||
|
|
|
@ -321,8 +321,29 @@ body {
|
||||||
margin-bottom: -14px;
|
margin-bottom: -14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! QUASAR
|
.error-message {
|
||||||
|
min-height: 525px !important;
|
||||||
|
color: $primary;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
& h1 {
|
||||||
|
font-size: $font-40;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: $med-md) {
|
||||||
|
min-height: 400px !important;
|
||||||
|
|
||||||
|
& h1 {
|
||||||
|
line-height: 1.2;
|
||||||
|
font-size: $font-28;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! QUASAR
|
||||||
.q-virtual-scroll__content .q-item .q-item__label {
|
.q-virtual-scroll__content .q-item .q-item__label {
|
||||||
font-family: $font-questrial;
|
font-family: $font-questrial;
|
||||||
font-size: $font-14;
|
font-size: $font-14;
|
||||||
|
|
|
@ -2,21 +2,20 @@ import { toTypedSchema } from "@vee-validate/zod";
|
||||||
import { useForm } from "vee-validate";
|
import { useForm } from "vee-validate";
|
||||||
import { computed, reactive, ref } from "vue";
|
import { computed, reactive, ref } from "vue";
|
||||||
|
|
||||||
|
import { apiBack } from "src/boot/axios";
|
||||||
import { useFormStore } from "src/stores/forms";
|
import { useFormStore } from "src/stores/forms";
|
||||||
import { checkoutSchema } from "src/utils/zod/schemas";
|
import { checkoutSchema } from "src/utils/zod/schemas";
|
||||||
import { useRouter } from "vue-router";
|
|
||||||
import { useLocalStorage } from "./useLocalStorage";
|
import { useLocalStorage } from "./useLocalStorage";
|
||||||
|
|
||||||
export function useCheckoutForm() {
|
export function useCheckoutForm() {
|
||||||
const { getItem } = useLocalStorage();
|
const { addItem, getItem, removeItem } = useLocalStorage();
|
||||||
const { push } = useRouter()
|
|
||||||
|
|
||||||
const formStore = useFormStore();
|
const formStore = useFormStore();
|
||||||
const { handleCheckoutData } = formStore;
|
const { handleCheckoutData } = formStore;
|
||||||
const { meta, errors, handleSubmit, defineField, resetForm } = useForm({
|
const { meta, errors, handleSubmit, defineField, resetForm } = useForm({
|
||||||
validationSchema: toTypedSchema(checkoutSchema),
|
validationSchema: toTypedSchema(checkoutSchema),
|
||||||
initialValues: {
|
initialValues: {
|
||||||
paymentMethod: "stripe",
|
paymentMethod: "paypal",
|
||||||
terms: false,
|
terms: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -36,6 +35,11 @@ export function useCheckoutForm() {
|
||||||
const [paymentMethod, paymentMethodAttrs] = defineField("paymentMethod");
|
const [paymentMethod, paymentMethodAttrs] = defineField("paymentMethod");
|
||||||
const [terms, termsAttrs] = defineField("terms");
|
const [terms, termsAttrs] = defineField("terms");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//TODO hacer el await de las provincias
|
||||||
|
//const provinceOptions = getProvinces();
|
||||||
|
|
||||||
const provinceOptions = ref([
|
const provinceOptions = ref([
|
||||||
{ code: "01", name: "Araba/Álava" },
|
{ code: "01", name: "Araba/Álava" },
|
||||||
{ code: "02", name: "Albacete" },
|
{ code: "02", name: "Albacete" },
|
||||||
|
@ -90,7 +94,6 @@ export function useCheckoutForm() {
|
||||||
{ code: "51", name: "Ceuta" },
|
{ code: "51", name: "Ceuta" },
|
||||||
{ code: "52", name: "Melilla" },
|
{ code: "52", name: "Melilla" },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const stepActive = reactive({ data: 1 });
|
const stepActive = reactive({ data: 1 });
|
||||||
const stepList = reactive({
|
const stepList = reactive({
|
||||||
data: [
|
data: [
|
||||||
|
@ -122,27 +125,90 @@ export function useCheckoutForm() {
|
||||||
return step;
|
return step;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
const isError = ref(false);
|
||||||
|
const onError = () => {
|
||||||
|
isError.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
const handleClickStep = (value) => {
|
const handleClickStep = (value) => {
|
||||||
stepActive["data"] = value;
|
stepActive["data"] = value;
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkoutBlock = ref(true);
|
const checkoutBlock = ref(true);
|
||||||
const onSubmit = handleSubmit((values) => {
|
const cart = getItem("cart");
|
||||||
handleCheckoutData(values);
|
const availability = getItem("availability");
|
||||||
stepList.data[2].active = true;
|
const totalPrice = computed(() => {
|
||||||
checkoutBlock.value = false;
|
return cart?.reduce((acc, { price }) => {
|
||||||
resetForm();
|
if (price) {
|
||||||
|
//const priceWithoutLetter = price?.replace("€", "");
|
||||||
|
return +price + acc;
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
const cart = getItem("cart");
|
const isLoadingSubmit = ref(false);
|
||||||
const totalPrice = ref(0)
|
const isErrorSubmit = ref(false);
|
||||||
totalPrice.value = cart?.reduce((acc, { price }) => {
|
|
||||||
if (price) {
|
const onSuccess = async (values) => {
|
||||||
const priceWithoutLetter = price?.replace("€", "");
|
isLoadingSubmit.value = true;
|
||||||
return +priceWithoutLetter + acc;
|
stepsFormated.value[1].active = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const productsId = cart.map((item) => item.id);
|
||||||
|
|
||||||
|
const cartItensData = cart.map((item) => {
|
||||||
|
const { id, message, ...rest } = item;
|
||||||
|
|
||||||
|
if (message) {
|
||||||
|
return { id, message };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { id, message: "" };
|
||||||
|
});
|
||||||
|
|
||||||
|
const deliveryData = {
|
||||||
|
customerData: {
|
||||||
|
custumerName: `${values.name} ${values.surname}`,
|
||||||
|
email: values.senderEmail,
|
||||||
|
custumerPhone: values.phone,
|
||||||
|
},
|
||||||
|
itemData: cartItensData,
|
||||||
|
deliveryData: {
|
||||||
|
dated: availability.dateExpired,
|
||||||
|
deliveryName: values.senderName,
|
||||||
|
address: values.address,
|
||||||
|
postalCode: availability.postalCode,
|
||||||
|
deliveryPhone: values.senderPhone,
|
||||||
|
deliveryMessage: values.senderNotes,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
addItem("costumer", deliveryData);
|
||||||
|
|
||||||
|
const productData = {
|
||||||
|
products: productsId,
|
||||||
|
price: totalPrice.value.toFixed(2).toString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: { data },
|
||||||
|
} = await apiBack.post("payment", productData);
|
||||||
|
|
||||||
|
isLoadingSubmit.value = false;
|
||||||
|
location.href = data;
|
||||||
|
removeItem("cart");
|
||||||
|
removeItem("availability");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`FATAL ERROR ::: ${error}`);
|
||||||
|
|
||||||
|
isErrorSubmit.value = true;
|
||||||
|
isLoadingSubmit.value = false;
|
||||||
|
} finally {
|
||||||
|
handleCheckoutData(values);
|
||||||
|
resetForm();
|
||||||
}
|
}
|
||||||
}, 0);
|
};
|
||||||
|
|
||||||
|
const onSubmit = handleSubmit(onSuccess);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
handleClickStep,
|
handleClickStep,
|
||||||
|
@ -152,11 +218,13 @@ export function useCheckoutForm() {
|
||||||
checkoutBlock,
|
checkoutBlock,
|
||||||
cart,
|
cart,
|
||||||
totalPrice,
|
totalPrice,
|
||||||
|
isError,
|
||||||
|
onError,
|
||||||
formState: {
|
formState: {
|
||||||
meta,
|
meta,
|
||||||
errors,
|
errors,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
submitLoading: ref(false),
|
isLoadingSubmit,
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
name,
|
name,
|
||||||
|
|
|
@ -1,22 +1,39 @@
|
||||||
import { LocalStorage } from "quasar";
|
import { LocalStorage } from "quasar";
|
||||||
|
|
||||||
export function useLocalStorage() {
|
export function useLocalStorage() {
|
||||||
|
/**
|
||||||
|
* Adds an item to localStorage.
|
||||||
|
* @param {string} key - The key of the item to be added.
|
||||||
|
* @param {*} value - The value of the item to be added.
|
||||||
|
*/
|
||||||
const addItem = (key, value) => {
|
const addItem = (key, value) => {
|
||||||
LocalStorage.set(`@${key}`, value);
|
const stringifyValue = JSON.stringify(value);
|
||||||
|
|
||||||
|
LocalStorage.set(`@${key}`, stringifyValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves an item from the local storage based on the provided key.
|
||||||
|
*
|
||||||
|
* @param {string} key - The key of the item to retrieve.
|
||||||
|
* @returns {Object|Array} - The retrieved item from the local storage. If the key is "availability", it returns an object, otherwise it returns an array.
|
||||||
|
*/
|
||||||
const getItem = (key) => {
|
const getItem = (key) => {
|
||||||
const data = JSON.parse(LocalStorage.getItem(`@${key}`));
|
const data = JSON.parse(LocalStorage.getItem(`@${key}`));
|
||||||
|
|
||||||
|
if (key === "availability") return data || {};
|
||||||
return (data || []);
|
return data || [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an item from local storage.
|
||||||
|
*
|
||||||
|
* @param {string} key - The key of the item to remove.
|
||||||
|
*/
|
||||||
const removeItem = (key) => {
|
const removeItem = (key) => {
|
||||||
LocalStorage.remove(`@${key}`);
|
LocalStorage.remove(`@${key}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
addItem,
|
addItem,
|
||||||
getItem,
|
getItem,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { toTypedSchema } from "@vee-validate/zod";
|
import { toTypedSchema } from "@vee-validate/zod";
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
import { useForm } from "vee-validate";
|
import { useForm } from "vee-validate";
|
||||||
import { ref, watch } from "vue";
|
import { computed, ref, watch } from "vue";
|
||||||
import { useRoute, useRouter } from "vue-router";
|
import { useRoute, useRouter } from "vue-router";
|
||||||
|
|
||||||
import { invertDate } from "src/functions/invertDate";
|
import { invertDate } from "src/functions/invertDate";
|
||||||
|
@ -12,38 +12,45 @@ import { useModalStore } from "src/stores/modalStore";
|
||||||
import { useRangePriceStore } from "src/stores/rangePrice";
|
import { useRangePriceStore } from "src/stores/rangePrice";
|
||||||
import { availabilitySchema } from "src/utils/zod/schemas";
|
import { availabilitySchema } from "src/utils/zod/schemas";
|
||||||
import { rangePriceSchema } from "src/utils/zod/schemas/rangePriceSchema";
|
import { rangePriceSchema } from "src/utils/zod/schemas/rangePriceSchema";
|
||||||
|
import { useLocalStorage } from "./useLocalStorage";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom hook for managing the postal and calendar functionality.
|
* Custom hook for managing postal calendar functionality.
|
||||||
*
|
*
|
||||||
* @param {Object} options - The options for the hook.
|
* @param {Object} options - The options for the hook.
|
||||||
* @param {string} options.modalItem - The modal item isOpenAvailability || isOpenFilters.
|
* @param {string} options.modalItem - The modal item.
|
||||||
* @param {string} options.type - The type of the hook. home || product || availability || filter
|
* @param {string} options.type - The type of the calendar.
|
||||||
* @returns {Object} - The hook functions and data.
|
* @returns {Object} - The hook functions and properties.
|
||||||
*/
|
*/
|
||||||
export function usePostalCalendar({ modalItem = "", type = "home" }) {
|
export function usePostalCalendar({ modalItem = "", type = "home" }) {
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { push } = useRouter()
|
const { push, go } = useRouter();
|
||||||
|
const { addItem, getItem, removeItem } = useLocalStorage();
|
||||||
|
|
||||||
const rangePriceStore = useRangePriceStore();
|
const rangePriceStore = useRangePriceStore();
|
||||||
const { rangeValue } = storeToRefs(rangePriceStore);
|
const { rangeValue } = storeToRefs(rangePriceStore);
|
||||||
|
|
||||||
const modalStore = useModalStore();
|
const modalStore = useModalStore();
|
||||||
const { openModal } = modalStore
|
|
||||||
|
|
||||||
const formStore = useFormStore();
|
const formStore = useFormStore();
|
||||||
const { sortProductFilters } = storeToRefs(formStore);
|
const { sortProductFilters, availability: availabilityForm } =
|
||||||
|
storeToRefs(formStore);
|
||||||
|
|
||||||
const cartStore = useCartStore();
|
const cartStore = useCartStore();
|
||||||
const { addToCart, getProducts } = cartStore;
|
const { addToCart, getProducts } = cartStore;
|
||||||
const { products, homeSection } = storeToRefs(cartStore);
|
const { products, cart } = storeToRefs(cartStore);
|
||||||
|
|
||||||
const min = 0;
|
const min = 0;
|
||||||
const max = 200;
|
const max = 200;
|
||||||
const category = ref(route.path.split("/")[2])
|
const category = ref(route.path.split("/")[2]);
|
||||||
|
const availability = ref(getItem("availability"));
|
||||||
|
const isAvailabilityEmpty = computed(() => {
|
||||||
|
return Object.keys(availability.value).length === 0;
|
||||||
|
});
|
||||||
|
|
||||||
const { handleSubmit, handleReset, defineField, errors, setValues } = useForm(
|
const { handleSubmit, handleReset, defineField, errors, setValues } = useForm(
|
||||||
{
|
{
|
||||||
|
validateOnMount: false,
|
||||||
validationSchema: toTypedSchema(
|
validationSchema: toTypedSchema(
|
||||||
type !== "filter" ? availabilitySchema : rangePriceSchema
|
type !== "filter" ? availabilitySchema : rangePriceSchema
|
||||||
),
|
),
|
||||||
|
@ -55,129 +62,206 @@ export function usePostalCalendar({ modalItem = "", type = "home" }) {
|
||||||
postalCode: "",
|
postalCode: "",
|
||||||
date: "",
|
date: "",
|
||||||
},
|
},
|
||||||
|
initialTouched: {
|
||||||
|
date: false,
|
||||||
|
postalCode: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const [calendar, calendarAttrs] = defineField("date");
|
|
||||||
const [postalCode, postalCodeAttrs] = defineField("postalCode");
|
const options = {
|
||||||
const [priceRange, priceRangeAttrs] = defineField("range");
|
validateOnBlur: false,
|
||||||
|
validateOnChange: false,
|
||||||
|
validateOnInput: false,
|
||||||
|
validateOnModelUpdate: false,
|
||||||
|
};
|
||||||
|
const [calendar, calendarAttrs] = defineField("date", options);
|
||||||
|
const [postalCode, postalCodeAttrs] = defineField("postalCode", options);
|
||||||
|
const [priceRange, priceRangeAttrs] = defineField("range", options);
|
||||||
const [dedication, dedicationAttrs] = defineField("dedication");
|
const [dedication, dedicationAttrs] = defineField("dedication");
|
||||||
|
|
||||||
watch(errors, (newErrors) => {
|
watch(errors, (newErrors) => {
|
||||||
const errorsObj = {
|
const hasErrors = {
|
||||||
postalCode: () =>
|
range: newErrors.range,
|
||||||
quasarNotify({ message: newErrors.postalCode, type: "erro" }),
|
dedication: newErrors.dedication,
|
||||||
date: () => quasarNotify({ message: newErrors.date, type: "erro" }),
|
|
||||||
range: () => quasarNotify({ message: newErrors.range, type: "erro" }),
|
|
||||||
dedication: () =>
|
|
||||||
quasarNotify({ message: newErrors.dedication, type: "erro" }),
|
|
||||||
};
|
};
|
||||||
const keys = Object.keys(newErrors);
|
for (const [field, hasError] of Object.entries(hasErrors)) {
|
||||||
keys.forEach((key) => {
|
if (hasError) {
|
||||||
errorsObj[key]();
|
quasarNotify({ message: newErrors[field], type: "erro" });
|
||||||
});
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch([() => route.path, () => sortProductFilters.value], ([newPath]) => {
|
||||||
[() => route.path, () => sortProductFilters.value],
|
const categoryPath = newPath.split("/")[2];
|
||||||
([newPath]) => {
|
category.value = categoryPath;
|
||||||
const categoryPath = newPath.split("/")[2];
|
});
|
||||||
category.value = categoryPath;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const onSubmit = handleSubmit((values) => {
|
const removeCart = () => {
|
||||||
const postalAndDateParams = {
|
removeItem("cart");
|
||||||
postalCode: values.postalCode,
|
cart.value = [];
|
||||||
dateExpired: invertDate(values.date),
|
};
|
||||||
|
|
||||||
|
const onSuccess = async (values) => {
|
||||||
|
const handleAvailability = async () => {
|
||||||
|
addItem("availability", {
|
||||||
|
postalCode: values.postalCode,
|
||||||
|
dateExpired: invertDate(values.date),
|
||||||
|
});
|
||||||
|
removeCart();
|
||||||
|
availabilityForm.value.dateExpired = invertDate(values.date);
|
||||||
|
availabilityForm.value.postalCode = values.postalCode;
|
||||||
|
|
||||||
|
await getProducts({
|
||||||
|
postalCode: values.postalCode,
|
||||||
|
dateExpired: invertDate(values.date),
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const categoryObj = {
|
const handleHome = async () => {
|
||||||
plantas: "Floranet Plantas",
|
console.log(type);
|
||||||
ramos: "Floranet Ramos",
|
|
||||||
};
|
|
||||||
|
|
||||||
const objVal = {
|
addItem("availability", {
|
||||||
home: async () => {
|
postalCode: values.postalCode,
|
||||||
console.log(type);
|
dateExpired: invertDate(values.date),
|
||||||
|
});
|
||||||
|
availabilityForm.value.dateExpired = invertDate(values.date);
|
||||||
|
availabilityForm.value.postalCode = values.postalCode;
|
||||||
|
removeCart();
|
||||||
|
|
||||||
await getProducts(
|
const callback = async () => {
|
||||||
{
|
await push("/categoria/all");
|
||||||
postalCode: values.postalCode,
|
};
|
||||||
dateExpired: invertDate(values.date),
|
|
||||||
},
|
|
||||||
() => homeSection.value.scrollIntoView()
|
|
||||||
);
|
|
||||||
},
|
|
||||||
product: async () => {
|
|
||||||
console.log(type);
|
|
||||||
|
|
||||||
await getProducts(postalAndDateParams);
|
await getProducts(
|
||||||
|
{
|
||||||
const hasProduct = products.value.data.some((item) => {
|
|
||||||
const date = new Date(item.dateExpired);
|
|
||||||
const day = date.getDate();
|
|
||||||
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
||||||
const year = date.getFullYear();
|
|
||||||
const dateExpired = `${day}/${month}/${year}`;
|
|
||||||
|
|
||||||
const id = +route.path.split('/')[2];
|
|
||||||
|
|
||||||
return item.postalCode === values.postalCode && item.id === id && values.date <= dateExpired
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!hasProduct) {
|
|
||||||
push('/categoria/ramos')
|
|
||||||
quasarNotify({ message: 'Seleccione una nueva fecha y un nuevo código postal.', type: 'warning' })
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
openModal({ modal: 'availability' })
|
|
||||||
}, 2000)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
addToCart(products.value.current, dedication)
|
|
||||||
},
|
|
||||||
availability: async () => {
|
|
||||||
console.log(type);
|
|
||||||
|
|
||||||
await getProducts({
|
|
||||||
postalCode: values.postalCode,
|
postalCode: values.postalCode,
|
||||||
dateExpired: invertDate(values.date),
|
dateExpired: invertDate(values.date),
|
||||||
});
|
},
|
||||||
},
|
callback
|
||||||
filter: async () => {
|
);
|
||||||
console.log(type);
|
|
||||||
|
|
||||||
rangeValue.value.max = values.range.max;
|
|
||||||
rangeValue.value.min = values.range.min;
|
|
||||||
|
|
||||||
const params = {
|
|
||||||
type: categoryObj[category.value],
|
|
||||||
minPrice: values.range.min,
|
|
||||||
maxPrice: values.range.max,
|
|
||||||
};
|
|
||||||
|
|
||||||
await getProducts(params);
|
|
||||||
},
|
|
||||||
default: () => {
|
|
||||||
console.error(
|
|
||||||
`INVALID TYPE! TYPE: ${type}, ONLY HOME, PRODUCT AND FILTER ARE VALID!`
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
objVal[type]() || objVal["default"]();
|
|
||||||
|
const handleProduct = async () => {
|
||||||
|
console.log(type);
|
||||||
|
|
||||||
|
addItem("availability", {
|
||||||
|
postalCode: values.postalCode,
|
||||||
|
dateExpired: invertDate(values.date),
|
||||||
|
});
|
||||||
|
removeCart();
|
||||||
|
availabilityForm.value.dateExpired = invertDate(values.date);
|
||||||
|
availabilityForm.value.postalCode = values.postalCode;
|
||||||
|
|
||||||
|
await getProducts({
|
||||||
|
postalCode: values.postalCode,
|
||||||
|
dateExpired: invertDate(values.date),
|
||||||
|
});
|
||||||
|
|
||||||
|
const hasProduct = computed(() => {
|
||||||
|
return products.value.data.some((item) => {
|
||||||
|
const date = new Date(item.dateExpired);
|
||||||
|
const day = date.getDate();
|
||||||
|
const month = (date.getMonth() + 1).toString().padStart(2, "0");
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const dateExpired = `${day}/${month}/${year}`;
|
||||||
|
const dateSelected = values.date.replaceAll("-", "/");
|
||||||
|
|
||||||
|
const id = +route.path.split("/")[2];
|
||||||
|
|
||||||
|
console.log(item.postalCode === values.postalCode);
|
||||||
|
console.log(item.id === id);
|
||||||
|
console.log(dateSelected <= dateExpired);
|
||||||
|
|
||||||
|
return (
|
||||||
|
item.postalCode === values.postalCode &&
|
||||||
|
item.id === id &&
|
||||||
|
dateSelected <= dateExpired
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!hasProduct.value) {
|
||||||
|
quasarNotify({
|
||||||
|
message: "Código postal y fecha de caducidad añadidos con éxito",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// go();
|
||||||
|
addToCart(products.value.current, dedication);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFilter = async () => {
|
||||||
|
console.log(type);
|
||||||
|
|
||||||
|
rangeValue.value.max = values.range.max;
|
||||||
|
rangeValue.value.min = values.range.min;
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
type: categoryObj[category.value],
|
||||||
|
minPrice: values.range.min,
|
||||||
|
maxPrice: values.range.max,
|
||||||
|
};
|
||||||
|
console.log(params);
|
||||||
|
|
||||||
|
if (category.value === "all") {
|
||||||
|
params.postalCode = availability.value.postalCode;
|
||||||
|
params.dateExpired = availability.value.dateExpired;
|
||||||
|
|
||||||
|
const { type, ...rest } = params;
|
||||||
|
await getProducts({ ...rest });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getProducts(params);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDefault = () => {
|
||||||
|
console.error(
|
||||||
|
`INVALID TYPE! TYPE: ${type}, ONLY HOME, PRODUCT AND FILTER ARE VALID!`
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlers = {
|
||||||
|
availability: handleAvailability,
|
||||||
|
home: handleHome,
|
||||||
|
product: handleProduct,
|
||||||
|
filter: handleFilter,
|
||||||
|
default: handleDefault,
|
||||||
|
};
|
||||||
|
|
||||||
|
const handler = handlers[type] || handlers.default;
|
||||||
|
await handler();
|
||||||
|
|
||||||
if (modalItem) {
|
if (modalItem) {
|
||||||
modalStore[modalItem] = false;
|
modalStore[modalItem] = false;
|
||||||
}
|
}
|
||||||
handleReset();
|
handleReset();
|
||||||
});
|
};
|
||||||
|
|
||||||
|
const onError = ({ values, errors, results }) => {
|
||||||
|
const hasErrors = {
|
||||||
|
postalCode: !!errors.postalCode,
|
||||||
|
date: !!errors.date,
|
||||||
|
};
|
||||||
|
for (const [field, hasError] of Object.entries(hasErrors)) {
|
||||||
|
if (hasError) {
|
||||||
|
quasarNotify({ message: errors[field], type: "erro" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSubmit = handleSubmit(onSuccess, onError);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
onSubmit,
|
onSubmit,
|
||||||
setValues,
|
setValues,
|
||||||
|
handleReset,
|
||||||
modalStore,
|
modalStore,
|
||||||
|
isAvailabilityEmpty,
|
||||||
fields: {
|
fields: {
|
||||||
calendar,
|
calendar,
|
||||||
calendarAttrs,
|
calendarAttrs,
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
import { storeToRefs } from "pinia";
|
|
||||||
import { useCartStore } from "src/stores/cart";
|
|
||||||
import { useModalStore } from "src/stores/modalStore";
|
|
||||||
import { watch } from "vue";
|
|
||||||
import { useRoute } from "vue-router";
|
|
||||||
import { usePostalCalendar } from "./usePostalCalendar";
|
|
||||||
|
|
||||||
export function useProductPage() {
|
|
||||||
const route = useRoute();
|
|
||||||
|
|
||||||
const {
|
|
||||||
fields: { dedication, dedicationAttrs },
|
|
||||||
} = usePostalCalendar({ modalItem: "isOpenAvailability" });
|
|
||||||
|
|
||||||
const modalStore = useModalStore();
|
|
||||||
const { openModal } = modalStore;
|
|
||||||
|
|
||||||
const cartStore = useCartStore();
|
|
||||||
const { getProduct, getProducts } = cartStore;
|
|
||||||
const { products, featuredProducts, addCartLoadingBtn } =
|
|
||||||
storeToRefs(cartStore);
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => products.value.current?.type,
|
|
||||||
(newCategory) => {
|
|
||||||
getProducts({
|
|
||||||
// type: newCategory,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => route.params.id,
|
|
||||||
(newId) => {
|
|
||||||
getProduct(newId);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const checkImageValidity = (imageLink) => {
|
|
||||||
const validExtensions = [".jpg", ".jpeg", ".png"];
|
|
||||||
|
|
||||||
if (imageLink) {
|
|
||||||
const extension = imageLink.substring(imageLink.lastIndexOf("."));
|
|
||||||
return validExtensions.includes(extension.toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
return { checkImageValidity, openModal }
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
import { defineComponent, onBeforeMount, onUpdated, ref, watch } from "vue";
|
import { computed, defineComponent, onBeforeMount, ref, watch } from "vue";
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
|
|
||||||
import SortSelect from "src/components/@inputs/SortSelect.vue";
|
import SortSelect from "src/components/@inputs/SortSelect.vue";
|
||||||
|
@ -13,6 +13,9 @@ import Card from "src/components/ui/Card.vue";
|
||||||
import Container from "src/components/ui/Container.vue";
|
import Container from "src/components/ui/Container.vue";
|
||||||
import Modal from "src/components/ui/Modal.vue";
|
import Modal from "src/components/ui/Modal.vue";
|
||||||
|
|
||||||
|
import { quasarNotify } from "src/functions/quasarNotify";
|
||||||
|
import { useLocalStorage } from "src/hooks/useLocalStorage";
|
||||||
|
import { usePostalCalendar } from "src/hooks/usePostalCalendar";
|
||||||
import { useCartStore } from "src/stores/cart";
|
import { useCartStore } from "src/stores/cart";
|
||||||
import { useFormStore } from "src/stores/forms";
|
import { useFormStore } from "src/stores/forms";
|
||||||
import { useMobileStore } from "src/stores/mobileNav";
|
import { useMobileStore } from "src/stores/mobileNav";
|
||||||
|
@ -34,6 +37,10 @@ export default defineComponent({
|
||||||
setup() {
|
setup() {
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
|
const { getItem } = useLocalStorage();
|
||||||
|
|
||||||
|
const { isAvailabilityEmpty } = usePostalCalendar({});
|
||||||
|
|
||||||
const mobileStore = useMobileStore();
|
const mobileStore = useMobileStore();
|
||||||
const { screenWidth } = storeToRefs(mobileStore);
|
const { screenWidth } = storeToRefs(mobileStore);
|
||||||
|
|
||||||
|
@ -41,29 +48,19 @@ export default defineComponent({
|
||||||
const { openModal } = modalStore;
|
const { openModal } = modalStore;
|
||||||
|
|
||||||
const formStore = useFormStore();
|
const formStore = useFormStore();
|
||||||
const { availability, sortProductFilters } = storeToRefs(formStore);
|
const { sortProductFilters, availability } = storeToRefs(formStore);
|
||||||
|
|
||||||
const cartStore = useCartStore();
|
const cartStore = useCartStore();
|
||||||
const { products } = storeToRefs(cartStore);
|
const { products } = storeToRefs(cartStore);
|
||||||
const { getProducts } = cartStore;
|
const { getProducts } = cartStore;
|
||||||
|
|
||||||
const monthTest = ref("");
|
|
||||||
const isOpenOrder = ref(false);
|
const isOpenOrder = ref(false);
|
||||||
|
const availabilityStoraged = ref(getItem("availability"));
|
||||||
|
const isNotAllCategory = computed(() => {
|
||||||
|
return route.path.split("/")[2] !== "all";
|
||||||
|
});
|
||||||
|
const datePostalCode = ref({});
|
||||||
|
|
||||||
const monthES = {
|
|
||||||
0: "Enero",
|
|
||||||
1: "Febrero",
|
|
||||||
2: "Marzo",
|
|
||||||
3: "Abril",
|
|
||||||
4: "Mayo",
|
|
||||||
5: "Junio",
|
|
||||||
6: "Julio",
|
|
||||||
7: "Agosto",
|
|
||||||
8: "Septiembre",
|
|
||||||
9: "Octubre",
|
|
||||||
10: "Noviembre",
|
|
||||||
11: "Diciembre",
|
|
||||||
};
|
|
||||||
const orderText = {
|
const orderText = {
|
||||||
"lowest-price": "menor precio",
|
"lowest-price": "menor precio",
|
||||||
"highest-price": "mayor precio",
|
"highest-price": "mayor precio",
|
||||||
|
@ -74,12 +71,32 @@ export default defineComponent({
|
||||||
plantas: "Floranet Plantas",
|
plantas: "Floranet Plantas",
|
||||||
ramos: "Floranet Ramos",
|
ramos: "Floranet Ramos",
|
||||||
};
|
};
|
||||||
|
const dateExpiredMonth = computed(
|
||||||
|
() =>
|
||||||
|
availability.value.dateExpired?.split("-")[1] ||
|
||||||
|
availabilityStoraged.value.dateExpired?.split("-")[1]
|
||||||
|
);
|
||||||
|
const dateExpiredDay = computed(
|
||||||
|
() =>
|
||||||
|
availability.value.dateExpired?.split("-")[2] ||
|
||||||
|
availabilityStoraged.value.dateExpired?.split("-")[2]
|
||||||
|
);
|
||||||
|
|
||||||
watch(availability, (newDate) => {
|
const months = {
|
||||||
const [_day, month, _year] = newDate.date.split("/");
|
"01": "Enero",
|
||||||
monthTest.value = monthES[+month - 1];
|
"02": "Febrero",
|
||||||
console.log(monthTest.value);
|
"03": "Marzo",
|
||||||
});
|
"04": "Abril",
|
||||||
|
"05": "Mayo",
|
||||||
|
"06": "Junio",
|
||||||
|
"07": "Julio",
|
||||||
|
"08": "Agosto",
|
||||||
|
"09": "Septiembre",
|
||||||
|
10: "Octubre",
|
||||||
|
11: "Noviembre",
|
||||||
|
12: "Diciembre",
|
||||||
|
};
|
||||||
|
const currentMonth = months[dateExpiredMonth.value];
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
[() => route.path, () => sortProductFilters.value.order],
|
[() => route.path, () => sortProductFilters.value.order],
|
||||||
|
@ -87,14 +104,29 @@ export default defineComponent({
|
||||||
const categoryPath = newPath.split("/")[2];
|
const categoryPath = newPath.split("/")[2];
|
||||||
sortProductFilters.value.category = categoryPath;
|
sortProductFilters.value.category = categoryPath;
|
||||||
|
|
||||||
const params = {
|
const params = {};
|
||||||
type: categoryObj[categoryPath],
|
|
||||||
};
|
if (categoryPath !== "all") {
|
||||||
|
params.type = categoryObj[categoryPath];
|
||||||
|
}
|
||||||
|
if (categoryPath === "all") {
|
||||||
|
params.dateExpired = availabilityStoraged.value.dateExpired;
|
||||||
|
params.postalCode = availabilityStoraged.value.postalCode;
|
||||||
|
}
|
||||||
|
|
||||||
const paramsObj = {
|
const paramsObj = {
|
||||||
"lowest-price": () => (params.lowPrice = 1),
|
"lowest-price": () => {
|
||||||
"highest-price": () => (params.bigPrice = 1),
|
params.lowPrice = 1;
|
||||||
latest: () => (params.isNew = 1),
|
},
|
||||||
recommended: () => (params.recommend = 1),
|
"highest-price": () => {
|
||||||
|
params.bigPrice = 1;
|
||||||
|
},
|
||||||
|
latest: () => {
|
||||||
|
params.isNew = 1;
|
||||||
|
},
|
||||||
|
recommended: () => {
|
||||||
|
params.recommend = 1;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
if (newOrder) {
|
if (newOrder) {
|
||||||
paramsObj[newOrder]();
|
paramsObj[newOrder]();
|
||||||
|
@ -104,19 +136,35 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => route.path,
|
||||||
|
() => {
|
||||||
|
datePostalCode.value = isNotAllCategory.value
|
||||||
|
? availability.value
|
||||||
|
: availabilityStoraged.value;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
const categoryPath = route.path.split("/")[2];
|
const categoryPath = route.path.split("/")[2];
|
||||||
|
|
||||||
await getProducts({
|
if (categoryPath !== "all") {
|
||||||
type: categoryObj[categoryPath],
|
await getProducts({
|
||||||
});
|
type: categoryObj[categoryPath],
|
||||||
});
|
});
|
||||||
|
datePostalCode.value = availability.value;
|
||||||
|
|
||||||
onUpdated(() => {
|
return;
|
||||||
console.groupCollapsed("%c Updated!", "color: green;");
|
}
|
||||||
console.log(sortProductFilters.value);
|
|
||||||
console.log(availability.value);
|
await getProducts(availabilityStoraged.value);
|
||||||
console.groupEnd();
|
datePostalCode.value = availabilityStoraged.value;
|
||||||
|
if (isAvailabilityEmpty.value) {
|
||||||
|
quasarNotify({
|
||||||
|
message: "Debes seleccionar una fecha y código postal",
|
||||||
|
type: "warning",
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function openOrderFilter() {
|
function openOrderFilter() {
|
||||||
|
@ -128,12 +176,17 @@ export default defineComponent({
|
||||||
openOrderFilter,
|
openOrderFilter,
|
||||||
openModal,
|
openModal,
|
||||||
sortProductFilters,
|
sortProductFilters,
|
||||||
availability,
|
|
||||||
isOpenOrder,
|
isOpenOrder,
|
||||||
screenWidth,
|
screenWidth,
|
||||||
modalStore,
|
modalStore,
|
||||||
orderText,
|
orderText,
|
||||||
products,
|
products,
|
||||||
|
isNotAllCategory,
|
||||||
|
availabilityStoraged,
|
||||||
|
currentMonth,
|
||||||
|
dateExpiredDay,
|
||||||
|
datePostalCode,
|
||||||
|
availability,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -144,12 +197,10 @@ export default defineComponent({
|
||||||
<section class="products-section">
|
<section class="products-section">
|
||||||
<header class="products-section-header">
|
<header class="products-section-header">
|
||||||
<Container>
|
<Container>
|
||||||
<div class="product-header-content">
|
<div class="product-header-content" v-if="isNotAllCategory">
|
||||||
<h3 class="product-header-title subtitle">
|
<h3 class="product-header-title subtitle">
|
||||||
{{ sortProductFilters.category }} para obsequiar
|
{{ sortProductFilters.category }} para obsequiar
|
||||||
</h3>
|
</h3>
|
||||||
<p class="product-header-paragraph">
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="product-header-filters">
|
<div class="product-header-filters">
|
||||||
|
@ -158,11 +209,15 @@ export default defineComponent({
|
||||||
<p class="filter-paragraph availability">
|
<p class="filter-paragraph availability">
|
||||||
Disponibilidad para:
|
Disponibilidad para:
|
||||||
<span
|
<span
|
||||||
v-if="availability.date && availability.postalCode"
|
v-if="
|
||||||
|
datePostalCode.dateExpired && datePostalCode.postalCode
|
||||||
|
"
|
||||||
class="green-text"
|
class="green-text"
|
||||||
>
|
>
|
||||||
25 Julio en
|
{{ dateExpiredDay }} {{ currentMonth }} en
|
||||||
{{ availability.postalCode.replace("-", "") }}</span
|
{{
|
||||||
|
availability.postalCode || datePostalCode.postalCode
|
||||||
|
}}</span
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -232,8 +287,8 @@ export default defineComponent({
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="products-section-footer">
|
<footer class="products-section-footer" v-if="isNotAllCategory">
|
||||||
<RouterLink class="btn rounded outlined" to="/">
|
<RouterLink class="btn rounded outlined" to="/categoria/all">
|
||||||
Ver todos los diseños <IconArrowCircleFilledRight />
|
Ver todos los diseños <IconArrowCircleFilledRight />
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<template>
|
||||||
|
<q-page class="checkout-error-page error-message">
|
||||||
|
<container>
|
||||||
|
<h1>¡Uy! Algo ha ido mal durante el proceso de compra.</h1>
|
||||||
|
</container>
|
||||||
|
</q-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Container from "src/components/ui/Container.vue";
|
||||||
|
import { defineComponent } from "vue";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "CheckoutErrorPage",
|
||||||
|
components: { Container },
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.checkout-error-page {
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -20,7 +20,9 @@ export default defineComponent({
|
||||||
checkoutBlock,
|
checkoutBlock,
|
||||||
cart,
|
cart,
|
||||||
totalPrice,
|
totalPrice,
|
||||||
formState: { errors, meta, onSubmit, submitLoading },
|
isError,
|
||||||
|
onError,
|
||||||
|
formState: { errors, meta, onSubmit, isLoadingSubmit },
|
||||||
fields: {
|
fields: {
|
||||||
name,
|
name,
|
||||||
nameAttrs,
|
nameAttrs,
|
||||||
|
@ -57,11 +59,6 @@ export default defineComponent({
|
||||||
if (cart.length === 0) return push("/");
|
if (cart.length === 0) return push("/");
|
||||||
});
|
});
|
||||||
|
|
||||||
const isError = ref(false);
|
|
||||||
const onError = () => {
|
|
||||||
isError.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
handleClickStep,
|
handleClickStep,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
|
@ -74,7 +71,7 @@ export default defineComponent({
|
||||||
stepList,
|
stepList,
|
||||||
cart,
|
cart,
|
||||||
step: ref(1),
|
step: ref(1),
|
||||||
submitLoading,
|
isLoadingSubmit,
|
||||||
successURL: ref(""),
|
successURL: ref(""),
|
||||||
cancelURL: ref(""),
|
cancelURL: ref(""),
|
||||||
meta,
|
meta,
|
||||||
|
@ -439,10 +436,18 @@ export default defineComponent({
|
||||||
<q-radio
|
<q-radio
|
||||||
v-model="paymentMethod"
|
v-model="paymentMethod"
|
||||||
v-bind="paymentMethodAttrs"
|
v-bind="paymentMethodAttrs"
|
||||||
val="stripe"
|
val="paypal"
|
||||||
color="primary"
|
color="primary"
|
||||||
>
|
>
|
||||||
<p>Stripe <a href="#">¿Qué es Stripe?</a></p>
|
<p>
|
||||||
|
Paypal
|
||||||
|
<!-- <a
|
||||||
|
href="https://www.paypal.com/br/digital-wallet/how-paypal-works"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>¿Qué es Paypal?</a
|
||||||
|
> -->
|
||||||
|
</p>
|
||||||
</q-radio>
|
</q-radio>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -455,7 +460,13 @@ export default defineComponent({
|
||||||
</p>
|
</p>
|
||||||
</q-checkbox>
|
</q-checkbox>
|
||||||
|
|
||||||
<q-btn flat class="btn" type="submit" form="checkout-form">
|
<q-btn
|
||||||
|
flat
|
||||||
|
class="btn"
|
||||||
|
type="submit"
|
||||||
|
form="checkout-form"
|
||||||
|
:loading="isLoadingSubmit"
|
||||||
|
>
|
||||||
PROCEDER AL PAGO
|
PROCEDER AL PAGO
|
||||||
</q-btn>
|
</q-btn>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,313 @@
|
||||||
|
<script>
|
||||||
|
import { apiBack } from "src/boot/axios";
|
||||||
|
import { useCheckoutForm } from "src/hooks/useCheckoutForm";
|
||||||
|
import { useLocalStorage } from "src/hooks/useLocalStorage";
|
||||||
|
import { defineComponent, onBeforeMount, reactive, ref } from "vue";
|
||||||
|
import { useRoute, useRouter } from "vue-router";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "CheckoutSuccessPage",
|
||||||
|
setup() {
|
||||||
|
const { query } = useRoute();
|
||||||
|
const { push } = useRouter();
|
||||||
|
const { getItem, removeItem } = useLocalStorage();
|
||||||
|
console.log(query);
|
||||||
|
const costumerData = getItem("costumer");
|
||||||
|
|
||||||
|
const productsPurchased = reactive({ data: [] });
|
||||||
|
const totalPrice = ref();
|
||||||
|
|
||||||
|
async function getSuccessData() {
|
||||||
|
try {
|
||||||
|
productsPurchased.data = await new Promise(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
const {
|
||||||
|
data: { data },
|
||||||
|
} = await apiBack.post("payment/success", {
|
||||||
|
// params: query,
|
||||||
|
data: JSON.stringify({ customer: costumerData, ...query }),
|
||||||
|
});
|
||||||
|
resolve(data.products);
|
||||||
|
removeItem("costumer");
|
||||||
|
} catch (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
}).then((res) => res);
|
||||||
|
|
||||||
|
totalPrice.value = await productsPurchased.data.reduce(
|
||||||
|
(acc, { price }) => acc + Number(price),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`FATAL ERROR ::: ${error}`);
|
||||||
|
push("/checkout/error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onBeforeMount(async () => {
|
||||||
|
const queryObj = {
|
||||||
|
paymentId: query.paymentId,
|
||||||
|
productsIds: query.productsIds,
|
||||||
|
PayerID: query.PayerID,
|
||||||
|
};
|
||||||
|
for (const [_, value] of Object.entries(queryObj)) {
|
||||||
|
if (!value) return push("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
await getSuccessData();
|
||||||
|
console.log(productsPurchased.data);
|
||||||
|
});
|
||||||
|
|
||||||
|
const { isError, onError } = useCheckoutForm();
|
||||||
|
const steppers = [
|
||||||
|
{
|
||||||
|
value: 1,
|
||||||
|
name: "Paso 1",
|
||||||
|
description: "Datos de facturación",
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 2,
|
||||||
|
name: "Paso 2",
|
||||||
|
description: "Confirmación",
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 3,
|
||||||
|
name: "Paso 3",
|
||||||
|
description: "Pago",
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return { isError, onError, steppers, productsPurchased, totalPrice };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<q-page class="success-container">
|
||||||
|
<div class="checkout-steps">
|
||||||
|
<div
|
||||||
|
v-for="({ active, description, name, value }, i) in steppers"
|
||||||
|
class="step-item-container"
|
||||||
|
:key="i"
|
||||||
|
>
|
||||||
|
<div class="step-item">
|
||||||
|
<div class="circle-step-container">
|
||||||
|
<span class="border-step" :class="[i == 0 && 'transparent']" />
|
||||||
|
|
||||||
|
<div class="circle-step" :class="active && 'active'">
|
||||||
|
<span class="step-value">{{ value }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="border-step"
|
||||||
|
:class="[i == steppers.length - 1 && 'transparent']"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="step-content">
|
||||||
|
<div class="title">
|
||||||
|
<h4>{{ name }}</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="description">
|
||||||
|
<p>{{ description }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="checkout-success" id="success-block">
|
||||||
|
<h6 class="checkout-success-title green-text">
|
||||||
|
Has efectuado la siguiente compra
|
||||||
|
</h6>
|
||||||
|
|
||||||
|
<div class="checkout-success-body">
|
||||||
|
<div class="checkout-success-content">
|
||||||
|
<ul class="checkout-success-list">
|
||||||
|
<li
|
||||||
|
v-for="({ name, price, image }, index) in productsPurchased.data"
|
||||||
|
:key="index"
|
||||||
|
class="checkout-success-item"
|
||||||
|
>
|
||||||
|
<div class="checkout-item-content">
|
||||||
|
<div class="checkout-product-details">
|
||||||
|
<img
|
||||||
|
:src="isError ? '../assets/empty-img.jpg' : image"
|
||||||
|
:alt="name"
|
||||||
|
class="checkout-product-img"
|
||||||
|
@error="onError"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<p class="checkout-product-title">
|
||||||
|
{{ name }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="checkout-product-price">{{ price }}€</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="checkout-success-footer">
|
||||||
|
<p class="checkout-success-paragraph">Total</p>
|
||||||
|
<p class="checkout-success-paragraph">{{ totalPrice }}€</p>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.success-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkout-steps {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-item-container {
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-step {
|
||||||
|
width: 90px;
|
||||||
|
height: 1px;
|
||||||
|
background-color: $primary-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle-step-container {
|
||||||
|
display: grid;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
grid-template-columns: 1fr auto 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle-step {
|
||||||
|
width: 56px;
|
||||||
|
height: 56px;
|
||||||
|
border: 1px solid $primary-dark;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
user-select: none;
|
||||||
|
.step-value {
|
||||||
|
font-family: $font-questrial;
|
||||||
|
color: $primary-dark;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
background-color: $primary-dark;
|
||||||
|
.step-value {
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
font-family: $font-questrial;
|
||||||
|
h4 {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: $text-default;
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: $text-default;
|
||||||
|
font-family: $font-lora;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkout-success {
|
||||||
|
width: min(100%, 499px);
|
||||||
|
margin: 122px auto 0;
|
||||||
|
text-align: center;
|
||||||
|
& .checkout-success-title {
|
||||||
|
margin-bottom: 26px;
|
||||||
|
}
|
||||||
|
& .checkout-success-body {
|
||||||
|
& .checkout-success-content {
|
||||||
|
background-color: $secondary-5;
|
||||||
|
padding: 30px 46px 42px 38px;
|
||||||
|
border-radius: 5px 5px 0px 0px;
|
||||||
|
& .checkout-success-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 28px;
|
||||||
|
& .checkout-success-item {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
& .checkout-item-content {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex: 1;
|
||||||
|
min-height: 61px;
|
||||||
|
& .checkout-product-details {
|
||||||
|
display: flex;
|
||||||
|
gap: 14px;
|
||||||
|
& .checkout-product-img {
|
||||||
|
object-fit: cover;
|
||||||
|
width: 54px;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .checkout-product-title {
|
||||||
|
font-size: $font-12;
|
||||||
|
line-height: 21px;
|
||||||
|
letter-spacing: 0.24px;
|
||||||
|
font-family: $font-questrial;
|
||||||
|
color: $text-default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& .checkout-product-price {
|
||||||
|
color: $text-muted-one;
|
||||||
|
font-family: $font-roboto;
|
||||||
|
font-size: $font-12;
|
||||||
|
line-height: 21px;
|
||||||
|
letter-spacing: 0.24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: $med-lg) {
|
||||||
|
padding-right: 9px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& .checkout-success-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: $secondary-40;
|
||||||
|
border-radius: 0px 0px 5px 5px;
|
||||||
|
padding: 14px 46px 7px 36px;
|
||||||
|
|
||||||
|
& .checkout-success-paragraph {
|
||||||
|
font-family: $font-lora;
|
||||||
|
letter-spacing: 0.32px;
|
||||||
|
line-height: 21px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: $text-muted-one;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,21 +0,0 @@
|
||||||
<script>
|
|
||||||
import { defineComponent } from "vue";
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: "ExamplePage",
|
|
||||||
components: {},
|
|
||||||
setup() {
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quam rerum omnis
|
|
||||||
repellat. Harum ducimus nulla repellendus neque officia eveniet corporis
|
|
||||||
odio sequi animi ut, non incidunt est error esse aperiam?
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
|
@ -62,8 +62,7 @@ export default defineComponent({
|
||||||
Diseños de ramos más vendidos
|
Diseños de ramos más vendidos
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<p class="products-header-paragraph section-paragraph">
|
<p class="products-header-paragraph section-paragraph"></p>
|
||||||
</p>
|
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="products-body">
|
<div class="products-body">
|
||||||
|
@ -85,7 +84,7 @@ export default defineComponent({
|
||||||
</template>
|
</template>
|
||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
<RouterLink class="btn rounded outlined" to="/">
|
<RouterLink class="btn rounded outlined" to="/categoria/all">
|
||||||
Ver todos los diseños <IconArrowCircleFilledRight />
|
Ver todos los diseños <IconArrowCircleFilledRight />
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</div>
|
</div>
|
||||||
|
@ -97,8 +96,7 @@ export default defineComponent({
|
||||||
Nuestra selección de plantas para el verano
|
Nuestra selección de plantas para el verano
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<p class="products-selection-paragraph section-paragraph">
|
<p class="products-selection-paragraph section-paragraph"></p>
|
||||||
</p>
|
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="products-selection-body">
|
<div class="products-selection-body">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
import { useMeta } from "quasar";
|
import { useMeta } from "quasar";
|
||||||
import { defineComponent, onBeforeMount, ref, watch } from "vue";
|
import { computed, defineComponent, onBeforeMount, ref, watch } from "vue";
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
|
|
||||||
import IconArrowCircleFilledLeft from "components/icons/IconArrowCircleFilledLeft.vue";
|
import IconArrowCircleFilledLeft from "components/icons/IconArrowCircleFilledLeft.vue";
|
||||||
|
@ -18,8 +18,10 @@ import Card from "components/ui/Card.vue";
|
||||||
import Container from "components/ui/Container.vue";
|
import Container from "components/ui/Container.vue";
|
||||||
import Modal from "components/ui/Modal.vue";
|
import Modal from "components/ui/Modal.vue";
|
||||||
|
|
||||||
|
import { useLocalStorage } from "src/hooks/useLocalStorage";
|
||||||
import { usePostalCalendar } from "src/hooks/usePostalCalendar";
|
import { usePostalCalendar } from "src/hooks/usePostalCalendar";
|
||||||
import { useCartStore } from "stores/cart";
|
import { useCartStore } from "stores/cart";
|
||||||
|
import { useFormStore } from "stores/forms";
|
||||||
import { useModalStore } from "stores/modalStore";
|
import { useModalStore } from "stores/modalStore";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
@ -41,28 +43,48 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
const { getItem } = useLocalStorage();
|
||||||
|
|
||||||
|
const formStore = useFormStore();
|
||||||
|
const { availability: availabilityForm } = storeToRefs(formStore);
|
||||||
|
|
||||||
|
const availability = ref(getItem("availability"));
|
||||||
|
const filteredAvailabilityForm = computed(() => {
|
||||||
|
return Object.fromEntries(
|
||||||
|
Object.entries(availabilityForm.value).filter(
|
||||||
|
([key, value]) => value !== ""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const isAvailabilityEmpty = computed(() => {
|
||||||
|
return (
|
||||||
|
Object.keys(filteredAvailabilityForm.value || availability.value)
|
||||||
|
.length === 0
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
handleReset,
|
||||||
fields: { dedication, dedicationAttrs },
|
fields: { dedication, dedicationAttrs },
|
||||||
} = usePostalCalendar({ modalItem: "isOpenAvailability" });
|
} = usePostalCalendar({ modalItem: "isOpenAvailability", type: "product" });
|
||||||
|
|
||||||
const modalStore = useModalStore();
|
const modalStore = useModalStore();
|
||||||
const { openModal } = modalStore;
|
const { openModal } = modalStore;
|
||||||
|
|
||||||
const cartStore = useCartStore();
|
const cartStore = useCartStore();
|
||||||
const { getProduct, getProducts } = cartStore;
|
const { getProduct, getProducts, addToCart } = cartStore;
|
||||||
const { products, featuredProducts, addCartLoadingBtn } =
|
const { products, addCartLoadingBtn } = storeToRefs(cartStore);
|
||||||
storeToRefs(cartStore);
|
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(async () => {
|
||||||
getProduct(route.params.id);
|
await getProduct(route.params.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => products.value.current?.type,
|
() => products.value.current?.type,
|
||||||
(newCategory) => {
|
(newCategory) => {
|
||||||
getProducts({
|
getProducts({
|
||||||
// type: newCategory,
|
type: newCategory,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -74,33 +96,34 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
useMeta(() => ({
|
useMeta(() => {
|
||||||
title: `${products.value.current?.title}`,
|
return {
|
||||||
titleTemplate: (title) => `${title} - FloraNet`,
|
title: "FloraNet",
|
||||||
meta: {
|
meta: {
|
||||||
description: {
|
description: {
|
||||||
name: "description",
|
name: "description",
|
||||||
content: `${products.value.current?.description}`,
|
content: `${products.value.current?.description}`,
|
||||||
},
|
},
|
||||||
keywords: {
|
keywords: {
|
||||||
name: "keywords",
|
name: "keywords",
|
||||||
content: `${products.value.current?.title}`,
|
content: `${products.value.current?.title}`,
|
||||||
},
|
},
|
||||||
equiv: {
|
equiv: {
|
||||||
"http-equiv": "Content-Type",
|
"http-equiv": "Content-Type",
|
||||||
content: "text/html; charset=UTF-8",
|
content: "text/html; charset=UTF-8",
|
||||||
},
|
},
|
||||||
ogTitle: {
|
ogTitle: {
|
||||||
property: "og:title",
|
property: "og:title",
|
||||||
template(ogTitle) {
|
template(ogTitle) {
|
||||||
return `${ogTitle} - FloraNet`;
|
return `${ogTitle} - FloraNet`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
noscript: {
|
||||||
|
default: "This is content for browsers with no JS (or disabled JS)",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
noscript: {
|
};
|
||||||
default: "This is content for browsers with no JS (or disabled JS)",
|
});
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
const checkImageValidity = (imageLink) => {
|
const checkImageValidity = (imageLink) => {
|
||||||
const validExtensions = [".jpg", ".jpeg", ".png"];
|
const validExtensions = [".jpg", ".jpeg", ".png"];
|
||||||
|
@ -113,15 +136,28 @@ export default defineComponent({
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const addModal = () => {
|
||||||
|
if (!isAvailabilityEmpty.value) {
|
||||||
|
addToCart(products.value.current, dedication);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
openModal({ modal: "availability" });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePagClick = () => {
|
||||||
|
handleReset();
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
addModal,
|
||||||
openModal,
|
openModal,
|
||||||
|
handlePagClick,
|
||||||
checkImageValidity,
|
checkImageValidity,
|
||||||
slide: ref(1),
|
slide: ref(1),
|
||||||
fullscreen: ref(false),
|
fullscreen: ref(false),
|
||||||
dedication,
|
dedication,
|
||||||
dedicationAttrs,
|
dedicationAttrs,
|
||||||
products,
|
products,
|
||||||
featuredProducts,
|
|
||||||
addCartLoadingBtn,
|
addCartLoadingBtn,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -156,9 +192,9 @@ export default defineComponent({
|
||||||
<span class="green-text" style="display: inline-flex">
|
<span class="green-text" style="display: inline-flex">
|
||||||
{{ products.current?.id }}
|
{{ products.current?.id }}
|
||||||
<q-skeleton
|
<q-skeleton
|
||||||
|
v-if="!products.current?.id"
|
||||||
width="100px"
|
width="100px"
|
||||||
type="text"
|
type="text"
|
||||||
v-if="!products.current?.id"
|
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
|
@ -168,9 +204,9 @@ export default defineComponent({
|
||||||
<span class="green-text">
|
<span class="green-text">
|
||||||
{{ products.current?.type }}
|
{{ products.current?.type }}
|
||||||
<q-skeleton
|
<q-skeleton
|
||||||
|
v-if="!products.current?.type"
|
||||||
type="text"
|
type="text"
|
||||||
width="50px"
|
width="50px"
|
||||||
v-if="!products.current?.type"
|
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
|
@ -182,10 +218,10 @@ export default defineComponent({
|
||||||
<p class="product-price green-text">
|
<p class="product-price green-text">
|
||||||
{{ products.current?.price }}€
|
{{ products.current?.price }}€
|
||||||
<q-skeleton
|
<q-skeleton
|
||||||
|
v-if="!products.current?.price"
|
||||||
type="text"
|
type="text"
|
||||||
height="90px"
|
height="90px"
|
||||||
width="80px"
|
width="80px"
|
||||||
v-if="!products.current?.price"
|
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<p class="product-delivery green-text">Envío Gratuito</p>
|
<p class="product-delivery green-text">Envío Gratuito</p>
|
||||||
|
@ -227,7 +263,7 @@ export default defineComponent({
|
||||||
color="primary"
|
color="primary"
|
||||||
class="btn sm-btn"
|
class="btn sm-btn"
|
||||||
label="AÑADIR AL CARRITO"
|
label="AÑADIR AL CARRITO"
|
||||||
@click="openModal({ modal: 'availability' })"
|
@click="addModal"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -254,7 +290,7 @@ export default defineComponent({
|
||||||
color="white"
|
color="white"
|
||||||
class="btn outlined rounded sm-btn product-pag-item product-prev-btn"
|
class="btn outlined rounded sm-btn product-pag-item product-prev-btn"
|
||||||
:to="`${+$route.params.id - 1}`"
|
:to="`${+$route.params.id - 1}`"
|
||||||
@click="products.current.value = undefined"
|
@click="handlePagClick"
|
||||||
>
|
>
|
||||||
<IconArrowCircleFilledLeft />
|
<IconArrowCircleFilledLeft />
|
||||||
|
|
||||||
|
@ -271,6 +307,7 @@ export default defineComponent({
|
||||||
color="white"
|
color="white"
|
||||||
class="btn outlined rounded sm-btn product-pag-item product-next-btn"
|
class="btn outlined rounded sm-btn product-pag-item product-next-btn"
|
||||||
:to="`${+$route.params.id + 1}`"
|
:to="`${+$route.params.id + 1}`"
|
||||||
|
@click="handlePagClick"
|
||||||
>
|
>
|
||||||
<div class="btn-pag-paragraphs">
|
<div class="btn-pag-paragraphs">
|
||||||
<p class="btn-paragraph-top green-text">Siguiente producto</p>
|
<p class="btn-paragraph-top green-text">Siguiente producto</p>
|
||||||
|
@ -293,8 +330,7 @@ export default defineComponent({
|
||||||
Quizás también te gusten estos ramos
|
Quizás también te gusten estos ramos
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<p class="like-another-paragraph">
|
<p class="like-another-paragraph"></p>
|
||||||
</p>
|
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<Container cardContainer class="no-padding">
|
<Container cardContainer class="no-padding">
|
||||||
|
@ -361,6 +397,7 @@ export default defineComponent({
|
||||||
height: 396px;
|
height: 396px;
|
||||||
& .q-carousel__navigation {
|
& .q-carousel__navigation {
|
||||||
bottom: -83px;
|
bottom: -83px;
|
||||||
|
display: block;
|
||||||
& .q-carousel__navigation-inner {
|
& .q-carousel__navigation-inner {
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
& .q-carousel__thumbnail {
|
& .q-carousel__thumbnail {
|
||||||
|
|
|
@ -26,6 +26,11 @@ const routes = [
|
||||||
name: "Plantas",
|
name: "Plantas",
|
||||||
component: () => import("pages/CategoryPage.vue"),
|
component: () => import("pages/CategoryPage.vue"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "all",
|
||||||
|
name: "All",
|
||||||
|
component: () => import("pages/CategoryPage.vue"),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -37,7 +42,17 @@ const routes = [
|
||||||
path: "",
|
path: "",
|
||||||
name: "Checkout",
|
name: "Checkout",
|
||||||
component: () => import("pages/CheckoutPage.vue"),
|
component: () => import("pages/CheckoutPage.vue"),
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
path: "success",
|
||||||
|
name: "CheckoutSuccess",
|
||||||
|
component: () => import("pages/CheckoutSuccessPage.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "error",
|
||||||
|
name: "CheckoutError",
|
||||||
|
component: () => import("pages/CheckoutErrorPage.vue"),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,40 +1,55 @@
|
||||||
import { defineStore } from "pinia";
|
import { defineStore, storeToRefs } from "pinia";
|
||||||
import { ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
|
|
||||||
import { apiBack } from "src/boot/axios";
|
import { apiBack } from "src/boot/axios";
|
||||||
import { quasarNotify } from "src/functions/quasarNotify";
|
import { quasarNotify } from "src/functions/quasarNotify";
|
||||||
import { useLocalStorage } from "src/hooks/useLocalStorage";
|
import { useLocalStorage } from "src/hooks/useLocalStorage";
|
||||||
|
import { useFormStore } from "./forms";
|
||||||
|
|
||||||
export const useCartStore = defineStore("cart", () => {
|
export const useCartStore = defineStore("cart", () => {
|
||||||
const { push } = useRouter();
|
const { push } = useRouter();
|
||||||
const { addItem, getItem, removeItem } = useLocalStorage()
|
const { addItem, getItem } = useLocalStorage();
|
||||||
|
|
||||||
|
const formStore = useFormStore();
|
||||||
|
const { availability: availabilityForm } = storeToRefs(formStore);
|
||||||
|
|
||||||
//! Elements
|
//! Elements
|
||||||
const checkoutRef = ref(null);
|
const checkoutRef = ref(null);
|
||||||
const homeSection = ref(null);
|
const homeSection = ref(null);
|
||||||
|
|
||||||
const initialValues = [{
|
const initialValues = [
|
||||||
id: null,
|
{
|
||||||
name: "",
|
id: null,
|
||||||
price: null,
|
name: "",
|
||||||
image: "",
|
price: null,
|
||||||
description: "",
|
image: "",
|
||||||
dateExpired: "",
|
description: "",
|
||||||
isNew: null,
|
dateExpired: "",
|
||||||
type: "",
|
isNew: null,
|
||||||
postalCode: "",
|
type: "",
|
||||||
order_position: null,
|
postalCode: "",
|
||||||
recommend: null
|
order_position: null,
|
||||||
}]
|
recommend: null,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
//! Variables
|
//! Variables
|
||||||
const cart = ref([]);
|
const cart = ref(getItem("cart"));
|
||||||
|
const availability = ref(getItem("availability"));
|
||||||
(() => {
|
const filteredAvailabilityForm = computed(() => {
|
||||||
cart.value = getItem('cart');
|
return Object.fromEntries(
|
||||||
})()
|
Object.entries(availabilityForm.value).filter(
|
||||||
|
([key, value]) => value !== ""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
const isAvailabilityEmpty = computed(() => {
|
||||||
|
return (
|
||||||
|
Object.keys(filteredAvailabilityForm.value || availability.value)
|
||||||
|
.length === 0
|
||||||
|
);
|
||||||
|
});
|
||||||
const addCartLoadingBtn = ref(false);
|
const addCartLoadingBtn = ref(false);
|
||||||
const routeId = ref(null);
|
const routeId = ref(null);
|
||||||
const products = ref({
|
const products = ref({
|
||||||
|
@ -43,44 +58,8 @@ export const useCartStore = defineStore("cart", () => {
|
||||||
current: initialValues,
|
current: initialValues,
|
||||||
next: initialValues,
|
next: initialValues,
|
||||||
});
|
});
|
||||||
const featuredProducts = ref({
|
|
||||||
page: undefined,
|
|
||||||
productsPerPage: undefined,
|
|
||||||
products: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
function transformOptionsToParams(options = {}) {
|
||||||
* Transforms options object into params object.
|
|
||||||
*
|
|
||||||
* @param {Object} options - The options object.
|
|
||||||
* @param {number} options.itens - The items array.
|
|
||||||
* @param {boolean} options.featured - The featured flag.
|
|
||||||
* @param {number} options.page - The page number.
|
|
||||||
* @param {string} options.type - The type name.
|
|
||||||
* @param {string} options.postalCode - The postal code.
|
|
||||||
* @param {string} options.dateExpired - The expiration date.
|
|
||||||
* @param {number} options.minPrice - The minimum price.
|
|
||||||
* @param {number} options.maxPrice - The maximum price.
|
|
||||||
* @param {number} options.bigPrice - The big price.
|
|
||||||
* @param {number} options.lowPrice - The low price.
|
|
||||||
* @param {boolean} options.isNew - The new flag.
|
|
||||||
* @returns {Object} - The params object.
|
|
||||||
*/
|
|
||||||
function transformOptionsToParams(
|
|
||||||
options = {
|
|
||||||
postalCode: undefined,
|
|
||||||
dateExpired: undefined,
|
|
||||||
type: undefined,
|
|
||||||
minPrice: undefined,
|
|
||||||
maxPrice: undefined,
|
|
||||||
bigPrice: undefined,
|
|
||||||
lowPrice: undefined,
|
|
||||||
isNew: undefined,
|
|
||||||
order_crescent: undefined,
|
|
||||||
order_descending: undefined,
|
|
||||||
recommend: undefined,
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
const optionsObj = {
|
const optionsObj = {
|
||||||
postalCode: options.postalCode,
|
postalCode: options.postalCode,
|
||||||
dateExpired: options.dateExpired,
|
dateExpired: options.dateExpired,
|
||||||
|
@ -105,24 +84,7 @@ export const useCartStore = defineStore("cart", () => {
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
const isEmpty = ref(false);
|
||||||
* Fetches products based on the provided options.
|
|
||||||
*
|
|
||||||
* @param {Object} options - The options for fetching products.
|
|
||||||
* @param {number} options.itens - The items to fetch.
|
|
||||||
* @param {boolean} options.featured - Whether to fetch only featured products.
|
|
||||||
* @param {number} options.page - The page number to fetch.
|
|
||||||
* @param {string} options.type - The type of products to fetch.
|
|
||||||
* @param {string} options.postalCode - The postal code for filtering products.
|
|
||||||
* @param {string} options.dateExpired - The expiration date for filtering products.
|
|
||||||
* @param {number} options.minPrice - The minimum price for filtering products.
|
|
||||||
* @param {number} options.maxPrice - The maximum price for filtering products.
|
|
||||||
* @param {number} options.bigPrice - The big price for filtering products.
|
|
||||||
* @param {number} options.lowPrice - The low price for filtering products.
|
|
||||||
* @param {boolean} options.isNew - Whether to fetch only new products.
|
|
||||||
* @param {Function} navigate - The navigation function to call after fetching products.
|
|
||||||
* @returns {Promise<void>} - A promise that resolves when the products are fetched.
|
|
||||||
*/
|
|
||||||
async function getProducts(
|
async function getProducts(
|
||||||
options = {
|
options = {
|
||||||
postalCode: undefined,
|
postalCode: undefined,
|
||||||
|
@ -137,16 +99,17 @@ export const useCartStore = defineStore("cart", () => {
|
||||||
order_descending: undefined,
|
order_descending: undefined,
|
||||||
recommend: undefined,
|
recommend: undefined,
|
||||||
},
|
},
|
||||||
scrollIntoView = () => { }
|
callback
|
||||||
) {
|
) {
|
||||||
const params = transformOptionsToParams(options);
|
const params = transformOptionsToParams(options);
|
||||||
console.log(params);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { data: { data } } = await apiBack.get("products", { params });
|
const {
|
||||||
|
data: { data },
|
||||||
|
} = await apiBack.get("products", { params });
|
||||||
|
|
||||||
if (data.length === 0) {
|
if (data.length === 0) {
|
||||||
|
isEmpty.value = true;
|
||||||
return quasarNotify({
|
return quasarNotify({
|
||||||
message:
|
message:
|
||||||
"No hay productos disponibles para la fecha y el código postal seleccionados",
|
"No hay productos disponibles para la fecha y el código postal seleccionados",
|
||||||
|
@ -154,10 +117,11 @@ export const useCartStore = defineStore("cart", () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isEmpty.value = false;
|
||||||
products.value.data = data;
|
products.value.data = data;
|
||||||
|
|
||||||
if (scrollIntoView) {
|
if (callback) {
|
||||||
scrollIntoView();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
console.groupCollapsed("%c PRODUCTS FETCHED!", "color: green;");
|
console.groupCollapsed("%c PRODUCTS FETCHED!", "color: green;");
|
||||||
|
@ -182,17 +146,6 @@ export const useCartStore = defineStore("cart", () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches a product by its ID and updates the cart state.
|
|
||||||
*
|
|
||||||
* @param {string} id - The ID of the product to fetch.
|
|
||||||
* @param {object} options - Additional options for the product fetch.
|
|
||||||
* @param {string} options.type - The type of the product.
|
|
||||||
* @param {string} options.postalCode - The postal code for location-based filtering.
|
|
||||||
* @param {string} options.dateExpired - The expiration date for time-based filtering.
|
|
||||||
* @param {boolean} debug - Flag indicating whether to enable debug mode.
|
|
||||||
* @returns {Promise<void>} - A promise that resolves when the product is fetched and the cart state is updated.
|
|
||||||
*/
|
|
||||||
async function getProduct(
|
async function getProduct(
|
||||||
id,
|
id,
|
||||||
options = {
|
options = {
|
||||||
|
@ -220,14 +173,14 @@ export const useCartStore = defineStore("cart", () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return result[res.status].data[0];
|
return result[res.status].data[0];
|
||||||
})
|
});
|
||||||
|
|
||||||
products.value.prev = prev;
|
products.value.prev = prev;
|
||||||
products.value.current = current;
|
products.value.current = current;
|
||||||
products.value.next = next;
|
products.value.next = next;
|
||||||
|
|
||||||
if (!current) {
|
if (!current) {
|
||||||
push({ name: "NotFound" })
|
push({ name: "NotFound" });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
|
@ -250,92 +203,48 @@ export const useCartStore = defineStore("cart", () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
async function addToCart(product, message) {
|
||||||
* Retrieves featured products based on the provided options.
|
const params = transformOptionsToParams(
|
||||||
*
|
availabilityForm.value || availability.value
|
||||||
* @param {Object} options - The options for retrieving featured products.
|
);
|
||||||
* @param {number} options.itens - The number of items to retrieve.
|
await getProducts(params);
|
||||||
* @param {number} options.featured - The flag indicating if the products should be featured.
|
|
||||||
* @param {number} [options.page] - The page number for pagination.
|
|
||||||
* @param {string} [options.type] - The type of the products.
|
|
||||||
* @param {string} [options.postalCode] - The postal code for location-based filtering.
|
|
||||||
* @param {string} [options.dateExpired] - The expiration date for filtering.
|
|
||||||
* @param {number} [options.minPrice] - The minimum price for filtering.
|
|
||||||
* @param {number} [options.maxPrice] - The maximum price for filtering.
|
|
||||||
* @param {number} [options.bigPrice] - The big price for filtering.
|
|
||||||
* @param {number} [options.lowPrice] - The low price for filtering.
|
|
||||||
* @param {boolean} [options.isNew] - The flag indicating if the products are new.
|
|
||||||
* @returns {Promise<void>} - A promise that resolves when the featured products are retrieved.
|
|
||||||
*/
|
|
||||||
async function getFeaturedProducts(
|
|
||||||
options = {
|
|
||||||
postalCode: undefined,
|
|
||||||
dateExpired: undefined,
|
|
||||||
type: undefined,
|
|
||||||
minPrice: undefined,
|
|
||||||
maxPrice: undefined,
|
|
||||||
bigPrice: undefined,
|
|
||||||
lowPrice: undefined,
|
|
||||||
isNew: undefined,
|
|
||||||
order_crescent: undefined,
|
|
||||||
order_descending: undefined,
|
|
||||||
recommend: 1,
|
|
||||||
},
|
|
||||||
debug = false
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
const params = transformOptionsToParams(options);
|
|
||||||
|
|
||||||
(async () => {
|
const hasCurrentProduct = computed(() => {
|
||||||
const {
|
return cart.value.find((p) => p.id === product.id);
|
||||||
data: { data },
|
|
||||||
} = await apiBack.get("products", { params });
|
|
||||||
featuredProducts.value = data[0];
|
|
||||||
|
|
||||||
if (debug) {
|
|
||||||
console.groupCollapsed(
|
|
||||||
"%c FEATURED PRODUCTS FETCHED!",
|
|
||||||
"color: green;"
|
|
||||||
);
|
|
||||||
console.table(data.products);
|
|
||||||
console.groupEnd();
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
} catch (err) {
|
|
||||||
new Error(`FATAL ERROR ::: ${err}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adiciona um produto ao carrinho.
|
|
||||||
* @param {Object} product - O produto a ser adicionado.
|
|
||||||
* @param {string} dedication - A dedicação associada ao produto.
|
|
||||||
*/
|
|
||||||
function addToCart(product, dedication) {
|
|
||||||
const existingProduct = cart.value.find(p => p.id === product.id);
|
|
||||||
console.log(existingProduct)
|
|
||||||
|
|
||||||
if (!existingProduct) {
|
|
||||||
const arr = [...cart.value];
|
|
||||||
arr.push(product);
|
|
||||||
console.log(arr)
|
|
||||||
addItem("cart", JSON.stringify(arr));
|
|
||||||
quasarNotify({ message: 'Producto añadido al carrito.', type: 'success' })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
quasarNotify({
|
|
||||||
message: "Este producto ya está en el carrito",
|
|
||||||
type: "info",
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
if (isEmpty.value) {
|
||||||
* Remove an item from the cart by its ID.
|
push("/");
|
||||||
* @param {number} id - The ID of the item to be removed.
|
return quasarNotify({
|
||||||
*/
|
message:
|
||||||
function removeFromCart(id) {
|
"No hay productos disponibles para la fecha y el código postal seleccionados",
|
||||||
const newArrRemovedItem = cart.value.filter((p) => id !== p.id);
|
type: "erro",
|
||||||
addItem("cart", JSON.stringify(newArrRemovedItem))
|
});
|
||||||
|
}
|
||||||
|
if (!products.value.data.some((item) => item.id === product.id)) {
|
||||||
|
push("/");
|
||||||
|
return quasarNotify({
|
||||||
|
message:
|
||||||
|
"Este producto no está disponible en su zona, intente añadir un nuevo código postal",
|
||||||
|
type: "erro",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasCurrentProduct.value) {
|
||||||
|
return quasarNotify({
|
||||||
|
message: "Este producto ya está en el carrito",
|
||||||
|
type: "info",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const arr = [...cart.value];
|
||||||
|
arr.push({ ...product, message: message.value });
|
||||||
|
cart.value = arr;
|
||||||
|
addItem("cart", arr);
|
||||||
|
quasarNotify({
|
||||||
|
message: "Producto añadido al carrito.",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -345,12 +254,9 @@ export const useCartStore = defineStore("cart", () => {
|
||||||
cart,
|
cart,
|
||||||
addCartLoadingBtn,
|
addCartLoadingBtn,
|
||||||
products,
|
products,
|
||||||
featuredProducts,
|
|
||||||
|
|
||||||
getFeaturedProducts,
|
|
||||||
getProducts,
|
getProducts,
|
||||||
addToCart,
|
addToCart,
|
||||||
removeFromCart,
|
|
||||||
getProduct,
|
getProduct,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,7 +18,7 @@ export const useFormStore = defineStore("forms", {
|
||||||
terms: false,
|
terms: false,
|
||||||
},
|
},
|
||||||
availability: {
|
availability: {
|
||||||
date: "",
|
dateExpired: "",
|
||||||
postalCode: "",
|
postalCode: "",
|
||||||
},
|
},
|
||||||
checkout: {
|
checkout: {
|
||||||
|
@ -34,28 +34,23 @@ export const useFormStore = defineStore("forms", {
|
||||||
senderEmail: "",
|
senderEmail: "",
|
||||||
senderPhone: "",
|
senderPhone: "",
|
||||||
senderNotes: "",
|
senderNotes: "",
|
||||||
paymentMethod: "credit",
|
paymentMethod: "paypal",
|
||||||
terms: false,
|
terms: false,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
handleQuestionData(values) {
|
handleQuestionData(values) {
|
||||||
console.log(values);
|
|
||||||
this.question = values;
|
this.question = values;
|
||||||
},
|
},
|
||||||
|
|
||||||
handleAvailabilityData(values) {
|
handleAvailabilityData(values) {
|
||||||
console.log(values);
|
|
||||||
this.availability = values;
|
this.availability = values;
|
||||||
},
|
},
|
||||||
|
|
||||||
registerAvailability() {
|
registerAvailability() {},
|
||||||
console.log(this.availability);
|
|
||||||
},
|
|
||||||
|
|
||||||
handleCheckoutData(values) {
|
handleCheckoutData(values) {
|
||||||
// console.log(values);
|
|
||||||
this.checkout = values;
|
this.checkout = values;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,8 +23,7 @@ export const useModalStore = defineStore("modal", () => {
|
||||||
isOpenAvailability: () => "Contenido modal availability",
|
isOpenAvailability: () => "Contenido modal availability",
|
||||||
isOpenFilters: () => "Contenido modal filters",
|
isOpenFilters: () => "Contenido modal filters",
|
||||||
};
|
};
|
||||||
console.log(availability.value);
|
isModal[content]()
|
||||||
console.log(isModal[content]());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return { openModal, handleSubmit, isOpenAvailability, isOpenFilters };
|
return { openModal, handleSubmit, isOpenAvailability, isOpenFilters };
|
||||||
|
|
|
@ -8,7 +8,6 @@ export const useRangePriceStore = defineStore("range-price", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
function handlePriceRange({ min, max }) {
|
function handlePriceRange({ min, max }) {
|
||||||
console.log({ min, max });
|
|
||||||
rangeValue.min = min;
|
rangeValue.min = min;
|
||||||
rangeValue.max = max;
|
rangeValue.max = max;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,16 +21,18 @@ const checkoutObjVal = {
|
||||||
phone: z
|
phone: z
|
||||||
.string({ required_error: M.requiredMessage })
|
.string({ required_error: M.requiredMessage })
|
||||||
.refine(handlePhoneVal, M.phoneMessage),
|
.refine(handlePhoneVal, M.phoneMessage),
|
||||||
senderName: z.string().regex(justOneWord, M.nameMessage),
|
senderName: z.string().regex(justLetters, M.nameMessage),
|
||||||
senderCifNif: z
|
senderCifNif: z
|
||||||
.string()
|
.string()
|
||||||
.length(9, "El código postal debe tener 9 caracteres numéricos válidos"),
|
.length(9, "El código postal debe tener 9 caracteres numéricos válidos"),
|
||||||
senderEmail: z.string().email(M.emailMessage),
|
senderEmail: z.string().email(M.emailMessage),
|
||||||
senderPhone: z.string().refine(handlePhoneVal, M.phoneMessage),
|
senderPhone: z.string().refine(handlePhoneVal, M.phoneMessage),
|
||||||
senderNotes: z.string(),
|
senderNotes: z.string(),
|
||||||
paymentMethod: z.enum(["credit", "stripe"], {
|
paymentMethod: z
|
||||||
required_error: "Seleccione uno de los métodos de pago!",
|
.enum(["credit", "paypal"], {
|
||||||
}),
|
required_error: "Seleccione uno de los métodos de pago!",
|
||||||
|
})
|
||||||
|
.default("paypal"),
|
||||||
terms: z.boolean().refine((val) => {
|
terms: z.boolean().refine((val) => {
|
||||||
return val === true;
|
return val === true;
|
||||||
}, "Acepte las condiciones antes de continuar con la compra"),
|
}, "Acepte las condiciones antes de continuar con la compra"),
|
||||||
|
|
|
@ -2,9 +2,7 @@ import { z } from "zod";
|
||||||
|
|
||||||
const rangePriceObj = {
|
const rangePriceObj = {
|
||||||
range: z.object({
|
range: z.object({
|
||||||
min: z
|
min: z.number(),
|
||||||
.number()
|
|
||||||
.refine((n) => n > 0, "El valor mínimo debe ser superior a cero"),
|
|
||||||
max: z.number(),
|
max: z.number(),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue