| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- <template>
- <q-dialog ref="dialogRef" @hide="onDialogHide">
- <q-card class="next-schedule-dialog-card bg-surface shadow-card" :flat="false">
- <div class="row justify-end q-pt-sm q-pr-sm">
- <q-btn flat round dense icon="close" color="grey-6" size="sm" @click="onDialogCancel" />
- </div>
- <q-card-section class="column items-center q-pt-xs q-pb-sm">
- <q-avatar size="72px" class="q-mb-sm">
- <img v-if="schedule.customer_photo" :src="schedule.customer_photo" style="object-fit:cover" />
- <span v-else class="full-width full-height flex flex-center" :style="avatarColors[schedule.id % avatarColors.length]" style="font-size:20px;border-radius:50%">{{ (schedule.customer_name ?? schedule.client_name)?.slice(0,2).toUpperCase() ?? '??' }}</span>
- </q-avatar>
- <div class="text-text font16 fontbold">
- {{ schedule.customer_name ?? schedule.client_name }}
- </div>
- <div class="text-price font16 fontbold q-mt-xs">{{ formatCurrency(schedule.total_amount) }}</div>
- <div class="text-grey-6 font12 q-mt-xxs">{{ periodLabel }}</div>
- </q-card-section>
- <q-separator class="q-mx-lg" />
- <q-card-section class="column items-center q-py-sm text-text font12">
- <div class="text-center">
- <span class="fontbold">{{ weekdayLabel }}</span>
- <span class="text-grey-7">{{', ' + dayMonthLabel }}</span>
- </div>
- <div class="text-center q-mt-xxs">
- {{ $t('common.from') }}
- <span class="fontbold">{{ schedule.start_time?.slice(0, 5) }}</span>
- {{ $t('common.to') }}
- <span class="fontbold">{{ schedule.end_time?.slice(0, 5) }}</span>
- </div>
- </q-card-section>
- <q-separator class="q-mx-lg" />
- <q-card-section class="column items-center q-py-sm">
- <div class="row items-center q-gutter-x-xs">
- <q-icon
- :name="schedule.offers_meal ? 'mdi-silverware' : 'mdi-close-circle-outline'"
- :color="schedule.offers_meal ? 'secondary' : 'grey-5'"
- size="18px"
- />
- <span class="font12" :class="schedule.offers_meal ? 'text-text' : 'text-grey-6'">
- {{ schedule.offers_meal
- ? $t('provider.dashboard.next_schedules.offers_meal')
- : $t('provider.dashboard.next_schedules.no_meal') }}
- </span>
- </div>
- </q-card-section>
- <q-separator class="q-mx-lg" />
- <q-card-section class="column items-center q-py-sm q-px-lg">
- <div class="row items-start q-gutter-x-xs no-wrap">
- <div class="col-1 q-my-auto">
- <q-icon name="mdi-map-marker-outline" color="primary" size="20px" class="q-mt-xxs flex-shrink-0" />
- </div>
- <div class="col">
- <span class="text-grey-8 text-center font12">{{ formattedAddress || 'N/A' }}</span>
- </div>
- </div>
- <div class="text-grey-6 text-center font12 q-mt-xs">
- {{ $t('provider.dashboard.solicitations.distance_prefix') }}
- <strong>{{ (schedule.distance_km ?? 0) + ' km' }}</strong>
- {{ $t('provider.dashboard.solicitations.distance_suffix') }}
- </div>
- <q-btn
- flat
- no-caps
- dense
- color="primary"
- size="sm"
- icon="mdi-content-copy"
- :label="$t('provider.dashboard.next_schedules.copy_address')"
- class="q-mt-xs"
- @click="copyAddress"
- />
- </q-card-section>
- <q-card-section class="q-pt-xs q-pb-sm q-px-lg">
- <q-btn
- unelevated
- rounded
- no-caps
- color="primary"
- size="sm"
- class="full-width btn-close font14 fontbold"
- :label="$t('provider.dashboard.cancel_schedule.close')"
- @click="onDialogCancel"
- />
- </q-card-section>
- <q-card-section class="q-pt-none q-pb-md text-center">
- <div class="row justify-center q-gutter-x-lg">
- <q-btn
- flat
- no-caps
- color="grey-7"
- size="sm"
- :label="$t('provider.dashboard.next_schedules.btn_cancel_service')"
- @click="openCancelDialog"
- />
- <q-btn
- flat
- no-caps
- color="grey-7"
- size="sm"
- :label="$t('provider.dashboard.next_schedules.btn_need_help')"
- @click="openHelp"
- />
- </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, formatAddress } from 'src/helpers/utils'
- import { labelsPeriodTypes } from 'src/helpers/arraysOptions/labelsPeriodTypes.js'
- import ScheduleCancelDialog from './ScheduleCancelDialog.vue'
- import ProfileHelpDialog from 'src/components/profile/ProfileHelpDialog.vue'
- const avatarColors = [
- { background: '#ffd5df', color: '#932e57' },
- { background: '#d7e8ff', color: '#2158a8' },
- { background: '#dfd', color: '#2a7a3b' },
- { background: '#ffe5cc', color: '#8a4500' },
- ];
- const props = defineProps({
- schedule: {
- type: Object,
- required: true
- }
- })
- const { t } = useI18n()
- const $q = useQuasar()
- const { dialogRef, onDialogHide, onDialogCancel, onDialogOK } = useDialogPluginComponent()
- const periodLabel = computed(() => {
- const found = labelsPeriodTypes.find(l => l.value == props.schedule.period_type)
- return found ? t(found.label) : ''
- })
- const parseLocalDate = (dateStr) => {
- if (!dateStr) return null
- const s = String(dateStr)
- const iso = s.match(/^(\d{4})-(\d{2})-(\d{2})/)
- if (iso) return new Date(+iso[1], +iso[2] - 1, +iso[3])
- const dmy = s.match(/^(\d{2})\/(\d{2})\/(\d{4})/)
- if (dmy) return new Date(+dmy[3], +dmy[2] - 1, +dmy[1])
- return null
- }
- const weekdayLabel = computed(() => {
- const d = parseLocalDate(props.schedule.date)
- if (!d) return ''
- const w = d.toLocaleDateString('pt-BR', { weekday: 'long' })
- return w.charAt(0).toUpperCase() + w.slice(1)
- })
- const dayMonthLabel = computed(() => {
- const d = parseLocalDate(props.schedule.date)
- if (!d) return ''
- return d.toLocaleDateString('pt-BR', { day: '2-digit', month: '2-digit' })
- })
- const formattedAddress = computed(() => formatAddress(props.schedule.address))
- const copyAddress = () => {
- const addr = formattedAddress.value
- if (addr) navigator.clipboard.writeText(addr)
- $q.notify({ message: t('provider.dashboard.next_schedules.address_copied'), color: 'positive' })
- }
- const openCancelDialog = () => {
- $q.dialog({
- component: ScheduleCancelDialog,
- componentProps: { schedule: props.schedule }
- }).onOk(() => {
- onDialogOK({ action: 'cancelled', id: props.schedule.id })
- })
- }
- const openHelp = () => {
- $q.dialog({ component: ProfileHelpDialog })
- }
- </script>
- <style scoped lang="scss">
- .next-schedule-dialog-card {
- width: 320px;
- max-width: 92vw;
- border-radius: 20px !important;
- overflow: hidden;
- }
- .text-price {
- color: var(--q-primary);
- }
- .btn-close {
- padding: 10px 0;
- }
- .flex-shrink-0 {
- flex-shrink: 0;
- }
- .q-mt-xxs {
- margin-top: 2px;
- }
- </style>
|