✨ feat(Devis.php): Ajoute adresses de facturation et de livraison au devis. 🔒️ fix(IntranetLocked.php): Autorise l'accès à la route st_control en mode debug. ✨ feat(CustomerAddress.php): Gère les adresses de facturation et livraison. ✨ feat: Ajoute la console superadmin pour le contrôle système. ✨ feat(DevisController.php): Supprime la génération PDF temporaire. ✨ feat(st_control.js): Ajoute la logique de contrôle système via JS. ✨ feat: Crée les templates CGV, Cookies, Hébergement et RGPD. 🎨 style(app.scss): Ajoute un style de fond pour la console. ✨ feat: Ajoute le template pour les informations d'hébergement. ✨ feat: Crée un template de mail d'alerte pour les accès root. ✨ feat: Crée le template RGPD (données personnelles). 🐛 fix(ErrorListener.php): Gère les erreurs 404 en prod (JSON/HTML). ✨ feat: Ajoute les mentions légales. ✨ feat(DevisPdfService.php): Améliore la génération PDF du devis. ✨ feat(admin.js): Charge dynamiquement les produits dans le select. ✨ feat(add.twig): Ajoute un sélecteur de produit et d'autres champs. ✅ chore(config): Ajoute INTRANET_LOCK à l'env. ```
160 lines
11 KiB
Twig
160 lines
11 KiB
Twig
{% extends 'base.twig' %}
|
|
|
|
{% block title %}Console SuperAdmin - SiteConseil{% endblock %}
|
|
|
|
{% block body %}
|
|
<div class="min-h-screen bg-console font-mono text-slate-300">
|
|
|
|
{# --- BARRE ROOT CONSOLE v1.0 --- #}
|
|
<div class="bg-slate-900 border-b-2 border-red-700 px-6 py-4 shadow-2xl">
|
|
<div class="flex flex-col md:flex-row md:justify-between md:items-center gap-4">
|
|
<div class="flex flex-col">
|
|
<h1 class="text-white font-black text-2xl tracking-tighter uppercase leading-none">
|
|
Root Console <span class="text-red-600">v1.0</span>
|
|
</h1>
|
|
<span class="text-[11px] text-slate-400 font-bold uppercase tracking-[0.3em] mt-1">
|
|
Siteconseil Privileged Access
|
|
</span>
|
|
</div>
|
|
|
|
<div class="flex items-center gap-6">
|
|
<div class="hidden sm:flex items-center gap-2 border border-green-500/50 bg-green-500/10 px-3 py-1 rounded shadow-[0_0_15px_rgba(34,197,94,0.2)]">
|
|
<span class="h-2 w-2 bg-green-500 rounded-full animate-ping"></span>
|
|
<span class="text-[10px] text-green-500 font-black uppercase tracking-widest">Access Granted</span>
|
|
</div>
|
|
|
|
<div class="flex items-center gap-3 bg-black/30 px-4 py-2 rounded border border-slate-800">
|
|
<div class="flex flex-col items-end">
|
|
<span class="text-[9px] text-slate-500 uppercase font-bold tracking-widest">Operator IP</span>
|
|
<span class="text-sm text-green-500 font-bold tracking-widest">
|
|
{{ app.request.headers.get('cf-connecting-ip') ?? app.request.clientIp }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{# --- BODY DOUBLE COLONNE --- #}
|
|
<div class="flex flex-col lg:flex-row h-[calc(100vh-84px)] overflow-hidden">
|
|
|
|
{# COLONNE GAUCHE #}
|
|
<div class="w-full lg:w-2/3 p-8 border-r border-slate-800 overflow-y-auto bg-slate-900/10">
|
|
|
|
{# BLOCK : SERVICE HEALTH #}
|
|
<div class="mb-12">
|
|
<h2 class="text-xs font-bold text-slate-500 uppercase tracking-widest mb-6 flex items-center gap-2">
|
|
<span class="w-2 h-2 bg-green-500 rounded-full"></span>
|
|
External Service Health
|
|
</h2>
|
|
<div class="grid grid-cols-1 sm:grid-cols-3 gap-4">
|
|
{# Stripe #}
|
|
<div class="bg-black/40 border border-slate-800 p-4 rounded flex items-center justify-between group">
|
|
<span class="text-xs font-bold text-slate-400 group-hover:text-indigo-400">STRIPE API</span>
|
|
<div class="flex items-center gap-2">
|
|
<span class="text-[10px] font-bold uppercase {{ stripeStatus == 1 ? 'text-green-500' : 'text-red-500 animate-pulse' }}">
|
|
{{ stripeStatus == 1 ? 'Online' : 'Offline' }}
|
|
</span>
|
|
<div class="w-1.5 h-1.5 rounded-full {{ stripeStatus == 1 ? 'bg-green-500' : 'bg-red-500' }}"></div>
|
|
</div>
|
|
</div>
|
|
{# Signature #}
|
|
<div class="bg-black/40 border border-slate-800 p-4 rounded flex items-center justify-between group">
|
|
<span class="text-xs font-bold text-slate-400 group-hover:text-blue-400">SIGNATURE</span>
|
|
<div class="flex items-center gap-2">
|
|
<span class="text-[10px] font-bold uppercase {{ signatureStatus == 1 ? 'text-green-500' : 'text-red-500 animate-pulse' }}">
|
|
{{ signatureStatus == 1 ? 'Online' : 'Offline' }}
|
|
</span>
|
|
<div class="w-1.5 h-1.5 rounded-full {{ signatureStatus == 1 ? 'bg-green-500' : 'bg-red-500' }}"></div>
|
|
</div>
|
|
</div>
|
|
{# Esysearch #}
|
|
<div class="bg-black/40 border border-slate-800 p-4 rounded flex items-center justify-between group">
|
|
<span class="text-xs font-bold text-slate-400 group-hover:text-orange-400">ESYSEARCH</span>
|
|
<div class="flex items-center gap-2">
|
|
<span class="text-[10px] font-bold uppercase {{ searchClient == 1 ? 'text-green-500' : 'text-red-500 animate-pulse' }}">
|
|
{{ searchClient == 1 ? 'Online' : 'Offline' }}
|
|
</span>
|
|
<div class="w-1.5 h-1.5 rounded-full {{ searchClient == 1 ? 'bg-green-500' : 'bg-red-500' }}"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{# BLOCK : CRITICAL COMMANDS #}
|
|
<div class="mb-12">
|
|
<h2 class="text-xs font-bold text-slate-500 uppercase tracking-widest mb-6 flex items-center gap-2">
|
|
<span class="w-2 h-2 bg-red-600 rounded-full"></span>
|
|
Critical Command Center
|
|
</h2>
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div class="bg-red-950/20 border border-red-900/50 p-6 rounded-lg group hover:bg-red-900/30 transition-all shadow-lg text-center">
|
|
<h3 class="text-red-500 font-bold uppercase text-sm mb-4">Maintenance Mode</h3>
|
|
<button id="btn-suspend" class="w-full bg-red-700 hover:bg-red-600 text-white font-black py-3 rounded uppercase text-[11px] tracking-[0.2em] active:scale-95 transition-transform">Suspendre l'accès</button>
|
|
</div>
|
|
<div class="bg-green-950/20 border border-green-900/50 p-6 rounded-lg group hover:bg-green-900/30 transition-all shadow-lg text-center">
|
|
<h3 class="text-green-500 font-bold uppercase text-sm mb-4">Live Mode</h3>
|
|
<button id="btn-enable" class="w-full bg-green-700 hover:bg-green-600 text-white font-black py-3 rounded uppercase text-[11px] tracking-[0.2em] active:scale-95 transition-transform">Réactiver l'accès</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{# BLOCK : OPTIMIZATION #}
|
|
<div class="mb-8">
|
|
<h2 class="text-xs font-bold text-slate-500 uppercase tracking-widest mb-6 flex items-center gap-2">
|
|
<span class="w-2 h-2 bg-blue-600 rounded-full"></span>
|
|
System Optimization
|
|
</h2>
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div class="bg-slate-900/40 border border-slate-800 p-6 rounded-lg group hover:border-blue-900/50 transition-all">
|
|
<h3 class="text-blue-500 font-bold uppercase text-sm mb-4 font-mono">cache:clear</h3>
|
|
<button id="btn-cache" class="w-full bg-slate-800 hover:bg-blue-700 text-white font-bold py-2 rounded uppercase text-[10px] tracking-widest">Run Command</button>
|
|
</div>
|
|
<div class="bg-slate-900/40 border border-slate-800 p-6 rounded-lg group hover:border-purple-900/50 transition-all">
|
|
<h3 class="text-purple-500 font-bold uppercase text-sm mb-4 font-mono">liip:cache:clear</h3>
|
|
<button id="btn-liip" class="w-full bg-slate-800 hover:bg-purple-700 text-white font-bold py-2 rounded uppercase text-[10px] tracking-widest">Run Command</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{# --- COLONNE DROITE : LE TERMINAL --- #}
|
|
<div class="w-full lg:w-1/3 bg-black p-0 flex flex-col h-full shadow-inner border-l border-slate-800">
|
|
<div class="bg-slate-800/50 px-4 py-2 flex items-center justify-between border-b border-slate-700">
|
|
<div class="flex gap-1.5">
|
|
<div class="w-2.5 h-2.5 rounded-full bg-red-500/20 border border-red-500/50"></div>
|
|
<div class="w-2.5 h-2.5 rounded-full bg-yellow-500/20 border border-yellow-500/50"></div>
|
|
<div class="w-2.5 h-2.5 rounded-full bg-green-500/20 border border-green-500/50"></div>
|
|
</div>
|
|
<span class="text-[10px] uppercase text-slate-500 font-bold tracking-widest">Live System Logs</span>
|
|
</div>
|
|
|
|
<div id="terminal-logs" class="p-6 font-mono text-[11px] leading-relaxed overflow-y-auto h-full space-y-1 scrollbar-thin scrollbar-thumb-slate-800">
|
|
<p class="text-slate-600">[{{ "now"|date('H:i:s') }}] INITIALIZING ROOT INTERFACE...</p>
|
|
<p class="text-slate-600">[{{ "now"|date('H:i:s') }}] SESSION_USER: <span class="text-white">SITECONSEIL_ADMIN</span></p>
|
|
|
|
<p class="text-slate-600">[{{ "now"|date('H:i:s') }}] DOMAIN_VALIDATION: <span class="text-green-500 font-bold">SUCCESSFUL</span></p>
|
|
<p class="text-slate-600">[{{ "now"|date('H:i:s') }}] IP_OPERATOR_VAL: <span class="text-green-500 font-bold">SUCCESSFUL</span></p>
|
|
<p class="text-slate-600">[{{ "now"|date('H:i:s') }}] SECRET_KEY_VAL: <span class="text-green-500 font-bold">SUCCESSFUL</span></p>
|
|
|
|
{# Statuts des services en 1/0 #}
|
|
<p class="text-slate-600">[{{ "now"|date('H:i:s') }}] STRIPE_VAL: <span class="{{ stripeStatus == 1 ? 'text-green-500' : 'text-red-500' }} font-bold">{{ stripeStatus == 1 ? 'ONLINE' : 'OFFLINE' }}</span></p>
|
|
<p class="text-slate-600">[{{ "now"|date('H:i:s') }}] SIGNATURE_VAL: <span class="{{ signatureStatus == 1 ? 'text-green-500' : 'text-red-500' }} font-bold">{{ signatureStatus == 1 ? 'ONLINE' : 'OFFLINE' }}</span></p>
|
|
<p class="text-slate-600">[{{ "now"|date('H:i:s') }}] ESYSEARCH_VAL: <span class="{{ searchClient == 1 ? 'text-green-500' : 'text-red-500' }} font-bold">{{ searchClient == 1 ? 'ONLINE' : 'OFFLINE' }}</span></p>
|
|
|
|
<div class="py-3">
|
|
<p class="text-green-400 font-bold bg-green-500/10 px-3 py-1.5 border-l-2 border-green-500 uppercase tracking-tighter">
|
|
*** Access granted to system core ***
|
|
</p>
|
|
</div>
|
|
|
|
<div id="dynamic-logs" class="space-y-1"></div>
|
|
|
|
<p class="text-white mt-4">> <span class="animate-pulse">_</span></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script nonce="{{ csp_nonce('script') }}" src="/st_control.js"></script>
|
|
{% endblock %}
|