Files
InvoiceShelf/resources/scripts/admin/layouts/partials/TheSiteHeader.vue
Darko Gjorgjijoski c85051161b Improve NoCompanyView design and fix header for no-company state
Personalize welcome heading with user name, add descriptive subtitle,
improve invitation card styling, remove redundant logout button. Fix
hasCreateAbilities check in header to actually call the function.
Widen company switcher dropdown and improve invitation row layout.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 00:48:00 +02:00

229 lines
5.9 KiB
Vue

<template>
<header
class="
fixed
top-0
left-0
z-20
flex
items-center
justify-between
w-full
px-4
py-3
md:h-16 md:px-8
bg-linear-to-r
from-primary-500
to-primary-400
"
>
<router-link
to="/admin/dashboard"
class="
float-none
text-lg
not-italic
font-black
tracking-wider
text-white
brand-main
md:float-left
font-base
hidden
md:block
"
>
<img v-if="adminLogo" :src="adminLogo" class="h-6" />
<MainLogo v-else class="h-6" light-color="white" dark-color="white" />
</router-link>
<!-- toggle button-->
<div
:class="{ 'is-active': globalStore.isSidebarOpen }"
class="
flex
float-left
p-1
overflow-visible
text-sm
ease-linear
bg-white
border-0
rounded
cursor-pointer
md:hidden md:ml-0
hover:bg-gray-100
"
@click.prevent="onToggle"
>
<BaseIcon name="Bars3Icon" class="!w-6 !h-6 text-gray-500" />
</div>
<ul class="flex float-right h-8 m-0 list-none md:h-9">
<li
v-if="hasCreateAbilities()"
class="relative hidden float-left m-0 md:block"
>
<BaseDropdown width-class="w-48">
<template #activator>
<div
class="
flex
items-center
justify-center
w-8
h-8
ml-2
text-sm text-black
bg-white
rounded
md:h-9 md:w-9
"
>
<BaseIcon name="PlusIcon" class="w-5 h-5 text-gray-600" />
</div>
</template>
<router-link to="/admin/invoices/create">
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.CREATE_INVOICE)"
>
<BaseIcon
name="DocumentTextIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
{{ $t('invoices.new_invoice') }}
</BaseDropdownItem>
</router-link>
<router-link to="/admin/estimates/create">
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.CREATE_ESTIMATE)"
>
<BaseIcon
name="DocumentIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
{{ $t('estimates.new_estimate') }}
</BaseDropdownItem>
</router-link>
<router-link to="/admin/customers/create">
<BaseDropdownItem
v-if="userStore.hasAbilities(abilities.CREATE_CUSTOMER)"
>
<BaseIcon
name="UserIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
{{ $t('customers.new_customer') }}
</BaseDropdownItem>
</router-link>
</BaseDropdown>
</li>
<li class="ml-2">
<GlobalSearchBar
v-if="
userStore.currentUser.is_owner ||
userStore.hasAbilities(abilities.VIEW_CUSTOMER)
"
/>
</li>
<li>
<CompanySwitcher />
</li>
<!-- User Dropdown-->
<li class="relative block float-left ml-2">
<BaseDropdown width-class="w-48">
<template #activator>
<img
:src="previewAvatar"
class="block w-8 h-8 rounded md:h-9 md:w-9 object-cover"
/>
</template>
<router-link to="/admin/user-settings">
<BaseDropdownItem>
<BaseIcon
name="CogIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
{{ $t('navigation.settings') }}
</BaseDropdownItem>
</router-link>
<BaseDropdownItem @click="logout">
<BaseIcon
name="ArrowRightOnRectangleIcon"
class="w-5 h-5 mr-3 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
{{ $t('navigation.logout') }}
</BaseDropdownItem>
</BaseDropdown>
</li>
</ul>
</header>
</template>
<script setup>
import { useAuthStore } from '@/scripts/admin/stores/auth'
import { useRouter } from 'vue-router'
import { computed } from 'vue'
import { useUserStore } from '@/scripts/admin/stores/user'
import { useGlobalStore } from '@/scripts/admin/stores/global'
import CompanySwitcher from '@/scripts/components/CompanySwitcher.vue'
import GlobalSearchBar from '@/scripts/components/GlobalSearchBar.vue'
import MainLogo from '@/scripts/components/icons/MainLogo.vue'
import abilities from '@/scripts/admin/stub/abilities'
const authStore = useAuthStore()
const userStore = useUserStore()
const globalStore = useGlobalStore()
const router = useRouter()
const previewAvatar = computed(() => {
return userStore.currentUser && userStore.currentUser.avatar !== 0
? userStore.currentUser.avatar
: getDefaultAvatar()
})
const adminLogo = computed(() => {
if (globalStore.globalSettings.admin_portal_logo) {
return '/storage/' + globalStore.globalSettings.admin_portal_logo
}
return false
})
function getDefaultAvatar() {
const imgUrl = new URL('$images/default-avatar.jpg', import.meta.url)
return imgUrl
}
function hasCreateAbilities() {
return userStore.hasAbilities([
abilities.CREATE_INVOICE,
abilities.CREATE_ESTIMATE,
abilities.CREATE_CUSTOMER,
])
}
async function logout() {
await authStore.logout()
router.push('/login')
}
function onToggle() {
globalStore.setSidebarVisibility(true)
}
</script>