develop #10

Merged
pablone merged 64 commits from develop into master 2024-04-22 11:35:55 +00:00
36 changed files with 895 additions and 797 deletions

View File

@ -0,0 +1,16 @@
const db = require("../../db/db");
const fs = require('fs');
const path = require('path');
class BannersController {
async findAll(req, res) {
const rows = await db.findAll_banner()
return res.status(200).send({
data: rows
})
}
}
module.exports = new BannersController()

View File

@ -4,7 +4,6 @@ class ContactController {
async Create(req, res) {
try {
const { name, phone, email, message } = req.body;
console.log(name, phone, email, message);
const contact = await db.contact_Request(name, phone, email, message);
return res.status(200).send({

View File

@ -1,21 +1,16 @@
const db = require("../../db/db");
const payPalProviders = require('./paypal.providers')
const redsysProviders = require('./redsys.providers')
const payPalProviders = require('./paypal/paypal.providers')
const redsysProviders = require('./redsys/redsys.providers')
class PaymentServices {
async Create(req, res) {
try {
//parâmetros para retornar os produtos que serão comprados
//parameters to return the products that will be purchased
const { products, dateExpired, postalCode, customer, type } = req.body
const _products = await db.getProducts(dateExpired, postalCode)
const productsFilter = _products[0].filter((item) => {
if (products.includes(item.id)) {
return item
}
});
const productsFilter = await db.getProductById(products[0]);
if (productsFilter.length !== products.length) {
if (productsFilter[0][0].length !== products.length) {
return res.status(422).send({
data: {
message: "Uno de los productos no existe."
@ -24,7 +19,7 @@ class PaymentServices {
}
let priceIntial = 0
let price = productsFilter.reduce((accumulator, curValue) => accumulator + Number(curValue.price), priceIntial)
let price = productsFilter[0][0].reduce((accumulator, curValue) => accumulator + Number(curValue.price), priceIntial)
let productsIds = ''
for (let i = 0; i < products.length; i++) {
@ -37,12 +32,13 @@ class PaymentServices {
customerData: {
...customer.customerData,
type: type,
products: productsFilter
products: productsFilter[0][0]
}
},
})
const order = await db.orderData_put(jsonOrderData);
const orderFk = order[0][0].orderFk
const orderFk = productsFilter[0][0][0].id;
if (type === "paypal") {
const data = await payPalProviders.New(orderFk, price)
@ -56,16 +52,12 @@ class PaymentServices {
data: { ...data, orderId: orderFk }
})
}
/* if (newOrder) {
return res.status(200).send({
data: { link: newOrder.links, orderId: orderFk }
})
} */
} catch (error) {
console.log(error);
return res.status(422).send({
data: {
message: "Error al iniciar el pago"
message: "Error al iniciar el pago",
error: error.message
}
})
}
@ -74,38 +66,33 @@ class PaymentServices {
async Success(req, res) {
try {
//Parameters payment
const { paymentId, PayerID, orderId } = req.body
const payerId = { 'payer_id': PayerID };
//API validation payent and confirnm order
paypal.payment.execute(paymentId, payerId, async function (error, payment) {
if (error) {
return res.status(422).send({
data: {
message: "payment not successful"
}
})
} else {
if (payment.state == 'approved') {
await db.order_confirm(orderId)
const { orderId, type, ...paramns } = req.body
if (type === "paypal") {
const payerId = { 'payer_id': paramns.PayerID };
const data = await payPalProviders.success(paramns.paymentId, payerId, orderId)
return res.status(200).send({
data: {
id: payment.id,
message: "payment completed successfully",
...data,
message: "Payment success"
}
})
} else {
return res.status(422).send({
}
if (type === "redsys") {
await redsysProviders.success(orderId)
return res.status(200).send({
data: {
message: "payment not successful"
message: "Payment success"
}
})
}
}
});
} catch (error) {
throw error;
return res.status(422).send({
data: {
message: "Payment Error"
}
})
}
}
}

View File

@ -1,4 +1,5 @@
const paypal = require('paypal-rest-sdk');
const db = require("../../../db/db");
class PayPalProviders {
async New(orderFk, price) {
@ -6,7 +7,7 @@ class PayPalProviders {
const payReq = JSON.stringify({
'intent': 'sale',
'redirect_urls': {
'return_url': `${process.env.BASE_URL}/checkout/success?orderId=${orderFk}`,
'return_url': `${process.env.BASE_URL}/checkout/success?orderId=${orderFk}&type=paypal`,
'cancel_url': `${process.env.BASE_URL}/checkout/error`
},
'payer': {
@ -14,14 +15,13 @@ class PayPalProviders {
},
'transactions': [{
'amount': {
'total': 0.0000000001,
'total': price,
'currency': 'EUR'
},
'description': 'This is the payment transaction description.'
}]
});
//Starting checkout process and returning sandbox url
const newOrder = await new Promise(async (resolve, reject) => {
paypal.payment.create(payReq, function (error, payment) {
if (error) {
@ -54,6 +54,28 @@ class PayPalProviders {
throw error;
}
}
async success(paymentId, payerId, orderId) {
try {
return new Promise(async (resolve, reject) => {
paypal.payment.execute(paymentId, payerId, async function (error, payment) {
if (error) {
reject()
} else {
if (payment.state == 'approved') {
await db.order_confirm(orderId)
resolve({ id: payment.id })
} else {
reject()
}
}
});
}).then(res => res)
} catch (error) {
throw error
}
}
}
module.exports = new PayPalProviders();

View File

@ -1,39 +0,0 @@
const Redsys = require('redsys-easy');
const {
SANDBOX_URLS,
PRODUCTION_URLS,
TRANSACTION_TYPES
} = Redsys
class RedsysProviders {
async New(orderFk, price) {
console.log("Chama");
try {
const redsys = new Redsys({
secretKey: 'sq7HjrUOBfKmC576ILgskD5srU870gJ7',
urls: SANDBOX_URLS, // Also PRODUCTION_URLS
});
const obj = {
amount: price,
currency: 'EUR',
order: orderFk,
merchantName: 'Floraner',
merchantCode: '999008881',
transactionType: TRANSACTION_TYPES.AUTHORIZATION, // '0'
terminal: '001',
merchantURL: `${process.env.BASE_URL}/payments/redsys/notification`,
successURL: `${process.env.BASE_URL}/checkout/success?orderId=${orderFk}`,
errorURL: `${process.env.BASE_URL}/checkout/error`
}
const form = redsys.redirectPetition(obj)
console.log(form);
return true
} catch (error) {
throw error;
}
}
}
module.exports = new RedsysProviders();

View File

@ -1,34 +0,0 @@
const RedsysPos = require('redsys-pos');
const {
CURRENCIES, TRANSACTION_TYPES
} = RedsysPos;
class RedsysProviders {
async New(orderFk, price) {
console.log("Chama");
try {
const MERCHANT_KEY = "sq7HjrUOBfKmC576ILgskD5srU870gJ7";
const redsys = new RedsysPos(MERCHANT_KEY);
const obj = JSON.stringify({
amount: 100, // 100 euros
orderReference: orderFk,
merchantName: "Floranet",
merchantCode: "999008881",
currency: CURRENCIES.EUR,
transactionType: TRANSACTION_TYPES.AUTHORIZATION, // '0'
terminal: "001",
merchantURL: `${process.env.BASE_URL}/payments/redsys/notification`,
successURL: `${process.env.BASE_URL}/checkout/success?orderId=${orderFk}`,
errorURL: `${process.env.BASE_URL}/checkout/error`
});
console.log(obj);
const result = redsys.makePaymentParameters(obj);
return ""
} catch (error) {
throw error;
}
}
}
module.exports = new RedsysProviders();

View File

@ -1,33 +0,0 @@
const RedsysPos = require('redsys-pos');
const {
CURRENCIES, TRANSACTION_TYPES
} = RedsysPos;
class RedsysProviders {
async New(orderFk, price) {
try {
const MERCHANT_KEY = "sq7HjrUOBfKmC576ILgskD5srU870gJ7";
const redsys = new RedsysPos(MERCHANT_KEY);
const obj = {
amount: String(price),
orderReference: String(orderFk),
merchantName: "Floranet",
merchantCode: "999008881",
currency: CURRENCIES.EUR,
transactionType: TRANSACTION_TYPES.AUTHORIZATION, // '0'
terminal: "001",
merchantURL: `${process.env.BASE_URL}/payments/redsys/notification`,
successURL: `${process.env.BASE_URL}/checkout/success?orderId=${orderFk}`,
errorURL: `${process.env.BASE_URL}/checkout/error`
};
const result = redsys.makePaymentParameters(obj);
console.log(result);
return result
} catch (error) {
throw error;
}
}
}
module.exports = new RedsysProviders();

View File

@ -0,0 +1,53 @@
const db = require("../../../db/db");
const RedsysPos = require('redsys-pos');
const {
CURRENCIES, TRANSACTION_TYPES
} = RedsysPos;
class RedsysProviders {
async New(orderFk, price) {
try {
const MERCHANT_KEY = process.env.REDSYS_MERCHANT_KEY;
const redsys = new RedsysPos(MERCHANT_KEY);
let orderValue = String(orderFk)
while (true) {
if (orderValue.length == 4) {
break
}
orderValue = '0' + orderValue
}
const regexAmount = /[,.]/
const amountValue = regexAmount.test(String(price)) ? String(price).replace(/[,.]/g, '') : String(price + '00')
const obj = {
amount: amountValue,
orderReference: orderValue,
merchantName: process.env.REDSYS_MERCHANT_NAME,
merchantCode: process.env.REDSYS_MERCHANT_CODE,
currency: "978",
transactionType: "0", // '0'
terminal: process.env.REDSYS_MERCHANT_TERMINAL,
merchantURL: `${process.env.BASE_URL}/payments/redsys/notification`,
successURL: `${process.env.BASE_URL}/checkout/success?orderId=${orderFk}&type=redsys`,
errorURL: `${process.env.BASE_URL}/checkout/error`
};
const result = redsys.makePaymentParameters(obj);
return { ...result, DS_MERCHANT_ORDER: obj.orderReference }
} catch (error) {
throw error;
}
}
async success(orderId) {
try {
return await db.order_confirm(orderId)
} catch (error) {
throw error
}
}
}
module.exports = new RedsysProviders();

View File

@ -95,9 +95,10 @@ class ProductController {
}
async findById(req, res) {
const { dateExpired, postalCode } = req.query
const id = Number(req.params.id)
const _products = await db.getProducts();
const filterProduct = _products[0].filter(item => item.id === id)
const product = await db.getProductById(req.params.id);
const filterProduct = (product[0][0] && product[0][0])?product[0][0]:{};
return res.status(200).send({
data: filterProduct

View File

@ -1,113 +0,0 @@
const db = require("../../db/db");
<<<<<<<< HEAD:api/controller/product/product.controller.js
const productsJson = require("./products.json")
========
>>>>>>>> master:api/controller/Product/product.controller.js
class ProductController {
async findAll(req, res) {
const params = req.query;
const _products = await db.getProducts(params.dateExpired, params.postalCode);
let productsFilter = _products[0]
if (Number(params.recommend)) {
productsFilter = productsFilter.filter(item => item.recommend == params.recommend)
}
if (params.type) {
productsFilter = productsFilter.filter(item => item.type === params.type)
}
if (params.minPrice && !params.maxPrice) {
productsFilter = productsFilter.filter(item => {
const price = Number(item.price)
if (price >= Number(params.minPrice)) {
return item
}
})
}
if (params.maxPrice && !params.minPrice) {
productsFilter = productsFilter.filter(item => {
const price = Number(item.price)
if (price <= Number(params.maxPrice)) {
return item
}
})
}
if (params.maxPrice && params.minPrice) {
productsFilter = productsFilter.filter(item => {
const price = Number(item.price)
if (price >= Number(params.minPrice) && price <= Number(params.maxPrice)) {
return item
}
})
}
if (Number(params.bigPrice)) {
productsFilter.sort((a, b) => {
const itemA = Number(a.price)
const itemB = Number(b.price)
return itemB - itemA;
})
}
if (Number(params.lowPrice)) {
productsFilter.sort((a, b) => {
const itemA = Number(a.price)
const itemB = Number(b.price)
return itemA - itemB;
})
}
if (Number(params.order_descending)) {
productsFilter.sort((a, b) => {
const itemA = a.order_position
const itemB = b.order_position
return itemB - itemA;
})
}
if (Number(params.order_crescent)) {
productsFilter.sort((a, b) => {
const itemA = a.order_position
const itemB = b.order_position
return itemA - itemB;
})
}
if (Number(params.isNew)) {
productsFilter = productsFilter.filter(item => item.isNew == Number(params.isNew))
}
/* let productsFilterPages = []
const totalItens = params?.itens ? Number(params.itens) : 200
const page = params.page ? Number(params.page) : 1
const startIndex = (totalItens * page) - totalItens
const lastIndex = (totalItens * page)
const products = productsFilter.slice(startIndex, lastIndex)
productsFilterPages.push({
page: page,
productsPerPage: products.length,
products: products
}) */
return res.status(200).send({
data: productsFilter
})
}
async findById(req, res) {
const id = Number(req.params.id)
const _products = await db.getProducts();
const filterProduct = _products[0].filter(item => item.id === id)
return res.status(200).send({
data: filterProduct
})
}
}
module.exports = new ProductController();

View File

@ -11,7 +11,7 @@ async function connect() {
const mysql = require("mysql2/promise");
const connection = await mysql.createConnection("mysql://" + user + ":" + password + "@" + host + ":" + port + "/" + database + "");
const connection = await mysql.createConnection({host: host,port: port,user: user,password: password,database: database});
global.connection = connection;
return connection;
}
@ -23,14 +23,20 @@ async function getProducts(dateExpired, postalCode) {
return rows;
}
async function getProductById(id) {
const conn = await connect();
const rows = await conn.query(`CALL catalogue_findById(${id})`);
return rows;
}
//Procedure for create transactions, do not carry out any manipulation at the bank
async function orderData_put(jsonOrderData) {
const conn = await connect();
const [rows] = await conn.query(`CALL orderData_put(?)`, [jsonOrderData], (err, results) => {
const [rows] = await conn.query(`CALL order_put(?)`, [jsonOrderData], (err, results) => {
if (err) {
console.error(err);
} else {
console.log('Result:', results);
}
});
return rows;
@ -68,9 +74,25 @@ async function deliveryDate_get(postalCode) {
async function contact_Request(name, phone, email, message) {
const conn = await connect();
const [rows] = await conn.query(`CALL contact_Request("${name}", "${phone}", "${email}", "${message}")`);
const [rows] = await conn.query(`CALL contact_request("${name}", "${phone}", "${email}", "${message}")`);
return rows;
}
async function findAll_banner() {
const conn = await connect();
const [rows] = await conn.query(`CALL sliders_get`);
return rows;
}
module.exports = { getProducts, orderData_get, orderData_put, getProvinces, deliveryDate_get, contact_Request, order_confirm }
module.exports = {
getProducts,
getProductById,
orderData_get,
orderData_put,
getProvinces,
deliveryDate_get,
contact_Request,
order_confirm,
findAll_banner
}

View File

@ -7,6 +7,7 @@ const paymengtController = require('./controller/Payment/payment.controller');
const provincesController = require('./controller/Provinces/provinces.controller');
const deliveryController = require('./controller/Delivery/delivery.controller');
const contactController = require('./controller/Contact/contact.controller');
const bannersController = require('./controller/Banners/banners.controller');
paypal.configure({
'mode': 'sandbox',
@ -17,7 +18,7 @@ paypal.configure({
const app = express();
const port = 9999;
const allowedOrigins = ['http://localhost:9100', 'https://floranet.onecommerce.dev','http://49.13.85.117','http://floranet.onecommerce.dev'];
const allowedOrigins = ['https://staging.floranet.es','http://localhost:9100', 'https://floranet.onecommerce.dev', 'http://49.13.85.117', 'http://floranet.onecommerce.dev'];
const corsOptions = {
origin: allowedOrigins,
optionsSuccessStatus: 200,
@ -46,7 +47,7 @@ app.get('/api/payment/cancel', paymengtController.Cancel)
app.get('/api/provinces', provincesController.findAll)
app.get('/api/delivery/dates', deliveryController.findByPostalCode)
app.post('/api/contact/save', contactController.Create)
app.get('/api/banners/', bannersController.findAll)
app.listen(port, () => {

335
package-lock.json generated
View File

@ -157,14 +157,6 @@
"npm": ">=6.14.13"
}
},
"node_modules/@fastify/busboy": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
"engines": {
"node": ">=14"
}
},
"node_modules/@floating-ui/core": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz",
@ -2162,6 +2154,118 @@
"esbuild-windows-arm64": "0.14.51"
}
},
"node_modules/esbuild-android-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.51.tgz",
"integrity": "sha512-6FOuKTHnC86dtrKDmdSj2CkcKF8PnqkaIXqvgydqfJmqBazCPdw+relrMlhGjkvVdiiGV70rpdnyFmA65ekBCQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-android-arm64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.51.tgz",
"integrity": "sha512-vBtp//5VVkZWmYYvHsqBRCMMi1MzKuMIn5XDScmnykMTu9+TD9v0NMEDqQxvtFToeYmojdo5UCV2vzMQWJcJ4A==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-darwin-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.51.tgz",
"integrity": "sha512-YFmXPIOvuagDcwCejMRtCDjgPfnDu+bNeh5FU2Ryi68ADDVlWEpbtpAbrtf/lvFTWPexbgyKgzppNgsmLPr8PA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-darwin-arm64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.51.tgz",
"integrity": "sha512-juYD0QnSKwAMfzwKdIF6YbueXzS6N7y4GXPDeDkApz/1RzlT42mvX9jgNmyOlWKN7YzQAYbcUEJmZJYQGdf2ow==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-freebsd-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.51.tgz",
"integrity": "sha512-cLEI/aXjb6vo5O2Y8rvVSQ7smgLldwYY5xMxqh/dQGfWO+R1NJOFsiax3IS4Ng300SVp7Gz3czxT6d6qf2cw0g==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-freebsd-arm64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.51.tgz",
"integrity": "sha512-TcWVw/rCL2F+jUgRkgLa3qltd5gzKjIMGhkVybkjk6PJadYInPtgtUBp1/hG+mxyigaT7ib+od1Xb84b+L+1Mg==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-32": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.51.tgz",
"integrity": "sha512-RFqpyC5ChyWrjx8Xj2K0EC1aN0A37H6OJfmUXIASEqJoHcntuV3j2Efr9RNmUhMfNE6yEj2VpYuDteZLGDMr0w==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.51.tgz",
@ -2178,6 +2282,198 @@
"node": ">=12"
}
},
"node_modules/esbuild-linux-arm": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.51.tgz",
"integrity": "sha512-LsJynDxYF6Neg7ZC7748yweCDD+N8ByCv22/7IAZglIEniEkqdF4HCaa49JNDLw1UQGlYuhOB8ZT/MmcSWzcWg==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-arm64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.51.tgz",
"integrity": "sha512-D9rFxGutoqQX3xJPxqd6o+kvYKeIbM0ifW2y0bgKk5HPgQQOo2k9/2Vpto3ybGYaFPCE5qTGtqQta9PoP6ZEzw==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-mips64le": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.51.tgz",
"integrity": "sha512-vS54wQjy4IinLSlb5EIlLoln8buh1yDgliP4CuEHumrPk4PvvP4kTRIG4SzMXm6t19N0rIfT4bNdAxzJLg2k6A==",
"cpu": [
"mips64el"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-ppc64le": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.51.tgz",
"integrity": "sha512-xcdd62Y3VfGoyphNP/aIV9LP+RzFw5M5Z7ja+zdpQHHvokJM7d0rlDRMN+iSSwvUymQkqZO+G/xjb4/75du8BQ==",
"cpu": [
"ppc64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-riscv64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.51.tgz",
"integrity": "sha512-syXHGak9wkAnFz0gMmRBoy44JV0rp4kVCEA36P5MCeZcxFq8+fllBC2t6sKI23w3qd8Vwo9pTADCgjTSf3L3rA==",
"cpu": [
"riscv64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-linux-s390x": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.51.tgz",
"integrity": "sha512-kFAJY3dv+Wq8o28K/C7xkZk/X34rgTwhknSsElIqoEo8armCOjMJ6NsMxm48KaWY2h2RUYGtQmr+RGuUPKBhyw==",
"cpu": [
"s390x"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-netbsd-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.51.tgz",
"integrity": "sha512-ZZBI7qrR1FevdPBVHz/1GSk1x5GDL/iy42Zy8+neEm/HA7ma+hH/bwPEjeHXKWUDvM36CZpSL/fn1/y9/Hb+1A==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-openbsd-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.51.tgz",
"integrity": "sha512-7R1/p39M+LSVQVgDVlcY1KKm6kFKjERSX1lipMG51NPcspJD1tmiZSmmBXoY5jhHIu6JL1QkFDTx94gMYK6vfA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-sunos-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.51.tgz",
"integrity": "sha512-HoHaCswHxLEYN8eBTtyO0bFEWvA3Kdb++hSQ/lLG7TyKF69TeSG0RNoBRAs45x/oCeWaTDntEZlYwAfQlhEtJA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-windows-32": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.51.tgz",
"integrity": "sha512-4rtwSAM35A07CBt1/X8RWieDj3ZUHQqUOaEo5ZBs69rt5WAFjP4aqCIobdqOy4FdhYw1yF8Z0xFBTyc9lgPtEg==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-windows-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.51.tgz",
"integrity": "sha512-HoN/5HGRXJpWODprGCgKbdMvrC3A2gqvzewu2eECRw2sYxOUoh2TV1tS+G7bHNapPGI79woQJGV6pFH7GH7qnA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild-windows-arm64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.51.tgz",
"integrity": "sha512-JQDqPjuOH7o+BsKMSddMfmVJXrnYZxXDHsoLHc0xgmAZkOOCflRmC43q31pk79F9xuyWY45jDBPolb5ZgGOf9g==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/escalade": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
@ -2819,6 +3115,20 @@
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"dev": true
},
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@ -5425,12 +5735,9 @@
}
},
"node_modules/undici": {
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/undici/-/undici-6.6.2.tgz",
"integrity": "sha512-vSqvUE5skSxQJ5sztTZ/CdeJb1Wq0Hf44hlYMciqHghvz+K88U0l7D6u1VsndoFgskDcnU+nG3gYmMzJVzd9Qg==",
"dependencies": {
"@fastify/busboy": "^2.0.0"
},
"version": "6.9.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-6.9.0.tgz",
"integrity": "sha512-XPWfXzJedevUziHwun70EKNvGnxv4CnfraFZ4f/JV01+fcvMYzHE26r/j8AY/9c/70nkN4B1zX7E2Oyuqwz4+Q==",
"engines": {
"node": ">=18.0"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

View File

@ -60,7 +60,7 @@ module.exports = configure(function (ctx) {
env: {
API: ctx.dev
? "http://localhost:9999/api/"
: "https://floranet-back.onecommerce.dev/api/",
: "https://api-staging.floranet.es/api/",
},
target: {

View File

@ -10,17 +10,16 @@ import IconCalendar from "../icons/IconCalendar.vue";
export default defineComponent({
name: "calendar-input",
components: { IconCalendar },
props: ["modelValue", "bindValue", "setValues"],
setup({ setValues }, { emit }) {
props: ["modelValue", "bindValue", "setValues", "dateCookies"],
setup({ setValues, dateCookies, modelValue }, { emit }) {
const formStore = useFormStore();
const { availability, postalCodeValid } = storeToRefs(formStore);
const [year, month, day] = fullCurrentDate.replaceAll("/", "-").split("-");
const currentDate = `${day}-${month}-${year}`;
const proxyDate = ref(invertDate(currentDate));
const proxyDate = ref(invertDate(modelValue));
function updateProxy() {
proxyDate.value = invertDate(currentDate);
proxyDate.value = invertDate(proxyDate.value);
}
function optionsValidDates(date) {
@ -37,6 +36,8 @@ export default defineComponent({
watch(proxyDate, (newProxy) => {
setValues({ date: invertDate(newProxy) });
const btn = document.querySelector(".buttons-close-modal button")
if(btn) btn.click()
});
const LOCALE = {
@ -71,7 +72,6 @@ export default defineComponent({
<IconCalendar />
<q-popup-proxy
@before-show="updateProxy"
cover
transition-show="scale"
transition-hide="scale"
@ -83,9 +83,9 @@ export default defineComponent({
:readonly="!postalCodeValid.isValid"
mask="YYYY-MM-DD"
>
<div class="row items-center justify-end q-gutter-sm">
<div class="row items-center justify-end q-gutter-sm buttons-close-modal">
<q-btn label="Cancel" color="primary" flat v-close-popup />
<q-btn label="OK" color="primary" flat v-close-popup />
<q-btn label="OK" color="primary" flat v-close-popup class="modal-close"/>
</div>
</q-date>
</q-popup-proxy>

View File

@ -43,8 +43,8 @@ export default defineComponent({
} = await apiBack.get(`/delivery/dates`, {
params: { postalCode: postalCodeInput.value },
});
const dates = data.map(({ dated }) => {
const getDate = new Date(dated);
const dates = data.map(({ nextDay }) => {
const getDate = new Date(nextDay);
const day = getDate.getDate().toString().padStart(2, "0");
const month = (getDate.getMonth() + 1).toString().padStart(2, "0");
const year = getDate.getFullYear();
@ -53,6 +53,14 @@ export default defineComponent({
return formattedDate;
});
if(!dates.length) {
quasarNotify({
type: "erro",
message: `No tenemos fechas de entrega posibles para este código postal`,
});
setFieldError("postalCode", M.fiveLength);
}
postalCodeValid.value.dataOptions = dates;
postalCodeValid.value.isValid = true;
isPostalCodeLoading.value = false;
@ -63,9 +71,8 @@ export default defineComponent({
"Se ha producido un error en el proceso de identificación del código postal",
});
isPostalCodeLoading.value = false;
console.error(`FATAL ERROR ::: ${error}`);
} finally {
jsolis marked this conversation as resolved
Review

revisar console.log

revisar console.log
// console.log("click");
}
}
@ -88,7 +95,7 @@ export default defineComponent({
:model-value="modelValue"
@update:model-value="updateModel"
v-bind="bindValue"
class="custom-main-paragraph"
class="custom-main-paragraph field-postal-code"
:error="false"
placeholder="código postal"
mask="#####"

View File

@ -66,6 +66,8 @@ export default defineComponent({
display: flex;
align-items: center;
gap: 34px;
min-width: 190px;
justify-content: flex-end;
& .user-area-link {
color: $white;
@ -108,6 +110,8 @@ export default defineComponent({
@media only screen and (max-width: $med-md) {
gap: 27px;
min-width: auto;
& .user-area-link {
&.help {
display: none;

View File

@ -1,4 +1,5 @@
<script>
import { storeToRefs } from "pinia";
import { defineComponent } from "vue";
import Calendar from "src/components/@inputs/Calendar.vue";
@ -6,14 +7,30 @@ import PostalCode from "src/components/@inputs/PostalCode.vue";
import IconSearch from "src/components/icons/IconSearch.vue";
import { usePostalCalendar } from "src/hooks/usePostalCalendar";
import { useVerticalCarouselImgs } from "src/hooks/useVerticalCarouselImgs";
import { useFormStore } from "src/stores/forms";
import { onMounted } from "vue";
import { useLocalStorage } from "../../../hooks/useLocalStorage";
export default defineComponent({
name: "vertical-carousel-imgs",
props: {
imgsArr: {
banners: {
type: Array,
default: () => [""],
default: () => [
{
"url": "/assets/Cabecera-flornatura-1.jpg",
"longName": "Regala un verano lleno de flores y plantas"
},
{
"url": "/assets/Cabecera-flornatura-2.jpg",
"longName": "Regala un verano lleno de flores y plantas"
},
{
"url": "/assets/Cabecera-flornatura-3.jpg",
"longName": "Regala un verano lleno de flores y plantas"
}
],
}
},
components: { IconSearch, Calendar, PostalCode },
setup() {
@ -26,6 +43,36 @@ export default defineComponent({
} = usePostalCalendar({ type: "home" });
const { navPos, screenWidth, slide, target } = useVerticalCarouselImgs();
const formStore = useFormStore();
const { getItem } = useLocalStorage();
const localValues = getItem("availability");
const lengthCp = 5;
const { postalCodeValid } = storeToRefs(formStore);
jsolis marked this conversation as resolved
Review

falta ;

falta ;
let isEventKeyActive = false;
function handleFormKeyPress() {
const postalCodeField = document.querySelector("#carousel-form .postal-code-control input");
const modalDate = document.querySelector("#carousel-form .calendar .custom-date-btn");
postalCodeField.addEventListener('input', (e) =>{
if (e.target.value.length === lengthCp) {
isEventKeyActive = true;
}
})
postalCodeField.addEventListener('keypress', e => {
jsolis marked this conversation as resolved
Review

unificar el 5 en una constante

unificar el 5 en una constante
if (e.target.value.length === lengthCp && isEventKeyActive) {
if (e.key === 'Enter') {
e.preventDefault();
modalDate.click();
isEventKeyActive = false;
}
}
})
}
onMounted(() => {
handleFormKeyPress();
})
return {
slide,
navPos,
@ -39,58 +86,35 @@ export default defineComponent({
postalCodeAttrs,
calendar,
calendarAttrs,
localValues
};
},
});
</script>
<template>
<div
ref="target"
class="vertical-carousel-container"
style="min-height: 100dvh"
>
<q-carousel
navigation-position="right"
style="min-height: 100dvh"
v-model="slide"
navigation
autoplay
infinite
animated
v-if="!!imgsArr.length"
class="custom-carousel"
>
<q-carousel-slide
v-for="(img, i) in imgsArr"
:key="i"
:name="img"
:img-src="img"
/>
</q-carousel>
<div ref="target" class="vertical-carousel-container" style="min-height: 100dvh">
<q-carousel navigation-position="right" style="min-height: 100dvh" v-model="slide" navigation autoplay infinite
animated v-if="!!banners.length" class="custom-carousel">
<q-carousel-slide v-for="(item, i) in banners" :key="`banner-${i}`" :name="`banner-${i}`" :img-src="item.url">
<div class="vertical-carousel-content">
<header class="carousel-content-header">
<h1 class="carousel-header-title">
Regala un verano lleno de flores y plantas
{{ item.longName }}
</h1>
</header>
</div>
</q-carousel-slide>
</q-carousel>
<form @submit="onSubmit" class="carousel-content-body">
<div class="carousel-content-item">
<PostalCode
v-model="postalCode"
v-bind:bindValue="postalCodeAttrs"
:setFieldError="setFieldError"
/>
<div class="carousel-form">
<form @submit="onSubmit" class="carousel-content-body" id="carousel-form">
<div class="carousel-content-item postal-code-control">
<PostalCode v-model="postalCode" v-bind:bindValue="postalCodeAttrs" :setFieldError="setFieldError" />
</div>
<div class="carousel-content-item">
<Calendar
v-model="calendar"
v-bind:bindValue="calendarAttrs"
:setValues="setValues"
/>
<div class="carousel-content-item date-expired-control">
<Calendar v-model="calendar" v-bind:bindValue="calendarAttrs" :setValues="setValues" :dateCookies="localValues.dateExpired"/>
</div>
<q-btn type="submit" class="btn carousel-content-item">
@ -98,46 +122,26 @@ export default defineComponent({
</q-btn>
</form>
</div>
</div>
</template>
<style lang="scss" scoped>
.vertical-carousel-container {
position: relative;
& .custom-carousel {
user-select: none;
}
& .vertical-carousel-content {
.carousel-form{
max-width: 850px;
margin: 0 auto;
position: absolute;
min-height: fit-content;
bottom: 15vh;
left: 0;
right: 0;
bottom: 110px;
width: min(100%, 845px);
margin: 0 auto;
& .carousel-content-header {
display: flex;
flex-direction: column;
gap: 17px;
color: $white;
text-align: center;
margin-bottom: 27px;
& .carousel-header-title {
font-size: $font-35;
font-weight: 500;
line-height: 30px;
color: currentColor;
}
& .carousel-header-paragraph {
color: currentColor;
font-family: $font-lora;
line-height: 22px;
}
}
& .carousel-content-body {
.carousel-content-body {
display: flex;
flex-wrap: wrap;
border-radius: 10px 0 0 10px;
@ -161,6 +165,7 @@ export default defineComponent({
padding-inline: 53px 34px;
flex: 1;
position: relative;
&:first-child::after {
content: "";
position: absolute;
@ -170,11 +175,14 @@ export default defineComponent({
right: 0;
top: 27px;
bottom: 29px;
@media only screen and (max-width: $med-md) {
display: none;
}
}
&.btn {
&:focus,
&:focus-visible {
outline: none;
@ -191,6 +199,41 @@ export default defineComponent({
}
}
}
& .vertical-carousel-content {
min-height: fit-content;
width: min(100%, 845px);
margin: 0 auto;
& .carousel-content-header {
display: flex;
flex-direction: column;
gap: 17px;
color: $white;
text-align: center;
position: absolute;
bottom: 30vh;
left: 0;
width: 100%;
margin-bottom: 27px;
& .carousel-header-title {
font-size: $font-35;
font-weight: 500;
line-height: 30px;
color: currentColor;
@media only screen and (max-width: $med-xmd) {
padding-left: 20px;
padding-right: 20px;
}
}
& .carousel-header-paragraph {
color: currentColor;
font-family: $font-lora;
line-height: 22px;
}
}
& .carousel-content-footer {
display: grid;
@ -199,12 +242,13 @@ export default defineComponent({
@media only screen and (max-width: $med-xmd) {
padding-inline: 20px;
top: 50%;
transform: translateY(-50%);
& .carousel-content-header {
gap: 15px;
margin-bottom: 49px;
margin-bottom: 20px;
bottom: initial;
top: calc(10dvh + 120px);
& .carousel-header-title {
font-size: $font-28;
line-height: 34px;
@ -215,33 +259,43 @@ export default defineComponent({
font-weight: 500;
}
}
& .carousel-content-body {
margin-bottom: initial;
flex-direction: column;
width: min(100%, 276px);
margin: 0 auto;
& .carousel-content-item {
padding-block: 24px;
&:first-child {
border-radius: 10px 10px 0px 0px;
}
&:last-child {
border-radius: 0 0 10px 10px;
}
}
}
& .carousel-content-footer {
display: none;
}
}
@media only screen and (max-width: $med-md) {
}
@media only screen and (max-width: $med-md) {}
@media only screen and (max-height: 360px) {
/* background-color: tomato; */
}
}
@media only screen and (max-width: $med-xmd) {
.carousel-form{
bottom: 0;
top: 120px;
display: flex;
align-items: center;
}
& .carousel-content-body {
margin-bottom: initial;
flex-direction: column;
width: min(100%, 276px);
margin: 0 auto;
& .carousel-content-item {
padding-block: 24px;
&:first-child {
border-radius: 10px 10px 0px 0px;
}
&:last-child {
border-radius: 0 0 10px 10px;
}
}
}
}
}
</style>

View File

@ -25,10 +25,10 @@ export default defineComponent({
<header class="question-content">
<LogoWhite class="white-logo" />
<p class="question-paragraph">
<!--<p class="question-paragraph">
Review

código comentado

código comentado
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore...
</p>
</p>-->
</header>
<div class="question-form">

View File

@ -34,6 +34,7 @@ export default defineComponent({
default: "",
},
isNew: String,
hasPostalCode: Boolean,
size: {
type: String,
default: "md-card",
@ -77,7 +78,7 @@ export default defineComponent({
<template>
<div class="card-container" :class="size">
<RouterLink
:to="`/product/${id}`"
:to="(hasPostalCode)?`/product/${id}`:''"
class="card-container-head"
:class="[headClass]"
role="heading"
@ -112,7 +113,7 @@ export default defineComponent({
<div class="card-container-body">
<p class="card-name" v-if="title">{{ title }}</p>
<div class="card-values">
<div class="card-values" v-if="hasPostalCode">
<p class="price" v-if="finalValue">{{ finalValue }}</p>
<p class="price offer tachado" v-if="+price !== finalValue">
{{ price }}

View File

@ -20,8 +20,6 @@ export default defineComponent({
messageAttrs,
phone,
phoneAttrs,
query,
queryAttrs,
secondName,
secondNameAttrs,
terms,
@ -40,8 +38,6 @@ export default defineComponent({
emailAttrs,
phone,
phoneAttrs,
query,
queryAttrs,
message,
messageAttrs,
terms,
@ -107,16 +103,6 @@ export default defineComponent({
</p>
</div>
<q-input
v-model="query"
v-bind="queryAttrs"
:error-message="errors.query"
:error="!!errors.query"
bg-color="white"
label="Motivo de consulta"
class="consult"
outlined
/>
<q-input
v-model="message"
v-bind="messageAttrs"

View File

@ -1,6 +1,6 @@
import { Notify } from "quasar";
export function quasarNotify({ message = "", type, timeout = 1000 }) {
export function quasarNotify({ message = "", type, timeout = 3000 }) {
const obj = {
success: () =>
Notify.create({

View File

@ -109,6 +109,14 @@ export function useCheckoutForm() {
isHidden.value = false;
};
const getFormatedDate = (date) => {
if(date){
let dated = new Date(date.replace('Z', ''));
return `${dated.toLocaleString('es-ES', { day: "numeric" })} de ${dated.toLocaleString('es-ES', { month: "short" })}`;
}
return '';
}
// TODO hacer el await de las provincias
/**
* const provinceOptions = getProvinces();
@ -241,7 +249,6 @@ export function useCheckoutForm() {
type: values.paymentMethod,
};
addItem("payment", values.paymentMethod);
const typeObj = {
paypal: async () => {
const {
@ -254,8 +261,10 @@ export function useCheckoutForm() {
const {
data: { data },
} = await apiBack.post("payment", productData);
redsysData.value = data;
redsysData.value = await data;
document.querySelector("input[name='Ds_SignatureVersion']").value = redsysData.value.Ds_SignatureVersion;
document.querySelector("input[name='Ds_MerchantParameters']").value = redsysData.value.Ds_MerchantParameters;
document.querySelector("input[name='Ds_Signature']").value = redsysData.value.Ds_Signature;
redsysFormRef.value.click();
},
default: () => {
@ -328,6 +337,7 @@ export function useCheckoutForm() {
phoneInputRef,
phoneSenderInputRef,
redsysFormRef,
getFormatedDate,
phone: { phoneData, phoneSenderData },

View File

@ -74,9 +74,17 @@ export function usePostalCalendar({ modalItem = "", type = "home" }) {
return isAvailabilityEmpty.value;
});
let DATE_INITIAL
const [YEAR, MONTH, DAY] = fullCurrentDate.replaceAll("/", "-").split("-");
const CURRENT_DATE = `${DAY}-${MONTH}-${YEAR}`;
DATE_INITIAL = CURRENT_DATE
if (availability.value.dateExpired) {
const [yearStorage, monthStorage, dayStorage] = availability.value.dateExpired.replaceAll("/", "-").split("-");
const STORAGE_DATE = `${dayStorage}-${monthStorage}-${yearStorage}`;
DATE_INITIAL = STORAGE_DATE
}
const POSTAL_CODE_INITIAL = availability.value.postalCode ? availability.value.postalCode : ""
const {
handleSubmit,
handleReset,
@ -94,11 +102,11 @@ export function usePostalCalendar({ modalItem = "", type = "home" }) {
min,
max,
},
postalCode: "",
date: CURRENT_DATE,
postalCode: POSTAL_CODE_INITIAL,
date: DATE_INITIAL,
},
initialTouched: {
date: false,
date: availability.value.dateExpired ? true : false,
postalCode: true,
},
});

View File

@ -41,7 +41,6 @@ export function useQuestionForm() {
const [phone, phoneAttrs] = defineField("phone", {
validateOnModelUpdate: false,
});
const [query, queryAttrs] = defineField("query");
const [message, messageAttrs] = defineField("message");
const [terms, termsAttrs] = defineField("terms");
@ -102,8 +101,6 @@ export function useQuestionForm() {
emailAttrs,
phone,
phoneAttrs,
query,
queryAttrs,
message,
messageAttrs,
terms,

View File

@ -283,6 +283,7 @@ export default defineComponent({
:imgSrc="item.image"
:isNew="item.isNew"
:id="item.id"
:hasPostalCode="(item.postalCode !== 'undefined')?true:false"
/>
</template>
</Container>

View File

@ -16,6 +16,7 @@ export default defineComponent({
provinceOptions,
handleClickStep,
stepsFormated,
getFormatedDate,
stepList,
checkoutBlock,
cart,
@ -92,6 +93,7 @@ export default defineComponent({
checkoutBlock,
stepsFormated,
getFormatedDate,
provinceOptions,
totalPrice,
stepList,
@ -141,39 +143,29 @@ export default defineComponent({
<q-page class="checkout-page">
<Container tag="section">
<header class="header-title">
<h1 class="pege-title">¿A quién y dónde lo entregamos"</h1>
<h1 class="pege-title">¿A quién y dónde lo entregamos?</h1>
<p class="page-subtitle checkout">
<!--<p class="page-subtitle checkout">
Review

comentario

comentario
Review

Deje el comentario porque si más adelante queremos utilizar el subtitulo de la pagina ya esta maquetado.

Deje el comentario porque si más adelante queremos utilizar el subtitulo de la pagina ya esta maquetado.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</p>
</p>-->
</header>
<div class="checkout-container">
<div class="checkout-steps">
<div
v-for="({ active, description, name, value }, i) in stepsFormated"
class="step-item-container"
:key="i"
>
<div v-for="({ active, description, name, value }, i) in stepsFormated" 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="[
<div class="circle-step" :class="[
(active || (meta.valid && i == 1) || !checkoutBlock) &&
'active',
]"
>
]">
<span class="step-value">{{ value }}</span>
</div>
<span
class="border-step"
:class="[i == stepList['data'].length - 1 && 'transparent']"
/>
<span class="border-step" :class="[i == stepList['data'].length - 1 && 'transparent']" />
</div>
<div class="step-content">
@ -199,85 +191,37 @@ export default defineComponent({
<div class="checkout-fields">
<div class="field-control field-input">
<q-input
placeholder="Nombre*"
name="name"
type="text"
v-model="name"
v-bind:="nameAttrs"
:error="!!errors.name"
:error-message="errors.name"
outlined
/>
<q-input placeholder="Nombre*" name="name" type="text" v-model="name" v-bind:="nameAttrs"
:error="!!errors.name" :error-message="errors.name" outlined />
</div>
<div class="field-control field-input">
<q-input
placeholder="Apellidos*"
name="surname"
type="text"
v-model="surname"
v-bind:="surnameAttrs"
:error="!!errors.surname"
:error-message="errors.surname"
outlined
/>
<q-input placeholder="Apellidos*" name="surname" type="text" v-model="surname"
v-bind:="surnameAttrs" :error="!!errors.surname" :error-message="errors.surname" outlined />
</div>
<div class="field-control field-input">
<q-input
placeholder="Dirección*"
name="address"
type="text"
v-model="address"
v-bind:="addressAttrs"
:error="!!errors.address"
:error-message="errors.address"
outlined
/>
<q-input placeholder="Dirección*" name="address" type="text" v-model="address"
v-bind:="addressAttrs" :error="!!errors.address" :error-message="errors.address" outlined />
</div>
<div class="field-control field-input">
<q-input
placeholder="Código postal*"
name="postalCode"
type="text"
mask="#####"
v-model="postalCode"
v-bind:="postalCodeAttrs"
:error="!!errors.postalCode"
:error-message="errors.postalCode"
ref="postalCodeRef"
readonly
outlined
@mouseenter="showTooltip"
@mouseleave="hideTooltip"
>
<q-input placeholder="Código postal*" name="postalCode" type="text" mask="#####"
v-model="postalCode" v-bind:="postalCodeAttrs" :error="!!errors.postalCode"
:error-message="errors.postalCode" ref="postalCodeRef" readonly outlined @mouseenter="showTooltip"
@mouseleave="hideTooltip">
<template #after>
<q-btn
to="/"
:style="'--clr: #ffffff'"
class="btn custom-btn-input paragraph-sm"
label="EDITAR"
/>
<q-btn to="/" :style="'--clr: #ffffff'" class="btn custom-btn-input paragraph-sm"
label="EDITAR" />
</template>
</q-input>
<div
ref="postalCodeTooltip"
:style="[floatingStyles, '--clr: #117564']"
:class="['tooltip ', isHidden && 'hidden']"
@mouseenter="showTooltip"
@mouseleave="hideTooltip"
>
<div ref="postalCodeTooltip" :style="[floatingStyles, '--clr: #117564']"
:class="['tooltip ', isHidden && 'hidden']" @mouseenter="showTooltip" @mouseleave="hideTooltip">
<p class="paragraph-sm">
No se puede editar este campo
<a
href="https://www.google.com/maps"
rel="noreferrer noopener"
target="_blank"
class="paragraph-sm link"
>
<a href="https://www.google.com/maps" rel="noreferrer noopener" target="_blank"
class="paragraph-sm link">
¿No conoce su código postal?
</a>
</p>
@ -285,49 +229,23 @@ export default defineComponent({
</div>
<div class="field-control field-select">
<q-select
name="province"
v-model="province"
v-bind:="provinceAttrs"
:error="!!errors.province"
:error-message="errors.province"
:options="provinceOptions"
option-value="code"
option-label="name"
label="País*"
stack-label
map-options
emit-value
outlined
/>
<q-select name="province" v-model="province" v-bind:="provinceAttrs" :error="!!errors.province"
:error-message="errors.province" :options="provinceOptions" option-value="code"
option-label="name" label="País*" stack-label map-options emit-value outlined />
</div>
<div class="field-control field-select">
<q-input
placeholder="Ciudad*"
name="city"
type="text"
v-model="city"
v-bind:="cityAttrs"
:error="!!errors.city"
:error-message="errors.city"
outlined
/>
<q-input placeholder="Ciudad*" name="city" type="text" v-model="city" v-bind:="cityAttrs"
:error="!!errors.city" :error-message="errors.city" outlined />
</div>
<div class="field-control field-input telephone">
<vue-tel-input
v-model="phone"
v-bind="phoneAttrs"
:styleClasses="[
<vue-tel-input v-model="phone" v-bind="phoneAttrs" :styleClasses="[
'custom-input',
!!errors.phone && 'error',
]"
ref="phoneInputRef"
:inputOptions="{
]" ref="phoneInputRef" :inputOptions="{
placeholder: 'Teléfono*',
}"
/>
}" />
<p v-if="!!errors.phone" class="error">
{{ errors.phone }}
</p>
@ -342,57 +260,30 @@ export default defineComponent({
<div class="checkout-fields">
<div class="field-control field-input">
<q-input
placeholder="Nombre y apellidos o nombre de empresa"
name="senderName"
type="text"
v-model="senderName"
v-bind:="senderNameAttrs"
:error="!!errors.senderName"
:error-message="errors.senderName"
outlined
/>
<q-input placeholder="Nombre y apellidos o nombre de empresa" name="senderName" type="text"
v-model="senderName" v-bind:="senderNameAttrs" :error="!!errors.senderName"
:error-message="errors.senderName" outlined />
</div>
<div class="field-control field-input">
<q-input
placeholder="CIF / NIF"
name="senderCifNif"
type="text"
v-model="senderCifNif"
v-bind:="senderCifNifAttrs"
:error="!!errors.senderCifNif"
:error-message="errors.senderCifNif"
outlined
/>
<q-input placeholder="CIF / NIF" name="senderCifNif" type="text" v-model="senderCifNif"
v-bind:="senderCifNifAttrs" :error="!!errors.senderCifNif" :error-message="errors.senderCifNif"
outlined />
</div>
<div class="field-control field-input">
<q-input
placeholder="Email"
name="senderEmail"
type="email"
v-model="senderEmail"
v-bind:="senderEmailAttrs"
:error="!!errors.senderEmail"
:error-message="errors.senderEmail"
outlined
/>
<q-input placeholder="Email" name="senderEmail" type="email" v-model="senderEmail"
v-bind:="senderEmailAttrs" :error="!!errors.senderEmail" :error-message="errors.senderEmail"
outlined />
</div>
<div class="field-control field-input telephone">
<vue-tel-input
v-model="senderPhone"
v-bind="senderPhoneAttrs"
:styleClasses="[
<vue-tel-input v-model="senderPhone" v-bind="senderPhoneAttrs" :styleClasses="[
'custom-input',
!!errors.senderPhone && 'error',
]"
ref="phoneSenderInputRef"
:inputOptions="{
]" ref="phoneSenderInputRef" :inputOptions="{
placeholder: 'Teléfono*',
}"
/>
}" />
<p v-if="!!errors.senderPhone" class="error">
{{ errors.senderPhone }}
</p>
@ -401,43 +292,19 @@ export default defineComponent({
<div class="field-control field-input">
<q-input
placeholder="Notas sobre tu pedido (Opcional), por ejemplo, notas especiales para la entrega"
name="senderNotes"
type="textarea"
v-model="senderNotes"
v-bind:="senderNotesAttrs"
:error="!!errors.senderNotes"
:error-message="errors.senderNotes"
class="message"
autogrow
outlined
/>
name="senderNotes" type="textarea" v-model="senderNotes" v-bind:="senderNotesAttrs"
:error="!!errors.senderNotes" :error-message="errors.senderNotes" class="message" autogrow
outlined />
</div>
</div>
</div>
</q-form>
<form
v-if="paymentMethod === 'redsys' && meta.valid"
name="from"
action="https://sis-t.redsys.es:25443/sis/realizarPago"
method="POST"
class="hide"
>
<input
type="hidden"
name="Ds_SignatureVersion"
:value="redsysData.Ds_SignatureVersion"
/>
<input
type="hidden"
name="Ds_MerchantParameters"
:value="redsysData.Ds_MerchantParameters"
/>
<input
type="hidden"
name="Ds_Signature"
:value="redsysData.Ds_Signature"
/>
<form v-if="paymentMethod === 'redsys' && meta.valid" name="from"
action="https://sis-t.redsys.es:25443/sis/realizarPago" method="POST" class="hide">
<input type="text" name="Ds_SignatureVersion" :value="redsysData.Ds_SignatureVersion" />
<input type="text" name="Ds_MerchantParameters" :value="redsysData.Ds_MerchantParameters" />
<input type="text" name="Ds_Signature" :value="redsysData.Ds_Signature" />
<input ref="redsysFormRef" type="submit" value="Go to pay" />
</form>
</div>
@ -449,7 +316,7 @@ export default defineComponent({
</header>
<div class="checkout-delivery-body">
<p class="green-text">13 de julio - De 11h - 12 h</p>
<p class="green-text">{{ getFormatedDate((cart.length > 0)?cart[0].dated:'') }}</p>
</div>
</div>
@ -462,11 +329,7 @@ export default defineComponent({
<div class="checkout-summary-body gray-bg">
<ul class="checkout-summary-list">
<li
class="checkout-summary-item"
v-for="({ name, price }, index) in cart"
:key="index"
>
<li class="checkout-summary-item" v-for="({ name, price }, index) in cart" :key="index">
<p>
{{ name }}
<span>{{ price }}</span>
@ -487,32 +350,19 @@ export default defineComponent({
<div class="checkout-payment-methods gray-bg">
<header class="checkout-aside-header">
<strong
class="checkout-aside-title"
:style="!!errors.paymentMethod && 'color: red'"
>
<strong class="checkout-aside-title" :style="!!errors.paymentMethod && 'color: red'">
Método de pago
</strong>
<p v-if="!!errors.paymentMethod"></p>
</header>
<div class="checkout-payment-body">
<q-radio
v-model="paymentMethod"
v-bind="paymentMethodAttrs"
val="paypal"
color="primary"
>
<q-radio v-model="paymentMethod" v-bind="paymentMethodAttrs" val="paypal" color="primary">
<p>Paypal</p>
</q-radio>
<q-radio
v-model="paymentMethod"
v-bind="paymentMethodAttrs"
val="redsys"
color="primary"
>
<p>Redsys</p>
<q-radio v-model="paymentMethod" v-bind="paymentMethodAttrs" val="redsys" color="primary">
<p>Tarjeta de crédito</p>
</q-radio>
</div>
</div>
@ -525,13 +375,7 @@ export default defineComponent({
</p>
</q-checkbox>
<q-btn
flat
class="btn"
type="submit"
form="checkout-form"
:loading="isLoadingSubmit"
>
<q-btn flat class="btn" type="submit" form="checkout-form" :loading="isLoadingSubmit">
PROCEDER AL PAGO
</q-btn>
</div>
@ -585,13 +429,16 @@ export default defineComponent({
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;
}
@ -603,6 +450,7 @@ export default defineComponent({
flex-direction: column;
align-items: center;
font-family: $font-questrial;
h4 {
font-size: 1rem;
font-weight: 700;
@ -611,6 +459,7 @@ export default defineComponent({
margin-bottom: 4px;
line-height: 1.3;
}
p {
font-size: 0.875rem;
color: $text-default;
@ -631,6 +480,7 @@ export default defineComponent({
width: 100%;
margin-bottom: 21px;
border-radius: 5px;
& h3 {
color: $text-default;
font-weight: 600;
@ -647,8 +497,10 @@ export default defineComponent({
& .checkout-form {
flex: 1 0 min(100%, 795px);
}
& .checkout-aside {
flex: 1 0 min(100%, 329px);
& .checkout-delivery-date,
& .checkout-summary,
& .checkout-payment-methods {
@ -672,6 +524,7 @@ export default defineComponent({
visibility: hidden;
height: 0;
overflow: hidden;
&.active {
height: min-content;
padding-block: 16px 18px;
@ -683,6 +536,7 @@ export default defineComponent({
& .checkout-summary {
margin-bottom: 33px;
& .checkout-aside-header,
& .checkout-summary-body,
& .checkout-summary-footer {
@ -691,6 +545,7 @@ export default defineComponent({
& .checkout-aside-header {
padding-block: 16px 17px;
& .checkout-aside-title {
font-family: $font-lora;
font-weight: 600;
@ -701,6 +556,7 @@ export default defineComponent({
& .checkout-summary-body {
padding-bottom: 23px;
& p {
font-size: $font-12;
line-height: 21px;
@ -713,12 +569,14 @@ export default defineComponent({
flex-direction: column;
gap: 4px;
margin-bottom: 4px;
& .checkout-summary-item p {
display: flex;
justify-content: space-between;
}
}
}
& .checkout-summary-footer {
display: flex;
justify-content: space-between;
@ -737,19 +595,23 @@ export default defineComponent({
& .checkout-payment-methods {
padding: 9px 16px 20px 21px;
margin-bottom: 21px;
& .checkout-aside-header {
margin-bottom: 14px;
}
& .checkout-payment-body {
display: flex;
flex-direction: column;
gap: 12px;
& p {
width: min(100%, 200px);
display: inline-flex;
justify-content: space-between;
gap: 31px;
font-size: $font-12;
& .card-flags {
display: inline-flex;
align-items: center;
@ -773,6 +635,7 @@ export default defineComponent({
display: flex;
flex-direction: column;
gap: 23px;
& .terms p {
margin-left: 10px;
font-size: $font-12;
@ -799,29 +662,36 @@ export default defineComponent({
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;
@ -875,8 +745,9 @@ export default defineComponent({
& .form-fields-container {
display: flex;
flex-wrap: wrap;
&.delivery {
}
&.delivery {}
&.sender {
margin-top: 12px;
}
@ -886,6 +757,7 @@ export default defineComponent({
display: flex;
flex-wrap: wrap;
gap: 12px 9px;
@media only screen and (max-width: $med-lg) {
gap: 15px;
}
@ -896,6 +768,7 @@ export default defineComponent({
&.telephone {
flex: 0 0 calc(50% - 5px);
@media only screen and (max-width: $med-lg) {
flex: 1 0 min(100%, 390px);
}
@ -905,10 +778,12 @@ export default defineComponent({
label {
padding-bottom: 10px;
}
& .q-field__control {
background-color: #fff;
height: 40px;
border: 1px solid $primary-light;
& input {
padding: 0px 0px 0px 20px;
font-family: $font-questrial;
@ -923,20 +798,24 @@ export default defineComponent({
&.text-negative {
border-color: $negative;
}
&::after,
&::before {
display: none;
}
}
.q-field__marginal {
height: 40px;
padding-right: 30px;
}
}
.q-field--error .q-field__bottom {
padding-top: 4px;
font-size: 0.675rem;
}
&.field-select {
.q-field__control {
min-height: initial;
@ -944,23 +823,28 @@ export default defineComponent({
height: 40px;
padding: 0px 30px;
border: 1px solid $primary-light;
.q-field__native span {
display: none;
}
}
.q-field__append {
height: 40px;
}
.q-field__label {
font-family: $font-questrial;
color: $text-default !important;
}
.q-field__control-container {
padding-top: 0;
height: 36px;
}
}
}
@media only screen and (max-width: $med-lg) {
&.sender {
margin-top: 45px;
@ -972,6 +856,7 @@ export default defineComponent({
padding: 10.5px 1px;
border-radius: 4px;
transition: 200ms ease-in-out;
&:hover {
border-color: $black;
}

View File

@ -55,7 +55,7 @@ export default defineComponent({
if (!value) return push("/");
} */
if (cart.length === 0) return push("/");
//if (cart.length === 0) return push("/");
await getSuccessData();
});
@ -130,12 +130,12 @@ export default defineComponent({
<div class="checkout-success" id="success-block">
<h6 class="checkout-success-title green-text">
Has efectuado la siguiente compra
Gracias por realizar tu compra
</h6>
<div class="checkout-success-body">
<div class="checkout-success-content">
<ul class="checkout-success-list">
<!--<ul class="checkout-success-list">
<li
v-for="({ name, price, image }, index) in cart"
:key="index"
@ -158,13 +158,13 @@ export default defineComponent({
<p class="checkout-product-price">{{ price }}</p>
</div>
</li>
</ul>
</ul>-->
</div>
<footer class="checkout-success-footer">
<!--<footer class="checkout-success-footer">
<p class="checkout-success-paragraph">Total</p>
<p class="checkout-success-paragraph">{{ totalPrice.toFixed(2) }}</p>
</footer>
</footer>-->
</div>
</div>
</q-page>

View File

@ -2,6 +2,7 @@
import { storeToRefs } from "pinia";
import { defineComponent, onBeforeMount, ref } from "vue";
import IconArrowCircleFilledRight from "src/components/icons/IconArrowCircleFilledRight.vue";
import VerticalCarouselImgs from "src/components/quasar-components/carousel/VerticalCarouselImgs.vue";
import Swiper from "src/components/swiper/Swiper.vue";
import Card from "src/components/ui/Card.vue";
@ -18,6 +19,7 @@ export default defineComponent({
Card,
},
setup() {
const banners = ref()
const mobileStore = useMobileStore();
const { isCarouselVisible, isOpenNav, screenWidth } =
storeToRefs(mobileStore);
@ -26,35 +28,37 @@ export default defineComponent({
const { getProducts } = cartStore;
const { products, homeSection } = storeToRefs(cartStore);
async function getBanners() {
Review

no se utiliza la función

no se utiliza la función
Review

Deje la función porque es la función que va a buscar los banners, entiendo que el día de mañana se utilizará.

Deje la función porque es la función que va a buscar los banners, entiendo que el día de mañana se utilizará.
//const { data: { data } } = await apiBack("/banners/")
return [
{
"url": "/assets/Cabecera-flornatura-1.jpg",
"longName": "Regala un verano lleno de flores y plantas"
},
{
"url": "/assets/Cabecera-flornatura-2.jpg",
"longName": "Regala un verano lleno de flores y plantas"
},
{
"url": "/assets/Cabecera-flornatura-3.jpg",
"longName": "Regala un verano lleno de flores y plantas"
}
]
}
onBeforeMount(async () => {
//banners.value = await getBanners();
await getProducts();
});
const slidesContent = ref([]);
onBeforeMount(async () => {
const images = await new Promise((resolve) => {
setTimeout(() => {
resolve([
"assets/1.jpg",
"assets/2.jpg",
"assets/3.jpg",
"assets/4.jpg",
"assets/5.jpg",
]);
}, 1000);
});
slidesContent.value = images;
});
return {
isCarouselVisible,
slidesContent,
screenWidth,
homeSection,
isOpenNav,
products,
banners
};
},
});
@ -63,7 +67,7 @@ export default defineComponent({
<template>
<q-page>
<q-no-ssr>
<VerticalCarouselImgs :imgsArr="slidesContent" class="home-carousel" />
<VerticalCarouselImgs class="home-carousel" />
</q-no-ssr>
<section class="products-section" ref="homeSection">
@ -77,25 +81,15 @@ export default defineComponent({
<div class="products-body">
<Container cardContainer>
<template
v-for="({ id, name, price, image, isNew }, i) in products?.data"
:key="id"
>
<Card
v-if="i < 8"
:id="id"
:price="price"
:title="name"
:imgSrc="image"
:isNew="isNew"
imgClass="list-products"
size="md-card"
/>
<template v-for="({ id, name, price, image, isNew, postalCode }, i) in products?.data" :key="id">
<Card v-if="i < 8" :id="id" :price="price" :title="name" :imgSrc="image" :isNew="isNew" :hasPostalCode="(postalCode !== 'undefined')?true:false"
imgClass="list-products" size="md-card" />
</template>
</Container>
<RouterLink class="btn rounded outlined" to="/categoria/all">
Ver todos los diseños <IconArrowCircleFilledRight />
Ver todos los diseños
<IconArrowCircleFilledRight />
</RouterLink>
</div>
</section>
@ -112,20 +106,10 @@ export default defineComponent({
<div class="products-selection-body">
<q-no-ssr>
<Swiper>
<template
v-for="({ id, isNew, price, name, image }, i) in products.data"
:key="id"
>
<template v-for="({ id, isNew, price, name, image }, i) in products.data" :key="id">
<swiper-slide class="swiper-slide" v-if="i < 10">
<Card
:id="id"
:price="price"
:title="name"
:imgSrc="image"
:isNew="isNew"
imgClass="carousel"
size="lg-card"
/>
<Card :id="id" :price="price" :title="name" :imgSrc="image" :isNew="isNew" imgClass="carousel"
size="lg-card" />
</swiper-slide>
</template>
</Swiper>
@ -134,7 +118,8 @@ export default defineComponent({
<footer class="products-selection-footer">
<RouterLink class="btn rounded outlined pd-icon" to="/">
Ver todas las plantas <IconArrowCircleFilledRight />
Ver todas las plantas
<IconArrowCircleFilledRight />
</RouterLink>
</footer>
</section>
@ -177,11 +162,9 @@ export default defineComponent({
scroll-margin: 30px;
& .products-section-header {
& .products-header-title {
}
& .products-header-title {}
& .products-header-paragraph {
}
& .products-header-paragraph {}
}
& .products-body {
@ -193,8 +176,7 @@ export default defineComponent({
}
@media only screen and (max-width: $med-xmd) {
& .products-body {
}
& .products-body {}
}
}

View File

@ -77,7 +77,7 @@ export default defineComponent({
const { products, addCartLoadingBtn } = storeToRefs(cartStore);
onBeforeMount(async () => {
await getProduct(route.params.id);
await getProduct(route.params.id, availability.value);
});
watch(
@ -128,10 +128,10 @@ export default defineComponent({
const checkImageValidity = (imageLink) => {
const validExtensions = [".jpg", ".jpeg", ".png"];
if (imageLink) {
/*if (imageLink) {
const extension = imageLink.substring(imageLink.lastIndexOf("."));
return validExtensions.includes(extension.toLowerCase());
}
}*/
return true;
};
@ -268,8 +268,8 @@ export default defineComponent({
</div>
</div>
<footer class="product-content-footer">
<p class="product-share-paragraph">Conmparte con tus amigos</p>
<!--<footer class="product-content-footer">
<p class="product-share-paragraph">Comparte con tus amigos</p>
<div class="product-share-content">
<a href="#" class="product-share-item"><IconShare /></a>
@ -278,7 +278,7 @@ export default defineComponent({
<a href="#" class="product-share-item"><IconEmail /></a>
<a href="#" class="product-share-item"><IconWhatsapp /></a>
</div>
</footer>
</footer>-->
</div>
<div
@ -336,7 +336,7 @@ export default defineComponent({
<Container cardContainer class="no-padding">
<template
v-for="(
{ image, discount, isNew, name, price, id }, i
{ image, discount, isNew, name, price, id, postalCode }, i
) in products.data"
:key="id"
>
@ -348,6 +348,7 @@ export default defineComponent({
:imgSrc="image"
:isNew="isNew"
:id="id"
:hasPostalCode="(postalCode !== 'undefined')?true:false"
/>
</template>
</Container>

View File

@ -147,11 +147,10 @@ export const useCartStore = defineStore("cart", () => {
routeId.value = id;
try {
const params = transformOptionsToParams(options);
const promises = [
apiBack.get(`products/${+id - 1}`),
apiBack.get(`products/${+id}`),
apiBack.get(`products/${+id + 1}`),
apiBack.get(`products/${+id - 1}`, { params }),
apiBack.get(`products/${+id}`, { params }),
apiBack.get(`products/${+id + 1}`, { params }),
];
const results = await Promise.allSettled(promises);
const [prev, current, next] = results.map((res) => {
@ -195,13 +194,13 @@ export const useCartStore = defineStore("cart", () => {
const params = transformOptionsToParams(
availabilityForm.value || availability.value
);
await getProducts(params);
const correctProduct = await apiBack.get(`products/${product.id}`, { params });
const hasCurrentProduct = computed(() => {
return cart.value.find((p) => p.id === product.id);
});
if (isEmpty.value) {
if (correctProduct.data.length === 0) {
push("/");
return quasarNotify({
message:
@ -210,15 +209,6 @@ export const useCartStore = defineStore("cart", () => {
});
}
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",

View File

@ -1,14 +0,0 @@
import { defineStore } from "pinia";
export const useTextInputStore = defineStore("text-input", () => {
const dedication = ref("");
function handleDedicationSubmit() {
console.log(dedication);
}
return {
dedication,
handleDedicationSubmit,
};
});

View File

@ -15,9 +15,6 @@ const questionObjVal = {
phone: z
.string({ required_error: M.requiredMessage })
.min(1, M.requiredMessage),
query: z
.string({ required_error: M.requiredMessage })
.min(1, M.requiredMessage),
message: z
.string({ required_error: M.requiredMessage })
.min(1, M.requiredMessage),