| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- <template>
- <div class="q-mx-md q-mb-md">
- <div class="font16 fontbold gradient-diarista q-mb-sm section-title">
- {{ $t("provider.dashboard.next_schedules.title") }}
- </div>
- <div v-if="!data.length" class="empty-alert row no-wrap items-start">
- <q-icon
- class="empty-alert__icon"
- name="mdi-alert-outline"
- size="28px"
- />
- <div class="empty-alert__text font10">
- <span class="fontbold">
- {{ $t("provider.dashboard.next_schedules.empty_alert_bold") }}
- </span>
- {{ $t("provider.dashboard.next_schedules.empty_alert_text") }}
- </div>
- </div>
- <div
- v-else
- class="scroll-wrapper"
- >
- <div
- class="scroll-track"
- :class="{ 'scroll-track--single': data.length === 1 }"
- >
- <q-card
- v-for="item in data"
- :key="item.id"
- :class="{ 'schedule-card--single': data.length === 1 }"
- :flat="false"
- class="schedule-card card-border shadow-card bg-surface"
- >
- <q-card-section class="q-pa-sm">
- <div class="row no-wrap items-center q-gutter-x-sm">
- <q-avatar size="48px">
- <img
- v-if="item.customer_photo"
- :src="item.customer_photo"
- style="object-fit: cover"
- />
- <span
- v-else
- class="flex flex-center full-height full-width"
- style="border-radius: 50%"
- :style="avatarColors[item.id % avatarColors.length]"
- >
- {{
- getFirstName(item.customer_name ?? item.client_name)
- ?.slice(0, 2)
- .toUpperCase() ?? "??"
- }}
- </span>
- </q-avatar>
- <div class="column flex-1">
- <div class="row items-center q-gutter-x-xs">
- <span class="ellipsis font12 fontmedium text-name">
- {{ getFirstName(item.customer_name ?? item.client_name) || "—" }}
- </span>
- <div
- v-if="item.customer_rating"
- class="row items-center"
- >
- <q-icon
- color="warning"
- name="mdi-star"
- size="14px"
- />
- <span class="text-text font11">
- {{ item.customer_rating }}
- </span>
- </div>
- </div>
- <div class="row items-center no-wrap">
- <span class="font9 fontbold text-schedule-date-bold">
- {{ formatWeekday(item.date) }}
- </span>
- <span class="font9 text-schedule-date-regular">
- {{ ", " + formatDayMonth(item.date) }}
- </span>
- </div>
- <div class="text-schedule-date-regular font9">
- {{ $t("common.from") }}
- <span class="text-schedule-date-bold fontbold">
- {{ item.start_time?.slice(0, 5) }}
- </span>
- {{ $t("common.to") }}
- <span class="text-schedule-date-bold fontbold">
- {{ item.end_time?.slice(0, 5) }}
- </span>
- </div>
- </div>
- <div class="column items-end text-text">
- <div class="font14 fontbold text-price">
- {{ formatCurrency(item.total_amount) }}
- </div>
- <div class="font10 fontmedium text-type">
- {{ t(labelsPeriodTypes.find((label) => label.value == item.period_type)?.label) }}
- </div>
- <div class="font10 text-distance">
- {{ item.distance_km ?? 0 }}{{ $t("common.km") }}
- </div>
- </div>
- </div>
- <div
- class="font9 fontmedium items-center q-mt-md q-px-xs row text-text"
- >
- <div class="col ellipsis text-grey-7">
- {{ formatAddress(item.address) || "N/A" }}
- </div>
- <q-icon
- class="q-ml-xs"
- color="primary"
- name="mdi-content-copy"
- size="12px"
- @click="copyAddress(item.address)"
- />
- </div>
- <div class="row q-mt-sm items-center">
- <q-btn
- color="primary"
- flat
- no-caps
- padding="4px 8px"
- size="xs"
- unelevated
- :label="$t('provider.dashboard.next_schedules.details')"
- @click="emit('view-details', item)"
- />
- <q-space />
- <div class="font9 items-center q-gutter-x-xs row text-grey-7">
- <q-icon
- size="14px"
- :color="item.offers_meal ? 'secondary' : 'grey-5'"
- :name="item.offers_meal ? 'mdi-silverware' : 'mdi-close-outline'"
- />
- <span :class="item.offers_meal ? 'fontmedium' : ''">
- {{
- item.offers_meal
- ? $t("provider.dashboard.next_schedules.offers_meal")
- : $t("provider.dashboard.next_schedules.no_meal")
- }}
- </span>
- </div>
- </div>
- </q-card-section>
- </q-card>
- </div>
- </div>
- </div>
- </template>
- <script setup>
- import { avatarColors, formatAddress, formatCurrency, getFirstName } from "src/helpers/utils";
- import { labelsPeriodTypes } from "src/helpers/labelsPeriodTypes.js";
- import { useI18n } from "vue-i18n";
- import { useQuasar } from "quasar";
- defineProps({
- data: {
- default: () => [],
- type: Array,
- },
- });
- const emit = defineEmits(["view-details"]);
- const $q = useQuasar();
- const { t } = useI18n();
- const copyAddress = (address) => {
- const formatted = formatAddress(address);
- if (formatted) {
- navigator.clipboard.writeText(formatted);
- }
- $q.notify({
- color: "positive",
- message: t("provider.dashboard.next_schedules.address_copied"),
- });
- };
- const formatDayMonth = (iso) => {
- if (!iso) {
- return "";
- }
- return new Date(iso).toLocaleDateString("pt-BR", {
- day: "2-digit",
- month: "2-digit",
- });
- };
- const formatWeekday = (iso) => {
- if (!iso) {
- return "";
- }
- const date = new Date(iso);
- const weekday = date.toLocaleDateString("pt-BR", { weekday: "long" });
- return weekday.charAt(0).toUpperCase() + weekday.slice(1);
- };
- </script>
- <style scoped lang="scss">
- .scroll-wrapper {
- overflow: hidden;
- }
- .empty-alert {
- background: #e3efff;
- border-radius: 8px;
- gap: 12px;
- padding: 13px 14px;
- }
- .empty-alert__icon {
- color: #6554d9;
- flex: 0 0 auto;
- }
- .empty-alert__text {
- color: #6554d9;
- line-height: 1.2;
- padding-top: 1px;
- }
- .scroll-track {
- display: flex;
- flex-direction: row;
- gap: 12px;
- overscroll-behavior-x: contain;
- overflow-x: auto;
- padding-bottom: 8px;
- scroll-snap-type: x proximity;
- &::-webkit-scrollbar {
- display: none;
- }
- &::after {
- content: "";
- flex: 0 0 1px;
- }
- }
- .schedule-card {
- border-radius: 12px;
- min-width: 82vw;
- }
- .schedule-card--single {
- min-width: 100%;
- width: 100%;
- }
- .text-name {
- color: #3a3a4a;
- }
- .text-schedule-date-bold {
- color: #3a3a4a;
- }
- .text-schedule-date-regular {
- color: #666;
- }
- .text-date,
- .text-time,
- .text-type,
- .text-region,
- .text-distance {
- color: #666;
- }
- .text-price {
- color: #3a3a4a;
- }
- .flex-1 {
- flex: 1;
- min-width: 0;
- }
- </style>
|