floranet/src/components/ui/Modal.vue

332 lines
7.5 KiB
Vue

<script>
import { defineComponent } from "vue";
import { usePostalCalendar } from "src/hooks/usePostalCalendar";
import Calendar from "../@inputs/Calendar.vue";
import PostalCode from "../@inputs/PostalCode.vue";
import PriceRange from "../@inputs/PriceRange.vue";
import IconCloseModal from "../icons/IconCloseModal.vue";
import IconSearch from "../icons/IconSearch.vue";
export default defineComponent({
name: "modal-component",
components: {
IconSearch,
IconCloseModal,
PriceRange,
Calendar,
PostalCode,
},
props: {
modalItem: {
type: String,
default: "",
},
typeModal: {
type: String,
default: "",
},
},
setup({ modalItem, typeModal }) {
const {
onSubmit,
setValues,
setFieldError,
fields: {
calendar,
calendarAttrs,
postalCode,
postalCodeAttrs,
priceRange,
priceRangeAttrs,
},
isPostalCalendarEmpty,
isAvailabilityEmpty,
errors,
modalStore,
} = usePostalCalendar({
modalItem,
type: typeModal,
});
const modalTextContent = {
isOpenAvailability: {
title: "Disponibilidad",
subtitle: "Elige a dónde y cuando quieres enviar el ramo",
},
isOpenFilters: {
title: "Filtros",
subtitle: "Personaliza tu búsqueda",
},
};
return {
errors,
onSubmit,
modalStore,
modalTextContent,
setValues,
setFieldError,
isAvailabilityEmpty,
isPostalCalendarEmpty,
postalCode,
postalCodeAttrs,
calendar,
calendarAttrs,
priceRange,
priceRangeAttrs,
};
},
});
</script>
<template>
<q-dialog v-model="modalStore[modalItem]" class="modal-container">
<q-card class="modal-content">
<q-btn flat round color="primary" class="close-modal-btn" v-close-popup>
<IconCloseModal />
</q-btn>
<q-card-section class="modal-header" role="heading">
<h5 class="modal-header-title subtitle green-text">
{{ modalTextContent[modalItem].title }}
</h5>
</q-card-section>
<q-card-section
class="modal-body"
:class="modalItem === 'isOpenAvailability' && 'availability'"
>
<p
class="modal-body-paragraph"
:class="modalItem === 'isOpenFilters' && 'green-text'"
>
{{ modalTextContent[modalItem].subtitle }}
</p>
<div class="modal-body-content">
<form @submit="onSubmit" id="filters-form">
<div
v-if="modalItem === 'isOpenFilters'"
class="modal-body-filters"
>
<div class="filter-field">
<PriceRange
:minDefault="0"
:maxDefault="200"
v-model="priceRange"
v-bind:bindValue="priceRangeAttrs"
:min="priceRange.min"
:max="priceRange.max"
/>
</div>
</div>
<div
v-if="modalItem === 'isOpenAvailability'"
class="modal-body-availability"
>
<PostalCode
v-model="postalCode"
v-bind:bindValue="postalCodeAttrs"
:setFieldError="setFieldError"
/>
<Calendar
v-model="calendar"
v-bind:bindValue="calendarAttrs"
:setValues="setValues"
/>
</div>
</form>
</div>
</q-card-section>
<q-btn
flat
type="submit"
align="center"
class="modal-footer"
form="filters-form"
:disabled="modalItem === 'isOpenFilters' && isPostalCalendarEmpty"
>
<IconSearch />
<p>ver disponibilidad</p>
</q-btn>
</q-card>
</q-dialog>
</template>
<style lang="scss">
.modal-container {
& .q-dialog__backdrop {
background: #ffffff90;
}
& .modal-content {
display: flex;
flex-direction: column;
border-radius: 20px;
background-color: $white;
border: 1px solid $primary;
overflow: hidden;
width: min(100%, 554px);
box-shadow: initial;
position: relative;
& .close-modal-btn {
position: absolute;
top: 14px;
right: 22px;
z-index: 1;
@media only screen and (max-width: $med-md) {
& svg {
width: 18px;
height: 18px;
}
}
}
& .modal-header {
display: flex;
justify-content: center;
align-items: center;
padding-block: 30px;
& .modal-header-title {
font-size: $font-25;
font-family: $font-lora;
font-weight: 500;
line-height: 14px;
}
@media only screen and (max-width: $med-md) {
padding-block: 72px 12px;
}
}
& .modal-body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 45px;
width: min(100%, 402px);
margin: 0 auto;
margin-bottom: 29px;
&.availability {
gap: 65px;
@media only screen and (max-width: $med-md) {
gap: 10px;
}
}
& .modal-body-paragraph {
font-size: $font-18;
line-height: 14px;
color: $text-default;
text-align: center;
@media only screen and (max-width: $med-md) {
line-height: 20px;
}
}
& .modal-body-content {
width: 100%;
& .filter-item-paragraph {
color: $text-default;
line-height: 20px;
opacity: 0.8;
}
& .modal-body-filters {
display: flex;
flex-direction: column;
gap: 4px;
}
& .modal-body-availability {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
position: relative;
gap: 60px;
&::after {
content: "";
position: absolute;
width: 1px;
height: 100%;
border-radius: 2px;
background-color: $text-normal-100;
opacity: 0.2;
left: 50%;
transform: translateX(-50%);
}
& .custom-input-el {
flex: 1 0 100px;
}
@media only screen and (max-width: $med-md) {
flex-direction: column;
justify-content: center;
align-items: flex-start;
gap: 41px;
margin: 0 auto;
width: min(100%, 142px);
&::after {
left: initial;
top: 50%;
transform: translateY(-50%);
left: -25%;
width: 150%;
height: 1px;
}
}
}
}
@media only screen and (max-width: $med-md) {
gap: 50px;
padding-inline: 55px;
}
}
& .modal-footer {
background-color: $primary;
padding: 34px 16px;
flex: 1;
color: $white;
border-radius: initial;
flex-direction: initial;
min-height: initial;
& .q-btn__content {
display: flex;
align-items: center;
justify-content: center;
gap: 9px;
}
& svg {
margin-top: -3px;
}
& p {
color: currentColor;
font-size: $font-18 !important;
line-height: 20px;
text-transform: lowercase;
}
@media only screen and (max-width: $med-md) {
padding-block: 32px;
}
}
}
}
</style>