38676-vm/admin.php
2026-02-26 03:04:39 +00:00

317 lines
41 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
require_once 'db/config.php';
session_start();
$db = db();
// Auth Check: Must be logged in and be admin
if (!isset($_SESSION['user_id'])) {
header("Location: auth.php?page=login");
exit;
}
$user_id = $_SESSION['user_id'];
$user_stmt = $db->prepare("SELECT role FROM users WHERE id = ?");
$user_stmt->execute([$user_id]);
$current_user = $user_stmt->fetch();
if (!$current_user || $current_user['role'] !== 'admin') {
die("Accès refusé. Cette console est réservée aux Administrateurs.");
}
$tab = isset($_GET['tab']) ? $_GET['tab'] : 'users';
// --- HANDLERS ---
// Status Profiles
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["action"]) && $_POST["action"] === "upsert_status_profile") {
$id = (int)$_POST["id"]; $name = $_POST["name"]; $slug = $_POST["slug"]; $enabled = isset($_POST["enabled"]) ? 1 : 0; $priority = (int)$_POST["priority"]; $scope_object_type = $_POST["scope_object_type"] === "" ? null : $_POST["scope_object_type"];
$rules = []; if (isset($_POST['rule_status_id']) && is_array($_POST['rule_status_id'])) { foreach ($_POST['rule_status_id'] as $idx => $sid) { $rules[] = ['status_id' => (int)$sid, 'condition_type' => $_POST['rule_condition_type'][$idx], 'min_value' => $_POST['rule_min_value'][$idx] !== "" ? (float)$_POST['rule_min_value'][$idx] : null, 'max_value' => $_POST['rule_max_value'][$idx] !== "" ? (float)$_POST['rule_max_value'][$idx] : null]; } }
$config = json_encode(['rules' => $rules]);
if ($id > 0) { $stmt = $db->prepare("UPDATE celestial_object_status_profiles SET name = ?, slug = ?, enabled = ?, priority = ?, scope_object_type = ?, config = ? WHERE id = ?"); $stmt->execute([$name, $slug, $enabled, $priority, $scope_object_type, $config, $id]); }
else { $stmt = $db->prepare("INSERT INTO celestial_object_status_profiles (name, slug, enabled, priority, scope_object_type, config) VALUES (?, ?, ?, ?, ?, ?)"); $stmt->execute([$name, $slug, $enabled, $priority, $scope_object_type, $config]); }
header("Location: admin.php?tab=status_profiles&success=1"); exit;
}
if (isset($_GET["delete_status_profile"])) { $db->prepare("DELETE FROM celestial_object_status_profiles WHERE id = ?")->execute([(int)$_GET["delete_status_profile"]]); header("Location: admin.php?tab=status_profiles&success=1"); exit; }
// User Roles
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'update_user_role') {
$target_user_id = (int)$_POST['target_user_id']; $new_role = $_POST['new_role'];
if (in_array($new_role, ['user', 'gm', 'admin'])) { $stmt = $db->prepare("UPDATE users SET role = ? WHERE id = ?"); $stmt->execute([$new_role, $target_user_id]); }
header("Location: admin.php?tab=users&success=1"); exit;
}
// Celestial Object Types
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_object_type') {
$id = (int)$_POST['id']; $name = $_POST['name']; $slug = $_POST['slug']; $icon = $_POST['icon']; $description = $_POST['description']; $status_profile_id = !empty($_POST['status_profile_id']) ? (int)$_POST['status_profile_id'] : null; $modifier_ids = isset($_POST['modifiers']) ? $_POST['modifiers'] : [];
$image_url = null; if ($id > 0) { $stmt_img = $db->prepare("SELECT image_url FROM celestial_object_types WHERE id = ?"); $stmt_img->execute([$id]); $image_url = $stmt_img->fetchColumn(); }
if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) { $ext = pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION); $filename = $slug . "_" . time() . "." . $ext; $target = "assets/images/celestial/" . $filename; if (move_uploaded_file($_FILES['image']['tmp_name'], $target)) $image_url = $target; }
$orbital_enabled = isset($_POST["orbital_control_enabled"]) ? 1 : 0; $terrestrial_enabled = isset($_POST["terrestrial_control_enabled"]) ? 1 : 0;
if ($id > 0) { $stmt = $db->prepare("UPDATE celestial_object_types SET name = ?, slug = ?, icon = ?, description = ?, image_url = ?, orbital_control_enabled = ?, terrestrial_control_enabled = ?, status_profile_id = ? WHERE id = ?"); $stmt->execute([$name, $slug, $icon, $description, $image_url, $orbital_enabled, $terrestrial_enabled, $status_profile_id, $id]); }
else { $stmt = $db->prepare("INSERT INTO celestial_object_types (name, slug, icon, description, image_url, orbital_control_enabled, terrestrial_control_enabled, status_profile_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); $stmt->execute([$name, $slug, $icon, $description, $image_url, $orbital_enabled, $terrestrial_enabled, $status_profile_id]); $id = $db->lastInsertId(); }
$db->prepare("DELETE FROM celestial_object_type_modifiers WHERE celestial_object_type_id = ?")->execute([$id]);
if (!empty($modifier_ids)) { $ins = $db->prepare("INSERT INTO celestial_object_type_modifiers (celestial_object_type_id, modifier_id) VALUES (?, ?)"); foreach ($modifier_ids as $mid) $ins->execute([$id, (int)$mid]); }
header("Location: admin.php?tab=objects&success=1"); exit;
}
if (isset($_GET['delete_object'])) { $db->prepare("DELETE FROM celestial_object_types WHERE id = ?")->execute([(int)$_GET['delete_object']]); header("Location: admin.php?tab=objects&success=1"); exit; }
// Statuses
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["action"]) && $_POST["action"] === "upsert_status") {
$id = (int)$_POST["id"]; $name = $_POST["name"]; $slug = $_POST["slug"]; $color = $_POST["color"]; $description = $_POST["description"];
if (isset($_POST["is_blinking"]) && $_POST["is_blinking"] === "on") { if (strpos($color, ";blink") === false) $color .= ";blink"; } else { $color = str_replace(";blink", "", $color); }
if ($id > 0) { $stmt = $db->prepare("UPDATE celestial_object_statuses SET name = ?, slug = ?, color = ?, description = ? WHERE id = ?"); $stmt->execute([$name, $slug, $color, $description, $id]); }
else { $stmt = $db->prepare("INSERT INTO celestial_object_statuses (name, slug, color, description) VALUES (?, ?, ?, ?)"); $stmt->execute([$name, $slug, $color, $description]); }
header("Location: admin.php?tab=statuses&success=1"); exit;
}
if (isset($_GET['delete_status'])) { $db->prepare("DELETE FROM celestial_object_statuses WHERE id = ?")->execute([(int)$_GET['delete_status']]); header("Location: admin.php?tab=statuses&success=1"); exit; }
// Factions
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_faction') {
$id = (int)$_POST['id']; $name = $_POST['name']; $slug = $_POST['slug']; $fa_icon = $_POST['fa_icon']; $color = $_POST['color']; $is_playable = isset($_POST['is_playable']) ? 1 : 0;
$image_url = null; if ($id > 0) { $stmt_img = $db->prepare("SELECT image_url FROM factions WHERE id = ?"); $stmt_img->execute([$id]); $image_url = $stmt_img->fetchColumn(); }
if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) { $ext = pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION); $filename = $slug . "_" . time() . "." . $ext; $target = "assets/images/factions/" . $filename; if (!is_dir("assets/images/factions")) mkdir("assets/images/factions", 0777, true); if (move_uploaded_file($_FILES['image']['tmp_name'], $target)) $image_url = $target; }
if ($id > 0) { $stmt = $db->prepare("UPDATE factions SET name = ?, slug = ?, fa_icon = ?, color = ?, image_url = ?, is_playable = ? WHERE id = ?"); $stmt->execute([$name, $slug, $fa_icon, $color, $image_url, $is_playable, $id]); }
else { $stmt = $db->prepare("INSERT INTO factions (name, slug, fa_icon, color, image_url, is_playable) VALUES (?, ?, ?, ?, ?, ?)"); $stmt->execute([$name, $slug, $fa_icon, $color, $image_url, $is_playable]); }
header("Location: admin.php?tab=factions&success=1"); exit;
}
if (isset($_GET['delete_faction'])) { $db->prepare("DELETE FROM factions WHERE id = ?")->execute([(int)$_GET['delete_faction']]); header("Location: admin.php?tab=factions&success=1"); exit; }
// Resources
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_resource') {
$id = (int)$_POST['id']; $name = $_POST['name']; $slug = $_POST['slug']; $icon = $_POST['icon']; $description = $_POST['description']; $show_in_header = isset($_POST["show_in_header"]) ? 1 : 0;
$image_url = null; if ($id > 0) { $stmt_img = $db->prepare("SELECT image_url FROM game_resources WHERE id = ?"); $stmt_img->execute([$id]); $image_url = $stmt_img->fetchColumn(); }
if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) { $ext = pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION); $filename = $slug . "_" . time() . "." . $ext; $target = "assets/images/resources/" . $filename; if (!is_dir("assets/images/resources")) mkdir("assets/images/resources", 0777, true); if (move_uploaded_file($_FILES['image']['tmp_name'], $target)) $image_url = $target; }
if ($id > 0) { $stmt = $db->prepare("UPDATE game_resources SET name = ?, slug = ?, icon = ?, description = ?, show_in_header = ?, image_url = ? WHERE id = ?"); $stmt->execute([$name, $slug, $icon, $description, $show_in_header, $image_url, $id]); }
else { $stmt = $db->prepare("INSERT INTO game_resources (name, slug, icon, description, show_in_header, image_url) VALUES (?, ?, ?, ?, ?, ?)"); $stmt->execute([$name, $slug, $icon, $description, $show_in_header, $image_url]); }
header("Location: admin.php?tab=resources&success=1"); exit;
}
if (isset($_GET['delete_resource'])) { $db->prepare("DELETE FROM game_resources WHERE id = ?")->execute([(int)$_GET['delete_resource']]); header("Location: admin.php?tab=resources&success=1"); exit; }
// Modifiers
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_modifier') {
$id = (int)$_POST['id']; $name = $_POST['name']; $type = $_POST['type']; $slug = $_POST['slug']; $description = $_POST['description']; $icon = $_POST['icon'];
if ($id > 0) { $stmt = $db->prepare("UPDATE modifiers SET name = ?, type = ?, slug = ?, description = ?, icon = ? WHERE id = ?"); $stmt->execute([$name, $type, $slug, $description, $icon, $id]); }
else { $stmt = $db->prepare("INSERT INTO modifiers (name, type, slug, description, icon) VALUES (?, ?, ?, ?, ?)"); $stmt->execute([$name, $type, $slug, $description, $icon]); }
header("Location: admin.php?tab=modifiers&success=1"); exit;
}
if (isset($_GET['delete_modifier'])) { $db->prepare("DELETE FROM modifiers WHERE id = ?")->execute([(int)$_GET['delete_modifier']]); header("Location: admin.php?tab=modifiers&success=1"); exit; }
// Settlement Types
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_settlement_type') {
$id = (int)$_POST['id']; $name = $_POST['name']; $slug = $_POST['slug']; $description = $_POST['description'];
if ($id > 0) { $stmt = $db->prepare("UPDATE settlement_types SET name = ?, slug = ?, description = ? WHERE id = ?"); $stmt->execute([$name, $slug, $description, $id]); }
else { $stmt = $db->prepare("INSERT INTO settlement_types (name, slug, description) VALUES (?, ?, ?)"); $stmt->execute([$name, $slug, $description]); }
header("Location: admin.php?tab=settlement_types&success=1"); exit;
}
if (isset($_GET['delete_settlement_type'])) { $db->prepare("DELETE FROM settlement_types WHERE id = ?")->execute([(int)$_GET['delete_settlement_type']]); header("Location: admin.php?tab=settlement_types&success=1"); exit; }
// Lootboxes
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_lootbox') {
$id = (int)$_POST['id']; $name = $_POST['name']; $slug = $_POST['slug']; $description = $_POST['description'];
if ($id > 0) { $db->prepare("UPDATE lootboxes SET name = ?, slug = ?, description = ? WHERE id = ?")->execute([$name, $slug, $description, $id]); }
else { $db->prepare("INSERT INTO lootboxes (name, slug, description) VALUES (?, ?, ?)")->execute([$name, $slug, $description]); }
header("Location: admin.php?tab=lootboxes&success=1"); exit;
}
if (isset($_GET['delete_lootbox'])) { $db->prepare("DELETE FROM lootboxes WHERE id = ?")->execute([(int)$_GET['delete_lootbox']]); header("Location: admin.php?tab=lootboxes&success=1"); exit; }
// --- DATA FETCHING ---
$users_list = []; $objects_list = []; $statuses_list = []; $status_profiles_list = []; $modifiers_list = []; $factions_list = []; $resources_list = []; $settlement_types_list = []; $lootboxes_list = []; $project_logs_list = [];
if ($tab === 'users') { $users_list = $db->query("SELECT id, username, email, role FROM users ORDER BY username ASC")->fetchAll(); }
elseif ($tab === 'objects') {
$objects_list = $db->query("SELECT o.*, p.name as profile_name FROM celestial_object_types o LEFT JOIN celestial_object_status_profiles p ON o.status_profile_id = p.id ORDER BY o.name ASC")->fetchAll();
foreach ($objects_list as &$obj) { $stmt = $db->prepare("SELECT modifier_id FROM celestial_object_type_modifiers WHERE celestial_object_type_id = ?"); $stmt->execute([$obj['id']]); $obj['modifier_ids'] = $stmt->fetchAll(PDO::FETCH_COLUMN); } unset($obj);
$status_profiles_list = $db->query("SELECT id, name FROM celestial_object_status_profiles WHERE enabled = 1 ORDER BY name ASC")->fetchAll();
$modifiers_list = $db->query("SELECT * FROM modifiers ORDER BY type, name ASC")->fetchAll();
}
elseif ($tab === 'statuses') { $statuses_list = $db->query("SELECT * FROM celestial_object_statuses ORDER BY name ASC")->fetchAll(); }
elseif ($tab === 'status_profiles') {
$status_profiles_list = $db->query("SELECT * FROM celestial_object_status_profiles ORDER BY priority DESC, name ASC")->fetchAll();
$statuses_list = $db->query("SELECT id, name FROM celestial_object_statuses ORDER BY name ASC")->fetchAll();
$object_types_list = $db->query("SELECT id, name, slug FROM celestial_object_types ORDER BY name ASC")->fetchAll();
}
elseif ($tab === 'resources') { $resources_list = $db->query("SELECT * FROM game_resources ORDER BY name ASC")->fetchAll(); }
elseif ($tab === 'factions') { $factions_list = $db->query("SELECT * FROM factions ORDER BY name ASC")->fetchAll(); }
elseif ($tab === 'modifiers') { $modifiers_list = $db->query("SELECT * FROM modifiers ORDER BY type, name ASC")->fetchAll(); }
elseif ($tab === 'settlement_types') { $settlement_types_list = $db->query("SELECT * FROM settlement_types ORDER BY name ASC")->fetchAll(); }
elseif ($tab === 'lootboxes') { $lootboxes_list = $db->query("SELECT * FROM lootboxes ORDER BY name ASC")->fetchAll(); }
elseif ($tab === 'project_logs') { $project_logs_list = $db->query("SELECT * FROM project_logs ORDER BY created_at DESC")->fetchAll(); }
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8"><title>Console Admin - Nexus</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<link href="assets/css/custom.css?v=<?php echo time(); ?>" rel="stylesheet">
<style>
body { background: #000; color: #fff; font-family: 'Segoe UI', sans-serif; margin: 0; }
header { background: #1a202c; padding: 10px 20px; border-bottom: 2px solid #2d3545; display: flex; justify-content: space-between; align-items: center; }
.nav-links a { color: #88c0d0; text-decoration: none; margin-right: 20px; font-weight: bold; font-size: 14px; }
.container { padding: 40px; max-width: 1400px; margin: 0 auto; }
.tabs { display: flex; gap: 5px; margin-bottom: 20px; border-bottom: 2px solid #2d3545; flex-wrap: wrap; }
.tab-link { padding: 10px 20px; text-decoration: none; color: #8c92a3; background: #0a0f1d; border: 1px solid #2d3545; border-bottom: none; font-weight: bold; font-size: 14px; }
.tab-link.active { background: #1a202c; color: #88c0d0; border-bottom: 2px solid #88c0d0; }
table { width: 100%; border-collapse: collapse; background: #0a0f1d; margin-top: 20px; }
th, td { border: 1px solid #2d3545; padding: 12px; text-align: left; }
th { background: #1a202c; color: #88c0d0; font-size: 13px; text-transform: uppercase; }
.form-card { background: #1e293b; padding: 20px; border: 1px solid #334155; margin-bottom: 30px; }
.form-group { margin-bottom: 15px; }
.form-group label { display: block; font-size: 12px; color: #8c92a3; margin-bottom: 5px; }
.form-group input, .form-group select, .form-group textarea { width: 100%; background: #0f172a; border: 1px solid #334155; color: #fff; padding: 8px; box-sizing: border-box; }
.btn { border: none; padding: 8px 15px; cursor: pointer; font-weight: bold; border-radius: 4px; font-size: 12px; }
.btn-add { background: #a3be8c; color: #000; }
.btn-edit { background: #ebcb8b; color: #000; }
.btn-del { background: #bf616a; color: #fff; text-decoration: none; }
.btn-ok { background: #88c0d0; color: #000; }
.modifier-tag { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 10px; font-weight: bold; margin-right: 5px; }
.tag-bonus { background: #a3be8c; color: #000; }
.tag-malus { background: #bf616a; color: #fff; }
.sub-form-row { display: flex; gap: 8px; margin-bottom: 5px; align-items: center; }
</style>
</head>
<body>
<header><div style="display: flex; align-items: center; gap: 20px;"><h2 style="margin: 0; color: #bf616a;"><i class="fa-solid fa-shield-halved"></i> ADMIN</h2><nav class="nav-links"><a href="index.php">Vue Joueur</a><a href="gm_console.php">Console MJ</a></nav></div></header>
<div class="container">
<div class="tabs">
<a href="?tab=users" class="tab-link <?php echo $tab === 'users' ? 'active' : ''; ?>">Utilisateurs</a>
<a href="?tab=objects" class="tab-link <?php echo $tab === 'objects' ? 'active' : ''; ?>">Objets Célestes</a>
<a href="?tab=status_profiles" class="tab-link <?php echo $tab === 'status_profiles' ? 'active' : ''; ?>">Profils de Statut</a>
<a href="?tab=statuses" class="tab-link <?php echo $tab === 'statuses' ? 'active' : ''; ?>">Statuts / États</a>
<a href="?tab=factions" class="tab-link <?php echo $tab === 'factions' ? 'active' : ''; ?>">Factions</a>
<a href="?tab=resources" class="tab-link <?php echo $tab === 'resources' ? 'active' : ''; ?>">Ressources</a>
<a href="?tab=modifiers" class="tab-link <?php echo $tab === 'modifiers' ? 'active' : ''; ?>">Bonus/Malus</a>
<a href="?tab=settlement_types" class="tab-link <?php echo $tab === 'settlement_types' ? 'active' : ''; ?>">Etablissements</a>
<a href="?tab=lootboxes" class="tab-link <?php echo $tab === 'lootboxes' ? 'active' : ''; ?>">Lootboxes</a>
<a href="?tab=project_logs" class="tab-link <?php echo $tab === 'project_logs' ? 'active' : ''; ?>">Journal</a>
</div>
<?php if ($tab === 'users'): ?>
<table><thead><tr><th>User</th><th>Role</th><th>Nouveau Role</th></tr></thead>
<tbody><?php foreach ($users_list as $u): ?><tr><td><?php echo htmlspecialchars($u['username']); ?></td><td><?php echo strtoupper($u['role']); ?></td><td><form method="POST"><input type="hidden" name="action" value="update_user_role"><input type="hidden" name="target_user_id" value="<?php echo $u['id']; ?>"><select name="new_role"><option value="user">USER</option><option value="gm">GM</option><option value="admin">ADMIN</option></select><button type="submit" class="btn btn-ok">OK</button></form></td></tr><?php endforeach; ?></tbody></table>
<?php elseif ($tab === 'objects'): ?>
<div class="form-card"><h4>Ajouter / Modifier un Type</h4>
<form method="POST" id="objectForm" enctype="multipart/form-data"><input type="hidden" name="action" value="upsert_object_type"><input type="hidden" name="id" id="obj_id" value="0">
<div style="display: flex; gap: 20px;"><div class="form-group" style="flex:1"><label>Nom</label><input type="text" name="name" id="obj_name" required></div><div class="form-group" style="flex:1"><label>Slug</label><input type="text" name="slug" id="obj_slug" required></div><div class="form-group" style="flex:1"><label>Profil de Statut</label><select name="status_profile_id" id="obj_profile_id"><option value="">-- Aucun --</option><?php foreach($status_profiles_list as $p): ?><option value="<?php echo $p['id']; ?>"><?php echo htmlspecialchars($p['name']); ?></option><?php endforeach; ?></select></div></div>
<div style="display: flex; gap: 20px;"><div class="form-group" style="flex:1"><label>Icône</label><input type="text" name="icon" id="obj_icon" required></div><div class="form-group" style="flex:1"><label>Image</label><input type="file" name="image"></div></div>
<div style="display: flex; gap: 20px;"><div style="flex: 1;"><input type="checkbox" name="orbital_control_enabled" id="obj_orb" checked> <label for="obj_orb">Orbital</label></div><div style="flex: 1;"><input type="checkbox" name="terrestrial_control_enabled" id="obj_terr" checked> <label for="obj_terr">Terrestre</label></div></div>
<div class="form-group"><label>Modifiers</label><select name="modifiers[]" id="obj_modifiers" multiple style="height:100px;"><?php foreach($modifiers_list as $m): ?><option value="<?php echo $m['id'];?>"><?php echo htmlspecialchars($m['name']);?></option><?php endforeach;?></select></div>
<div class="form-group"><label>Description</label><textarea name="description" id="obj_desc"></textarea></div>
<button type="submit" class="btn btn-add">ENREGISTRER</button><button type="button" class="btn" onclick="resetObjectForm()">ANNULER</button>
</form>
</div>
<table><thead><tr><th>Visuel</th><th>Nom</th><th>Slug</th><th>Profil</th><th>Actions</th></tr></thead>
<tbody><?php foreach ($objects_list as $o): ?><tr><td><i class="fa-solid <?php echo htmlspecialchars($o['icon']); ?>"></i></td><td><strong><?php echo htmlspecialchars($o['name']); ?></strong></td><td><code><?php echo htmlspecialchars($o['slug']); ?></code></td><td><?php echo htmlspecialchars($o['profile_name'] ?? 'Aucun'); ?></td><td><button class="btn btn-edit" onclick='editObject(<?php echo json_encode($o, JSON_HEX_APOS); ?>)'>Editer</button> <a href="?tab=objects&delete_object=<?php echo $o['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer?')">X</a></td></tr><?php endforeach; ?></tbody></table>
<?php elseif ($tab === 'status_profiles'): ?>
<div class="form-card"><h4>Profil de Statut Automatique</h4>
<form method="POST" id="statusProfileForm"><input type="hidden" name="action" value="upsert_status_profile"><input type="hidden" name="id" id="prof_id" value="0">
<div style="display: flex; gap: 20px;"><div class="form-group" style="flex:2"><label>Nom</label><input type="text" name="name" id="prof_name" required></div><div class="form-group" style="flex:1"><label>Slug</label><input type="text" name="slug" id="prof_slug" required></div><div class="form-group" style="flex:1"><label>Prio</label><input type="number" name="priority" id="prof_priority" value="0"></div></div>
<div id="rules_container"></div><button type="button" class="btn btn-ok" onclick="addProfileRule()">+ Ajouter Règle</button>
<div style="margin-top: 20px;"><button type="submit" class="btn btn-add">ENREGISTRER</button><button type="button" class="btn" onclick="resetProfileForm()">ANNULER</button></div>
</form>
</div>
<table><thead><tr><th>Prio</th><th>Nom</th><th>Slug</th><th>Actions</th></tr></thead>
<tbody><?php foreach ($status_profiles_list as $p): ?><tr><td><?php echo $p['priority']; ?></td><td><strong><?php echo htmlspecialchars($p['name']); ?></strong></td><td><code><?php echo htmlspecialchars($p['slug']); ?></code></td><td><button class="btn btn-edit" onclick='editProfile(<?php echo json_encode($p, JSON_HEX_APOS); ?>)'>Editer</button> <a href="?tab=status_profiles&delete_status_profile=<?php echo $p['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer?')">X</a></td></tr><?php endforeach; ?></tbody></table>
<?php elseif ($tab === 'statuses'): ?>
<div class="form-card"><h4>Statuts / États</h4>
<form method="POST" id="statusForm"><input type="hidden" name="action" value="upsert_status"><input type="hidden" name="id" id="st_id" value="0">
<div style="display: flex; gap: 20px;"><div class="form-group" style="flex:1"><label>Nom</label><input type="text" name="name" id="st_name" required></div><div class="form-group" style="flex:1"><label>Slug</label><input type="text" name="slug" id="st_slug" required></div><div class="form-group" style="flex:1"><label>Couleur</label><input type="text" name="color" id="st_color" required></div></div>
<div class="form-group"><label>Description</label><textarea name="description" id="st_desc"></textarea></div>
<button type="submit" class="btn btn-add">ENREGISTRER</button><button type="button" class="btn" onclick="resetStatusForm()">ANNULER</button>
</form>
</div>
<table><thead><tr><th>Couleur</th><th>Nom</th><th>Slug</th><th>Actions</th></tr></thead>
<tbody><?php foreach ($statuses_list as $s): ?><tr><td><div style="width:20px; height:20px; background:<?php echo str_replace(';blink','',$s['color']);?>"></div></td><td><?php echo htmlspecialchars($s['name']); ?></td><td><code><?php echo htmlspecialchars($s['slug']); ?></code></td><td><button class="btn btn-edit" onclick='editStatus(<?php echo json_encode($s, JSON_HEX_APOS); ?>)'>Editer</button> <a href="?tab=statuses&delete_status=<?php echo $s['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer?')">X</a></td></tr><?php endforeach; ?></tbody></table>
<?php elseif ($tab === 'factions'): ?>
<div class="form-card"><h4>Factions</h4>
<form method="POST" id="factionForm" enctype="multipart/form-data"><input type="hidden" name="action" value="upsert_faction"><input type="hidden" name="id" id="fac_id" value="0">
<div style="display: flex; gap: 20px;"><div class="form-group" style="flex:2"><label>Nom</label><input type="text" name="name" id="fac_name" required></div><div class="form-group" style="flex:1"><label>Slug</label><input type="text" name="slug" id="fac_slug" required></div></div>
<div style="display: flex; gap: 20px;"><div class="form-group" style="flex:1"><label>Icône FontAwesome</label><input type="text" name="fa_icon" id="fac_icon"></div><div class="form-group" style="flex:1"><label>Couleur</label><input type="color" name="color" id="fac_color"></div><div class="form-group" style="flex:1"><label>Jouable</label><input type="checkbox" name="is_playable" id="fac_playable"></div></div>
<div class="form-group"><label>Logo</label><input type="file" name="image"></div>
<button type="submit" class="btn btn-add">ENREGISTRER</button><button type="button" class="btn" onclick="resetFactionForm()">ANNULER</button>
</form>
</div>
<table><thead><tr><th>Visuel</th><th>Nom</th><th>Slug</th><th>Actions</th></tr></thead>
<tbody><?php foreach ($factions_list as $f): ?><tr><td><i class="fa-solid <?php echo htmlspecialchars($f['fa_icon']); ?>" style="color:<?php echo $f['color'];?>"></i></td><td><strong><?php echo htmlspecialchars($f['name']); ?></strong></td><td><code><?php echo htmlspecialchars($f['slug']); ?></code></td><td><button class="btn btn-edit" onclick='editFaction(<?php echo json_encode($f, JSON_HEX_APOS); ?>)'>Editer</button> <a href="?tab=factions&delete_faction=<?php echo $f['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer?')">X</a></td></tr><?php endforeach; ?></tbody></table>
<?php elseif ($tab === 'resources'): ?>
<div class="form-card"><h4>Ressources</h4>
<form method="POST" id="resForm" enctype="multipart/form-data"><input type="hidden" name="action" value="upsert_resource"><input type="hidden" name="id" id="res_id" value="0">
<div style="display: flex; gap: 20px;"><div class="form-group" style="flex:2"><label>Nom</label><input type="text" name="name" id="res_name" required></div><div class="form-group" style="flex:1"><label>Slug</label><input type="text" name="slug" id="res_slug" required></div><div class="form-group" style="flex:1"><label>Icône</label><input type="text" name="icon" id="res_icon" required></div></div>
<div style="display: flex; gap: 20px;"><div class="form-group" style="flex:1"><input type="checkbox" name="show_in_header" id="res_show"> <label for="res_show">Afficher dans le header</label></div><div class="form-group" style="flex:1"><label>Image Custom</label><input type="file" name="image"></div></div>
<div class="form-group"><label>Description</label><textarea name="description" id="res_desc"></textarea></div>
<button type="submit" class="btn btn-add">ENREGISTRER</button><button type="button" class="btn" onclick="resetResForm()">ANNULER</button>
</form>
</div>
<table><thead><tr><th>Icône</th><th>Nom</th><th>Slug</th><th>Header</th><th>Actions</th></tr></thead>
<tbody><?php foreach ($resources_list as $r): ?><tr><td><i class="fa-solid <?php echo htmlspecialchars($r['icon']); ?>"></i></td><td><strong><?php echo htmlspecialchars($r['name']); ?></strong></td><td><code><?php echo htmlspecialchars($r['slug']); ?></code></td><td><?php echo $r['show_in_header']?'OUI':'NON';?></td><td><button class="btn btn-edit" onclick='editRes(<?php echo json_encode($r, JSON_HEX_APOS); ?>)'>Editer</button> <a href="?tab=resources&delete_resource=<?php echo $r['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer?')">X</a></td></tr><?php endforeach; ?></tbody></table>
<?php elseif ($tab === 'modifiers'): ?>
<div class="form-card"><h4>Bonus / Malus</h4>
<form method="POST" id="modForm"><input type="hidden" name="action" value="upsert_modifier"><input type="hidden" name="id" id="mod_id" value="0">
<div style="display: flex; gap: 20px;"><div class="form-group" style="flex:2"><label>Nom</label><input type="text" name="name" id="mod_name" required></div><div class="form-group" style="flex:1"><label>Slug</label><input type="text" name="slug" id="mod_slug" required></div><div class="form-group" style="flex:1"><label>Icône</label><input type="text" name="icon" id="mod_icon"></div><div class="form-group" style="flex:1"><label>Type</label><select name="type" id="mod_type"><option value="bonus">Bonus</option><option value="malus">Malus</option></select></div></div>
<div class="form-group"><label>Description</label><textarea name="description" id="mod_desc"></textarea></div>
<button type="submit" class="btn btn-add">ENREGISTRER</button><button type="button" class="btn" onclick="resetModForm()">ANNULER</button>
</form>
</div>
<table><thead><tr><th>Type</th><th>Nom</th><th>Slug</th><th>Actions</th></tr></thead>
<tbody><?php foreach ($modifiers_list as $m): ?><tr><td><span class="modifier-tag tag-<?php echo $m['type'];?>"><?php echo strtoupper($m['type']);?></span></td><td><strong><?php echo htmlspecialchars($m['name']); ?></strong></td><td><code><?php echo htmlspecialchars($m['slug']); ?></code></td><td><button class="btn btn-edit" onclick='editMod(<?php echo json_encode($m, JSON_HEX_APOS); ?>)'>Editer</button> <a href="?tab=modifiers&delete_modifier=<?php echo $m['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer?')">X</a></td></tr><?php endforeach; ?></tbody></table>
<?php elseif ($tab === 'settlement_types'): ?>
<div class="form-card"><h4>Types d'Établissements</h4>
<form method="POST" id="settleForm"><input type="hidden" name="action" value="upsert_settlement_type"><input type="hidden" name="id" id="settle_id" value="0">
<div style="display: flex; gap: 20px;"><div class="form-group" style="flex:2"><label>Nom</label><input type="text" name="name" id="settle_name" required></div><div class="form-group" style="flex:1"><label>Slug</label><input type="text" name="slug" id="settle_slug" required></div></div>
<div class="form-group"><label>Description</label><textarea name="description" id="settle_desc"></textarea></div>
<button type="submit" class="btn btn-add">ENREGISTRER</button><button type="button" class="btn" onclick="resetSettleForm()">ANNULER</button>
</form>
</div>
<table><thead><tr><th>Nom</th><th>Slug</th><th>Actions</th></tr></thead>
<tbody><?php foreach ($settlement_types_list as $t): ?><tr><td><strong><?php echo htmlspecialchars($t['name']); ?></strong></td><td><code><?php echo htmlspecialchars($t['slug']); ?></code></td><td><button class="btn btn-edit" onclick='editSettle(<?php echo json_encode($t, JSON_HEX_APOS); ?>)'>Editer</button> <a href="?tab=settlement_types&delete_settlement_type=<?php echo $t['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer?')">X</a></td></tr><?php endforeach; ?></tbody></table>
<?php elseif ($tab === 'lootboxes'): ?>
<div class="form-card"><h4>Lootboxes</h4>
<form method="POST" id="lootForm"><input type="hidden" name="action" value="upsert_lootbox"><input type="hidden" name="id" id="loot_id" value="0">
<div style="display: flex; gap: 20px;"><div class="form-group" style="flex:2"><label>Nom</label><input type="text" name="name" id="loot_name" required></div><div class="form-group" style="flex:1"><label>Slug</label><input type="text" name="slug" id="loot_slug" required></div></div>
<div class="form-group"><label>Description</label><textarea name="description" id="loot_desc"></textarea></div>
<button type="submit" class="btn btn-add">ENREGISTRER</button><button type="button" class="btn" onclick="resetLootForm()">ANNULER</button>
</form>
</div>
<table><thead><tr><th>Nom</th><th>Slug</th><th>Actions</th></tr></thead>
<tbody><?php foreach ($lootboxes_list as $l): ?><tr><td><strong><?php echo htmlspecialchars($l['name']); ?></strong></td><td><code><?php echo htmlspecialchars($l['slug']); ?></code></td><td><button class="btn btn-edit" onclick='editLoot(<?php echo json_encode($l, JSON_HEX_APOS); ?>)'>Editer</button> <a href="?tab=lootboxes&delete_lootbox=<?php echo $l['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer?')">X</a></td></tr><?php endforeach; ?></tbody></table>
<?php elseif ($tab === 'project_logs'): ?>
<table><thead><tr><th>Date</th><th>Version</th><th>Titre</th></tr></thead>
<tbody><?php foreach ($project_logs_list as $log): ?><tr><td><?php echo $log['created_at']; ?></td><td><?php echo htmlspecialchars($log['version']); ?></td><td><?php echo htmlspecialchars($log['title']); ?></td></tr><?php endforeach; ?></tbody></table>
<?php endif; ?>
</div>
<script>
const statusesList = <?php echo json_encode($statuses_list ?? []); ?>;
function addProfileRule(data = null) {
const container = document.getElementById('rules_container'); if(!container) return; const div = document.createElement('div'); div.className = 'sub-form-row';
let opts = statusesList.map(s => `<option value="${s.id}" ${data && data.status_id == s.id ? 'selected' : ''}>${s.name}</option>`).join('');
div.innerHTML = `<select name="rule_status_id[]">${opts}</select><select name="rule_condition_type[]"><option value="fixed" ${data && data.condition_type=='fixed'?'selected':''}>Fixe</option><option value="orbital_control" ${data && data.condition_type=='orbital_control'?'selected':''}>Orbital %</option><option value="terrestrial_control" ${data && data.condition_type=='terrestrial_control'?'selected':''}>Terrestre %</option><option value="uncontrolled" ${data && data.condition_type=='uncontrolled'?'selected':''}>Inoccupé</option></select><input type="number" step="0.1" name="rule_min_value[]" value="${data?data.min_value:''}" placeholder="Min %" style="width:80px;"><input type="number" step="0.1" name="rule_max_value[]" value="${data?data.max_value:''}" placeholder="Max %" style="width:80px;"><button type="button" onclick="this.parentElement.remove()">×</button>`;
container.appendChild(div);
}
function editProfile(data) { document.getElementById('prof_id').value = data.id; document.getElementById('prof_name').value = data.name; document.getElementById('prof_slug').value = data.slug; document.getElementById('prof_priority').value = data.priority; document.getElementById('rules_container').innerHTML = ''; const config = JSON.parse(data.config || '{}'); if(config.rules) config.rules.forEach(r => addProfileRule(r)); else addProfileRule(); window.scrollTo(0,0); }
function resetProfileForm() { document.getElementById('statusProfileForm').reset(); document.getElementById('prof_id').value = 0; document.getElementById('rules_container').innerHTML = ''; addProfileRule(); }
function editObject(data) { document.getElementById('obj_id').value = data.id; document.getElementById('obj_name').value = data.name; document.getElementById('obj_slug').value = data.slug; document.getElementById('obj_profile_id').value = data.status_profile_id || ''; document.getElementById('obj_orb').checked = data.orbital_control_enabled == 1; document.getElementById('obj_terr').checked = data.terrestrial_control_enabled == 1; document.getElementById('obj_desc').value = data.description || ''; if(data.modifier_ids) { Array.from(document.getElementById('obj_modifiers').options).forEach(opt => opt.selected = data.modifier_ids.includes(opt.value)); } window.scrollTo(0,0); }
function resetObjectForm() { document.getElementById('objectForm').reset(); document.getElementById('obj_id').value = 0; }
function editStatus(data) { document.getElementById('st_id').value = data.id; document.getElementById('st_name').value = data.name; document.getElementById('st_slug').value = data.slug; document.getElementById('st_color').value = data.color.replace(';blink',''); document.getElementById('st_desc').value = data.description || ''; window.scrollTo(0,0); }
function resetStatusForm() { document.getElementById('statusForm').reset(); document.getElementById('st_id').value = 0; }
function editFaction(data) { document.getElementById('fac_id').value = data.id; document.getElementById('fac_name').value = data.name; document.getElementById('fac_slug').value = data.slug; document.getElementById('fac_icon').value = data.fa_icon || ''; document.getElementById('fac_color').value = data.color || '#808080'; document.getElementById('fac_playable').checked = data.is_playable == 1; window.scrollTo(0,0); }
function resetFactionForm() { document.getElementById('factionForm').reset(); document.getElementById('fac_id').value = 0; }
function editRes(data) { document.getElementById('res_id').value = data.id; document.getElementById('res_name').value = data.name; document.getElementById('res_slug').value = data.slug; document.getElementById('res_icon').value = data.icon; document.getElementById('res_show').checked = data.show_in_header == 1; document.getElementById('res_desc').value = data.description || ''; window.scrollTo(0,0); }
function resetResForm() { document.getElementById('resForm').reset(); document.getElementById('res_id').value = 0; }
function editMod(data) { document.getElementById('mod_id').value = data.id; document.getElementById('mod_name').value = data.name; document.getElementById('mod_slug').value = data.slug; document.getElementById('mod_type').value = data.type; document.getElementById('mod_icon').value = data.icon || ''; document.getElementById('mod_desc').value = data.description || ''; window.scrollTo(0,0); }
function resetModForm() { document.getElementById('modForm').reset(); document.getElementById('mod_id').value = 0; }
function editSettle(data) { document.getElementById('settle_id').value = data.id; document.getElementById('settle_name').value = data.name; document.getElementById('settle_slug').value = data.slug; document.getElementById('settle_desc').value = data.description || ''; window.scrollTo(0,0); }
function resetSettleForm() { document.getElementById('settleForm').reset(); document.getElementById('settle_id').value = 0; }
function editLoot(data) { document.getElementById('loot_id').value = data.id; document.getElementById('loot_name').value = data.name; document.getElementById('loot_slug').value = data.slug; document.getElementById('loot_desc').value = data.description || ''; window.scrollTo(0,0); }
function resetLootForm() { document.getElementById('lootForm').reset(); document.getElementById('loot_id').value = 0; }
<?php if($tab === 'status_profiles'): ?>window.onload = function(){ if(document.getElementById('rules_container').children.length === 0) addProfileRule(); }; <?php endif; ?>
</script>
</body></html>