| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- <template>
- <q-page class="dashboard-page bg-page">
- <template v-if="loading">
- <div class="row items-center justify-center full-width bg-surface" style="height: 80vh">
- <q-spinner-dots color="primary" />
- </div>
- </template>
- <template v-else>
- <q-pull-to-refresh color="primary" @refresh="onRefresh">
- <DashboardHeaderBar
- :data="headerBar"
- :notifications="notifications"
- />
- <DashboardRegistrationIncomplete v-if="!registrationComplete" />
- <DashboardSummaryInfos v-else :data="summaryInfos" />
- <DashboardPaymentIncomplete v-if="showPaymentBanner" />
- <AddressIncompleteBanner v-if="!hasLocation" @resolved="reloadDashboard" />
- <DashboardPendingCustomSchedules v-if="customSchedulesNoProposals.length > 0" />
- <DashboardClientProposals v-if="clientProposals.length > 0" :data="clientProposals" @refresh-data="reloadDashboard" />
- <DashboardPendingSchedules
- v-if="pendingServicePackages.length > 0"
- progress-class="progress-fill--urgent"
- :data="pendingServicePackages"
- :type="'servicePackage'"
- @view-details="openServicePackagePaymentDialog"
- />
- <DashboardPendingSchedules
- v-if="pendingRequests.length > 0"
- progress-class="progress-fill--loop"
- :data="pendingRequests"
- @cancel="openCancelRequestDialog"
- @view-details="openPackageDetailsDialog"
- />
- <DashboardTodaySchedules
- v-if="todaySchedules.length > 0"
- :data="todaySchedules"
- @rate="openRatingDialog"
- @view-details="openScheduleOnCalendar"
- />
- <DashboardScrollAreaSchedules />
- <DashboardNextSchedules v-if="nextSchedules.length > 0" :data="nextSchedules" @view-details="openNextScheduleDialog" />
- <DashboardLastDoneSchedules v-if="lastDoneSchedules.length > 0" :data="lastDoneSchedules" />
- <DashboardFavoriteProviders v-if="favoriteProviders.length > 0" :data="favoriteProviders" />
- <DashboardProvidersClose v-if="hasLocation" :data="providersClose" />
- </q-pull-to-refresh>
- </template>
- </q-page>
- </template>
- <script setup>
- import { computed, onMounted, ref } from 'vue';
- import { dadosDashboard } from 'src/api/dashboard';
- import { LocalStorage, useQuasar } from 'quasar';
- import { updateMe } from 'src/api/user';
- import { useI18n } from 'vue-i18n';
- import { usePaymentStore } from 'src/stores/payment';
- import { useRoute, useRouter } from 'vue-router'
- import { userStore } from 'src/stores/user';
- import AddressIncompleteBanner from 'src/components/shared/AddressIncompleteBanner.vue';
- import DashboardClientProposals from 'src/pages/dashboard/components/DashboardClientProposals.vue';
- import DashboardFavoriteProviders from 'src/components/dashboard/DashboardFavoriteProviders.vue';
- import DashboardHeaderBar from 'src/components/dashboard/DashboardHeaderBar.vue';
- import DashboardLastDoneSchedules from 'src/components/dashboard/DashboardLastDoneSchedules.vue';
- import DashboardNextSchedules from 'src/components/dashboard/DashboardNextSchedules.vue';
- import DashboardPaymentIncomplete from 'src/components/dashboard/DashboardPaymentIncomplete.vue';
- import DashboardPendingCustomSchedules from 'src/pages/dashboard/components/DashboardPendingCustomSchedules.vue';
- import DashboardPendingSchedules from 'src/components/dashboard/DashboardPendingSchedules.vue';
- import PackageScheduleDetailsDialog from 'src/components/dashboard/PackageScheduleDetailsDialog.vue';
- import DashboardProvidersClose from 'src/components/dashboard/DashboardProvidersClose.vue';
- import DashboardRegistrationIncomplete from 'src/components/dashboard/DashboardRegistrationIncomplete.vue';
- import DashboardScrollAreaSchedules from 'src/components/dashboard/DashboardScrollAreaSchedules.vue';
- import DashboardSummaryInfos from 'src/components/dashboard/DashboardSummaryInfos.vue';
- import DashboardTodaySchedules from 'src/components/dashboard/DashboardTodaySchedules.vue';
- import FinalSuccesModal from '../schedules/components/FinalSuccesModal.vue';
- import NextSchedulesDetailsDialog from 'src/pages/dashboard/components/schedule/NextSchedulesDetailsDialog.vue';
- import ScheduleAcceptedDialog from 'src/pages/dashboard/components/schedule/ScheduleAcceptedDialog.vue';
- import ScheduleCancelDialog from 'src/pages/dashboard/components/schedule/ScheduleCancelDialog.vue';
- import ScheduleRatingDialog from 'src/pages/dashboard/components/schedule/ScheduleRatingDialog.vue';
- const $q = useQuasar();
- const paymentStore = usePaymentStore();
- const route = useRoute()
- const router = useRouter()
- const store = userStore();
- const { t } = useI18n();
- const clientProposals = ref([]);
- const customSchedulesNoProposals = ref([]);
- const favoriteProviders = ref([]);
- const hasLocation = ref(true);
- const hasPaymentMethods = ref(true);
- const headerBar = ref({});
- const lastDoneSchedules = ref([]);
- const loading = ref(true);
- const nextSchedules = ref([]);
- const notifications = ref([]);
- const pendingSchedules = ref([]);
- const pendingServicePackages = ref([]);
- const providersClose = ref([]);
- const showPaymentBanner = ref(false);
- const successModalKey = ref(
- route.query.success ??
- (router.currentRoute.value.fullPath.includes('showSuccessModal') ? 'custom_schedule' : null),
- );
- const summaryInfos = ref({});
- const todaySchedules = ref([]);
- const pendingRequests = computed(() => {
- const seenPackages = new Set();
- return pendingSchedules.value.filter((schedule) => {
- if (schedule.status !== 'pending') return false;
- if (!schedule.service_package_id) return true;
- if (seenPackages.has(schedule.service_package_id)) return false;
- seenPackages.add(schedule.service_package_id);
- return true;
- });
- });
- const openPackageDetailsDialog = (schedule) => {
- $q.dialog({
- component: PackageScheduleDetailsDialog,
- componentProps: { schedule },
- });
- };
- const registrationComplete = computed(() => store.user?.registration_complete ?? true);
- const AUTO_SHOWN_PACKAGES_KEY = "sp_payment_popup_shown_ids";
- const successModalContents = {
- custom_schedule: null,
- order_sent: () => ({
- titleLine1: t('service_package.sent_title_line1'),
- titleLine2: t('service_package.sent_title_line2'),
- subtitleBefore: t('service_package.sent_subtitle_before'),
- subtitleHighlight: t('service_package.sent_subtitle_highlight'),
- subtitleAfter: t('service_package.sent_subtitle_after'),
- }),
- };
- let autoOpeningPackageDialog = false;
- const maybeOpenSuccessModal = () => {
- if (!successModalKey.value) return;
- if (!(successModalKey.value in successModalContents)) {
- successModalKey.value = null;
- return;
- }
- const buildContent = successModalContents[successModalKey.value];
- successModalKey.value = null;
- $q.dialog({
- component: FinalSuccesModal,
- componentProps: { content: buildContent ? buildContent() : null },
- }).onDismiss(() => {
- router.replace({ path: route.path, query: {} });
- });
- };
- const openCancelRequestDialog = (schedule) => {
- $q.dialog({
- component: ScheduleCancelDialog,
- componentProps: { schedule },
- }).onDismiss(() => {
- reloadDashboard(false);
- });
- };
- const openServicePackagePaymentDialog = (servicePackage) => {
- paymentStore.setPackage(servicePackage);
- $q.dialog({
- component: ScheduleAcceptedDialog,
- }).onOk(() => {
- reloadDashboard();
- }).onDismiss(() => {
- paymentStore.clearPackage();
- });
- };
- const maybeAutoOpenServicePackagePayment = () => {
- if (autoOpeningPackageDialog) return;
- const shownIds = LocalStorage.getItem(AUTO_SHOWN_PACKAGES_KEY) ?? [];
- const packageToShow = pendingServicePackages.value.find(
- (servicePackage) => !shownIds.includes(servicePackage.id),
- );
- if (!packageToShow) return;
- autoOpeningPackageDialog = true;
- LocalStorage.set(AUTO_SHOWN_PACKAGES_KEY, [...shownIds, packageToShow.id]);
- paymentStore.setPackage(packageToShow);
- $q.dialog({
- component: ScheduleAcceptedDialog,
- })
- .onOk(() => {
- reloadDashboard();
- })
- .onDismiss(() => {
- autoOpeningPackageDialog = false;
- paymentStore.clearPackage();
- });
- };
- const reloadDashboard = async (showLoader = true) => {
- if (showLoader) loading.value = true;
- const response = await dadosDashboard();
- if (response) {
- headerBar.value = response.headerBar;
- summaryInfos.value = response.summaryInfos;
- pendingSchedules.value = response.pendingSchedules ?? [];
- pendingServicePackages.value = response.pendingServicePackages ?? [];
- nextSchedules.value = response.nextSchedules ?? [];
- lastDoneSchedules.value = response.lastDoneSchedules ?? [];
- favoriteProviders.value = response.favoriteProviders ?? [];
- providersClose.value = response.providersClose ?? [];
- clientProposals.value = response.schedulesProposals ?? [];
- customSchedulesNoProposals.value = response.customSchedulesNoProposals ?? [];
- todaySchedules.value = response.todaySchedules ?? [];
- notifications.value = response.notifications ?? [];
- hasPaymentMethods.value = response.has_payment_methods ?? true;
- hasLocation.value = response.has_location ?? true;
- }
- loading.value = false;
- maybeAutoOpenServicePackagePayment();
- };
- const onRefresh = async (done) => {
- try {
- await reloadDashboard(false);
- } finally {
- done();
- }
- };
- const openNextScheduleDialog = (schedule) => {
- $q.dialog({
- component: NextSchedulesDetailsDialog,
- componentProps: { schedule }
- }).onOk(() => {
- reloadDashboard();
- });
- };
- const openScheduleOnCalendar = (schedule) => {
- router.push({
- name: 'CalendarPage',
- query: { scheduleId: schedule.id },
- });
- };
- const openRatingDialog = (schedule) => {
- $q.dialog({
- component: ScheduleRatingDialog,
- componentProps: { schedule }
- }).onOk(() => {
- reloadDashboard()
- })
- }
- onMounted(async () => {
- await reloadDashboard();
- maybeOpenSuccessModal();
- const isFirstAccess = store.user?.client?.first_access ?? false;
- showPaymentBanner.value = isFirstAccess && !hasPaymentMethods.value;
- if (isFirstAccess) {
- updateMe({ first_access: false }).catch(() => {});
- store.markFirstAccessSeen();
- }
- });
- </script>
- <style scoped>
- .dashboard-page {
- width: 100%;
- min-height: 100%;
- box-sizing: border-box;
- }
- </style>
|