138 lines
5.6 KiB
Vue
138 lines
5.6 KiB
Vue
<script setup>
|
|
import ApplicationLogo from '@/Components/ApplicationLogo.vue';
|
|
import { Link, usePage } from '@inertiajs/vue3';
|
|
import { computed } from 'vue';
|
|
|
|
defineProps({
|
|
title: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
});
|
|
|
|
const page = usePage();
|
|
const supervisor = computed(() => page.props.auth.supervisor);
|
|
|
|
const navItems = [
|
|
{ label: 'Tableau de bord', route: 'supervisor.dashboard', icon: 'dashboard' },
|
|
{ label: 'Machines', route: 'supervisor.machines.index', icon: 'machines' },
|
|
{ label: 'Réservations', route: 'supervisor.bookings.index', icon: 'bookings' },
|
|
{ label: 'Lavages', route: 'supervisor.washes.index', icon: 'washes' },
|
|
{ label: 'Tarifs', route: 'supervisor.pricing.index', icon: 'pricing' },
|
|
{ label: 'Promotions', route: 'supervisor.promotions.index', icon: 'promotions' },
|
|
];
|
|
|
|
const isActive = (routeName) => {
|
|
if (routeName === 'supervisor.machines.index') {
|
|
return route().current('supervisor.machines.*');
|
|
}
|
|
return route().current(routeName);
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div class="min-h-screen bg-gray-100">
|
|
<div class="flex min-h-screen">
|
|
<!-- Sidebar -->
|
|
<aside class="hidden w-64 flex-shrink-0 bg-indigo-900 lg:flex lg:flex-col">
|
|
<div class="flex h-16 items-center px-6">
|
|
<Link :href="route('supervisor.dashboard')" class="flex items-center gap-2">
|
|
<ApplicationLogo class="h-8 w-auto fill-current text-white" />
|
|
<span class="text-lg font-semibold text-white">Laverie</span>
|
|
</Link>
|
|
</div>
|
|
|
|
<nav class="mt-4 flex-1 space-y-1 px-3">
|
|
<Link
|
|
v-for="item in navItems"
|
|
:key="item.route"
|
|
:href="route(item.route)"
|
|
class="flex items-center rounded-md px-3 py-2 text-sm font-medium transition"
|
|
:class="
|
|
isActive(item.route)
|
|
? 'bg-indigo-800 text-white'
|
|
: 'text-indigo-100 hover:bg-indigo-800 hover:text-white'
|
|
"
|
|
>
|
|
{{ item.label }}
|
|
</Link>
|
|
</nav>
|
|
|
|
<div class="border-t border-indigo-800 p-4">
|
|
<p class="truncate text-sm font-medium text-white">
|
|
{{ supervisor?.name }}
|
|
</p>
|
|
<p class="truncate text-xs text-indigo-300">
|
|
{{ supervisor?.email }}
|
|
</p>
|
|
</div>
|
|
</aside>
|
|
|
|
<!-- Main content -->
|
|
<div class="flex flex-1 flex-col">
|
|
<!-- Header -->
|
|
<header class="border-b border-gray-200 bg-white shadow-sm">
|
|
<div class="flex h-16 items-center justify-between px-4 sm:px-6 lg:px-8">
|
|
<div class="flex items-center gap-4">
|
|
<Link
|
|
:href="route('supervisor.dashboard')"
|
|
class="text-lg font-semibold text-gray-800 lg:hidden"
|
|
>
|
|
Laverie
|
|
</Link>
|
|
<h1 v-if="title" class="text-lg font-semibold text-gray-800">
|
|
{{ title }}
|
|
</h1>
|
|
<slot name="header" />
|
|
</div>
|
|
|
|
<div class="flex items-center gap-4">
|
|
<span class="hidden text-sm text-gray-600 sm:inline">
|
|
{{ supervisor?.name }}
|
|
</span>
|
|
<Link
|
|
:href="route('logout')"
|
|
method="post"
|
|
as="button"
|
|
class="rounded-md bg-gray-100 px-3 py-1.5 text-sm font-medium text-gray-700 hover:bg-gray-200"
|
|
>
|
|
Déconnexion
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Mobile nav -->
|
|
<nav class="flex gap-1 overflow-x-auto border-t border-gray-100 px-4 py-2 lg:hidden">
|
|
<Link
|
|
v-for="item in navItems"
|
|
:key="item.route"
|
|
:href="route(item.route)"
|
|
class="whitespace-nowrap rounded-md px-3 py-1.5 text-xs font-medium"
|
|
:class="
|
|
isActive(item.route)
|
|
? 'bg-indigo-100 text-indigo-800'
|
|
: 'text-gray-600 hover:bg-gray-100'
|
|
"
|
|
>
|
|
{{ item.label }}
|
|
</Link>
|
|
</nav>
|
|
</header>
|
|
|
|
<!-- Flash message -->
|
|
<div
|
|
v-if="page.props.flash?.success"
|
|
class="mx-4 mt-4 rounded-md bg-green-50 px-4 py-3 text-sm text-green-800 sm:mx-6 lg:mx-8"
|
|
>
|
|
{{ page.props.flash.success }}
|
|
</div>
|
|
|
|
<!-- Page content -->
|
|
<main class="flex-1 p-4 sm:p-6 lg:p-8">
|
|
<slot />
|
|
</main>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|