|
1 | 1 | <template> |
2 | 2 | <div> |
3 | 3 | <nav |
4 | | - v-if="loggedIn && routerIsReady && loginRedirectCheckIsReady && defaultLayout" |
5 | | - class="fixed h-14 top-0 z-20 w-full border-b shadow-sm bg-lightNavbar shadow-headerShadow dark:bg-darkNavbar dark:border-darkSidebarDevider" |
| 4 | + v-if="loggedIn && routerIsReady && loginRedirectCheckIsReady" |
| 5 | + class="h-14 top-0 z-20 w-full border-b shadow-sm bg-lightNavbar shadow-headerShadow dark:bg-darkNavbar dark:border-darkSidebarDevider" |
6 | 6 | > |
7 | 7 | <div class="af-header px-3 lg:px-5 lg:pl-3 flex items-center justify-between h-full w-full" > |
8 | 8 | <div class="flex items-center justify-start rtl:justify-end"> |
|
69 | 69 | </div> |
70 | 70 | </nav> |
71 | 71 | </div> |
| 72 | + <div class="m-4 h-full w-full"> |
| 73 | + |
| 74 | + <div v-if="!coreStore?.config?.settingPages || coreStore?.config?.settingPages.length === 0"> |
| 75 | + <p>No setting pages configured or still loading...</p> |
| 76 | + </div> |
| 77 | + <VerticalTabs v-else> |
| 78 | + <template v-for="(c,i) in coreStore?.config?.settingPages" :key="`tab:${settingPageSlotName(c,i)}`" v-slot:['tab:'+settingPageSlotName(c,i)]> |
| 79 | + <div class="flex items-center justify-center whitespace-nowrap px-4 mx-4"> |
| 80 | + {{ c.pageLabel }} |
| 81 | + </div> |
| 82 | + </template> |
| 83 | + |
| 84 | + <template v-for="(c,i) in coreStore?.config?.settingPages" :key="`${settingPageSlotName(c,i)}-content`" v-slot:[settingPageSlotName(c,i)]> |
| 85 | + <component |
| 86 | + :is="getCustomComponent({file: c.component || ''})" |
| 87 | + :resource="coreStore.resource" |
| 88 | + :adminUser="coreStore.adminUser" |
| 89 | + /> |
| 90 | + </template> |
| 91 | + </VerticalTabs> |
| 92 | + </div> |
72 | 93 | </template> |
73 | 94 |
|
74 | 95 | <script setup lang="ts"> |
75 | | -
|
76 | | -import { useCoreStore } from '@/stores/core'; |
77 | | -import { computed, ref } from 'vue'; |
| 96 | +import { computed, ref, onMounted, watch } from 'vue'; |
78 | 97 | import { useRouter } from 'vue-router'; |
| 98 | +import { useCoreStore } from '@/stores/core'; |
| 99 | +import { useUserStore } from '@/stores/user'; |
| 100 | +import { getCustomComponent } from '@/utils'; |
| 101 | +import { Dropdown } from 'flowbite'; |
| 102 | +import { IconMoonSolid, IconSunSolid } from '@iconify-prerendered/vue-flowbite'; |
| 103 | +import adminforth from '@/adminforth'; |
| 104 | +import { VerticalTabs } from '@/afcl' |
| 105 | +
|
79 | 106 | const coreStore = useCoreStore(); |
| 107 | +const userStore = useUserStore(); |
80 | 108 | const router = useRouter(); |
81 | 109 |
|
82 | | -const loggedIn = computed(() => !!coreStore?.adminUser); |
| 110 | +const loggedIn = computed(() => { return !!coreStore?.adminUser }); |
83 | 111 | const routerIsReady = ref(false); |
84 | 112 | const loginRedirectCheckIsReady = ref(false); |
| 113 | +const sideBarOpen = ref(false); |
| 114 | +const theme = ref('light'); |
| 115 | +const dropdownUserButton = ref<HTMLElement | null>(null); |
85 | 116 |
|
86 | 117 | async function initRouter() { |
87 | 118 | await router.isReady(); |
88 | 119 | routerIsReady.value = true; |
89 | 120 | } |
90 | 121 |
|
91 | | -async function loadMenu() { |
92 | | - await initRouter(); |
93 | | - if (!route.meta.customLayout) { |
94 | | - // for custom layouts we don't need to fetch menu |
95 | | - await coreStore.fetchMenuAndResource(); |
| 122 | +function toggleTheme() { |
| 123 | + theme.value = theme.value === 'light' ? 'dark' : 'light'; |
| 124 | + coreStore.toggleTheme(); |
| 125 | +} |
| 126 | +
|
| 127 | +function settingPageSlotName(c: { slug?: string; pageLabel?: string }, idx: number) { |
| 128 | + const base = (c.slug && c.slug.trim()) || (c.pageLabel && c.pageLabel.trim()) || `tab-${idx}`; |
| 129 | + return base |
| 130 | + .toString() |
| 131 | + .toLowerCase() |
| 132 | + .replace(/\s+/g, '-') |
| 133 | + .replace(/[^a-z0-9-_]/g, '-') || `tab-${idx}`; |
| 134 | +} |
| 135 | +
|
| 136 | +
|
| 137 | +async function logout() { |
| 138 | + userStore.unauthorize(); |
| 139 | + await userStore.logout(); |
| 140 | + router.push({ name: 'login' }) |
| 141 | +} |
| 142 | +
|
| 143 | +watch(dropdownUserButton, (el) => { |
| 144 | + if (el) { |
| 145 | + const dd = new Dropdown( |
| 146 | + document.querySelector('#dropdown-user') as HTMLElement, |
| 147 | + document.querySelector('[data-dropdown-toggle="dropdown-user"]') as HTMLElement, |
| 148 | + ); |
| 149 | + adminforth.closeUserMenuDropdown = () => dd.hide(); |
96 | 150 | } |
| 151 | +}); |
| 152 | +
|
| 153 | +onMounted(async () => { |
| 154 | + await loadMenu(); |
| 155 | + await loadPublicConfig(); |
97 | 156 | loginRedirectCheckIsReady.value = true; |
| 157 | + console.log('Setting pages:', coreStore?.config?.settingPages); |
| 158 | + console.log('Full config:', coreStore?.config); |
| 159 | +}); |
| 160 | +
|
| 161 | +async function loadPublicConfig() { |
| 162 | + await coreStore.getPublicConfig(); |
| 163 | +} |
| 164 | +
|
| 165 | +async function loadMenu() { |
| 166 | + await initRouter(); |
| 167 | + await coreStore.fetchMenuAndResource(); |
98 | 168 | } |
| 169 | +
|
99 | 170 | </script> |
0 commit comments