Files
ficheagent/resources/js/Layouts/AuthenticatedLayout.vue

315 lines
17 KiB
Vue
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup>
import { ref } from 'vue';
import ApplicationLogo from '@/Components/ApplicationLogo.vue';
import Dropdown from '@/Components/Dropdown.vue';
import DropdownLink from '@/Components/DropdownLink.vue';
import NavLink from '@/Components/NavLink.vue';
import ResponsiveNavLink from '@/Components/ResponsiveNavLink.vue';
import { Link } from '@inertiajs/vue3';
const showingNavigationDropdown = ref(false);
</script>
<template>
<div>
<div class="min-h-screen bg-gray-100 dark:bg-gray-900">
<!-- Impersonation Banner -->
<div v-if="$page.props.tenant.is_impersonating" class="bg-amber-500 text-white py-2 px-4 shadow-md">
<div class="max-w-7xl mx-auto flex justify-between items-center text-sm font-bold">
<div class="flex items-center space-x-2">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
</svg>
<span>MODE SIMULATION ACTIF : Vous modifiez actuellement le locataire "{{ $page.props.tenant?.current?.name || 'VUE GLOBALE' }}"</span>
</div>
<Link :href="route('superadmin.reset')" method="post" as="button" class="bg-white text-amber-600 px-3 py-1 rounded-md hover:bg-amber-50 transition-colors">
Arrêter la simulation
</Link>
</div>
</div>
<nav
class="border-b border-gray-100 bg-white dark:border-gray-700 dark:bg-gray-800"
>
<!-- Primary Navigation Menu -->
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div class="flex h-16 justify-between">
<div class="flex">
<!-- Logo and Structure Name -->
<div class="flex shrink-0 items-center space-x-3">
<Link :href="route('dashboard')">
<ApplicationLogo
class="block h-9 w-auto"
/>
</Link>
<span class="text-lg font-bold text-gray-800 dark:text-gray-200">
{{ $page.props.tenant?.current?.name || $page.props.auth?.user?.structure?.name || '' }}
</span>
</div>
<!-- Navigation Links -->
<div
class="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex"
>
<NavLink
:href="route('dashboard')"
:active="route().current('dashboard')"
>
Tableau de Bord
</NavLink>
<NavLink
v-if="$page.props.auth.user.roles.some(r => r.name === 'Admin' || r.name === 'SuperAdmin')"
:href="route('users.index')"
:active="route().current('users.*')"
>
Utilisateurs
</NavLink>
<NavLink
v-if="$page.props.auth.user.roles.some(r => r.name === 'Admin' || r.name === 'SuperAdmin')"
:href="route('roles.index')"
:active="route().current('roles.*')"
>
Rôles
</NavLink>
<NavLink
v-if="$page.props.auth.user.roles.some(r => r.name === 'Admin' || r.name === 'SuperAdmin')"
:href="route('permissions.index')"
:active="route().current('permissions.*')"
>
Permissions
</NavLink>
<NavLink
v-if="$page.props.auth.user.roles.some(r => r.name === 'Admin' || r.name === 'SuperAdmin')"
:href="route('services.index')"
:active="route().current('services.*')"
>
Services
</NavLink>
<NavLink
v-if="$page.props.auth.user.roles.some(r => r.name === 'Admin' || r.name === 'SuperAdmin')"
:href="route('templates.index')"
:active="route().current('templates.*')"
>
Modèles
</NavLink>
<NavLink
v-if="$page.props.auth.user.roles.some(r => r.name === 'SuperAdmin')"
:href="route('superadmin.index')"
:active="route().current('superadmin.*')"
class="text-indigo-600 dark:text-indigo-400 font-bold"
>
🛠 SaaS Admin
</NavLink>
</div>
</div>
<div class="hidden sm:ms-6 sm:flex sm:items-center">
<!-- Settings Dropdown -->
<div class="relative ms-3">
<Dropdown align="right" width="48">
<template #trigger>
<span class="inline-flex rounded-md">
<button
type="button"
class="inline-flex items-center rounded-md border border-transparent bg-white px-3 py-2 text-sm font-medium leading-4 text-gray-500 transition duration-150 ease-in-out hover:text-gray-700 focus:outline-none dark:bg-gray-800 dark:text-gray-400 dark:hover:text-gray-300"
>
{{ $page.props.auth.user.name }}
<svg
class="-me-0.5 ms-2 h-4 w-4"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd"
/>
</svg>
</button>
</span>
</template>
<template #content>
<DropdownLink
:href="route('profile.edit')"
>
Profil
</DropdownLink>
<DropdownLink
:href="route('logout')"
method="post"
as="button"
>
Déconnexion
</DropdownLink>
</template>
</Dropdown>
</div>
</div>
<!-- Hamburger -->
<div class="-me-2 flex items-center sm:hidden">
<button
@click="
showingNavigationDropdown =
!showingNavigationDropdown
"
class="inline-flex items-center justify-center rounded-md p-2 text-gray-400 transition duration-150 ease-in-out hover:bg-gray-100 hover:text-gray-500 focus:bg-gray-100 focus:text-gray-500 focus:outline-none dark:text-gray-500 dark:hover:bg-gray-900 dark:hover:text-gray-400 dark:focus:bg-gray-900 dark:focus:text-gray-400"
>
<svg
class="h-6 w-6"
stroke="currentColor"
fill="none"
viewBox="0 0 24 24"
>
<path
:class="{
hidden: showingNavigationDropdown,
'inline-flex':
!showingNavigationDropdown,
}"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 6h16M4 12h16M4 18h16"
/>
<path
:class="{
hidden: !showingNavigationDropdown,
'inline-flex':
showingNavigationDropdown,
}"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
</div>
</div>
<!-- Responsive Navigation Menu -->
<div
:class="{
block: showingNavigationDropdown,
hidden: !showingNavigationDropdown,
}"
class="sm:hidden"
>
<div class="space-y-1 pb-3 pt-2">
<ResponsiveNavLink
:href="route('dashboard')"
:active="route().current('dashboard')"
>
Tableau de Bord
</ResponsiveNavLink>
<ResponsiveNavLink
v-if="$page.props.auth.user.roles.some(r => r.name === 'Admin' || r.name === 'SuperAdmin')"
:href="route('users.index')"
:active="route().current('users.*')"
>
Utilisateurs
</ResponsiveNavLink>
<ResponsiveNavLink
v-if="$page.props.auth.user.roles.some(r => r.name === 'Admin' || r.name === 'SuperAdmin')"
:href="route('roles.index')"
:active="route().current('roles.*')"
>
Rôles
</ResponsiveNavLink>
<ResponsiveNavLink
v-if="$page.props.auth.user.roles.some(r => r.name === 'Admin' || r.name === 'SuperAdmin')"
:href="route('permissions.index')"
:active="route().current('permissions.*')"
>
Permissions
</ResponsiveNavLink>
<ResponsiveNavLink
v-if="$page.props.auth.user.roles.some(r => r.name === 'Admin' || r.name === 'SuperAdmin')"
:href="route('services.index')"
:active="route().current('services.*')"
>
Services
</ResponsiveNavLink>
<ResponsiveNavLink
v-if="$page.props.auth.user.roles.some(r => r.name === 'Admin' || r.name === 'SuperAdmin')"
:href="route('templates.index')"
:active="route().current('templates.*')"
>
Modèles
</ResponsiveNavLink>
<ResponsiveNavLink
v-if="$page.props.auth.user.roles.some(r => r.name === 'SuperAdmin')"
:href="route('superadmin.index')"
:active="route().current('superadmin.*')"
class="text-indigo-600 dark:text-indigo-400 font-bold"
>
🛠 SaaS Admin
</ResponsiveNavLink>
</div>
<!-- Responsive Settings Options -->
<div
class="border-t border-gray-200 pb-1 pt-4 dark:border-gray-600"
>
<div class="px-4">
<div
class="text-base font-medium text-gray-800 dark:text-gray-200"
>
{{ $page.props.auth.user.name }}
</div>
<div class="text-sm font-medium text-gray-500">
{{ $page.props.auth.user.email }}
</div>
</div>
<div class="mt-3 space-y-1">
<ResponsiveNavLink :href="route('profile.edit')">
Profil
</ResponsiveNavLink>
<ResponsiveNavLink
:href="route('logout')"
method="post"
as="button"
>
Déconnexion
</ResponsiveNavLink>
</div>
</div>
</div>
</nav>
<!-- Page Heading -->
<header
class="bg-white shadow dark:bg-gray-800"
v-if="$slots.header"
>
<div class="mx-auto max-w-7xl px-4 py-6 sm:px-6 lg:px-8">
<slot name="header" />
</div>
</header>
<!-- Page Content -->
<main>
<!-- Flash Messages -->
<div v-if="$page.props.flash.success" class="max-w-7xl mx-auto mt-4 px-4 sm:px-6 lg:px-8">
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded relative" role="alert">
<span class="block sm:inline">{{ $page.props.flash.success }}</span>
</div>
</div>
<div v-if="$page.props.flash.error" class="max-w-7xl mx-auto mt-4 px-4 sm:px-6 lg:px-8">
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
<span class="block sm:inline">{{ $page.props.flash.error }}</span>
</div>
</div>
<slot />
</main>
</div>
</div>
</template>