Files
consumocuidado/components/ProductModal.vue
2025-09-09 16:28:25 +02:00

311 lines
7.1 KiB
Vue

<template>
<transition name="modal">
<div v-if="product" class="mask">
<div class="wrapper" @click.self="handleEmit">
<div class="container">
<div class="element header">
<h2>Interesado en comprar el producto</h2>
<img src="@/assets/img/latienda-lineapuntos-2.svg" alt="" />
</div>
<div class="modal-body">
<form @submit.prevent="sendForm">
<div>
<BFormGroup class="element">
<BFormInput
v-model="form.email"
required
class="input"
size="lg"
placeholder="Email"
/>
</BFormGroup>
</div>
<div>
<BFormGroup class="element">
<BFormInput
v-model="form.telephone"
required
class="input"
size="lg"
placeholder="Teléfono"
/>
</BFormGroup>
</div>
<div v-if="!isAuthenticated" class="element">
<BButton
class="input"
size="lg"
variant="outline-primary w-100"
@click="redirectToLogin"
>Login</BButton
>
</div>
<div class="element coop">
<!-- <BCard
img-src="https://placekitten.com/1000/300"
img-alt="Card image"
img-left
>
<BCardText>
<h3>Cooperativa</h3>
<p>Dirección</p>
</BCardText>
</BCard> -->
<div class="content">
<img :src="getImgUrl(product.company.logo)" alt="" />
<div class="text">
<h3>{{ product?.company?.company_name }}</h3>
<p>{{ product?.company?.address }}</p>
<br />
</div>
</div>
</div>
<div class="element coop">
<!-- <BCard
img-src="https://placekitten.com/1000/300"
img-alt="Card image"
img-left
>
<BCardText>
<h3>Cooperativa</h3>
<p>Dirección</p>
</BCardText>
</BCard> -->
<div class="content">
<img :src="getImgUrl(product.image)" alt="" />
<div class="text">
<h3>{{ product?.name }}</h3>
<p>{{ product?.price }} </p>
<p class="text-muted">
{{ product?.shipping_cost || 'Sin gastos de envío' }}
</p>
</div>
</div>
</div>
<div class="element">
<BFormTextarea
id="textarea-no-resize"
v-model="form.comment"
class="input"
placeholder="Comentarios"
rows="3"
no-resize
/>
</div>
<div>
<BButton type="submit" class="enviar-button">
<v-progress-circular
v-if="loading"
:size="15"
:width="2"
indeterminate
/>
<span v-else>Enviar</span>
</BButton>
</div>
</form>
</div>
</div>
</div>
</div>
</transition>
</template>
<script>
import { useAuthStore } from '@/stores/auth'
export default {
props: {
product: { type: Object, default: () => ({}) },
},
emits: ['closeModal'],
setup() {
const authStore = useAuthStore()
return {
authStore
}
},
data() {
return {
isAuthenticated: true,
form: {
email: undefined,
telephone: undefined,
company: undefined,
product: undefined,
comment: '',
},
loading: false,
}
},
mounted() {
this.isAuthenticated = this.authStore.isAuthenticated
if (this.isAuthenticated) {
const email = this.authStore.email
this.form.email = email
}
},
methods: {
async sendForm() {
this.form.company = this.product.company.id
this.form.product = this.product.id
this.loading = true
let response
let status
const config = useRuntimeConfig()
try {
response = await $fetch(`/purchase_email/`, {
baseURL: config.public.baseURL,
method: 'POST',
body: { ...this.form }
})
status = response.status
} catch {
status = 500
}
this.loading = false
this.$emit('closeModal', status)
},
getImgUrl(image) {
if (image) return image
return `@/assets/img/consumo-default.png`
},
redirectToLogin() {
this.$router.push({
name: 'login',
})
},
handleEmit() {
this.$emit('closeModal', null)
},
},
}
</script>
<style lang="css" scoped>
.mask {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: table;
transition: opacity 0.3s ease;
}
.wrapper {
display: table-cell;
vertical-align: middle;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 500px;
margin: 0px auto;
padding: 20px 40px;
background-color: #fff;
border-radius: 7px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
transition: all 0.3s ease;
}
.element {
margin-bottom: 10px;
}
.header {
display: flex;
flex-direction: column;
align-items: center;
}
.header > h2 {
margin-bottom: 20px;
text-align: center;
font-size: 1.125rem;
font-weight: 500;
color: #374493;
}
.header > img {
width: 50px;
}
.modal-body {
width: 300px;
}
.input {
font-size: 0.75rem;
margin: 0;
}
.input-group-text {
width: 48px;
border-right: none;
background-color: #ffffff;
}
.coop {
border: 1px lightgray solid;
border-radius: 5px;
}
.coop > .content {
display: flex;
flex-direction: row;
align-items: flex-end;
margin: 5px 10px;
}
.coop > .content > img {
width: 80px;
height: 80px;
object-fit: cover;
margin-right: 5px;
}
.coop > .content > .text > h3,
p {
font-size: 0.75rem;
margin-bottom: 0.5rem;
}
.enviar-button {
width: 100%;
background: #fd6871;
border-color: #fd6871;
color: white;
}
/*
* The following styles are auto-applied to elements with
* transition="modal" when their visibility is toggled
* by Vue.js.
*
* You can easily play with the modal transition by editing
* these styles.
*/
.modal-enter {
opacity: 0;
}
.modal-leave-active {
opacity: 0;
}
.modal-enter .modal-container,
.modal-leave-active .modal-container {
-webkit-transform: scale(1.1);
transform: scale(0.8);
}
</style>