Files
CABM-IT/resources/views/components/layouts/app.blade.php
T
mrKamooandClaude Sonnet 5 da589d0627 Ajoute un menu admin pour éditer les variables .env de l'app
Nouvelle page "Configuration (.env)" réservée au rôle Administrateur :
- EnvFileManager lit/réécrit le .env ligne à ligne en préservant
  commentaires et mise en forme, avec écriture atomique (fichier
  temporaire + rename).
- Variables critiques (APP_KEY, DB_*, SESSION_DRIVER) en lecture seule
  pour éviter de casser la connexion base de données ou de bloquer
  l'accès admin — protection appliquée aussi côté serveur, pas
  seulement dans l'affichage.
- Valeurs sensibles (mots de passe, jetons, clés) masquées par défaut
  avec un bouton de révélation par champ.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 08:58:29 +02:00

171 lines
11 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>
@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.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.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 (.env)
</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 }} &middot; 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>