| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- <template>
- <q-dialog
- ref="dialogRef"
- position="bottom"
- @hide="onDialogHide"
- >
- <q-card class="bg-surface text-text full-width sheet-card">
- <q-card-section class="row items-center q-pb-none">
- <q-space />
- <q-btn
- color="grey-6"
- dense
- flat
- icon="mdi-close-circle-outline"
- round
- @click="onDialogCancel"
- />
- </q-card-section>
- <q-separator class="q-mt-sm" />
- <q-card-section class="q-pt-sm q-pb-md">
- <div
- v-if="availableServiceTypes.length === 0"
- class="text-center text-grey-6 text-body2 q-py-md"
- >
- {{ $t("scheduling_page.no_slots_available") }}
- </div>
- <div
- v-for="type in availableServiceTypes"
- :key="type.key"
- class="row items-center no-wrap q-py-sm"
- >
- <div class="col">
- <div class="row items-center no-wrap q-gutter-x-xs">
- <span class="font14 fontbold text-text">
- {{ type.label }}
- </span>
- <q-btn
- color="primary"
- dense
- flat
- icon="mdi-information-outline"
- size="xs"
- @click="openInfo(type)"
- />
- </div>
- <div class="font12 fontmedium text-grey-6">
- {{ type.hours }}
- </div>
- </div>
- <div class="row items-center no-wrap q-gutter-x-sm">
- <span class="font12 fontmedium text-text">
- {{ formatServicePrice(type.price) }}
- </span>
- <q-btn
- color="secondary"
- no-caps
- padding="2px 16px"
- rounded
- size="sm"
- unelevated
- :label="$t('common.actions.select')"
- @click="onDialogOK({ action: 'servicePackage', serviceType: type, date: selectedDate, provider })"
- />
- </div>
- </div>
- </q-card-section>
- </q-card>
- </q-dialog>
- </template>
- <script setup>
- import { computed } from "vue";
- import { useDialogPluginComponent, useQuasar } from "quasar";
- import { useI18n } from "vue-i18n";
- import { formatCurrency } from "src/helpers/utils";
- import ServiceTypeInfoDialog from "./ServiceTypeInfoDialog.vue";
- defineEmits([...useDialogPluginComponent.emits]);
- const props = defineProps({
- partialBlocks: { default: () => [], required: false, type: Array },
- provider: { required: true, type: Object },
- selectedDate: { required: true, type: String },
- });
- const $q = useQuasar();
- const { dialogRef, onDialogCancel, onDialogHide, onDialogOK } =
- useDialogPluginComponent();
- const { t } = useI18n();
- const formatServicePrice = (price) =>
- price === null || price === undefined
- ? t("search_page.no_price")
- : formatCurrency(price);
- const slotConflicts = (slotStart, slotEnd, blocks) =>
- blocks.some((b) => {
- const blockEnd = parseInt(b.end_hour);
- const blockStart = parseInt(b.init_hour);
- return slotEnd >= blockStart && slotStart <= blockEnd;
- });
- const hasValidSlots = (hoursCount) => {
- for (let s = 7; s + hoursCount <= 20; s++) {
- if (!slotConflicts(s, s + hoursCount, props.partialBlocks)) return true;
- }
- return false;
- };
- const availableServiceTypes = computed(() =>
- [
- {
- description: t("scheduling_page.service_types.integral.description"),
- hours: t("scheduling_page.service_types.integral.hours"),
- hoursCount: 8,
- key: "integral",
- label: t("scheduling_page.service_types.integral.label"),
- basePrice:
- props.provider?.daily_price_8h_base ??
- props.provider?.daily_price_8h ??
- null,
- price: props.provider?.daily_price_8h ?? null,
- },
- {
- description: t("scheduling_page.service_types.padrao.description"),
- hours: t("scheduling_page.service_types.padrao.hours"),
- hoursCount: 6,
- key: "padrao",
- label: t("scheduling_page.service_types.padrao.label"),
- basePrice:
- props.provider?.daily_price_6h_base ??
- props.provider?.daily_price_6h ??
- null,
- price: props.provider?.daily_price_6h ?? null,
- },
- {
- description: t("scheduling_page.service_types.meio_periodo.description"),
- hours: t("scheduling_page.service_types.meio_periodo.hours"),
- hoursCount: 4,
- key: "meio_periodo",
- label: t("scheduling_page.service_types.meio_periodo.label"),
- basePrice:
- props.provider?.daily_price_4h_base ??
- props.provider?.daily_price_4h ??
- null,
- price: props.provider?.daily_price_4h ?? null,
- },
- {
- description: t("scheduling_page.service_types.diaria_rapida.description"),
- hours: t("scheduling_page.service_types.diaria_rapida.hours"),
- hoursCount: 2,
- key: "diaria_rapida",
- label: t("scheduling_page.service_types.diaria_rapida.label"),
- basePrice:
- props.provider?.daily_price_2h_base ??
- props.provider?.daily_price_2h ??
- null,
- price: props.provider?.daily_price_2h ?? null,
- },
- ].filter((type) => hasValidSlots(type.hoursCount)),
- );
- const openInfo = (type) => {
- $q.dialog({
- component: ServiceTypeInfoDialog,
- componentProps: { serviceType: type },
- });
- };
- </script>
- <style scoped lang="scss">
- .sheet-card {
- border-radius: 20px 20px 0 0;
- }
- </style>
|