123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. <script setup>
  2. import { ref, computed } from "vue";
  3. import { usePage } from "@inertiajs/inertia-vue3";
  4. import AppTopBar from "@/components/AppTopBar.vue";
  5. import AppSidebar from "@/components/AppSidebar.vue";
  6. import AppFooter from "@/components/AppFooter.vue";
  7. import AppMessage from "@/components/AppMessage.vue";
  8. import menu from "@/utils/menu";
  9. import menuAdmin from "@/utils/menu_admin";
  10. const containerClass = computed(() => {
  11. return [
  12. "layout-wrapper",
  13. "layout-static",
  14. {
  15. "layout-static-sidebar-inactive": staticMenuInactive.value,
  16. "layout-mobile-sidebar-active": mobileMenuActive.value,
  17. },
  18. ];
  19. });
  20. const mobileMenuActive = ref(false);
  21. const staticMenuInactive = ref(false);
  22. const menuClick = ref(false);
  23. const isDesktop = () => window.innerWidth >= 992;
  24. const isAdmin = computed(() => usePage().props.value.isAdmin);
  25. const onMenuToggle = () => {
  26. menuClick.value = true;
  27. if (isDesktop()) {
  28. staticMenuInactive.value = !staticMenuInactive.value;
  29. } else {
  30. mobileMenuActive.value = !mobileMenuActive.value;
  31. }
  32. };
  33. const onWrapperClick = () => {
  34. if (!menuClick.value) {
  35. mobileMenuActive.value = false;
  36. }
  37. menuClick.value = false;
  38. };
  39. </script>
  40. <template>
  41. <div :class="containerClass" @click="onWrapperClick">
  42. <AppTopBar @menu-toggle="onMenuToggle" />
  43. <div class="layout-sidebar">
  44. <AppSidebar :model="isAdmin ? menuAdmin : menu" />
  45. </div>
  46. <div class="layout-main-container">
  47. <div class="layout-main">
  48. <AppMessage />
  49. <slot />
  50. </div>
  51. <AppFooter />
  52. </div>
  53. <Transition name="layout-mask">
  54. <div
  55. class="layout-mask p-component-overlay"
  56. v-if="mobileMenuActive"
  57. ></div>
  58. </Transition>
  59. </div>
  60. </template>