- Fiche d'identité par organisation (technicien référent, FAI, IP publiques, prestataires liés) accessible depuis un nouveau menu. - Nouveau module Prestataires dédié (catalogue léger réutilisable entre communes, avec journal de suivi des échanges) plutôt que de détourner les organisations de type "Fournisseur". - Nouveau menu Infrastructure par organisation avec schémas réseau/fonctionnel édités via draw.io embarqué (URL configurable, cf. réglages admin). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
183 lines
12 KiB
PHP
183 lines
12 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>{{ $title ?? config('app.name') }}</title>
|
|
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
|
@livewireStyles
|
|
</head>
|
|
<body class="bg-slate-50 text-slate-900 antialiased">
|
|
<div class="flex min-h-screen">
|
|
@php
|
|
$currentOrganization = request()->route('organization');
|
|
@endphp
|
|
<aside class="w-60 shrink-0 bg-slate-900 text-slate-200">
|
|
<div class="px-4 py-4 text-lg font-semibold text-white">{{ config('app.name') }}</div>
|
|
<nav class="mt-2 space-y-1 px-2 text-sm">
|
|
<a href="{{ route('organizations.index') }}"
|
|
class="block rounded px-3 py-2 hover:bg-slate-800 {{ request()->routeIs('organizations.*') ? 'bg-slate-800 text-white' : '' }}">
|
|
Organisations
|
|
</a>
|
|
<a href="{{ route('providers.index') }}"
|
|
class="block rounded px-3 py-2 hover:bg-slate-800 {{ request()->routeIs('providers.*') ? 'bg-slate-800 text-white' : '' }}">
|
|
Prestataires
|
|
</a>
|
|
|
|
@if ($currentOrganization)
|
|
@php
|
|
$assetTypes = \App\Models\FlexibleAssetType::whereHas('assets', fn ($q) => $q->where('organization_id', $currentOrganization->id))
|
|
->orderBy('name')
|
|
->get();
|
|
$shortcuts = \App\Models\Shortcut::where('organization_id', $currentOrganization->id)
|
|
->orWhereNull('organization_id')
|
|
->orderBy('label')
|
|
->get();
|
|
@endphp
|
|
|
|
<div class="mt-3 border-t border-slate-800 pt-3">
|
|
<p class="px-3 pb-1 text-xs font-semibold uppercase tracking-wide text-slate-500">{{ $currentOrganization->name }}</p>
|
|
|
|
<a href="{{ route('organizations.dashboard', $currentOrganization) }}"
|
|
class="block rounded px-3 py-2 hover:bg-slate-800 {{ request()->routeIs('organizations.dashboard') ? 'bg-slate-800 text-white' : '' }}">
|
|
Tableau de bord
|
|
</a>
|
|
<a href="{{ route('organizations.identity-card', $currentOrganization) }}"
|
|
class="block rounded px-3 py-2 hover:bg-slate-800 {{ request()->routeIs('organizations.identity-card') ? 'bg-slate-800 text-white' : '' }}">
|
|
Fiche d'identité
|
|
</a>
|
|
<a href="{{ route('organizations.todos.index', $currentOrganization) }}"
|
|
class="block rounded px-3 py-2 hover:bg-slate-800 {{ request()->routeIs('organizations.todos.*') ? 'bg-slate-800 text-white' : '' }}">
|
|
ToDo
|
|
</a>
|
|
<a href="{{ route('organizations.passwords.index', $currentOrganization) }}"
|
|
class="block rounded px-3 py-2 hover:bg-slate-800 {{ request()->routeIs('organizations.passwords.*') ? 'bg-slate-800 text-white' : '' }}">
|
|
Mots de passe
|
|
</a>
|
|
<a href="{{ route('organizations.contacts.index', $currentOrganization) }}"
|
|
class="block rounded px-3 py-2 hover:bg-slate-800 {{ request()->routeIs('organizations.contacts.*') ? 'bg-slate-800 text-white' : '' }}">
|
|
Contacts
|
|
</a>
|
|
<a href="{{ route('organizations.locations.index', $currentOrganization) }}"
|
|
class="block rounded px-3 py-2 hover:bg-slate-800 {{ request()->routeIs('organizations.locations.*') ? 'bg-slate-800 text-white' : '' }}">
|
|
Sites
|
|
</a>
|
|
<a href="{{ route('organizations.domains.index', $currentOrganization) }}"
|
|
class="block rounded px-3 py-2 hover:bg-slate-800 {{ request()->routeIs('organizations.domains.*') ? 'bg-slate-800 text-white' : '' }}">
|
|
Domaines
|
|
</a>
|
|
<a href="{{ route('organizations.documents.index', $currentOrganization) }}"
|
|
class="block rounded px-3 py-2 hover:bg-slate-800 {{ request()->routeIs('organizations.documents.*') ? 'bg-slate-800 text-white' : '' }}">
|
|
Documents
|
|
</a>
|
|
<a href="{{ route('organizations.infrastructure.index', $currentOrganization) }}"
|
|
class="block rounded px-3 py-2 hover:bg-slate-800 {{ request()->routeIs('organizations.infrastructure.*') ? 'bg-slate-800 text-white' : '' }}">
|
|
Infrastructure
|
|
</a>
|
|
<a href="{{ route('organizations.virtual-machines.index', $currentOrganization) }}"
|
|
class="block rounded px-3 py-2 hover:bg-slate-800 {{ request()->routeIs('organizations.virtual-machines.*') ? 'bg-slate-800 text-white' : '' }}">
|
|
Machines virtuelles
|
|
</a>
|
|
<div x-data="{ open: localStorage.getItem('nav-assets-open') === '1' }" x-init="$watch('open', value => localStorage.setItem('nav-assets-open', value ? '1' : '0'))">
|
|
<div class="flex items-center rounded hover:bg-slate-800 {{ request()->routeIs('organizations.assets.picker') ? 'bg-slate-800 text-white' : '' }}">
|
|
<a href="{{ route('organizations.assets.picker', $currentOrganization) }}"
|
|
class="block flex-1 px-3 py-2">
|
|
Actifs
|
|
</a>
|
|
@if ($assetTypes->isNotEmpty())
|
|
<button type="button" x-on:click="open = !open" class="px-2 py-2 text-slate-400 hover:text-white" :aria-expanded="open" aria-label="Replier/déplier les actifs">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="h-3.5 w-3.5 transition-transform" :class="open ? 'rotate-90' : ''">
|
|
<path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" />
|
|
</svg>
|
|
</button>
|
|
@endif
|
|
</div>
|
|
@if ($assetTypes->isNotEmpty())
|
|
<div x-show="open" class="ml-4 space-y-0.5 border-l border-slate-700 pl-2">
|
|
@foreach ($assetTypes as $assetType)
|
|
<a href="{{ route('organizations.assets.index', [$currentOrganization, $assetType]) }}"
|
|
class="block rounded px-3 py-1.5 text-slate-400 hover:bg-slate-800 hover:text-slate-100 {{ request()->routeIs('organizations.assets.*') && request()->route('type')?->is($assetType) ? 'bg-slate-800 text-white' : '' }}">
|
|
{{ $assetType->icon }} {{ \Illuminate\Support\Str::ucfirst(\Illuminate\Support\Str::lower($assetType->name)) }}
|
|
</a>
|
|
@endforeach
|
|
</div>
|
|
@endif
|
|
</div>
|
|
<div x-data="{ open: localStorage.getItem('nav-shortcuts-open') === '1' }" x-init="$watch('open', value => localStorage.setItem('nav-shortcuts-open', value ? '1' : '0'))">
|
|
<div class="flex items-center rounded hover:bg-slate-800 {{ request()->routeIs('organizations.shortcuts.*') ? 'bg-slate-800 text-white' : '' }}">
|
|
<a href="{{ route('organizations.shortcuts.index', $currentOrganization) }}"
|
|
class="block flex-1 px-3 py-2">
|
|
Raccourcis
|
|
</a>
|
|
@if ($shortcuts->isNotEmpty())
|
|
<button type="button" x-on:click="open = !open" class="px-2 py-2 text-slate-400 hover:text-white" :aria-expanded="open" aria-label="Replier/déplier les raccourcis">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="h-3.5 w-3.5 transition-transform" :class="open ? 'rotate-90' : ''">
|
|
<path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" />
|
|
</svg>
|
|
</button>
|
|
@endif
|
|
</div>
|
|
@if ($shortcuts->isNotEmpty())
|
|
<div x-show="open" class="ml-4 space-y-0.5 border-l border-slate-700 pl-2">
|
|
@foreach ($shortcuts as $shortcut)
|
|
<a href="{{ $shortcut->url }}" target="_blank" rel="noopener"
|
|
class="flex items-center gap-1 rounded px-3 py-1.5 text-slate-400 hover:bg-slate-800 hover:text-slate-100">
|
|
<span class="truncate">{{ $shortcut->icon ?: '🔗' }} {{ $shortcut->label }}</span>
|
|
</a>
|
|
@endforeach
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
@role('Administrateur')
|
|
<div class="mt-3 border-t border-slate-800 pt-3">
|
|
<p class="px-3 pb-1 text-xs font-semibold uppercase tracking-wide text-slate-500">Administration</p>
|
|
|
|
<a href="{{ route('asset-types.index') }}"
|
|
class="block rounded px-3 py-2 hover:bg-slate-800 {{ request()->routeIs('asset-types.*') ? 'bg-slate-800 text-white' : '' }}">
|
|
Types d'actifs
|
|
</a>
|
|
<a href="{{ route('users.index') }}"
|
|
class="block rounded px-3 py-2 hover:bg-slate-800 {{ request()->routeIs('users.*') ? 'bg-slate-800 text-white' : '' }}">
|
|
Utilisateurs
|
|
</a>
|
|
<a href="{{ route('settings.env') }}"
|
|
class="block rounded px-3 py-2 hover:bg-slate-800 {{ request()->routeIs('settings.env') ? 'bg-slate-800 text-white' : '' }}">
|
|
Configuration
|
|
</a>
|
|
</div>
|
|
@endrole
|
|
</nav>
|
|
</aside>
|
|
|
|
<div class="flex-1">
|
|
<header class="flex items-center justify-between border-b border-slate-200 bg-white px-6 py-3">
|
|
<div class="text-sm text-slate-500">{{ $header ?? '' }}</div>
|
|
@auth
|
|
<form method="POST" action="{{ route('logout') }}">
|
|
@csrf
|
|
<button type="submit" class="text-sm text-slate-500 hover:text-slate-900">
|
|
{{ auth()->user()->name }} · Déconnexion
|
|
</button>
|
|
</form>
|
|
@endauth
|
|
</header>
|
|
|
|
<main class="p-6">
|
|
@if (session('status'))
|
|
<div class="mb-4 rounded border border-emerald-200 bg-emerald-50 px-4 py-2 text-sm text-emerald-700">
|
|
{{ session('status') }}
|
|
</div>
|
|
@endif
|
|
|
|
{{ $slot }}
|
|
</main>
|
|
</div>
|
|
</div>
|
|
|
|
@livewireScripts
|
|
</body>
|
|
</html>
|