Merge pull request 'develop' (#10) from develop into master

Reviewed-on: #10
Reviewed-by: Pablo Natek <pablone@verdnatura.es>
This commit is contained in:
Pablo Natek 2024-04-22 11:35:54 +00:00
commit 4dbc6833d9
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,40 +66,35 @@ 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)
return res.status(200).send({
data: {
id: payment.id,
message: "payment completed successfully",
}
})
} else {
return res.status(422).send({
data: {
message: "payment not successful"
}
})
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: {
...data,
message: "Payment success"
}
}
});
})
}
if (type === "redsys") {
await redsysProviders.success(orderId)
return res.status(200).send({
data: {
message: "Payment success"
}
})
}
} catch (error) {
throw error;
return res.status(422).send({
data: {
message: "Payment Error"
}
})
}
}
}
module.exports = new PaymentServices();
module.exports = new PaymentServices();

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>
@ -108,4 +108,4 @@ export default defineComponent({
/>
</div>
</div>
</template>
</template>

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 {
// 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="#####"
@ -110,4 +117,4 @@ export default defineComponent({
}
}
}
</style>
</style>

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);
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 => {
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"
/>
<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">
{{ item.longName }}
</h1>
</header>
</div>
</q-carousel-slide>
</q-carousel>
<div class="vertical-carousel-content">
<header class="carousel-content-header">
<h1 class="carousel-header-title">
Regala un verano lleno de flores y plantas
</h1>
</header>
<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,36 +122,110 @@ 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;
}
.carousel-content-body {
display: flex;
flex-wrap: wrap;
border-radius: 10px 0 0 10px;
overflow: hidden;
min-height: 96px;
/* & .carousel-content {
border-radius: 10px 10px 0 0;
overflow: hidden;
flex-direction: column;
justify-content: center;
align-items: center;
display: flex;
flex: 2;
background-color: $white;
} */
& .carousel-content-item {
display: flex;
align-items: center;
padding-inline: 53px 34px;
flex: 1;
position: relative;
&:first-child::after {
content: "";
position: absolute;
width: 1px;
opacity: 0.2;
background-color: $text-normal-100;
right: 0;
top: 27px;
bottom: 29px;
@media only screen and (max-width: $med-md) {
display: none;
}
}
&.btn {
&:focus,
&:focus-visible {
outline: none;
}
}
&:not(:last-child) {
background-color: $white;
}
&:last-child {
border-radius: 0 10px 10px 0;
padding-inline: 56px;
}
}
}
& .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 {
@ -137,61 +235,6 @@ export default defineComponent({
}
}
& .carousel-content-body {
display: flex;
flex-wrap: wrap;
border-radius: 10px 0 0 10px;
overflow: hidden;
min-height: 96px;
/* & .carousel-content {
border-radius: 10px 10px 0 0;
overflow: hidden;
flex-direction: column;
justify-content: center;
align-items: center;
display: flex;
flex: 2;
background-color: $white;
} */
& .carousel-content-item {
display: flex;
align-items: center;
padding-inline: 53px 34px;
flex: 1;
position: relative;
&:first-child::after {
content: "";
position: absolute;
width: 1px;
opacity: 0.2;
background-color: $text-normal-100;
right: 0;
top: 27px;
bottom: 29px;
@media only screen and (max-width: $med-md) {
display: none;
}
}
&.btn {
&:focus,
&:focus-visible {
outline: none;
}
}
&:not(:last-child) {
background-color: $white;
}
&:last-child {
border-radius: 0 10px 10px 0;
padding-inline: 56px;
}
}
}
& .carousel-content-footer {
display: grid;
place-items: center;
@ -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">
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">
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="[
(active || (meta.valid && i == 1) || !checkoutBlock) &&
'active',
]"
>
<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="[
'custom-input',
!!errors.phone && 'error',
]"
ref="phoneInputRef"
:inputOptions="{
placeholder: 'Teléfono*',
}"
/>
<vue-tel-input v-model="phone" v-bind="phoneAttrs" :styleClasses="[
'custom-input',
!!errors.phone && 'error',
]" 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="[
'custom-input',
!!errors.senderPhone && 'error',
]"
ref="phoneSenderInputRef"
:inputOptions="{
placeholder: 'Teléfono*',
}"
/>
<vue-tel-input v-model="senderPhone" v-bind="senderPhoneAttrs" :styleClasses="[
'custom-input',
!!errors.senderPhone && 'error',
]" 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;
}
@ -1007,4 +892,4 @@ export default defineComponent({
font-family: "Roboto" !important;
}
}
</style>
</style>

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() {
//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

@ -28,11 +28,11 @@ export default defineComponent({
name: "ProductPage",
components: {
IconPencilGreen,
IconWhatsapp,
IconLinkedin,
IconTwitter,
IconShare,
IconEmail,
IconWhatsapp,
IconLinkedin,
IconTwitter,
IconShare,
IconEmail,
DudasSection,
Container,
Card,
@ -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),