From c3a59a46db8057b4035483345a9cd7f97f44caf7 Mon Sep 17 00:00:00 2001 From: Darko Gjorgjijoski Date: Sat, 4 Apr 2026 00:36:00 +0200 Subject: [PATCH] Add frontend handling for users without a company Make setSelectedCompany null-safe and clear stale localStorage. Conditionally initialize company store state in bootstrap. Add router guard to redirect no-company users to NoCompanyView while allowing super admins through. Hide sidebar when no company. Co-Authored-By: Claude Opus 4.6 (1M context) --- resources/scripts/admin/admin-router.js | 11 +++++------ .../scripts/admin/layouts/LayoutBasic.vue | 18 ++++++++++++++++-- resources/scripts/admin/stores/company.js | 6 +++++- resources/scripts/admin/stores/global.js | 18 ++++++++++++------ resources/scripts/router/index.js | 8 ++++++++ 5 files changed, 46 insertions(+), 15 deletions(-) diff --git a/resources/scripts/admin/admin-router.js b/resources/scripts/admin/admin-router.js index fbc1b70b..f68b6536 100644 --- a/resources/scripts/admin/admin-router.js +++ b/resources/scripts/admin/admin-router.js @@ -147,12 +147,6 @@ export default [ component: RegisterWithInvitation, meta: { requiresAuth: false }, }, - { - path: '/admin/no-company', - name: 'no.company', - component: NoCompanyView, - meta: { requiresAuth: true }, - }, { path: '/installation', component: LayoutInstallation, @@ -203,6 +197,11 @@ export default [ component: LayoutBasic, meta: { requiresAuth: true }, children: [ + { + path: 'no-company', + name: 'no.company', + component: NoCompanyView, + }, { path: 'dashboard', name: 'dashboard', diff --git a/resources/scripts/admin/layouts/LayoutBasic.vue b/resources/scripts/admin/layouts/LayoutBasic.vue index 807ea18a..1f98078a 100644 --- a/resources/scripts/admin/layouts/LayoutBasic.vue +++ b/resources/scripts/admin/layouts/LayoutBasic.vue @@ -6,12 +6,15 @@ - +
@@ -51,8 +54,19 @@ const isAppLoaded = computed(() => { return globalStore.isAppLoaded }) +const hasCompany = computed(() => { + return !!companyStore.selectedCompany || !!userStore.currentUser?.is_super_admin +}) + onMounted(() => { globalStore.bootstrap().then((res) => { + if (!res.data.current_company && !res.data.current_user.is_super_admin) { + if (route.name !== 'no.company') { + router.push({ name: 'no.company' }) + } + return + } + if (route.meta.ability && !userStore.hasAbilities(route.meta.ability)) { router.push({ name: 'account.settings' }) } else if (route.meta.isSuperAdmin && !userStore.currentUser.is_super_admin) { diff --git a/resources/scripts/admin/stores/company.js b/resources/scripts/admin/stores/company.js index b7c1f661..2b1694d3 100644 --- a/resources/scripts/admin/stores/company.js +++ b/resources/scripts/admin/stores/company.js @@ -18,7 +18,11 @@ export const useCompanyStore = (useWindow = false) => { actions: { setSelectedCompany(data) { - window.Ls.set('selectedCompany', data.id) + if (data) { + window.Ls.set('selectedCompany', data.id) + } else { + window.Ls.remove('selectedCompany') + } this.selectedCompany = data }, diff --git a/resources/scripts/admin/stores/global.js b/resources/scripts/admin/stores/global.js index 1787fd59..c41df335 100644 --- a/resources/scripts/admin/stores/global.js +++ b/resources/scripts/admin/stores/global.js @@ -79,12 +79,18 @@ export const useGlobalStore = (useWindow = false) => { // company store companyStore.companies = response.data.companies - companyStore.selectedCompany = response.data.current_company - companyStore.setSelectedCompany(response.data.current_company) - companyStore.selectedCompanySettings = - response.data.current_company_settings - companyStore.selectedCompanyCurrency = - response.data.current_company_currency + + if (response.data.current_company) { + companyStore.setSelectedCompany(response.data.current_company) + companyStore.selectedCompanySettings = + response.data.current_company_settings + companyStore.selectedCompanyCurrency = + response.data.current_company_currency + } else { + companyStore.setSelectedCompany(null) + companyStore.selectedCompanySettings = {} + companyStore.selectedCompanyCurrency = null + } // Determine and load the appropriate language const userLanguage = response.data.current_user_settings?.language diff --git a/resources/scripts/router/index.js b/resources/scripts/router/index.js index 00bea52e..3d38c144 100644 --- a/resources/scripts/router/index.js +++ b/resources/scripts/router/index.js @@ -1,6 +1,7 @@ import { createRouter, createWebHistory } from 'vue-router' import { useUserStore } from '@/scripts/admin/stores/user' import { useGlobalStore } from '@/scripts/admin/stores/global' +import { useCompanyStore } from '@/scripts/admin/stores/company' //admin routes import AdminRoutes from '@/scripts/admin/admin-router' @@ -20,9 +21,16 @@ const router = createRouter({ router.beforeEach((to) => { const userStore = useUserStore() const globalStore = useGlobalStore() + const companyStore = useCompanyStore() let ability = to.meta.ability const { isAppLoaded } = globalStore + if (isAppLoaded && to.meta.requiresAuth && to.name !== 'no.company') { + if (!companyStore.selectedCompany && !(to.meta.isSuperAdmin && userStore.currentUser?.is_super_admin)) { + return { name: 'no.company' } + } + } + if (ability && isAppLoaded && to.meta.requiresAuth) { if (!userStore.hasAbilities(ability)) { return { name: 'account.settings' }