mirror of
https://github.com/InvoiceShelf/InvoiceShelf.git
synced 2026-04-16 01:34:08 +00:00
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>
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
"accept": "Accept",
|
||||
"decline": "Decline",
|
||||
"welcome": "Welcome",
|
||||
"no_company_description": "You are not a member of any company yet. Accept an invitation below or contact your administrator.",
|
||||
"update": "Update",
|
||||
"deselect": "Deselect",
|
||||
"download": "Download",
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
|
||||
<ul class="flex float-right h-8 m-0 list-none md:h-9">
|
||||
<li
|
||||
v-if="hasCreateAbilities"
|
||||
v-if="hasCreateAbilities()"
|
||||
class="relative hidden float-left m-0 md:block"
|
||||
>
|
||||
<BaseDropdown width-class="w-48">
|
||||
|
||||
@@ -1,70 +1,60 @@
|
||||
<template>
|
||||
<div class="flex items-center justify-center min-h-screen bg-gray-50">
|
||||
<div class="w-full max-w-lg p-8">
|
||||
<div class="flex items-center justify-center min-h-[70vh]">
|
||||
<div class="w-full max-w-xl p-8">
|
||||
<div class="text-center mb-8">
|
||||
<BaseIcon
|
||||
name="BuildingOfficeIcon"
|
||||
class="w-16 h-16 mx-auto text-gray-400 mb-4"
|
||||
class="w-16 h-16 mx-auto text-gray-300 mb-4"
|
||||
/>
|
||||
<h1 class="text-2xl font-semibold text-gray-900">
|
||||
{{ $t('general.welcome') }}
|
||||
{{ $t('general.welcome') }}, {{ userStore.currentUser.name }}
|
||||
</h1>
|
||||
<p class="mt-2 text-sm text-gray-500">
|
||||
{{ $t('general.no_company_description') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Pending Invitations -->
|
||||
<div v-if="invitationStore.pendingInvitations.length > 0">
|
||||
<h2 class="text-lg font-medium text-gray-700 mb-4 text-center">
|
||||
<h2
|
||||
class="text-sm font-semibold uppercase tracking-wide text-gray-400 mb-3"
|
||||
>
|
||||
{{ $t('members.pending_invitations') }}
|
||||
</h2>
|
||||
<div class="space-y-3">
|
||||
<BaseCard
|
||||
<div
|
||||
v-for="invitation in invitationStore.pendingInvitations"
|
||||
:key="invitation.id"
|
||||
class="p-4"
|
||||
class="flex items-center justify-between p-4 bg-white rounded-lg border border-gray-200"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="font-medium text-gray-900">
|
||||
{{ invitation.company?.name }}
|
||||
</p>
|
||||
<p class="text-sm text-gray-500">
|
||||
{{ invitation.role?.title }} ·
|
||||
{{ $t('members.invited_by') }}: {{ invitation.invited_by?.name }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex space-x-2">
|
||||
<BaseButton
|
||||
size="sm"
|
||||
@click="acceptInvitation(invitation.token)"
|
||||
>
|
||||
{{ $t('general.accept') }}
|
||||
</BaseButton>
|
||||
<BaseButton
|
||||
variant="danger"
|
||||
size="sm"
|
||||
@click="declineInvitation(invitation.token)"
|
||||
>
|
||||
{{ $t('general.decline') }}
|
||||
</BaseButton>
|
||||
</div>
|
||||
<div>
|
||||
<p class="font-medium text-gray-900">
|
||||
{{ invitation.company?.name }}
|
||||
</p>
|
||||
<p class="text-sm text-gray-500">
|
||||
{{ invitation.role?.title }} ·
|
||||
{{ $t('members.invited_by') }}:
|
||||
{{ invitation.invited_by?.name }}
|
||||
</p>
|
||||
</div>
|
||||
</BaseCard>
|
||||
<div class="flex space-x-2 ml-4 shrink-0">
|
||||
<BaseButton
|
||||
size="sm"
|
||||
@click="acceptInvitation(invitation.token)"
|
||||
>
|
||||
{{ $t('general.accept') }}
|
||||
</BaseButton>
|
||||
<BaseButton
|
||||
variant="white"
|
||||
size="sm"
|
||||
@click="declineInvitation(invitation.token)"
|
||||
>
|
||||
{{ $t('general.decline') }}
|
||||
</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- No Invitations -->
|
||||
<div v-else class="text-center">
|
||||
<p class="text-gray-500">
|
||||
You don't belong to any company yet. Ask your administrator to invite you.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Logout -->
|
||||
<div class="mt-8 text-center">
|
||||
<BaseButton variant="primary-outline" @click="logout">
|
||||
{{ $t('navigation.logout') }}
|
||||
</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -73,10 +63,10 @@
|
||||
import { onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useInvitationStore } from '@/scripts/admin/stores/invitation'
|
||||
import { useAuthStore } from '@/scripts/admin/stores/auth'
|
||||
import { useUserStore } from '@/scripts/admin/stores/user'
|
||||
|
||||
const invitationStore = useInvitationStore()
|
||||
const authStore = useAuthStore()
|
||||
const userStore = useUserStore()
|
||||
const router = useRouter()
|
||||
|
||||
onMounted(async () => {
|
||||
@@ -91,9 +81,4 @@ async function acceptInvitation(token) {
|
||||
async function declineInvitation(token) {
|
||||
await invitationStore.decline(token)
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
await authStore.logout()
|
||||
router.push('/login')
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
class="
|
||||
overflow-y-auto
|
||||
scrollbar-thin scrollbar-thumb-rounded-full
|
||||
w-[250px]
|
||||
w-[300px]
|
||||
max-h-[350px]
|
||||
scrollbar-thumb-gray-300 scrollbar-track-gray-10
|
||||
pb-4
|
||||
@@ -93,7 +93,7 @@
|
||||
"
|
||||
:class="{
|
||||
'bg-gray-100 text-primary-500':
|
||||
companyStore.selectedCompany.id === company.id,
|
||||
companyStore.selectedCompany && companyStore.selectedCompany.id === company.id,
|
||||
}"
|
||||
@click="changeCompany(company)"
|
||||
>
|
||||
@@ -148,39 +148,37 @@
|
||||
<div
|
||||
v-for="invitation in invitationStore.pendingInvitations"
|
||||
:key="invitation.id"
|
||||
class="p-2 px-3 rounded-md opacity-60"
|
||||
class="p-2 px-3 rounded-md"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<span
|
||||
class="
|
||||
flex items-center justify-center mr-3
|
||||
overflow-hidden text-xs font-semibold
|
||||
bg-gray-200 rounded-md w-9 h-9 text-gray-400
|
||||
"
|
||||
>
|
||||
{{ initGenerator(invitation.company?.name || '?') }}
|
||||
</span>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-sm text-gray-500">{{ invitation.company?.name }}</span>
|
||||
<span class="text-xs text-gray-400">{{ invitation.role?.title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex space-x-1">
|
||||
<button
|
||||
class="text-xs px-2 py-1 rounded bg-primary-500 text-white hover:bg-primary-600"
|
||||
@click.stop="acceptInvitation(invitation.token)"
|
||||
>
|
||||
{{ $t('general.accept') }}
|
||||
</button>
|
||||
<button
|
||||
class="text-xs px-2 py-1 rounded bg-gray-200 text-gray-600 hover:bg-gray-300"
|
||||
@click.stop="declineInvitation(invitation.token)"
|
||||
>
|
||||
{{ $t('general.decline') }}
|
||||
</button>
|
||||
<div class="flex items-center mb-2">
|
||||
<span
|
||||
class="
|
||||
flex items-center justify-center mr-3
|
||||
overflow-hidden text-xs font-semibold
|
||||
bg-gray-200 rounded-md w-9 h-9 shrink-0 text-gray-400
|
||||
"
|
||||
>
|
||||
{{ initGenerator(invitation.company?.name || '?') }}
|
||||
</span>
|
||||
<div class="flex flex-col min-w-0">
|
||||
<span class="text-sm text-gray-700 truncate">{{ invitation.company?.name }}</span>
|
||||
<span class="text-xs text-gray-400">{{ invitation.role?.title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex space-x-1 pl-12">
|
||||
<button
|
||||
class="text-xs px-2 py-1 rounded bg-primary-500 text-white hover:bg-primary-600"
|
||||
@click.stop="acceptInvitation(invitation.token)"
|
||||
>
|
||||
{{ $t('general.accept') }}
|
||||
</button>
|
||||
<button
|
||||
class="text-xs px-2 py-1 rounded bg-gray-200 text-gray-600 hover:bg-gray-300"
|
||||
@click.stop="declineInvitation(invitation.token)"
|
||||
>
|
||||
{{ $t('general.decline') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user