| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- <template>
- <q-layout class="main-layout relative" view="hHh lpR fFf">
- <q-header
- class="system-bar-spacer"
- :style="{ height: 'env(safe-area-inset-top)' }"
- >
- </q-header>
- <q-page-container>
- <q-page class="bg-surface main-layout-page" style="overflow: hidden;">
- <q-scroll-area
- ref="scrollAreaRef"
- class="main-layout-scroll-area"
- :style="scrollAreaHeight"
- :content-style="{ width: '100%', maxWidth: '100%', overflowX: 'hidden', boxSizing: 'border-box' }"
- :content-active-style="{ width: '100%', maxWidth: '100%', overflowX: 'hidden', boxSizing: 'border-box' }"
- >
- <router-view v-slot="{ Component }">
- <Transition mode="out-in">
- <component
- :is="Component"
- class="main-layout-view"
- />
- </Transition>
- </router-view>
- </q-scroll-area>
- </q-page>
- </q-page-container>
- <q-footer class="provider-bottom-nav bg-white">
- <nav class="provider-bottom-nav-inner">
- <component
- :is="item.disabled ? 'div' : 'router-link'"
- v-for="item in navItems"
- :key="item.name"
- :class="{
- 'provider-bottom-nav-item--active': isNavItemActive(item),
- 'provider-bottom-nav-item--disabled': item.disabled,
- }"
- :to="item.disabled ? undefined : { name: item.name }"
- class="provider-bottom-nav-item"
- >
- <q-icon :name="item.icon" class="provider-bottom-nav-icon font30" />
- <span
- class="provider-bottom-nav-label font12"
- :class="isNavItemActive(item) ? 'fontbold' : 'fontregular'"
- >
- {{ item.label }}
- </span>
- </component>
- </nav>
- <div class="system-bar-spacer provider-bottom-nav-safe-area"></div>
- </q-footer>
- </q-layout>
- </template>
- <script setup>
- import { computed, onMounted, useTemplateRef, watch } from "vue";
- import { useI18n } from "vue-i18n";
- import { useQuasar } from "quasar";
- import { useRoute } from "vue-router";
- import { useProviderApproval } from "src/composables/useProviderApproval";
- import { userStore } from "src/stores/user";
- import MissingBankDataDialog from "src/components/profile/MissingBankDataDialog.vue";
- import ProfileBankDataDialog from "src/components/profile/ProfileBankDataDialog.vue";
- defineOptions({
- name: "MainLayout",
- });
- const route = useRoute();
- const scrollAreaRef = useTemplateRef("scrollAreaRef");
- const { t } = useI18n();
- const $q = useQuasar();
- const user = userStore();
- const { isPendingProvider } = useProviderApproval();
- let oldValue = route.path;
- let missingBankDataAlertShown = false;
- const navItems = computed(() => [
- {
- name: "DashboardPage",
- label: t('nav.home'),
- icon: "mdi-home-outline",
- disabled: false,
- },
- {
- name: "PaymentsPage",
- label: t('nav.payments'),
- icon: "mdi-credit-card-outline",
- disabled: isPendingProvider.value,
- },
- {
- name: "CalendarPage",
- label: t('nav.agenda'),
- icon: "mdi-calendar-blank-outline",
- disabled: isPendingProvider.value,
- },
- {
- name: "ProfilePage",
- label: t('nav.profile'),
- icon: "mdi-account-circle-outline",
- disabled: false,
- },
- ]);
- const scrollAreaHeight = computed(() => {
- return 'height: calc(100dvh - env(safe-area-inset-top) - 60px - env(safe-area-inset-bottom)) !important;';
- });
- const checkMissingBankData = async () => {
- if (!user.user?.provider && !user.user?.provider_id) {
- return;
- }
- // Cadastro em análise não edita dados bancários.
- if (isPendingProvider.value) {
- return;
- }
- try {
- await user.fetchUser();
- } catch (error) {
- console.error('Erro ao carregar dados do prestador:', error);
- }
- openMissingBankDataAlert();
- };
- const hasCompleteBankAccount = () => Boolean(user.user?.provider?.has_primary_bank_account);
- const isNavItemActive = (item) => route.name === item.name;
- const openBankDataDialog = () => {
- $q.dialog({
- component: ProfileBankDataDialog,
- });
- };
- const openMissingBankDataAlert = () => {
- if (missingBankDataAlertShown || hasCompleteBankAccount()) {
- return;
- }
- missingBankDataAlertShown = true;
- $q.dialog({
- component: MissingBankDataDialog,
- }).onOk(openBankDataDialog);
- };
- watch(
- () => route.path,
- (value) => {
- if (oldValue !== value) {
- scrollAreaRef.value?.setScrollPosition("vertical", 0, 0);
- scrollAreaRef.value?.setScrollPosition("horizontal", 0, 0);
- }
- oldValue = value;
- }
- );
- onMounted(() => {
- checkMissingBankData();
- });
- </script>
- <style scoped>
- .main-layout {
- width: 100%;
- max-width: 100%;
- overflow-x: hidden;
- }
- .main-layout-page {
- width: 100%;
- max-width: 100%;
- overflow: hidden;
- }
- .main-layout-scroll-area {
- width: 100%;
- max-width: 100%;
- overflow: hidden;
- }
- .main-layout-view {
- width: 100%;
- max-width: 100%;
- min-width: 0;
- padding: 0 !important;
- box-sizing: border-box;
- overflow-x: hidden;
- }
- .v-enter-active {
- opacity: 1;
- transition: all 0.15s ease-in;
- }
- .v-leave-active {
- opacity: 1;
- transition: all 0.15s ease-out;
- }
- .v-enter-from,
- .v-leave-to {
- opacity: 0;
- transition: all 0.15s ease-in;
- }
- .v-leave-to {
- transition: all 0.15s ease-out;
- }
- .provider-bottom-nav {
- background: #ffffff;
- box-shadow: 0 -12px 30px rgba(38, 27, 52, 0.1);
- }
- .provider-bottom-nav-inner {
- display: grid;
- grid-template-columns: repeat(4, minmax(0, 1fr));
- align-items: end;
- height: 60px;
- }
- .provider-bottom-nav-safe-area {
- height: env(safe-area-inset-bottom, 0px);
- }
- .provider-bottom-nav-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: flex-end;
- gap: 2px;
- min-height: 40px;
- color: #a1a1a1;
- text-decoration: none;
- transition: color 0.2s ease;
- }
- .provider-bottom-nav-item--active {
- color: #ff00ea;
- }
- .provider-bottom-nav-item--disabled {
- color: #d4d4d4;
- cursor: default;
- pointer-events: none;
- }
- .provider-bottom-nav-icon {
- font-size: 24px;
- line-height: 1;
- }
- .provider-bottom-nav-label {
- line-height: 1.1;
- letter-spacing: -0.02em;
- }
- </style>
|