Initial commit — Serveur Lucas SmartEye

API réception alertes chute (SmartEye/YOLO), analyse IA (Gemini 2.5 Flash),
gestion alertes avec escalade (watchdog), notifications Firebase,
dashboard web, documentation MkDocs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Debian
2026-03-14 21:26:06 +01:00
commit 24dbc7cd6a
64 changed files with 9677 additions and 0 deletions

482
admin.php Executable file
View File

@@ -0,0 +1,482 @@
<?php
// --- SMARTEYE ADMIN DASHBOARD v3.0 (Lucas Edition) ---
session_start();
$ADMIN_PASS = "smart123"; // ⚠️ Mot de passe Admin
$DB_FILE = "database.json";
// --- AUTHENTIFICATION ---
if (isset($_POST['login'])) {
if ($_POST['pass'] === $ADMIN_PASS) { $_SESSION['admin'] = true; }
else { $error = "Mot de passe incorrect"; }
}
if (isset($_GET['logout'])) { session_destroy(); header("Location: admin.php"); exit; }
if (!isset($_SESSION['admin'])) {
// Page de Login
echo '<!DOCTYPE html><html lang="fr"><head><title>Admin Login</title><script src="https://cdn.tailwindcss.com"></script></head>
<body class="bg-slate-900 flex items-center justify-center h-screen">
<div class="bg-slate-800 p-8 rounded-xl shadow-2xl border border-slate-700 w-96 text-center">
<div class="w-12 h-12 bg-emerald-500 rounded-full mx-auto mb-4 animate-pulse"></div>
<h1 class="text-2xl font-bold text-white mb-6 tracking-wider">SMARTEYE <span class="text-emerald-400">LUCAS</span></h1>
<form method="post" class="space-y-4">
<input type="password" name="pass" placeholder="Code d\'accès" class="w-full bg-slate-900 border border-slate-700 text-white px-4 py-3 rounded focus:outline-none focus:border-emerald-500 text-center text-lg">
<button name="login" class="w-full bg-emerald-600 hover:bg-emerald-500 text-white font-bold py-3 rounded transition">Connexion</button>
</form>
'.(isset($error)?'<p class="text-red-500 mt-4 text-sm">'.$error.'</p>':'').'
</div></body></html>';
exit;
}
// --- CHARGEMENT DES DONNÉES ---
$data = file_exists($DB_FILE) ? json_decode(file_get_contents($DB_FILE), true) : ['clients' => []];
// Sécurité : structure minimale si fichier vide ou corrompu
if (!isset($data['clients'])) $data['clients'] = [];
// --- FONCTION TEST ALERTE (SIMULATION SMS) ---
if (isset($_GET['test_alert'])) {
$idTest = $_GET['test_alert'];
if (isset($data['clients'][$idTest])) {
$client = $data['clients'][$idTest];
$contacts = $client['contacts'] ?? [];
$count = 0;
$mobiles = [];
// ICI : Simulation de l'appel API SMS
// Dans le futur api.php, on utilisera ces numéros
foreach($contacts as $c) {
if(!empty($c['phone'])) {
$mobiles[] = $c['phone'];
$count++;
// LOG l'envoi pour preuve
$log_msg = date("Y-m-d H:i:s") . " [TEST ADMIN] SMS vers {$c['phone']} pour {$client['name']}\n";
file_put_contents("sms_history.log", $log_msg, FILE_APPEND);
}
}
$successMsg = "✅ Test d'alerte simulé envoyé à $count contacts !<br><span class='text-xs opacity-70'>(" . implode(', ', $mobiles) . ")</span>";
}
}
// --- SAUVEGARDE CLIENT (AJOUT / EDIT) ---
if (isset($_POST['save_client'])) {
// Nettoyage de l'ID pour éviter les caractères spéciaux
$id = preg_replace('/[^a-z0-9_]/', '', strtolower($_POST['client_id']));
// Initialisation si nouveau
if (!isset($data['clients'][$id])) {
$data['clients'][$id]['created_at'] = date('Y-m-d H:i:s');
$data['clients'][$id]['alerte'] = false;
// Création dossier images
$client_dir = "clients/" . $_POST['name'] . "/";
if (!is_dir($client_dir)) { mkdir($client_dir, 0775, true); }
}
// Token : saisi manuellement, ou auto-généré si vide
$token_input = trim($_POST['token'] ?? '');
if (!empty($token_input)) {
$data['clients'][$id]['token'] = $token_input;
} elseif (!isset($data['clients'][$id]['token'])) {
$data['clients'][$id]['token'] = bin2hex(random_bytes(4));
}
// Mot de passe LucasApp (bcrypt) — ignorer si valeur inchangée (bullets)
$new_password = trim($_POST['client_password'] ?? '');
if (!empty($new_password) && $new_password !== str_repeat("\xE2\x80\xA2", 8) && $new_password !== '••••••••') {
$data['clients'][$id]['password_hash'] = password_hash($new_password, PASSWORD_BCRYPT);
}
// Mise à jour des champs
$data['clients'][$id]['name'] = $_POST['name'];
$data['clients'][$id]['address'] = $_POST['address'];
$data['clients'][$id]['city'] = $_POST['city'];
$data['clients'][$id]['phone_mobile'] = $_POST['phone_mobile'];
$data['clients'][$id]['phone_fixed'] = $_POST['phone_fixed'];
$data['clients'][$id]['cp'] = $_POST['cp'] ?? '';
$data['clients'][$id]['date_naissance'] = $_POST['date_naissance'] ?? '';
$data['clients'][$id]['sex'] = $_POST['sex'];
// Champs bénéficiaire
$data['clients'][$id]['senior_name'] = $_POST['senior_name'] ?? '';
$data['clients'][$id]['senior_nickname'] = $_POST['senior_nickname'] ?? '';
$data['clients'][$id]['senior_photo'] = $_POST['senior_photo'] ?? '';
if (!isset($data['clients'][$id]['fcm_tokens'])) {
$data['clients'][$id]['fcm_tokens'] = [];
}
// Champs compte / technique
$data['clients'][$id]['jetson_id'] = $_POST['jetson_id'] ?? '';
$data['clients'][$id]['jetson_ip'] = $_POST['jetson_ip'] ?? '';
$data['clients'][$id]['jetson_modele'] = $_POST['jetson_modele'] ?? '';
$data['clients'][$id]['jetson_ram'] = $_POST['jetson_ram'] ?? '';
$data['clients'][$id]['jetson_ssd'] = $_POST['jetson_ssd'] ?? '';
// Caméras (5 max)
$cameras = [];
if (isset($_POST['cam_marque'])) {
for ($i = 0; $i < count($_POST['cam_marque']); $i++) {
if (!empty($_POST['cam_marque'][$i]) || !empty($_POST['cam_ip'][$i])) {
$cameras[] = [
'marque' => $_POST['cam_marque'][$i] ?? '',
'modele' => $_POST['cam_modele'][$i] ?? '',
'serie' => $_POST['cam_serie'][$i] ?? '',
'ip' => $_POST['cam_ip'][$i] ?? '',
'port_rtsp' => $_POST['cam_port_rtsp'][$i] ?? '',
];
}
}
}
$data['clients'][$id]['cameras'] = $cameras;
// Gestion des contacts multiples
$contacts = [];
if (isset($_POST['contact_name'])) {
for ($i = 0; $i < count($_POST['contact_name']); $i++) {
if (!empty($_POST['contact_name'][$i])) {
$contacts[] = [
'name' => $_POST['contact_name'][$i],
'role' => $_POST['contact_role'][$i],
'phone' => $_POST['contact_phone'][$i],
'email' => $_POST['contact_email'][$i],
'os' => $_POST['contact_os'][$i] ?? ''
];
}
}
}
$data['clients'][$id]['contacts'] = $contacts;
// Écriture DB
file_put_contents($DB_FILE, json_encode($data, JSON_PRETTY_PRINT));
$tab = $_POST['current_tab'] ?? 'identite';
header("Location: admin.php?edit=$id&success=1&tab=$tab"); exit;
}
// --- ARRÊT ALERTE ---
if (isset($_GET['stop_alert'])) {
$stopId = $_GET['stop_alert'];
if (isset($data['clients'][$stopId])) {
$data['clients'][$stopId]['alerte'] = false;
unset($data['clients'][$stopId]['handled_by']);
unset($data['clients'][$stopId]['handled_at']);
unset($data['clients'][$stopId]['message']);
unset($data['clients'][$stopId]['last_update']);
file_put_contents($DB_FILE, json_encode($data, JSON_PRETTY_PRINT));
// Reload data after save
$data = json_decode(file_get_contents($DB_FILE), true);
}
header("Location: admin.php?alert_stopped=1"); exit;
}
// --- SUPPRESSION ---
if (isset($_GET['del'])) {
unset($data['clients'][$_GET['del']]);
file_put_contents($DB_FILE, json_encode($data, JSON_PRETTY_PRINT));
header("Location: admin.php"); exit;
}
// --- PRÉPARATION VUE ---
$editClient = null; $editId = "";
if (isset($_GET['edit'])) {
$editId = $_GET['edit'];
$editClient = $data['clients'][$editId] ?? null;
} elseif (isset($_GET['new'])) {
// Mode nouveau client
$editClient = null;
}
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SmartEye Admin</title>
<script src="https://cdn.tailwindcss.com"></script>
<script>
function addContact() {
const tpl = document.getElementById('contact-template').innerHTML;
document.getElementById('contacts-container').insertAdjacentHTML('beforeend', tpl);
}
function removeContact(btn) { btn.closest('.contact-row').remove(); }
function switchTab(name) {
document.querySelectorAll('.tab-panel').forEach(p => p.classList.add('hidden'));
document.querySelectorAll('.tab-btn').forEach(b => {
b.classList.remove('border-violet-500','border-emerald-500','border-blue-500','text-violet-400','text-emerald-400','text-blue-400','bg-slate-800/50');
b.classList.add('text-slate-500','border-transparent');
});
document.getElementById('panel-'+name).classList.remove('hidden');
const btn = document.getElementById('tab-'+name);
btn.classList.remove('text-slate-500','border-transparent');
const colors = {identite:['violet'],compte:['emerald'],contacts:['blue']};
const c = (colors[name]||['violet'])[0];
btn.classList.add('border-'+c+'-500','text-'+c+'-400','bg-slate-800/50');
const h = document.getElementById('current_tab');
if (h) h.value = name;
}
document.addEventListener('DOMContentLoaded', function() {
const params = new URLSearchParams(window.location.search);
const tab = params.get('tab');
if (tab && document.getElementById('panel-'+tab)) switchTab(tab);
});
</script>
<style>body { background-color: #0f172a; color: #e2e8f0; }</style>
</head>
<body class="min-h-screen flex flex-col">
<nav class="bg-slate-900 border-b border-slate-800 px-6 py-4 flex justify-between items-center sticky top-0 z-50 shadow-md">
<div class="flex items-center gap-3">
<div class="w-3 h-3 rounded-full bg-emerald-500"></div>
<span class="font-bold text-xl tracking-wider text-white">SMARTEYE <span class="text-slate-500 text-sm font-normal">MANAGER</span></span>
</div>
<?php if($editClient): ?>
<span class="text-slate-400 font-mono text-sm bg-slate-800 px-4 py-2 rounded border border-slate-700"><?php echo $editId; ?></span>
<?php endif; ?>
<div class="flex gap-4">
<?php if($editClient || isset($_GET['new'])): ?>
<a href="admin.php" class="bg-slate-700 hover:bg-slate-600 text-white px-4 py-2 rounded text-sm flex items-center gap-2 transition"><span>↩</span> Retour</a>
<?php endif; ?>
<a href="?logout" class="text-red-400 hover:text-white text-sm border border-red-900/50 px-3 py-2 rounded transition">Déconnexion</a>
</div>
</nav>
<div class="flex-1 p-8 max-w-7xl mx-auto w-full">
<?php if(isset($_GET['success'])): ?>
<div class="bg-emerald-900/50 border border-emerald-500/50 text-emerald-200 px-4 py-3 rounded mb-6 text-center animate-bounce">✅ Modifications enregistrées avec succès !</div>
<?php endif; ?>
<?php if(isset($successMsg)): ?>
<div class="bg-blue-900/50 border border-blue-500/50 text-blue-200 px-4 py-3 rounded mb-6 text-center"><?php echo $successMsg; ?></div>
<?php endif; ?>
<?php if(isset($_GET['alert_stopped'])): ?>
<div class="bg-emerald-900/50 border border-emerald-500/50 text-emerald-200 px-4 py-3 rounded mb-6 text-center">✅ Alerte arrêtée avec succès — Le client est revenu en surveillance active.</div>
<?php endif; ?>
<?php if($editClient || isset($_GET['new'])): ?>
<form method="post" class="max-w-4xl mx-auto">
<div class="bg-slate-800 rounded-xl border border-slate-700 shadow-lg overflow-hidden">
<?php if($editClient): ?>
<input type="hidden" name="client_id" value="<?php echo $editId; ?>">
<?php endif; ?>
<input type="hidden" name="current_tab" id="current_tab" value="<?php echo htmlspecialchars($_GET['tab'] ?? 'identite'); ?>">
<!-- ONGLETS -->
<div class="flex border-b border-slate-700 bg-slate-900">
<button type="button" onclick="switchTab('identite')" id="tab-identite" class="tab-btn flex-1 px-4 py-3 text-sm font-bold text-violet-400 border-b-2 border-violet-500 bg-slate-800/50 transition">👤 Identité</button>
<button type="button" onclick="switchTab('compte')" id="tab-compte" class="tab-btn flex-1 px-4 py-3 text-sm font-bold text-slate-500 border-b-2 border-transparent hover:text-emerald-400 transition">📱 Infos Compte</button>
<button type="button" onclick="switchTab('contacts')" id="tab-contacts" class="tab-btn flex-1 px-4 py-3 text-sm font-bold text-slate-500 border-b-2 border-transparent hover:text-blue-400 transition">📞 Réseau de Contact</button>
</div>
<div class="p-6">
<!-- TAB IDENTITÉ -->
<div id="panel-identite" class="tab-panel space-y-4">
<div class="grid grid-cols-2 gap-4">
<div>
<label class="text-xs text-violet-300 uppercase font-bold">Nom complet</label>
<input name="senior_name" value="<?php echo $editClient['senior_name'] ?? ''; ?>" placeholder="Marie Dupont" class="w-full bg-slate-900 border border-violet-500/50 rounded px-3 py-2 text-white text-lg font-bold">
</div>
<div>
<label class="text-xs text-violet-300 uppercase font-bold">Surnom</label>
<input name="senior_nickname" value="<?php echo $editClient['senior_nickname'] ?? ''; ?>" placeholder="Mamie" class="w-full bg-slate-900 border border-violet-500/50 rounded px-3 py-2 text-white">
</div>
</div>
<div class="grid grid-cols-3 gap-3">
<div><label class="text-xs text-slate-500 uppercase font-bold">Date de naissance</label><input name="date_naissance" type="date" value="<?php echo $editClient['date_naissance'] ?? ''; ?>" class="w-full bg-slate-900 border border-slate-600 rounded px-3 py-2 text-white"></div>
<div><label class="text-xs text-slate-500 uppercase font-bold">Sexe</label><select name="sex" class="w-full bg-slate-900 border border-slate-600 rounded px-3 py-2 text-white"><option value="F" <?php echo ($editClient['sex']??'')=='F'?'selected':''; ?>>Femme</option><option value="H" <?php echo ($editClient['sex']??'')=='H'?'selected':''; ?>>Homme</option></select></div>
<div><label class="text-xs text-slate-500 uppercase font-bold">Photo</label><input name="senior_photo" value="<?php echo $editClient['senior_photo'] ?? ''; ?>" placeholder="photos/mamie.jpg" class="w-full bg-slate-900 border border-slate-600 rounded px-3 py-2 text-white text-sm"></div>
</div>
<div><label class="text-xs text-slate-500 uppercase font-bold">Adresse</label><input name="address" value="<?php echo $editClient['address'] ?? ''; ?>" class="w-full bg-slate-900 border border-slate-600 rounded px-3 py-2 text-white"></div>
<div class="grid grid-cols-3 gap-3">
<div><label class="text-xs text-slate-500 uppercase font-bold">Code postal</label><input name="cp" value="<?php echo $editClient['cp'] ?? ''; ?>" placeholder="75001" class="w-full bg-slate-900 border border-slate-600 rounded px-3 py-2 text-white font-mono"></div>
<div class="col-span-2"><label class="text-xs text-slate-500 uppercase font-bold">Ville</label><input name="city" value="<?php echo $editClient['city'] ?? ''; ?>" placeholder="Paris" class="w-full bg-slate-900 border border-slate-600 rounded px-3 py-2 text-white"></div>
</div>
<div class="grid grid-cols-2 gap-3">
<div><label class="text-xs text-slate-500 uppercase font-bold">Mobile</label><input name="phone_mobile" value="<?php echo $editClient['phone_mobile'] ?? ''; ?>" required class="w-full bg-slate-900 border border-slate-600 rounded px-3 py-2 text-white"></div>
<div><label class="text-xs text-slate-500 uppercase font-bold">Fixe</label><input name="phone_fixed" value="<?php echo $editClient['phone_fixed'] ?? ''; ?>" class="w-full bg-slate-900 border border-slate-600 rounded px-3 py-2 text-white"></div>
</div>
</div>
<!-- TAB INFOS COMPTE -->
<div id="panel-compte" class="tab-panel space-y-4 hidden">
<?php if(!$editClient): ?>
<div>
<label class="text-xs text-emerald-400 uppercase font-bold">ID Système (clé unique)</label>
<input name="client_id" required placeholder="ex: pizzulo" class="w-full bg-slate-900 border border-emerald-500/50 rounded px-3 py-2 text-white font-mono text-sm">
<p class="text-xs text-slate-600 mt-1">Identifiant technique interne, non modifiable</p>
</div>
<?php endif; ?>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="text-xs text-emerald-400 uppercase font-bold">Identifiant App *</label>
<input name="name" value="<?php echo $editClient['name'] ?? ''; ?>" required class="w-full bg-slate-900 border border-emerald-500/50 rounded px-3 py-2 text-white font-bold">
<p class="text-xs text-slate-600 mt-1">Saisi par le client dans LucasApp</p>
</div>
<div>
<label class="text-xs text-emerald-400 uppercase font-bold">Mot de passe App *</label>
<input name="client_password" type="password" value="<?php echo !empty($editClient['password_hash']) ? '••••••••' : ''; ?>" <?php echo empty($editClient['password_hash']) ? 'required' : ''; ?> placeholder="<?php echo empty($editClient['password_hash']) ? 'non renseigné' : ''; ?>" class="w-full bg-slate-900 border <?php echo empty($editClient['password_hash']) ? 'border-red-500/50' : 'border-emerald-500/50'; ?> rounded px-3 py-2 text-white">
<p class="text-xs <?php echo !empty($editClient['password_hash']) ? 'text-slate-500' : 'text-red-400'; ?> mt-1"><?php echo !empty($editClient['password_hash']) ? 'Laisser tel quel pour ne pas changer' : 'Obligatoire — l\'app ne peut pas se connecter'; ?></p>
</div>
</div>
<?php if(!empty($editClient['fcm_tokens'])): ?>
<div class="bg-emerald-900/20 border border-emerald-500/30 rounded px-3 py-2 text-xs text-emerald-300"><?php echo count($editClient['fcm_tokens']); ?> appareil(s) connecté(s)</div>
<?php endif; ?>
<div>
<label class="text-xs text-amber-400 uppercase font-bold">Token SmartEye *</label>
<div class="flex gap-2">
<input name="token" value="<?php echo $editClient['token'] ?? ''; ?>" <?php echo $editClient ? '' : 'placeholder="Auto-généré si vide"'; ?> class="flex-1 bg-slate-900 border border-amber-500/50 rounded px-3 py-2 text-amber-200 font-mono text-sm">
<?php if($editClient): ?>
<button type="button" onclick="if(confirm('Régénérer le token ?')){document.querySelector('input[name=token]').value='<?php echo bin2hex(random_bytes(4)); ?>';}" class="bg-amber-600/20 text-amber-400 hover:bg-amber-600 hover:text-white px-3 rounded text-xs border border-amber-900 transition">Régénérer</button>
<?php endif; ?>
</div>
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="text-xs text-slate-500 uppercase font-bold">Date de création</label>
<input value="<?php echo $editClient['created_at'] ?? date('Y-m-d H:i:s'); ?>" disabled class="w-full bg-slate-950 border border-slate-700 rounded px-3 py-2 text-slate-400 text-sm">
</div>
<div>
<label class="text-xs text-emerald-400 uppercase font-bold">Identifiant Jetson</label>
<input name="jetson_id" value="<?php echo $editClient['jetson_id'] ?? ''; ?>" placeholder="ex: jetson-nano-01" class="w-full bg-slate-900 border border-emerald-500/50 rounded px-3 py-2 text-white font-mono text-sm">
</div>
</div>
<div class="grid grid-cols-4 gap-3">
<div><label class="text-xs text-slate-500 uppercase font-bold">IP Jetson</label><input name="jetson_ip" value="<?php echo $editClient['jetson_ip'] ?? ''; ?>" placeholder="192.168.1.x" class="w-full bg-slate-900 border border-slate-600 rounded px-2 py-1.5 text-white text-sm font-mono"></div>
<div><label class="text-xs text-slate-500 uppercase font-bold">Modèle</label><input name="jetson_modele" value="<?php echo $editClient['jetson_modele'] ?? ''; ?>" placeholder="Nano / Orin" class="w-full bg-slate-900 border border-slate-600 rounded px-2 py-1.5 text-white text-sm"></div>
<div><label class="text-xs text-slate-500 uppercase font-bold">RAM (Go)</label><input name="jetson_ram" value="<?php echo $editClient['jetson_ram'] ?? ''; ?>" placeholder="4" type="number" class="w-full bg-slate-900 border border-slate-600 rounded px-2 py-1.5 text-white text-sm font-mono"></div>
<div><label class="text-xs text-slate-500 uppercase font-bold">SSD (Go)</label><input name="jetson_ssd" value="<?php echo $editClient['jetson_ssd'] ?? ''; ?>" placeholder="128" type="number" class="w-full bg-slate-900 border border-slate-600 rounded px-2 py-1.5 text-white text-sm font-mono"></div>
</div>
<!-- CAMÉRAS -->
<div class="mt-2">
<label class="text-xs text-amber-400 uppercase font-bold tracking-wider">Caméras</label>
</div>
<?php for ($cam = 1; $cam <= 5; $cam++): $camData = $editClient['cameras'][$cam - 1] ?? []; ?>
<div class="bg-slate-900/50 border border-slate-700 rounded p-3 <?php echo empty($camData['marque']) && $cam > 1 ? 'opacity-50' : ''; ?>">
<div class="text-xs text-slate-500 font-bold mb-2">CAM <?php echo $cam; ?></div>
<div class="grid grid-cols-5 gap-2">
<div><input name="cam_marque[]" value="<?php echo $camData['marque'] ?? ''; ?>" placeholder="Marque" class="w-full bg-slate-900 border border-slate-600 rounded px-2 py-1.5 text-white text-sm"></div>
<div><input name="cam_modele[]" value="<?php echo $camData['modele'] ?? ''; ?>" placeholder="Modèle" class="w-full bg-slate-900 border border-slate-600 rounded px-2 py-1.5 text-white text-sm"></div>
<div><input name="cam_serie[]" value="<?php echo $camData['serie'] ?? ''; ?>" placeholder="N° série" class="w-full bg-slate-900 border border-slate-600 rounded px-2 py-1.5 text-white text-sm font-mono"></div>
<div><input name="cam_ip[]" value="<?php echo $camData['ip'] ?? ''; ?>" placeholder="192.168.1.x" class="w-full bg-slate-900 border border-slate-600 rounded px-2 py-1.5 text-white text-sm font-mono"></div>
<div><input name="cam_port_rtsp[]" value="<?php echo $camData['port_rtsp'] ?? ''; ?>" placeholder="Port tunnel" type="number" class="w-full bg-slate-900 border border-amber-500/50 rounded px-2 py-1.5 text-amber-200 text-sm font-mono"></div>
</div>
</div>
<?php endfor; ?>
</div>
<!-- TAB RÉSEAU DE CONTACT -->
<div id="panel-contacts" class="tab-panel space-y-4 hidden">
<div class="flex justify-between items-center">
<p class="text-xs text-slate-500">Famille, voisins, aidants — prévenus en cas d'alerte</p>
<div class="flex gap-2">
<?php if($editClient): ?>
<a href="?test_alert=<?php echo $editId; ?>" onclick="return confirm('Envoyer un SMS de test simulé ?')" class="bg-orange-600 hover:bg-orange-500 text-white px-3 py-1 rounded text-xs font-bold transition">Simulation Alerte</a>
<?php endif; ?>
<button type="button" onclick="addContact()" class="text-xs bg-blue-600 hover:bg-blue-500 px-3 py-1 rounded text-white transition">+ Ajouter</button>
</div>
</div>
<div id="contacts-container" class="space-y-3 max-h-[400px] overflow-y-auto">
<?php if(!empty($editClient['contacts'])): foreach($editClient['contacts'] as $c): ?>
<div class="contact-row grid grid-cols-12 gap-2 items-center bg-slate-900/50 p-3 rounded border border-slate-700 group hover:border-slate-500 transition">
<div class="col-span-2"><input name="contact_name[]" value="<?php echo $c['name']; ?>" placeholder="Nom" class="w-full bg-transparent border-b border-slate-600 text-sm px-2 py-1 focus:border-blue-500 outline-none text-white"></div>
<div class="col-span-2"><input name="contact_role[]" value="<?php echo $c['role']; ?>" placeholder="Rôle" class="w-full bg-transparent border-b border-slate-600 text-sm px-2 py-1 focus:border-blue-500 outline-none text-white"></div>
<div class="col-span-3"><input name="contact_phone[]" value="<?php echo $c['phone']; ?>" placeholder="Tél" class="w-full bg-transparent border-b border-slate-600 text-sm px-2 py-1 focus:border-blue-500 outline-none text-white"></div>
<div class="col-span-2"><input name="contact_email[]" value="<?php echo $c['email']; ?>" placeholder="Email" class="w-full bg-transparent border-b border-slate-600 text-sm px-2 py-1 focus:border-blue-500 outline-none text-white"></div>
<div class="col-span-2"><select name="contact_os[]" class="w-full bg-transparent border-b border-slate-600 text-sm px-1 py-1 outline-none text-white"><option value="" <?php echo empty($c['os'])?'selected':''; ?>>OS</option><option value="Android" <?php echo ($c['os']??'')==='Android'?'selected':''; ?>>Android</option><option value="iOS" <?php echo ($c['os']??'')==='iOS'?'selected':''; ?>>iOS</option></select></div>
<div class="col-span-1 text-right"><button type="button" onclick="removeContact(this)" class="text-red-500 hover:text-red-300 p-1 font-bold">×</button></div>
</div>
<?php endforeach; endif; ?>
</div>
<script type="text/template" id="contact-template">
<div class="contact-row grid grid-cols-12 gap-2 items-center bg-slate-900/50 p-3 rounded border border-slate-700">
<div class="col-span-2"><input name="contact_name[]" placeholder="Nom" class="w-full bg-transparent border-b border-slate-600 text-sm px-2 py-1 outline-none text-white"></div>
<div class="col-span-2"><input name="contact_role[]" placeholder="Rôle" class="w-full bg-transparent border-b border-slate-600 text-sm px-2 py-1 outline-none text-white"></div>
<div class="col-span-3"><input name="contact_phone[]" placeholder="Tél" class="w-full bg-transparent border-b border-slate-600 text-sm px-2 py-1 outline-none text-white"></div>
<div class="col-span-2"><input name="contact_email[]" placeholder="Email" class="w-full bg-transparent border-b border-slate-600 text-sm px-2 py-1 outline-none text-white"></div>
<div class="col-span-2"><select name="contact_os[]" class="w-full bg-transparent border-b border-slate-600 text-sm px-1 py-1 outline-none text-white"><option value="">OS</option><option value="Android">Android</option><option value="iOS">iOS</option></select></div>
<div class="col-span-1 text-right"><button type="button" onclick="removeContact(this)" class="text-red-500 hover:text-red-300 p-1 font-bold">×</button></div>
</div>
</script>
</div>
<!-- BOUTON SAVE (toujours visible) -->
<div class="mt-6 pt-4 border-t border-slate-700 flex justify-between items-center">
<a href="admin.php" class="text-slate-400 hover:text-white px-4 py-2 rounded border border-slate-600 transition">Annuler</a>
<button name="save_client" class="bg-emerald-600 hover:bg-emerald-500 text-white font-bold py-3 px-8 rounded shadow-lg transition">Enregistrer</button>
</div>
</div>
</div>
</form>
<?php else: ?>
<div class="bg-slate-800 rounded-xl border border-slate-700 shadow-lg overflow-hidden">
<div class="p-6 border-b border-slate-700 flex justify-between items-center bg-slate-800/80 backdrop-blur">
<h2 class="text-slate-200 font-bold text-lg flex items-center gap-2"><span class="bg-emerald-500 w-2 h-6 rounded-full"></span> Parc Clients Surveillés</h2>
<a href="?new=1" class="bg-emerald-600 hover:bg-emerald-500 text-white px-6 py-2 rounded font-bold transition shadow-lg flex items-center gap-2"><span>+</span> Nouveau Dossier</a>
</div>
<?php if(empty($data['clients'])): ?>
<div class="p-12 text-center text-slate-500">
<p class="text-4xl mb-4">📭</p>
<p>Aucun client enregistré.</p>
<p class="text-sm">Cliquez sur "Nouveau Dossier" pour commencer.</p>
</div>
<?php else: ?>
<table class="w-full text-left text-sm">
<thead class="bg-slate-900 text-slate-400 text-xs uppercase"><tr><th class="p-4">Bénéficiaire</th><th class="p-4">Localisation</th><th class="p-4">Contacts</th><th class="p-4">Statut</th><th class="p-4 text-right">Actions</th></tr></thead>
<tbody class="divide-y divide-slate-700">
<?php foreach ($data['clients'] as $id => $client): ?>
<tr class="hover:bg-slate-700/30 transition group">
<td class="p-4">
<div class="font-bold text-white text-base"><?php echo $client['name']; ?></div>
<div class="text-xs text-slate-500 mt-1">ID: <?php echo $id; ?></div>
</td>
<td class="p-4 text-slate-300">
<?php echo $client['city'] ?? '-'; ?><br>
<span class="text-xs text-slate-500 truncate max-w-[150px] block"><?php echo $client['address'] ?? ''; ?></span>
</td>
<td class="p-4">
<div class="flex -space-x-2">
<?php if(!empty($client['contacts'])): foreach(array_slice($client['contacts'],0,3) as $c): ?>
<div class="w-8 h-8 rounded-full bg-blue-900 border-2 border-slate-800 flex items-center justify-center text-xs font-bold text-blue-200" title="<?php echo $c['name']; ?>"><?php echo strtoupper(substr($c['name'],0,1)); ?></div>
<?php endforeach; endif; ?>
<div class="w-8 h-8 rounded-full bg-slate-700 border-2 border-slate-800 flex items-center justify-center text-xs text-slate-400"><?php echo count($client['contacts'] ?? []); ?></div>
</div>
</td>
<td class="p-4">
<?php if($client['alerte'] ?? false): ?>
<span class="bg-red-900 text-red-200 px-2 py-1 rounded text-xs font-bold animate-pulse">ALERTE EN COURS</span>
<?php else: ?>
<span class="bg-emerald-900/30 text-emerald-400 px-2 py-1 rounded text-xs">Surveillance Active</span>
<?php endif; ?>
</td>
<td class="p-4 text-right">
<div class="flex justify-end gap-2 opacity-80 group-hover:opacity-100 transition">
<?php if($client['alerte'] ?? false): ?>
<a href="?stop_alert=<?php echo $id; ?>" onclick="return confirm('Confirmer l\'arrêt de l\'alerte pour <?php echo addslashes($client['name']); ?> ?\nLe statut repassera en Surveillance Active.')" class="bg-emerald-600/20 text-emerald-400 hover:bg-emerald-600 hover:text-white px-2 py-1 rounded text-xs border border-emerald-900 transition animate-pulse" title="Arrêter l'alerte (traitée)">✅</a>
<?php endif; ?>
<a href="sms_dashboard.php" class="bg-purple-600/20 text-purple-400 hover:bg-purple-600 hover:text-white px-2 py-1 rounded text-xs border border-purple-900 transition" title="Historique SMS">📱</a>
<a href="?test_alert=<?php echo $id; ?>" onclick="return confirm('Lancer une simulation ?')" class="bg-orange-600/20 text-orange-400 hover:bg-orange-600 hover:text-white px-2 py-1 rounded text-xs border border-orange-900 transition" title="Test Alerte">🔔</a>
<a href="?edit=<?php echo $id; ?>" class="bg-blue-600/20 text-blue-400 hover:bg-blue-600 hover:text-white px-3 py-1 rounded text-xs border border-blue-900 transition">Éditer</a>
<a href="index.php?id=<?php echo $id; ?>" target="_blank" class="bg-slate-700 text-slate-300 hover:bg-slate-600 hover:text-white px-3 py-1 rounded text-xs border border-slate-600 transition">Voir</a>
<a href="?del=<?php echo $id; ?>" onclick="return confirm('Supprimer ce dossier définitivement ?')" class="text-red-500 hover:text-red-400 px-2 py-1">×</a>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
</body>
</html>