MainLayout.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <template>
  2. <UnreadNotificationsDialog
  3. v-if="store.isAssociado || store.isParceiro"
  4. v-model="showUnreadDialog"
  5. />
  6. <q-layout class="relative" view="hHh lpR fFf">
  7. <LeftMenuLayoutAdministrador v-if="!$q.screen.lt.sm && store.userTipo == 'administrador'" />
  8. <LeftMenuLayoutAssociado v-if="!$q.screen.lt.sm && store.userTipo == 'associado'" />
  9. <LeftMenuLayoutParceiro v-if="!$q.screen.lt.sm && store.userTipo == 'parceiro'" />
  10. <LeftMenuLayoutMobile v-if="$q.screen.lt.sm" v-model="leftDrawerOpen" />
  11. <q-header v-if="!$q.screen.lt.sm" elevated style="height: 52px">
  12. <AppHeader />
  13. </q-header>
  14. <q-header v-if="$q.screen.lt.sm" class="bg-transparent q-pa-sm">
  15. <q-toolbar
  16. class="flex justify-between bg-surface"
  17. style="border-radius: 6px !important"
  18. >
  19. <q-btn dense flat @click="toggleLeftDrawer">
  20. <q-icon
  21. name="menu"
  22. :color="$q.dark.isActive ? 'white' : 'black'"
  23. style="font-size: 20px"
  24. />
  25. </q-btn>
  26. <div>
  27. <q-btn dense flat class="q-mr-sm" @click="changeTheme">
  28. <q-icon
  29. :color="$q.dark.isActive ? 'white' : 'black'"
  30. :name="
  31. $q.dark.isActive ? 'mdi-weather-sunny' : 'mdi-weather-night'
  32. "
  33. style="font-size: 20px"
  34. />
  35. </q-btn>
  36. <q-btn dense flat @click="logoutFn">
  37. <q-icon name="logout" color="negative" style="font-size: 20px" />
  38. </q-btn>
  39. </div>
  40. </q-toolbar>
  41. </q-header>
  42. <q-page-container>
  43. <q-page class="bg-violet-light">
  44. <q-scroll-area
  45. ref="scrollAreaRef"
  46. :style="
  47. $q.screen.lt.sm
  48. ? 'height: calc(100dvh - 68px - env(safe-area-inset-top)) !important;'
  49. : 'height: calc(100dvh - 52px - env(safe-area-inset-top)) !important;'
  50. "
  51. >
  52. <router-view v-slot="{ Component }">
  53. <Transition mode="out-in">
  54. <component
  55. :is="Component"
  56. style="padding: 20px !important; padding-right: 10px !important"
  57. :style="$q.screen.lt.sm ? 'padding-left: 10px !important;' : ''"
  58. />
  59. </Transition>
  60. </router-view>
  61. </q-scroll-area>
  62. </q-page>
  63. </q-page-container>
  64. </q-layout>
  65. </template>
  66. <script setup>
  67. import { ref, useTemplateRef, watch, onMounted } from "vue";
  68. import { useRoute, useRouter } from "vue-router";
  69. import { useAuth } from "src/composables/useAuth";
  70. import { useQuasar } from "quasar";
  71. import { userStore } from "src/stores/user";
  72. import LeftMenuLayoutAdministrador from "src/components/layout/LeftMenuLayoutAdministrador.vue";
  73. import LeftMenuLayoutAssociado from "src/components/layout/LeftMenuLayoutAssociado.vue";
  74. import LeftMenuLayoutParceiro from "src/components/layout/LeftMenuLayoutParceiro.vue";
  75. import LeftMenuLayoutMobile from "src/components/layout/LeftMenuLayoutMobile.vue";
  76. import AppHeader from "src/components/layout/AppHeader.vue";
  77. import UnreadNotificationsDialog from "src/components/UnreadNotificationsDialog.vue";
  78. const store = userStore();
  79. const router = useRouter();
  80. const { logout } = useAuth();
  81. const route = useRoute();
  82. const $q = useQuasar();
  83. const leftDrawerOpen = ref(false);
  84. const scrollAreaRef = useTemplateRef("scrollAreaRef");
  85. const showUnreadDialog = ref(false);
  86. onMounted(async () => {
  87. if (store.isAssociado || store.isParceiro) {
  88. await store.fetchUser();
  89. if (store.hasUnreadNotifications) {
  90. showUnreadDialog.value = true;
  91. }
  92. }
  93. });
  94. let oldValue = route.path;
  95. // const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches
  96. // ? "dark"
  97. // : "light";
  98. const systemTheme = "light";
  99. const logoutFn = async () => {
  100. await logout();
  101. router.push({ name: "LoginPage" });
  102. };
  103. const toggleLeftDrawer = () => {
  104. leftDrawerOpen.value = !leftDrawerOpen.value;
  105. };
  106. const changeTheme = async () => {
  107. const theme = $q.cookies.get("theme") || systemTheme;
  108. if (theme == "dark") {
  109. $q.dark.set(false);
  110. } else {
  111. $q.dark.set(true);
  112. }
  113. };
  114. watch(route, (value) => {
  115. if (oldValue.path != value.path) {
  116. scrollAreaRef.value.setScrollPosition("vertical", 0, 0);
  117. scrollAreaRef.value.setScrollPosition("horizontal", 0, 0);
  118. }
  119. oldValue = value.path;
  120. });
  121. </script>
  122. <style scoped>
  123. .v-enter-active {
  124. opacity: 1;
  125. transition: all 0.15s ease-in;
  126. }
  127. .v-leave-active {
  128. opacity: 1;
  129. transition: all 0.15s ease-out;
  130. }
  131. .v-enter-from,
  132. .v-leave-to {
  133. opacity: 0;
  134. transition: all 0.15s ease-in;
  135. }
  136. .v-leave-to {
  137. transition: all 0.15s ease-out;
  138. }
  139. </style>