Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
| Numéro du ticket | Titre du ticket | |------------------|-----------------| | | | ## Description de la PR ## Modification du .env ## Check list - [ ] Pas de régression - [ ] TU/TI/TF rédigée - [ ] TU/TI/TF OK - [ ] CHANGELOG modifié Reviewed-on: #16 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
199 lines
9.8 KiB
Vue
199 lines
9.8 KiB
Vue
<template>
|
|
<div class="h-screen overflow-hidden">
|
|
<div class="flex h-full">
|
|
<!-- Mobile overlay -->
|
|
<Transition
|
|
enter-active-class="transition-opacity duration-300"
|
|
enter-from-class="opacity-0"
|
|
enter-to-class="opacity-100"
|
|
leave-active-class="transition-opacity duration-300"
|
|
leave-from-class="opacity-100"
|
|
leave-to-class="opacity-0"
|
|
>
|
|
<div
|
|
v-if="sidebarOpen"
|
|
class="fixed inset-0 z-40 bg-black/50 lg:hidden"
|
|
@click="sidebarOpen = false"
|
|
/>
|
|
</Transition>
|
|
|
|
<!-- Sidebar -->
|
|
<aside
|
|
:class="[
|
|
'fixed inset-y-0 left-0 z-50 flex w-64 flex-col border-r border-neutral-200 bg-tertiary-500 transition-transform duration-300 lg:static lg:translate-x-0 lg:flex-shrink-0',
|
|
sidebarOpen ? 'translate-x-0' : '-translate-x-full'
|
|
]"
|
|
>
|
|
<div class="flex h-[75px] items-center justify-between">
|
|
<img src="/malio.png" alt="Logo" class="w-auto"/>
|
|
<button
|
|
type="button"
|
|
class="mr-3 rounded-md p-1 text-primary-500 hover:text-secondary-500 lg:hidden"
|
|
@click="sidebarOpen = false"
|
|
>
|
|
<Icon name="mdi:close" size="24"/>
|
|
</button>
|
|
</div>
|
|
<nav class="flex-1 overflow-y-auto px-4 pb-6">
|
|
<template v-if="isAdmin">
|
|
<NuxtLink
|
|
to="/calendar"
|
|
class="flex items-center gap-2 pb-2 pt-3 text-md text-black hover:bg-tertiary-500 hover:text-primary-500 border-t border-secondary-500"
|
|
:class="route.path.startsWith('/calendar')
|
|
? 'bg-tertiary-500 text-primary-500 font-bold'
|
|
: ''"
|
|
@click="closeSidebarOnMobile"
|
|
>
|
|
<Icon name="mdi:calendar-blank" size="24"/>
|
|
<p>Calendrier</p>
|
|
</NuxtLink>
|
|
</template>
|
|
<NuxtLink
|
|
v-if="isAdmin || !isDriver"
|
|
to="/hours"
|
|
class="flex items-center gap-2 py-2 text-md text-black hover:bg-tertiary-500 hover:text-primary-500"
|
|
:class="[
|
|
route.path.startsWith('/hours') ? 'bg-tertiary-500 text-primary-500 font-bold' : '',
|
|
!isAdmin ? 'border-t border-secondary-500 pt-3' : ''
|
|
]"
|
|
@click="closeSidebarOnMobile"
|
|
>
|
|
<Icon name="mdi:clock-time-four-outline" size="24"/>
|
|
<p>Heures</p>
|
|
</NuxtLink>
|
|
<NuxtLink
|
|
v-if="isAdmin || isDriver"
|
|
to="/driver-hours"
|
|
class="flex items-center gap-2 py-2 text-md text-black hover:bg-tertiary-500 hover:text-primary-500"
|
|
:class="[
|
|
route.path.startsWith('/driver-hours') ? 'bg-tertiary-500 text-primary-500 font-bold' : '',
|
|
!isAdmin && isDriver ? 'border-t border-secondary-500 pt-3' : ''
|
|
]"
|
|
@click="closeSidebarOnMobile"
|
|
>
|
|
<Icon name="mdi:truck-outline" size="24"/>
|
|
<p>Heures Conducteurs</p>
|
|
</NuxtLink>
|
|
<template v-if="isAdmin">
|
|
<NuxtLink
|
|
to="/employees"
|
|
class="flex items-center gap-2 py-2 text-md text-black hover:bg-tertiary-500 hover:text-primary-500"
|
|
:class="route.path.startsWith('/employees')
|
|
? 'bg-tertiary-500 text-primary-500 font-bold'
|
|
: ''"
|
|
@click="closeSidebarOnMobile"
|
|
>
|
|
<Icon name="mdi:account-group-outline" size="24"/>
|
|
<p>Employés</p>
|
|
</NuxtLink>
|
|
<NuxtLink
|
|
v-if="hasLeaveRecapAccess"
|
|
to="/leave-recap"
|
|
class="flex items-center gap-2 py-3 text-md text-black hover:bg-tertiary-500 hover:text-primary-500"
|
|
:class="route.path.startsWith('/leave-recap')
|
|
? 'bg-tertiary-500 text-primary-500 font-bold'
|
|
: ''"
|
|
@click="closeSidebarOnMobile"
|
|
>
|
|
<Icon name="mdi:beach" size="24"/>
|
|
<p>Récap. congés</p>
|
|
</NuxtLink>
|
|
<NuxtLink
|
|
to="/sites"
|
|
class="flex items-center gap-2 py-3 text-md text-black hover:bg-tertiary-500 hover:text-primary-500"
|
|
:class="route.path.startsWith('/sites')
|
|
? 'bg-tertiary-500 text-primary-500 font-bold'
|
|
: ''"
|
|
@click="closeSidebarOnMobile"
|
|
>
|
|
<Icon name="mdi:business" size="24"/>
|
|
<p>Sites</p>
|
|
</NuxtLink>
|
|
<NuxtLink
|
|
to="/absence-types"
|
|
class="flex items-center gap-2 py-3 text-md text-black hover:bg-tertiary-500 hover:text-primary-500"
|
|
:class="route.path.startsWith('/absence-types')
|
|
? 'bg-tertiary-500 text-primary-500 font-bold'
|
|
: ''"
|
|
@click="closeSidebarOnMobile"
|
|
>
|
|
<Icon name="mdi:umbrella-beach-outline" size="24"/>
|
|
<p>Types de statut</p>
|
|
</NuxtLink>
|
|
<NuxtLink
|
|
to="/users"
|
|
class="flex items-center gap-3 py-3 text-md text-black hover:bg-tertiary-500 hover:text-primary-500"
|
|
:class="route.path.startsWith('/users')
|
|
? 'bg-tertiary-500 text-primary-500 font-bold'
|
|
: ''"
|
|
@click="closeSidebarOnMobile"
|
|
>
|
|
<Icon name="mdi:account-outline" size="24"/>
|
|
<p>Utilisateurs</p>
|
|
</NuxtLink>
|
|
</template>
|
|
<NuxtLink
|
|
v-if="hasLeaveRecapAccess && !isAdmin"
|
|
to="/leave-recap"
|
|
class="flex items-center gap-2 py-3 text-md text-black hover:bg-tertiary-500 hover:text-primary-500 pt-3"
|
|
:class="route.path.startsWith('/leave-recap') ? 'bg-tertiary-500 text-primary-500 font-bold' : ''"
|
|
@click="closeSidebarOnMobile"
|
|
>
|
|
<Icon name="mdi:beach" size="24"/>
|
|
<p>Récap. congés</p>
|
|
</NuxtLink>
|
|
<NuxtLink
|
|
v-if="isSuperAdmin"
|
|
to="/audit-logs"
|
|
class="flex items-center gap-2 py-3 text-md text-black hover:bg-tertiary-500 hover:text-primary-500"
|
|
:class="route.path.startsWith('/audit-logs')
|
|
? 'bg-tertiary-500 text-primary-500 font-bold'
|
|
: ''"
|
|
@click="closeSidebarOnMobile"
|
|
>
|
|
<Icon name="mdi:clipboard-text-clock-outline" size="24"/>
|
|
<p>Journal</p>
|
|
</NuxtLink>
|
|
<NuxtLink
|
|
to="/documentation"
|
|
class="flex items-center gap-2 py-3 text-md text-black hover:bg-tertiary-500 hover:text-primary-500"
|
|
:class="route.path.startsWith('/documentation')
|
|
? 'bg-tertiary-500 text-primary-500 font-bold'
|
|
: ''"
|
|
@click="closeSidebarOnMobile"
|
|
>
|
|
<Icon name="mdi:book-open-page-variant-outline" size="24"/>
|
|
<p>Documentation</p>
|
|
</NuxtLink>
|
|
</nav>
|
|
|
|
<div class="flex flex-col gap-2 items-center p-4">
|
|
<p class="font-bold">v{{ version }}</p>
|
|
</div>
|
|
</aside>
|
|
|
|
<div class="h-full flex-1 overflow-hidden flex flex-col min-w-0">
|
|
<AppTopNav :user="auth.user" @toggle-sidebar="sidebarOpen = !sidebarOpen" />
|
|
<main class="flex-1 overflow-y-auto px-4 py-6 lg:px-8 lg:py-12">
|
|
<slot/>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
const auth = useAuthStore()
|
|
const {version} = useAppVersion()
|
|
const isAdmin = computed(() => auth.user?.roles?.includes('ROLE_ADMIN') ?? false)
|
|
const isSuperAdmin = computed(() => auth.user?.roles?.includes('ROLE_SUPER_ADMIN') ?? false)
|
|
const isDriver = computed(() => auth.user?.isDriver ?? false)
|
|
const hasLeaveRecapAccess = computed(() => auth.user?.hasLeaveRecapAccess ?? false)
|
|
const route = useRoute()
|
|
const sidebarOpen = ref(false)
|
|
|
|
const closeSidebarOnMobile = () => {
|
|
sidebarOpen.value = false
|
|
}
|
|
</script>
|