38676-vm/admin.php
2026-03-07 03:32:51 +00:00

2687 lines
153 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
function get_user_grade($pdo, $user_id) {
$stmt = $pdo->prepare("SELECT role FROM users WHERE id = ?");
$stmt->execute([$user_id]);
$user = $stmt->fetch();
if (!$user) return null;
$role = $user['role'];
$level = 0;
try {
$stmt_lvl = $pdo->prepare("SELECT level FROM users WHERE id = ?");
$stmt_lvl->execute([$user_id]);
$level = (int)$stmt_lvl->fetchColumn();
} catch (Exception $e) {
// level column might not exist
}
if ($role === 'admin') {
$stmt = $pdo->prepare("SELECT * FROM grades WHERE user_type = 'admin' LIMIT 1");
$stmt->execute();
return $stmt->fetch();
} elseif ($role === 'gm') {
$stmt = $pdo->prepare("SELECT * FROM grades WHERE user_type = 'GM' LIMIT 1");
$stmt->execute();
return $stmt->fetch();
} else {
$stmt = $pdo->prepare("SELECT * FROM grades WHERE user_type = 'utilisateur' AND ? BETWEEN min_level AND max_level LIMIT 1");
$stmt->execute([$level]);
return $stmt->fetch();
}
}
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.");
}
// Default tab is now users as before, but let's see if we should change it to project_logs
$tab = isset($_GET['tab']) ? $_GET['tab'] : 'project_logs';
// --- HANDLERS ---
// Handle User Role Update
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;
}
// Handle Celestial Object Type CRUD
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();
}
// Sync modifiers
$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'])) {
$id = (int)$_GET['delete_object'];
$db->prepare("DELETE FROM celestial_object_types WHERE id = ?")->execute([$id]);
header("Location: admin.php?tab=objects&success=1");
exit;
}
// Handle Title CRUD
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_title') {
$id = (int)$_POST['id'];
$name = $_POST["name"];
$slug = $_POST['slug'];
$color = $_POST["color"] ?? "#ffffff";
$allowed_user_type = $_POST['allowed_user_type'];
$required_level = (int)$_POST['required_level'];
if ($id > 0) {
$stmt = $db->prepare("UPDATE titles SET name = ?, slug = ?, allowed_user_type = ?, required_level = ?, color = ? WHERE id = ?");
$stmt->execute([$name, $slug, $allowed_user_type, $required_level, $color, $id]);
} else {
$stmt = $db->prepare("INSERT INTO titles (name, slug, allowed_user_type, required_level, color) VALUES (?, ?, ?, ?, ?)");
$stmt->execute([$name, $slug, $allowed_user_type, $required_level, $color]);
}
header("Location: admin.php?tab=badges&success=1");
exit;
}
// Handle Badge CRUD
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_badge') {
$id = (int)$_POST['id'];
$name = $_POST["name"];
$slug = $_POST['slug'];
$allowed_user_type = $_POST['allowed_user_type'];
$required_level = (int)$_POST['required_level'];
$image_url = null;
if ($id > 0) {
$stmt_img = $db->prepare("SELECT image_url FROM badges 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 = "badge_" . $slug . "_" . time() . "." . $ext;
$target = "assets/images/badges/" . $filename;
if (!is_dir("assets/images/badges/")) mkdir("assets/images/badges/", 0775, true);
if (move_uploaded_file($_FILES['image']['tmp_name'], $target)) {
$image_url = $target;
}
}
if ($id > 0) {
$stmt = $db->prepare("UPDATE badges SET name = ?, slug = ?, allowed_user_type = ?, required_level = ?, image_url = ? WHERE id = ?");
$stmt->execute([$name, $slug, $allowed_user_type, $required_level, $image_url, $id]);
} else {
$stmt = $db->prepare("INSERT INTO badges (name, slug, allowed_user_type, required_level, image_url) VALUES (?, ?, ?, ?, ?)");
$stmt->execute([$name, $slug, $allowed_user_type, $required_level, $image_url]);
}
header("Location: admin.php?tab=badges&success=1");
exit;
}
// Handle Title/Badge Deletion
if (isset($_GET['delete_title'])) {
$id = (int)$_GET['delete_title'];
$db->prepare("DELETE FROM titles WHERE id = ?")->execute([$id]);
header("Location: admin.php?tab=badges&success=deleted");
exit;
}
if (isset($_GET['delete_badge'])) {
$id = (int)$_GET['delete_badge'];
$db->prepare("DELETE FROM badges WHERE id = ?")->execute([$id]);
header("Location: admin.php?tab=badges&success=deleted");
exit;
}
// Handle Status CRUD
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"];
// Gérer le clignotement
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'])) {
$id = (int)$_GET['delete_status'];
$db->prepare("DELETE FROM celestial_object_statuses WHERE id = ?")->execute([$id]);
header("Location: admin.php?tab=statuses&success=1");
exit;
}
// Handle Status Profile CRUD
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["action"]) && $_POST["action"] === "upsert_status_profile") {
$id = (int)$_POST["id"];
$name = $_POST["name"];
$slug = $_POST["slug"];
if ($id > 0) {
$stmt = $db->prepare("UPDATE celestial_object_status_profiles SET name = ?, slug = ? WHERE id = ?");
$stmt->execute([$name, $slug, $id]);
} else {
$stmt = $db->prepare("INSERT INTO celestial_object_status_profiles (name, slug) VALUES (?, ?)");
$stmt->execute([$name, $slug]);
}
header("Location: admin.php?tab=statuses&success=1");
exit;
}
if (isset($_GET["delete_status_profile"])) {
$id = (int)$_GET["delete_status_profile"];
// Check if it is used
$count = $db->query("SELECT COUNT(*) FROM celestial_object_status_rules WHERE profile_id = $id")->fetchColumn();
$count2 = $db->query("SELECT COUNT(*) FROM celestial_object_types WHERE status_profile_id = $id")->fetchColumn();
if ($count == 0 && $count2 == 0) {
$db->prepare("DELETE FROM celestial_object_status_profiles WHERE id = ?")->execute([$id]);
header("Location: admin.php?tab=statuses&success=1");
} else {
header("Location: admin.php?tab=statuses&error=profile_in_use");
}
exit;
}
// Handle Status Rule CRUD
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_status_rule') {
$id = (int)$_POST['id'];
$name = $_POST["name"];
$status_id = (int)$_POST['status_id'];
$profile_id = (int)$_POST['profile_id'];
$priority = (int)$_POST['priority'];
$orbital_count_op = $_POST['orbital_count_op'] ?: null;
$orbital_count_val = $_POST['orbital_count_val'] !== '' ? (int)$_POST['orbital_count_val'] : null;
$terrestrial_count_op = $_POST['terrestrial_count_op'] ?: null;
$terrestrial_count_val = $_POST['terrestrial_count_val'] !== '' ? (int)$_POST['terrestrial_count_val'] : null;
$orbital_dominance = isset($_POST['orbital_dominance']) ? implode(',', (array)$_POST['orbital_dominance']) : null;
$terrestrial_dominance = isset($_POST['terrestrial_dominance']) ? implode(',', (array)$_POST['terrestrial_dominance']) : null;
$is_empty_case = isset($_POST['is_empty_case']) ? 1 : 0;
$combine_mode = $_POST['combine_mode'] ?? 'OR';
if ($id > 0) {
$stmt = $db->prepare("UPDATE celestial_object_status_rules SET name = ?, status_id = ?, profile_id = ?, priority = ?, orbital_count_op = ?, orbital_count_val = ?, terrestrial_count_op = ?, terrestrial_count_val = ?, orbital_dominance = ?, terrestrial_dominance = ?, is_empty_case = ?, combine_mode = ? WHERE id = ?");
$stmt->execute([$name, $status_id, $profile_id, $priority, $orbital_count_op, $orbital_count_val, $terrestrial_count_op, $terrestrial_count_val, $orbital_dominance, $terrestrial_dominance, $is_empty_case, $combine_mode, $id]);
} else {
$stmt = $db->prepare("INSERT INTO celestial_object_status_rules (name, status_id, profile_id, priority, orbital_count_op, orbital_count_val, terrestrial_count_op, terrestrial_count_val, orbital_dominance, terrestrial_dominance, is_empty_case, combine_mode) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$name, $status_id, $profile_id, $priority, $orbital_count_op, $orbital_count_val, $terrestrial_count_op, $terrestrial_count_val, $orbital_dominance, $terrestrial_dominance, $is_empty_case, $combine_mode]);
}
header("Location: admin.php?tab=statuses&success=1");
exit;
}
if (isset($_GET['delete_status_rule'])) {
$id = (int)$_GET['delete_status_rule'];
$db->prepare("DELETE FROM celestial_object_status_rules WHERE id = ?")->execute([$id]);
header("Location: admin.php?tab=statuses&success=1");
exit;
}
// Handle Settlement Type CRUD
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'])) {
$id = (int)$_GET['delete_settlement_type'];
$db->prepare("DELETE FROM settlement_types WHERE id = ?")->execute([$id]);
header("Location: admin.php?tab=settlement_types&success=1");
exit;
}
// Handle Modifiers CRUD
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_modifier') {
$id = (int)$_POST['id'];
$name = $_POST["name"];
$slug = $_POST['slug'];
$type = $_POST['type'];
$description = $_POST['description'];
if ($id > 0) {
$stmt = $db->prepare("UPDATE modifiers SET name = ?, slug = ?, type = ?, description = ? WHERE id = ?");
$stmt->execute([$name, $slug, $type, $description, $id]);
} else {
$stmt = $db->prepare("INSERT INTO modifiers (name, slug, type, description) VALUES (?, ?, ?, ?)");
$stmt->execute([$name, $slug, $type, $description]);
}
header("Location: admin.php?tab=modifiers&success=1");
exit;
}
if (isset($_GET['delete_modifier'])) {
$id = (int)$_GET['delete_modifier'];
$db->prepare("DELETE FROM modifiers WHERE id = ?")->execute([$id]);
header("Location: admin.php?tab=modifiers&success=1");
exit;
}
// Handle Faction CRUD
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'];
$image_url = null;
$alliance_ids = isset($_POST['alliances']) ? $_POST['alliances'] : [];
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 = "faction_" . time() . "." . $ext;
$target = "assets/images/factions/" . $filename;
if (move_uploaded_file($_FILES['image']['tmp_name'], $target)) {
$image_url = $target;
}
}
if ($id > 0) {
$stmt = $db->prepare("UPDATE factions SET name = ?, slug = ?, image_url = ?, fa_icon = ?, color = ? WHERE id = ?");
$stmt->execute([$name, $slug, $image_url, $fa_icon, $color, $id]);
} else {
$stmt = $db->prepare("INSERT INTO factions (name, slug, image_url, fa_icon, color) VALUES (?, ?, ?, ?, ?)");
$stmt->execute([$name, $slug, $image_url, $fa_icon, $color]);
$id = $db->lastInsertId();
}
// Handle Alliances (Reciprocal)
$db->prepare("DELETE FROM faction_alliances WHERE faction_id_1 = ? OR faction_id_2 = ?")->execute([$id, $id]);
foreach ($alliance_ids as $ally_id) {
$f1 = min((int)$id, (int)$ally_id);
$f2 = max((int)$id, (int)$ally_id);
if ($f1 === $f2) continue;
$db->prepare("INSERT IGNORE INTO faction_alliances (faction_id_1, faction_id_2) VALUES (?, ?)")->execute([$f1, $f2]);
}
header("Location: admin.php?tab=factions&success=1");
exit;
}
if (isset($_GET['delete_faction'])) {
$id = (int)$_GET['delete_faction'];
$db->prepare("DELETE FROM factions WHERE id = ?")->execute([$id]);
header("Location: admin.php?tab=factions&success=1");
exit;
}
// Handle Levels CRUD
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["action"]) && $_POST["action"] === "upsert_level") {
$id = (int)$_POST["id"];
$name = $_POST["name"];
$slug = $_POST["slug"];
$resource_id = (int)$_POST["resource_id"];
$required_quantity = (int)$_POST["required_quantity"];
if ($required_quantity <= 0) {
header("Location: admin.php?tab=levels&error=invalid_amount");
exit;
}
if ($id > 0) {
$stmt = $db->prepare("UPDATE levels SET name = ?, slug = ?, resource_id = ?, required_quantity = ? WHERE id = ?");
$stmt->execute([$name, $slug, $resource_id, $required_quantity, $id]);
} else {
$stmt = $db->prepare("INSERT INTO levels (name, slug, resource_id, required_quantity) VALUES (?, ?, ?, ?)");
$stmt->execute([$name, $slug, $resource_id, $required_quantity]);
}
header("Location: admin.php?tab=levels&success=1");
exit;
}
if (isset($_GET["delete_level"])) {
$id = (int)$_GET["delete_level"];
$db->prepare("DELETE FROM levels WHERE id = ?")->execute([$id]);
header("Location: admin.php?tab=levels&success=1");
exit;
}
// Handle Resource CRUD
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 = "res_" . $slug . "_" . time() . "." . $ext;
if (!is_dir("assets/images/resources")) {
mkdir("assets/images/resources", 0775, true);
}
$target = "assets/images/resources/" . $filename;
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 = ?, image_url = ?, show_in_header = ? WHERE id = ?");
$stmt->execute([$name, $slug, $icon, $description, $image_url, $show_in_header, $id]);
} else {
$stmt = $db->prepare("INSERT INTO game_resources (name, slug, icon, description, image_url, show_in_header) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->execute([$name, $slug, $icon, $description, $image_url, $show_in_header]);
}
header("Location: admin.php?tab=resources&success=1");
exit;
}
if (isset($_GET['delete_resource'])) {
$id = (int)$_GET['delete_resource'];
$db->prepare("DELETE FROM game_resources WHERE id = ?")->execute([$id]);
header("Location: admin.php?tab=resources&success=1");
exit;
}
// Handle Guild System Config
error_log(print_r($_POST, true));
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["action"]) && $_POST["action"] === "update_guild_requirements") {
$db->exec("DELETE FROM guild_creation_requirements");
$stmt = $db->prepare("INSERT INTO guild_creation_requirements (resource_id, amount) VALUES (?, ?)");
foreach ($_POST as $key => $value) {
if (strpos($key, "res_") === 0 && (int)$value >= 0) {
$res_id = (int)str_replace("res_", "", $key);
$stmt->execute([$res_id, (int)$value]);
}
}
if (isset($_POST['guild_member_limit'])) {
$stmt = $db->prepare("UPDATE guild_restrictions SET value = ? WHERE restriction_key = 'member_limit'");
$stmt->execute([(int)$_POST['guild_member_limit']]);
}
header("Location: admin.php?tab=guilds&success=1");
exit;
}
// Handle Lootbox CRUD
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_grade') {
$id = (int)$_POST['id'];
$name = trim($_POST["name"]);
$slug = trim($_POST['slug']);
$user_type = $_POST['user_type'];
$min_level = ($user_type === 'utilisateur') ? (int)$_POST['min_level'] : null;
$max_level = ($user_type === 'utilisateur') ? (int)$_POST['max_level'] : null;
if ($user_type === 'utilisateur' && $min_level > $max_level) {
header('Location: ?tab=ranks&error=invalid_range');
exit;
}
// Check for overlap if user_type is 'utilisateur'
if ($user_type === 'utilisateur') {
$check = db()->prepare("SELECT id FROM grades WHERE user_type = 'utilisateur' AND id != ? AND NOT (max_level < ? OR min_level > ?)");
$check->execute([$id, $min_level, $max_level]);
if ($check->fetch()) {
header('Location: ?tab=ranks&error=overlap_levels');
exit;
}
}
try {
$image_url = null;
if (!empty($_FILES["image"]["name"])) {
$ext = pathinfo($_FILES["image"]["name"], PATHINFO_EXTENSION);
$filename = "grade_" . time() . "_" . uniqid() . "." . $ext;
if (!is_dir("assets/images/grades/")) mkdir("assets/images/grades/", 0775, true);
move_uploaded_file($_FILES["image"]["tmp_name"], "assets/images/grades/" . $filename);
$image_url = "assets/images/grades/" . $filename;
}
if ($id > 0) {
$stmt = db()->prepare("UPDATE grades SET name = ?, slug = ?, user_type = ?, min_level = ?, max_level = ?, image_url = COALESCE(?, image_url) WHERE id = ?");
$stmt->execute([$name, $slug, $user_type, $min_level, $max_level, $image_url, $id]);
} else {
$stmt = db()->prepare("INSERT INTO grades (name, slug, user_type, min_level, max_level, image_url) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->execute([$name, $slug, $user_type, $min_level, $max_level, $image_url]);
}
header('Location: ?tab=ranks&success=1');
exit;
} catch (PDOException $e) {
header('Location: ?tab=ranks&error=db');
exit;
}
}
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) {
$stmt = $db->prepare("UPDATE lootboxes SET name = ?, slug = ?, description = ? WHERE id = ?");
$stmt->execute([$name, $slug, $description, $id]);
} else {
$stmt = $db->prepare("INSERT INTO lootboxes (name, slug, description) VALUES (?, ?, ?)");
$stmt->execute([$name, $slug, $description]);
$id = $db->lastInsertId();
}
// Handle Rolls
$db->prepare("DELETE FROM lootbox_rolls WHERE lootbox_id = ?")->execute([$id]);
if (isset($_POST['rolls_count']) && is_array($_POST['rolls_count'])) {
$ins_roll = $db->prepare("INSERT INTO lootbox_rolls (lootbox_id, roll_count, probability) VALUES (?, ?, ?)");
foreach ($_POST['rolls_count'] as $idx => $rc) {
$prob = (float)$_POST['rolls_prob'][$idx];
if ($prob > 0) {
$ins_roll->execute([$id, (int)$rc, $prob]);
}
}
}
// Handle Items
$db->prepare("DELETE FROM lootbox_items WHERE lootbox_id = ?")->execute([$id]);
if (isset($_POST['item_slug']) && is_array($_POST['item_slug'])) {
$ins_item = $db->prepare("INSERT INTO lootbox_items (lootbox_id, resource_slug, probability, quantity_min, quantity_max, is_guaranteed) VALUES (?, ?, ?, ?, ?, ?)");
foreach ($_POST['item_slug'] as $idx => $islug) {
$is_guaranteed = isset($_POST['item_is_guaranteed'][$idx]) ? (int)$_POST['item_is_guaranteed'][$idx] : 0;
$iprob = $is_guaranteed ? 100.00 : (float)$_POST['item_prob'][$idx];
if ($is_guaranteed || $iprob > 0) {
$qmin = (int)$_POST['item_qmin'][$idx];
$qmax = (int)$_POST['item_qmax'][$idx];
$ins_item->execute([$id, $islug ?: null, $iprob, $qmin, $qmax, $is_guaranteed]);
}
}
}
header("Location: admin.php?tab=lootboxes&success=1");
exit;
}
if (isset($_GET['delete_lootbox'])) {
$id = (int)$_GET['delete_lootbox'];
$db->prepare("DELETE FROM lootboxes WHERE id = ?")->execute([$id]);
header("Location: admin.php?tab=lootboxes&success=1");
exit;
}
// Handle Project Log CRUD
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["action"]) && $_POST["action"] === "upsert_project_log") {
$id = (int)$_POST["id"];
$version = $_POST["version"];
$title = $_POST["title"];
$content_log = $_POST["content"];
if ($id > 0) {
$stmt = $db->prepare("UPDATE project_logs SET version = ?, title = ?, content = ? WHERE id = ?");
$stmt->execute([$version, $title, $content_log, $id]);
} else {
$stmt = $db->prepare("INSERT INTO project_logs (version, title, content) VALUES (?, ?, ?)");
$stmt->execute([$version, $title, $content_log]);
}
header("Location: admin.php?tab=project_logs&success=1");
exit;
}
if (isset($_GET['delete_grade'])) {
$id = (int)$_GET['delete_grade'];
$stmt = db()->prepare("DELETE FROM grades WHERE id = ?");
$stmt->execute([$id]);
header('Location: ?tab=ranks&success=deleted');
exit;
}
if (isset($_GET["delete_project_log"])) {
$id = (int)$_GET["delete_project_log"];
$db->prepare("DELETE FROM project_logs WHERE id = ?")->execute([$id]);
header("Location: admin.php?tab=project_logs&success=1");
exit;
}
// Handle Unit CRUD
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["action"]) && $_POST["action"] === "upsert_unit") {
$id = (int)$_POST["id"];
$name = $_POST["name"];
$slug = $_POST["slug"];
$faction_id = !empty($_POST["faction_id"]) ? (int)$_POST["faction_id"] : null;
$can_be_destroyed = isset($_POST["can_be_destroyed"]) ? 1 : 0;
$can_be_captured = isset($_POST["can_be_captured"]) ? 1 : 0;
$points_per_hit = (int)$_POST["points_per_hit"];
$bonus_destruction = (int)$_POST["bonus_destruction"];
$bonus_capture = (int)$_POST["bonus_capture"];
$grid_data = $_POST["grid_data"];
$image_url = null;
if ($id > 0) {
$stmt_img = $db->prepare("SELECT image_url FROM units 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 = "unit_" . $slug . "_" . time() . "." . $ext;
$target = "assets/images/units/" . $filename;
if (!is_dir("assets/images/units/")) mkdir("assets/images/units/", 0775, true);
if (move_uploaded_file($_FILES["image"]["tmp_name"], $target)) {
$image_url = $target;
}
}
if ($id > 0) {
$stmt = $db->prepare("UPDATE units SET name = ?, slug = ?, faction_id = ?, can_be_destroyed = ?, can_be_captured = ?, points_per_hit = ?, bonus_destruction = ?, bonus_capture = ?, grid_data = ?, image_url = ? WHERE id = ?");
$stmt->execute([$name, $slug, $faction_id, $can_be_destroyed, $can_be_captured, $points_per_hit, $bonus_destruction, $bonus_capture, $grid_data, $image_url, $id]);
} else {
$stmt = $db->prepare("INSERT INTO units (name, slug, faction_id, can_be_destroyed, can_be_captured, points_per_hit, bonus_destruction, bonus_capture, grid_data, image_url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$name, $slug, $faction_id, $can_be_destroyed, $can_be_captured, $points_per_hit, $bonus_destruction, $bonus_capture, $grid_data, $image_url]);
$id = $db->lastInsertId();
}
// Handle Rewards
$db->prepare("DELETE FROM unit_rewards WHERE unit_id = ?")->execute([$id]);
if (isset($_POST["reward_action"]) && is_array($_POST["reward_action"])) {
$ins_rw = $db->prepare("INSERT INTO unit_rewards (unit_id, action_type, resource_id, amount) VALUES (?, ?, ?, ?)");
foreach ($_POST["reward_action"] as $idx => $action) {
$res_id = (int)$_POST["reward_resource_id"][$idx];
$amount = (int)$_POST["reward_amount"][$idx];
if ($amount > 0) {
$ins_rw->execute([$id, $action, $res_id, $amount]);
}
}
}
header("Location: admin.php?tab=units&success=1");
exit;
}
if (isset($_GET["delete_unit"])) {
$id = (int)$_GET["delete_unit"];
$db->prepare("DELETE FROM units WHERE id = ?")->execute([$id]);
header("Location: admin.php?tab=units&success=1");
exit;
}
// --- DATA FETCHING ---
$users_list = [];
$objects_list = [];
$statuses_list = [];
$status_rules_list = [];
$status_profiles_list = [];
$settlement_types_list = [];
$modifiers_list = [];
$factions_list = [];
$resources_list = [];
$lootboxes_list = [];
$project_logs_list = [];
$units_list = [];
$titles_list = [];
$badges_list = [];
$levels_list = [];
$ranks_list = [];
$guild_requirements = [];
$guild_member_limit = 50;
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 * FROM celestial_object_types ORDER BY 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);
$modifiers_list = $db->query("SELECT * FROM modifiers ORDER BY type, name ASC")->fetchAll();
$status_profiles_list = $db->query("SELECT * FROM celestial_object_status_profiles ORDER BY name ASC")->fetchAll();
} elseif ($tab === 'statuses') {
$statuses_list = $db->query("SELECT * FROM celestial_object_statuses ORDER BY name ASC")->fetchAll();
$status_rules_list = $db->query("SELECT r.*, s.name as status_name, p.name as profile_name FROM celestial_object_status_rules r JOIN celestial_object_statuses s ON r.status_id = s.id LEFT JOIN celestial_object_status_profiles p ON r.profile_id = p.id ORDER BY r.profile_id, r.priority DESC, r.name ASC")->fetchAll();
$status_profiles_list = $db->query("SELECT * FROM celestial_object_status_profiles ORDER BY name ASC")->fetchAll();
$factions_list = $db->query("SELECT * FROM factions ORDER BY name ASC")->fetchAll();
} elseif ($tab === 'settlement_types') {
$settlement_types_list = $db->query("SELECT * FROM settlement_types ORDER BY name ASC")->fetchAll();
} elseif ($tab === 'modifiers') {
$modifiers_list = $db->query("SELECT * FROM modifiers ORDER BY type, name ASC")->fetchAll();
} elseif ($tab === 'factions') {
$factions_list = $db->query("SELECT * FROM factions ORDER BY name ASC")->fetchAll();
foreach ($factions_list as &$f) {
$stmt = $db->prepare("SELECT faction_id_1 as ally_id FROM faction_alliances WHERE faction_id_2 = ? UNION SELECT faction_id_2 as ally_id FROM faction_alliances WHERE faction_id_1 = ?");
$stmt->execute([$f['id'], $f['id']]);
$f['alliance_ids'] = $stmt->fetchAll(PDO::FETCH_COLUMN);
}
unset($f);
} elseif ($tab === 'levels') {
$levels_list = $db->query("SELECT l.*, r.name as resource_name FROM levels l JOIN game_resources r ON l.resource_id = r.id ORDER BY l.required_quantity ASC")->fetchAll();
$resources_list = $db->query("SELECT id, name FROM game_resources ORDER BY name ASC")->fetchAll();
} elseif ($tab === 'resources') {
$resources_list = $db->query("SELECT * FROM game_resources ORDER BY name ASC")->fetchAll();
} elseif ($tab === 'project_logs') {
$project_logs_list = $db->query("SELECT * FROM project_logs ORDER BY created_at DESC")->fetchAll();
} elseif ($tab === 'badges') {
$titles_list = $db->query("SELECT * FROM titles ORDER BY name ASC")->fetchAll();
$badges_list = $db->query("SELECT * FROM badges ORDER BY name ASC")->fetchAll();
} elseif ($tab === 'ranks') {
$ranks_list = $db->query("SELECT * FROM grades ORDER BY user_type DESC, min_level ASC")->fetchAll();
} elseif ($tab === 'lootboxes') {
$lootboxes_list = $db->query("SELECT * FROM lootboxes ORDER BY name ASC")->fetchAll();
$resources_list = $db->query("SELECT name, slug FROM game_resources ORDER BY name ASC")->fetchAll();
foreach ($lootboxes_list as &$lb) {
$stmt_r = $db->prepare("SELECT * FROM lootbox_rolls WHERE lootbox_id = ?");
$stmt_r->execute([$lb['id']]);
$lb['rolls'] = $stmt_r->fetchAll();
$stmt_i = $db->prepare("SELECT * FROM lootbox_items WHERE lootbox_id = ?");
$stmt_i->execute([$lb['id']]);
$lb['items'] = $stmt_i->fetchAll();
}
unset($lb);
} elseif ($tab === 'guilds') {
$guild_requirements = $db->query("SELECT r.id, r.name, r.icon, gr.amount FROM game_resources r LEFT JOIN guild_creation_requirements gr ON r.id = gr.resource_id")->fetchAll();
$stmt = $db->query("SELECT value FROM guild_restrictions WHERE restriction_key = 'member_limit'");
$guild_member_limit = $stmt->fetchColumn() ?: 50;
}
elseif ($tab === "units") {
$units_list = $db->query("SELECT u.*, f.name as faction_name FROM units u LEFT JOIN factions f ON u.faction_id = f.id ORDER BY u.name ASC")->fetchAll();
foreach ($units_list as &$unit) {
$stmt_rw = $db->prepare("SELECT action_type, resource_id, amount FROM unit_rewards WHERE unit_id = ?");
$stmt_rw->execute([$unit["id"]]);
$unit["rewards"] = $stmt_rw->fetchAll();
}
unset($unit);
$factions_list = $db->query("SELECT id, name FROM factions ORDER BY name ASC")->fetchAll();
$resources_list = $db->query("SELECT id, name FROM game_resources ORDER BY name ASC")->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', Tahoma, Geneva, Verdana, 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; }
.nav-links a:hover { color: #fff; }
.container { padding: 40px; max-width: 1400px; margin: 0 auto; }
.tabs { display: flex; gap: 5px; margin-bottom: 10px; 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; }
.success-msg { background: #a3be8c; color: #000; padding: 10px; margin-bottom: 20px; border-radius: 4px; font-weight: bold; }
.modifier-tag { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 10px; font-weight: bold; margin-right: 5px; margin-bottom: 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; }
.sub-form-row .btn-del-row { flex: 0 0 30px; background: #bf616a; color: #fff; padding: 5px; border-radius: 4px; text-align: center; cursor: pointer; }
.sub-form-header { display: flex; gap: 8px; margin-bottom: 5px; font-size: 10px; color: #8c92a3; text-transform: uppercase; font-weight: bold; }
.sub-form-header .btn-del-row-placeholder { flex: 0 0 30px; }
/* Custom toggle switch */
.toggle-container { display: flex; align-items: center; gap: 5px; font-size: 9px; color: #8c92a3; flex: 0 0 100px; }
.switch { position: relative; display: inline-block; width: 40px; height: 20px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
@keyframes blink {
0% { opacity: 1; }
50% { opacity: 0.3; }
100% { opacity: 1; }
}
.blink-effect {
animation: blink 1s infinite;
}
/* Color picker custom style */
.color-group { display: flex; gap: 5px; }
.color-picker-input { width: 45px !important; height: 34px !important; padding: 2px !important; border: 1px solid #334155 !important; background: #0f172a !important; cursor: pointer; }
/* Multi-select dropdown */
.ms-container { position: relative; width: 100%; }
.ms-display {
background: #0f172a; border: 1px solid #334155; color: #fff; padding: 8px; cursor: pointer; min-height: 34px; box-sizing: border-box; font-size: 12px; display: flex; align-items: center; justify-content: space-between;
}
.ms-display:after { content: '▼'; font-size: 8px; color: #8c92a3; }
.ms-dropdown {
position: absolute; top: 100%; left: 0; right: 0; background: #1a202c; border: 1px solid #334155; z-index: 1000; display: none; max-height: 200px; overflow-y: auto; padding: 5px;
}
.ms-item { padding: 5px 8px; cursor: pointer; display: flex; align-items: center; gap: 8px; font-size: 11px; }
.ms-item:hover { background: #2d3545; }
.ms-item input { width: auto !important; }
.unit-grid-container { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.unit-grid { display: grid; grid-template-columns: repeat(6, 64px); grid-template-rows: repeat(6, 64px); gap: 2px; background: #2d3545; padding: 2px; width: fit-content; }
.unit-cell { width: 64px; height: 64px; background: #0f172a; cursor: pointer; border: 1px solid #334155; }
.unit-cell.active { background: #88c0d0; }
.unit-cell:hover { border-color: #88c0d0; }
</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> CONSOLE ADMIN</h2>
<nav class="nav-links">
<a href="project_log.php"><i class="fa-solid fa-clipboard-list"></i> Journal</a> <a href="index.php"><i class="fa-solid fa-eye"></i> Vue Joueur</a>
<a href="gm_console.php"><i class="fa-solid fa-headset"></i> Console MJ</a>
</nav>
</div>
<div>
<span style="font-weight: bold; color: #88c0d0;"><?php echo htmlspecialchars($_SESSION['username']); ?></span>
</div>
</header>
<div class="container">
<?php if (isset($_GET['error']) && $_GET['error'] === 'invalid_amount'): ?>
<div class="success-msg" style="background: #bf616a; color: #fff;"><i class="fa-solid fa-triangle-exclamation"></i> Erreur : La quantité doit être un nombre strictement positif.</div>
<?php endif; ?>
<?php if (isset($_GET['success'])): ?>
<div class="success-msg"><i class="fa-solid fa-check-circle"></i> Opération effectuée avec succès.</div>
<?php endif; ?>
<!-- LIGNE 1 (UTILISATEUR) -->
<div class="tabs">
<a href="?tab=project_logs" class="tab-link <?php echo $tab === "project_logs" ? "active" : ""; ?>"><i class="fa-solid fa-clipboard-list"></i> Journal de Bord</a>
<a href="?tab=users" class="tab-link <?php echo $tab === 'users' ? 'active' : ''; ?>"><i class="fa-solid fa-users"></i> Utilisateurs</a>
<a href="?tab=levels" class="tab-link <?php echo $tab === 'levels' ? 'active' : ''; ?>"><i class="fa-solid fa-layer-group"></i> Niveaux</a>
<a href="?tab=ranks" class="tab-link <?php echo $tab === 'ranks' ? 'active' : ''; ?>"><i class="fa-solid fa-medal"></i> Grades</a>
<a href="?tab=badges" class="tab-link <?php echo $tab === 'badges' ? 'active' : ''; ?>"><i class="fa-solid fa-id-badge"></i> Titres & Badges</a>
<a href="?tab=guilds" class="tab-link <?php echo $tab === "guilds" ? "active" : ""; ?>"><i class="fa-solid fa-building-shield"></i> Gestion de guilde</a>
</div>
<!-- LIGNE 2 (JEU) -->
<div class="tabs" style="margin-bottom: 20px;">
<a href="?tab=objects" class="tab-link <?php echo $tab === 'objects' ? 'active' : ''; ?>"><i class="fa-solid fa-earth-europe"></i> Objets Célestes</a>
<a href="?tab=modifiers" class="tab-link <?php echo $tab === 'modifiers' ? 'active' : ''; ?>"><i class="fa-solid fa-bolt"></i> Bonus & Malus</a>
<a href="?tab=statuses" class="tab-link <?php echo $tab === 'statuses' ? 'active' : ''; ?>"><i class="fa-solid fa-signal"></i> Statuts / États</a>
<a href="?tab=settlement_types" class="tab-link <?php echo $tab === 'settlement_types' ? 'active' : ''; ?>"><i class="fa-solid fa-city"></i> Lieux et points dintérêt</a>
<a href="?tab=factions" class="tab-link <?php echo $tab === 'factions' ? 'active' : ''; ?>"><i class="fa-solid fa-flag"></i> Factions</a>
<a href="?tab=resources" class="tab-link <?php echo $tab === 'resources' ? 'active' : ''; ?>"><i class="fa-solid fa-gem"></i> Ressources</a>
<a href="?tab=lootboxes" class="tab-link <?php echo $tab === 'lootboxes' ? 'active' : ''; ?>"><i class="fa-solid fa-box-open"></i> Lootboxes</a>
<a href="?tab=units" class="tab-link <?php echo $tab === 'units' ? 'active' : ''; ?>"><i class="fa-solid fa-rocket"></i> Unité</a>
</div>
<?php if ($tab === 'users'): ?>
<h3 style="color: #88c0d0;">Gestion des Rôles</h3>
<table>
<thead>
<tr><th>Utilisateur</th><th>Email</th><th>Rôle Actuel</th><th>Nouveau Rôle</th></tr>
</thead>
<tbody>
<?php foreach ($users_list as $u): ?>
<tr>
<td><strong><?php echo htmlspecialchars($u['username']); ?></strong></td>
<td><?php echo htmlspecialchars($u['email']); ?></td>
<td>
<span style="background: <?php echo $u['role'] === 'admin' ? '#bf616a' : ($u['role'] === 'gm' ? '#ebcb8b' : '#4c566a'); ?>; padding: 2px 8px; border-radius: 10px; font-size: 11px; color: #000; font-weight: bold;">
<?php echo strtoupper($u['role']); ?>
</span>
</td>
<td>
<form method="POST" style="display: flex; gap: 10px;">
<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" <?php echo $u['role'] === 'user' ? 'selected' : ''; ?>>Utilisateur</option>
<option value="gm" <?php echo $u['role'] === 'gm' ? 'selected' : ''; ?>>Maître du Jeu (MJ)</option>
<option value="admin" <?php echo $u['role'] === 'admin' ? 'selected' : ''; ?>>Administrateur</option>
</select>
<button type="submit" class="btn btn-ok">Modifier</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php elseif ($tab === 'units'): ?>
<h3 style="color: #88c0d0;">Gestion des Unités</h3>
<div class="form-card">
<h4>Ajouter / Modifier une Unité</h4>
<form method="POST" enctype="multipart/form-data" id="unitForm">
<input type="hidden" name="action" value="upsert_unit">
<input type="hidden" name="id" id="unit_id" value="0">
<div style="display: flex; gap: 20px; flex-wrap: wrap;">
<div class="form-group" style="flex: 1; min-width: 250px;">
<label>Nom de l'unité</label>
<input type="text" name="name" id="unit_name" required placeholder="Chasseur Stellaire" onkeyup="syncSlug(this.value, 'unit_slug')">
</div>
<div class="form-group" style="flex: 1; min-width: 200px;">
<label>Slug (unique)</label>
<input type="text" name="slug" id="unit_slug" required placeholder="chasseur_stellaire">
</div>
<div class="form-group" style="flex: 1; min-width: 200px;">
<label>Faction</label>
<select name="faction_id" id="unit_faction_id">
<option value="">Aucune (Neutre)</option>
<?php foreach ($factions_list as $f): ?>
<option value="<?php echo $f['id']; ?>"><?php echo htmlspecialchars($f['name']); ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<div style="display: flex; gap: 20px; flex-wrap: wrap; align-items: flex-end;">
<div class="form-group" style="flex: 1; min-width: 250px;">
<label>Image de l'unité</label>
<input type="file" name="image" accept="image/*">
</div>
<div class="form-group" style="flex: 1; min-width: 200px;">
<label>Points par coup (dégâts)</label>
<input type="number" name="points_per_hit" id="unit_points_per_hit" value="1" min="0">
</div>
<div class="form-group" style="display: flex; gap: 20px; flex: 1; min-width: 200px; padding-bottom: 10px;">
<label style="display: flex; align-items: center; gap: 5px; cursor: pointer;">
<input type="checkbox" name="can_be_destroyed" id="unit_can_be_destroyed" value="1"> Destructible
</label>
<label style="display: flex; align-items: center; gap: 5px; cursor: pointer;">
<input type="checkbox" name="can_be_captured" id="unit_can_be_captured" value="1"> Capturable
</label>
</div>
</div>
<div style="display: flex; gap: 20px; flex-wrap: wrap;">
<div class="form-group" style="flex: 1;">
<label>Bonus Destruction (Points)</label>
<input type="number" name="bonus_destruction" id="unit_bonus_destruction" value="0" min="0">
</div>
<div class="form-group" style="flex: 1;">
<label>Bonus Capture (Points)</label>
<input type="number" name="bonus_capture" id="unit_bonus_capture" value="0" min="0">
</div>
</div>
<div class="form-group">
<label>Données de Grille (Format JSON)</label>
<div class="unit-grid-container">
<div class="unit-grid" id="unitGrid"></div>
<div style="font-size: 10px; color: #8c92a3;">Cliquez sur les cases pour définir la forme de l'unité (6x6).</div>
<textarea name="grid_data" id="unit_grid_data" style="height: 40px; font-size: 10px;" readonly></textarea>
</div>
</div>
<div class="form-group">
<label>Récompenses additionnelles (Action / Ressource / Quantité)</label>
<div id="unitRewardsContainer">
<div class="sub-form-header">
<div style="flex: 1;">Action</div>
<div style="flex: 1;">Ressource</div>
<div style="flex: 1;">Quantité</div>
<div class="btn-del-row-placeholder"></div>
</div>
</div>
<button type="button" class="btn" style="background: #4c566a; color: #fff; margin-top: 5px;" onclick="addUnitRewardRow()">+ AJOUTER UNE RÉCOMPENSE</button>
</div>
<div style="margin-top: 20px;">
<button type="submit" class="btn btn-add" id="unit_submit_btn">ENREGISTRER L'UNITÉ</button>
<button type="button" class="btn" style="background: #4c566a; color: #fff;" onclick="resetUnitForm()">ANNULER</button>
</div>
</form>
</div>
<table>
<thead>
<tr>
<th>Image</th>
<th>Nom / Slug</th>
<th>Faction</th>
<th>Propriétés</th>
<th>Récompenses</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if (empty($units_list)): ?>
<tr><td colspan="6" style="text-align: center; color: #8c92a3;">Aucune unité configurée.</td></tr>
<?php else: ?>
<?php foreach ($units_list as $unit): ?>
<tr>
<td>
<?php if ($unit['image_url']): ?>
<img src="<?php echo $unit['image_url']; ?>" style="width: 40px; height: 40px; object-fit: contain; background: #1a202c; border-radius: 4px;">
<?php else: ?>
<div style="width: 40px; height: 40px; background: #1a202c; border-radius: 4px; display: flex; align-items: center; justify-content: center;">
<i class="fa-solid fa-rocket" style="color: #2d3545;"></i>
</div>
<?php endif; ?>
</td>
<td>
<strong><?php echo htmlspecialchars($unit['name']); ?></strong><br>
<code style="font-size: 10px;"><?php echo htmlspecialchars($unit['slug']); ?></code>
</td>
<td>
<span style="color: #88c0d0; font-weight: bold; font-size: 12px;">
<?php echo $unit['faction_name'] ? htmlspecialchars($unit['faction_name']) : 'Neutre'; ?>
</span>
</td>
<td style="font-size: 11px;">
Pts/Coup: <?php echo $unit['points_per_hit']; ?><br>
<?php if ($unit['can_be_destroyed']): ?><span style="color: #bf616a;">● Destructible</span><br><?php endif; ?>
<?php if ($unit['can_be_captured']): ?><span style="color: #a3be8c;">● Capturable</span><?php endif; ?>
</td>
<td style="font-size: 10px;">
<?php if ($unit['bonus_destruction'] > 0): ?>Destr: +<?php echo $unit['bonus_destruction']; ?> pts<br><?php endif; ?>
<?php if ($unit['bonus_capture'] > 0): ?>Capt: +<?php echo $unit['bonus_capture']; ?> pts<br><?php endif; ?>
<?php foreach ($unit['rewards'] as $rw): ?>
<?php
$rName = '?';
foreach($resources_list as $res) { if($res['id'] == $rw['resource_id']) { $rName = $res['name']; break; } }
?>
<span style="color: #8c92a3;"><?php echo $rw['action_type'] === 'destroy' ? 'Destr' : 'Capt'; ?>:</span>
+<?php echo $rw['amount']; ?> <?php echo htmlspecialchars($rName); ?><br>
<?php endforeach; ?>
</td>
<td>
<button class="btn btn-edit" onclick='editUnit(<?php echo json_encode($unit, JSON_HEX_APOS); ?>)'>Modifier</button>
<a href="?tab=units&delete_unit=<?php echo $unit['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer cette unité ?')">Supprimer</a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
<?php elseif ($tab === 'levels'): ?>
<h3 style="color: #88c0d0;">Gestion des Niveaux</h3>
<div class="form-card">
<h4>Ajouter / Modifier un Niveau</h4>
<form method="POST" id="levelForm">
<input type="hidden" name="action" value="upsert_level">
<input type="hidden" name="id" id="level_id" value="0">
<div style="display: flex; gap: 20px;">
<div class="form-group" style="flex: 2;">
<label>Nom du niveau (ex : Niveau 1)</label>
<input type="text" name="name" id="level_name" required placeholder="Niveau 1">
</div>
<div class="form-group" style="flex: 1;">
<label>Slug (identifiant technique unique)</label>
<input type="text" name="slug" id="level_slug" required placeholder="niveau_1">
</div>
</div>
<div style="display: flex; gap: 20px;">
<div class="form-group" style="flex: 1;">
<label>Ressource requise</label>
<select name="resource_id" id="level_resource_id" required>
<?php foreach ($resources_list as $res): ?>
<option value="<?php echo $res['id']; ?>" <?php echo (stripos($res["name"], 'Expérience') !== false || stripos($res["name"], 'Experience') !== false) ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($res["name"]); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="form-group" style="flex: 1;">
<label>Quantité requise (nombre strictement positif)</label>
<input type="number" name="required_quantity" id="level_required_quantity" required min="1" placeholder="100">
</div>
</div>
<button type="submit" class="btn btn-add">ENREGISTRER LE NIVEAU</button>
<button type="button" class="btn" style="background: #4c566a; color: #fff;" onclick="resetLevelForm()">ANNULER</button>
</form>
</div>
<table>
<thead>
<tr>
<th>Nom</th>
<th>Slug</th>
<th>Ressource requise</th>
<th>Quantité requise</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if (empty($levels_list)): ?>
<tr><td colspan="5" style="text-align: center; color: #8c92a3;">Aucun niveau configuré.</td></tr>
<?php else: ?>
<?php foreach ($levels_list as $lvl): ?>
<tr>
<td><strong><?php echo htmlspecialchars($lvl["name"]); ?></strong></td>
<td><code><?php echo htmlspecialchars($lvl['slug']); ?></code></td>
<td><?php echo htmlspecialchars($lvl['resource_name']); ?></td>
<td><?php echo number_format($lvl['required_quantity'], 0, ',', ' '); ?></td>
<td>
<button class="btn btn-edit" onclick='editLevel(<?php echo json_encode($lvl, JSON_HEX_APOS); ?>)'>Modifier</button>
<a href="?tab=levels&delete_level=<?php echo $lvl['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer ce niveau ?')">Supprimer</a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
<?php elseif ($tab === 'ranks'): ?>
<h3 style="color: #88c0d0;">Gestion des Grades</h3>
<?php if (isset($_GET['error']) && $_GET['error'] === 'overlap_levels'): ?>
<div style="background: #bf616a; color: #fff; padding: 10px; border-radius: 4px; margin-bottom: 15px;">
Erreur : Les intervalles de niveaux pour les grades utilisateurs ne doivent pas se chevaucher.
</div>
<?php elseif (isset($_GET['error']) && $_GET['error'] === 'invalid_range'): ?>
<div style="background: #bf616a; color: #fff; padding: 10px; border-radius: 4px; margin-bottom: 15px;">
Erreur : Le niveau maximum doit être supérieur ou égal au niveau minimum.
</div>
<?php endif; ?>
<div class="form-card">
<h4>Ajouter / Modifier un Grade</h4>
<form method="POST" id="rankForm" enctype="multipart/form-data">
<input type="hidden" name="action" value="upsert_grade">
<input type="hidden" name="id" id="rank_id" value="0">
<div style="display: flex; gap: 20px; margin-bottom: 15px;">
<div class="form-group" style="flex: 2;">
<label>Nom du Grade</label>
<input type="text" name="name" id="rank_name" required placeholder="Ex: Pionnier">
</div>
<div class="form-group" style="flex: 2;">
<label>Slug (Identifiant technique unique)</label>
<input type="text" name="slug" id="rank_slug" required placeholder="Ex: pionnier">
</div>
<div class="form-group" style="flex: 1;">
<label>Type d'utilisateur</label>
<select name="user_type" id="rank_type" required onchange="updateRankFields()">
<option value="utilisateur">Utilisateur</option>
<option value="GM">GM</option>
<option value="admin">Admin</option>
</select>
</div>
</div>
<div style="display: flex; gap: 20px;">
<div class="form-group" style="flex: 1;">
<label>Niveau Minimum</label>
<input type="number" name="min_level" id="rank_min" min="0" placeholder="Ex: 1">
</div>
<div class="form-group" style="flex: 1;">
<label>Niveau Maximum</label>
<input type="number" name="max_level" id="rank_max" min="0" placeholder="Ex: 10">
</div>
<div class="form-group" style="flex: 1;">
<label>Image (PNG) - Optionnel</label>
<input type="file" name="image" accept="image/png">
</div>
</div>
<div style="margin-top: 15px;">
<button type="submit" class="btn btn-add">ENREGISTRER LE GRADE</button>
<button type="button" class="btn" style="background: #4c566a; color: #fff;" onclick="resetRankForm()">ANNULER</button>
</div>
</form>
</div>
<table>
<thead>
<tr>
<th>Visuel</th>
<th>Nom</th>
<th>Slug</th>
<th>Type</th>
<th>Intervalle Niveau</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if (empty($ranks_list)): ?>
<tr><td colspan="6" style="text-align: center;">Aucun grade configuré.</td></tr>
<?php else: ?>
<?php foreach ($ranks_list as $r): ?>
<tr>
<td><img src="<?php echo htmlspecialchars($r["image_url"]); ?>" style="width:40px;"></td><td><strong><?php echo htmlspecialchars($r["name"]); ?></strong></td>
<td><code><?php echo htmlspecialchars($r['slug']); ?></code></td>
<td>
<span class="badge <?php echo $r['user_type'] === 'admin' ? 'tag-malus' : ($r['user_type'] === 'GM' ? 'tag-bonus' : ''); ?>"
style="background: <?php echo $r['user_type'] === 'admin' ? '#bf616a' : ($r['user_type'] === 'GM' ? '#ebcb8b' : '#88c0d0'); ?>; color: #2e3440; padding: 2px 8px; border-radius: 10px; font-size: 10px; text-transform: uppercase; font-weight: bold;">
<?php echo htmlspecialchars($r['user_type']); ?>
</span>
</td>
<td>
<?php if ($r['user_type'] === 'utilisateur'): ?>
<?php echo $r['min_level']; ?> - <?php echo $r['max_level']; ?>
<?php else: ?>
<span style="color: #4c566a;">N/A</span>
<?php endif; ?>
</td>
<td>
<button class="btn btn-edit" onclick='editRank(<?php echo json_encode($r, JSON_HEX_APOS); ?>)'>Modifier</button>
<a href="?tab=ranks&delete_grade=<?php echo $r['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer ce grade ?')">Supprimer</a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
<?php elseif ($tab === 'guilds'): ?>
<h3 style="color: #88c0d0;">Gestion des Guildes</h3>
<div class="form-card">
<h4>Paramètres globaux des Guildes</h4>
<form method="POST" action="admin.php?tab=guilds">
<input type="hidden" name="action" value="update_guild_requirements">
<div class="form-group">
<label>Limite de membres par guilde</label>
<input type="number" name="guild_member_limit" value="<?php echo htmlspecialchars($guild_member_limit); ?>">
</div>
<h4>Coût de création</h4>
<table>
<thead><tr><th>Ressource</th><th>Quantité requise</th></tr></thead>
<tbody>
<?php foreach ($guild_requirements as $req): ?>
<tr>
<td>
<i class="fa-solid <?php echo htmlspecialchars($req['icon'] ?: 'fa-gem'); ?>"></i>
<?php echo htmlspecialchars($req["name"]); ?>
</td>
<td><input type="number" name="res_<?php echo $req["id"]; ?>" value="<?php echo $req["amount"] ?: 0; ?>"></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<button type="submit" class="btn btn-add" style="margin-top: 15px;">ENREGISTRER</button>
</form>
</div>
<?php elseif ($tab === 'badges'): ?>
<h3 style="color: #88c0d0;">Titres & Badges</h3>
<div style="display: flex; gap: 20px; align-items: flex-start;">
<!-- COLONNE GAUCHE : TITRES -->
<div style="flex: 1; background: #0a1420; padding: 20px; border: 1px solid #2d3545; border-radius: 4px;">
<h4 style="color: #88c0d0; border-bottom: 1px solid #2d3545; padding-bottom: 10px; margin-bottom: 20px;">
<i class="fa-solid fa-id-card"></i> Gestion des Titres
</h4>
<form method="POST" id="titleForm" class="form-card" style="margin-bottom: 20px;">
<input type="hidden" name="action" value="upsert_title">
<input type="hidden" name="id" id="title_id" value="0">
<div class="form-group">
<label>Nom du titre</label>
<input type="text" name="name" id="title_name" required placeholder="Ex: Pionnier du Nexus">
</div>
<div class="form-group">
<label>Slug (Identifiant technique)</label>
<input type="text" name="slug" id="title_slug" required placeholder="Ex: pioneer">
</div>
<div class="form-group">
<label>Type d'utilisateur autorisé</label>
<select name="allowed_user_type" id="title_allowed_type">
<option value="all">Tous (all)</option>
<option value="user">Utilisateurs standards</option>
<option value="gm">Maîtres de jeu (GM)</option>
<option value="admin">Administrateurs</option>
</select>
</div>
<div class="form-group">
<label>Niveau minimum requis</label>
<input type="number" name="required_level" id="title_req_level" value="0" min="0">
</div>
<div class="form-group">
<label>Couleur du titre</label>
<input type="color" name="color" id="title_color" value="#ffffff">
</div>
<div style="display: flex; gap: 10px;">
<button type="submit" class="btn btn-add" style="flex: 1;">ENREGISTRER</button>
<button type="button" class="btn" style="background: #4c566a; color: #fff;" onclick="resetTitleForm()">ANNULER</button>
</div>
</form>
<table style="font-size: 13px;">
<thead>
<tr>
<th>Titre</th>
<th>Slug</th>
<th>Niveau</th>
<th>Couleur</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($titles_list as $t): ?>
<tr>
<td><strong style="color: <?php echo $t['color'] ?: '#ffffff'; ?>;"><?php echo htmlspecialchars($t['name']); ?></strong></td>
<td><code style="color: #ebcb8b;"><?php echo htmlspecialchars($t['slug']); ?></code></td>
<td><?php echo $t['required_level']; ?></td>
<td><div style="width: 20px; height: 20px; border-radius: 50%; background: <?php echo $t['color'] ?: '#ffffff'; ?>; border: 1px solid #2d3545;"></div></td>
<td>
<button class="btn btn-edit" onclick='editTitle(<?php echo json_encode($t, JSON_HEX_APOS); ?>)'>Modifier</button>
<a href="?tab=badges&delete_title=<?php echo $t['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer ce titre ?')">X</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<!-- COLONNE DROITE : BADGES -->
<div style="flex: 1; background: #0a1420; padding: 20px; border: 1px solid #2d3545; border-radius: 4px;">
<h4 style="color: #88c0d0; border-bottom: 1px solid #2d3545; padding-bottom: 10px; margin-bottom: 20px;">
<i class="fa-solid fa-id-badge"></i> Gestion des Badges
</h4>
<form method="POST" id="badgeForm" class="form-card" enctype="multipart/form-data" style="margin-bottom: 20px;">
<input type="hidden" name="action" value="upsert_badge">
<input type="hidden" name="id" id="badge_id" value="0">
<div style="display: flex; gap: 10px;">
<div class="form-group" style="flex: 2;">
<label>Image du badge</label>
<input type="file" name="image" accept="image/*">
</div>
<div id="badge_preview_container" style="flex: 1; text-align: center; background: #0f172a; border: 1px solid #334155; border-radius: 4px; padding: 5px; display: none;">
<img id="badge_preview" src="" style="max-height: 50px; max-width: 50px;">
</div>
</div>
<div class="form-group">
<label>Nom du badge</label>
<input type="text" name="name" id="badge_name" required placeholder="Ex: Fondateur">
</div>
<div class="form-group">
<label>Slug (Identifiant technique)</label>
<input type="text" name="slug" id="badge_slug" required placeholder="Ex: founder">
</div>
<div class="form-group">
<label>Type d'utilisateur autorisé</label>
<select name="allowed_user_type" id="badge_allowed_type">
<option value="all">Tous (all)</option>
<option value="user">Utilisateurs standards</option>
<option value="gm">Maîtres de jeu (GM)</option>
<option value="admin">Administrateurs</option>
</select>
</div>
<div class="form-group">
<label>Niveau minimum requis</label>
<input type="number" name="required_level" id="badge_req_level" value="0" min="0">
</div>
<div style="display: flex; gap: 10px;">
<button type="submit" class="btn btn-add" style="flex: 1;">ENREGISTRER</button>
<button type="button" class="btn" style="background: #4c566a; color: #fff;" onclick="resetBadgeForm()">ANNULER</button>
</div>
</form>
<table style="font-size: 13px;">
<thead>
<tr>
<th>Visuel</th>
<th>Badge</th>
<th>Slug</th>
<th>Niveau</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($badges_list as $b): ?>
<tr>
<td style="text-align: center;">
<img src="<?php echo htmlspecialchars($b['image_url']); ?>" style="max-height: 30px; max-width: 30px;">
</td>
<td><strong><?php echo htmlspecialchars($b['name']); ?></strong></td>
<td><code style="color: #ebcb8b;"><?php echo htmlspecialchars($b['slug']); ?></code></td>
<td><?php echo $b['required_level']; ?></td>
<td>
<button class="btn btn-edit" onclick='editBadge(<?php echo json_encode($b, JSON_HEX_APOS); ?>)'>Modifier</button>
<a href="?tab=badges&delete_badge=<?php echo $b['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer ce badge ?')">X</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<?php elseif ($tab === 'objects'): ?>
<h3 style="color: #88c0d0;">Objets Célestes</h3>
<div class="form-card">
<h4>Ajouter / Modifier un Objet</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 (Affichage)</label>
<input type="text" name="name" id="obj_name" required placeholder="Ex: Planète">
</div>
<div class="form-group" style="flex: 1;">
<label>Slug (Identifiant technique)</label>
<input type="text" name="slug" id="obj_slug" required placeholder="Ex: planet">
</div>
<div class="form-group" style="flex: 1;">
<label>Icône (FontAwesome)</label>
<input type="text" name="icon" id="obj_icon" required placeholder="Ex: fa-earth-europe">
</div>
<div class="form-group" style="flex: 1;">
<label>Image (PNG/JPG) - Optionnel</label>
<input type="file" name="image" accept="image/*">
</div>
</div>
<div style="display: flex; gap: 20px; margin-bottom: 15px;">
<div class="form-group" style="flex: 1; background: rgba(0,0,0,0.2); padding: 10px; border-radius: 4px; border: 1px solid #334155;">
<label style="color: #88c0d0; font-weight: bold;">Contrôles activés</label>
<div style="display: flex; gap: 20px; margin-top: 5px;">
<div style="display: flex; align-items: center; gap: 10px;">
<input type="checkbox" name="orbital_control_enabled" id="obj_orbital_enabled" checked style="width: auto;">
<label for="obj_orbital_enabled" style="margin-bottom: 0; cursor: pointer;">Orbital</label>
</div>
<div style="display: flex; align-items: center; gap: 10px;">
<input type="checkbox" name="terrestrial_control_enabled" id="obj_terrestrial_enabled" checked style="width: auto;">
<label for="obj_terrestrial_enabled" style="margin-bottom: 0; cursor: pointer;">Terrestre</label>
</div>
</div>
</div>
<div class="form-group" style="flex: 1; background: rgba(136, 192, 208, 0.1); padding: 10px; border-radius: 4px; border: 1px solid #88c0d0;">
<label style="color: #88c0d0; font-weight: bold;">Règle(s) à appliquer</label>
<select name="status_profile_id" id="obj_profile_id" style="margin-top: 5px;">
<option value="">(Aucune règle - Statut fixe)</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 style="flex: 1;">
<label style="font-size: 12px; color: #8c92a3;">Bonus / Malus attribués</label>
<div style="background: #0f172a; border: 1px solid #334155; padding: 10px; max-height: 150px; overflow-y: auto; display: flex; flex-wrap: wrap; gap: 10px; margin-top: 5px;">
<?php foreach ($modifiers_list as $m): ?>
<label style="font-size: 11px; display: flex; align-items: center; gap: 5px; cursor: pointer;">
<input type="checkbox" name="modifiers[]" value="<?php echo $m['id']; ?>" class="modifier-checkbox" data-id="<?php echo $m['id']; ?>">
<span class="modifier-tag <?php echo $m['type'] === 'bonus' ? 'tag-bonus' : 'tag-malus'; ?>">
<?php echo htmlspecialchars($m["name"]); ?>
</span>
</label>
<?php endforeach; ?>
</div>
</div>
</div>
<div class="form-group" style="margin-top: 15px;">
<label>Description</label>
<textarea name="description" id="obj_desc" rows="2"></textarea>
</div>
<button type="submit" class="btn btn-add">ENREGISTRER L'OBJET</button>
<button type="button" class="btn" style="background: #4c566a; color: #fff;" onclick="resetObjectForm()">ANNULER</button>
</form>
</div>
<table>
<thead><tr><th>Visuel</th><th>Nom</th><th>Contrôles</th><th>Règles</th><th>Bonus/Malus</th><th>Actions</th></tr></thead>
<tbody>
<?php foreach ($objects_list as $o): ?>
<tr>
<td style="text-align: center;">
<?php if (!empty($o["image_url"])): ?>
<img src="<?php echo htmlspecialchars($o["image_url"]); ?>?v=<?php echo time(); ?>" style="max-width: 40px; max-height: 40px; display: block; margin: 0 auto;">
<?php else: ?>
<i class="fa-solid <?php echo htmlspecialchars($o['icon']); ?> fa-lg"></i>
<?php endif; ?>
</td>
<td><strong><?php echo htmlspecialchars($o["name"]); ?></strong><br><small><code><?php echo htmlspecialchars($o['slug']); ?></code></small></td>
<td style="text-align: center;">
<div style="display: flex; flex-direction: column; gap: 4px; align-items: center;">
<span style="font-size: 10px; display: inline-flex; align-items: center; gap: 3px; padding: 2px 6px; border-radius: 4px; background: <?php echo $o['orbital_control_enabled'] ? 'rgba(163, 190, 140, 0.2)' : 'rgba(191, 97, 106, 0.2)'; ?>; color: <?php echo $o['orbital_control_enabled'] ? '#a3be8c' : '#bf616a'; ?>; border: 1px solid <?php echo $o['orbital_control_enabled'] ? '#a3be8c' : '#bf616a'; ?>; width: 90px; justify-content: center;">
<i class="fa-solid <?php echo $o['orbital_control_enabled'] ? 'fa-check' : 'fa-xmark'; ?>"></i> ORBITAL
</span>
<span style="font-size: 10px; display: inline-flex; align-items: center; gap: 3px; padding: 2px 6px; border-radius: 4px; background: <?php echo $o['terrestrial_control_enabled'] ? 'rgba(163, 190, 140, 0.2)' : 'rgba(191, 97, 106, 0.2)'; ?>; color: <?php echo $o['terrestrial_control_enabled'] ? '#a3be8c' : '#bf616a'; ?>; border: 1px solid <?php echo $o['terrestrial_control_enabled'] ? '#a3be8c' : '#bf616a'; ?>; width: 90px; justify-content: center;">
<i class="fa-solid <?php echo $o['terrestrial_control_enabled'] ? 'fa-check' : 'fa-xmark'; ?>"></i> TERRESTRE
</span>
</div>
</td>
<td>
<?php
$p_name = "<em>Fixe</em>";
foreach($status_profiles_list as $p) if($p['id'] == $o['status_profile_id']) $p_name = htmlspecialchars($p["name"]);
echo $p_name;
?>
</td>
<td>
<?php
$stmt = $db->prepare("SELECT m.name, m.type FROM modifiers m JOIN celestial_object_type_modifiers cotm ON m.id = cotm.modifier_id WHERE cotm.celestial_object_type_id = ?");
$stmt->execute([$o['id']]);
$m_list = $stmt->fetchAll();
foreach ($m_list as $ml): ?>
<span class="modifier-tag <?php echo $ml['type'] === 'bonus' ? 'tag-bonus' : 'tag-malus'; ?>">
<?php echo htmlspecialchars($ml["name"]); ?>
</span>
<?php endforeach; ?>
</td>
<td>
<button class="btn btn-edit" onclick='editObject(<?php echo json_encode($o, JSON_HEX_APOS); ?>)'>Modifier</button>
<a href="?tab=objects&delete_object=<?php echo $o['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer cet objet ?')">Supprimer</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php elseif ($tab === 'modifiers'): ?>
<h3 style="color: #88c0d0;">Gestion des Bonus & Malus</h3>
<div class="form-card">
<h4>Ajouter / Modifier un Modificateur</h4>
<form method="POST" id="modifierForm">
<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 du Bonus/Malus</label>
<input type="text" name="name" id="mod_name" required placeholder="Ex: Chaleur Extrême">
</div>
<div class="form-group" style="flex: 1;">
<label>Slug</label>
<input type="text" name="slug" id="mod_slug" required placeholder="Ex: chaleur_extreme">
</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 (Effet en jeu)</label>
<textarea name="description" id="mod_desc" rows="2" placeholder="Ex: Vitesse de déplacement divisée par 2"></textarea>
</div>
<button type="submit" class="btn btn-add">ENREGISTRER</button>
<button type="button" class="btn" style="background: #4c566a; color: #fff;" onclick="resetModifierForm()">ANNULER</button>
</form>
</div>
<table>
<thead><tr><th>Type</th><th>Nom</th><th>Description</th><th>Slug</th><th>Actions</th></tr></thead>
<tbody>
<?php foreach ($modifiers_list as $m): ?>
<tr>
<td>
<span class="modifier-tag <?php echo $m['type'] === 'bonus' ? 'tag-bonus' : 'tag-malus'; ?>">
<?php echo strtoupper($m['type']); ?>
</span>
</td>
<td><strong><?php echo htmlspecialchars($m["name"]); ?></strong></td>
<td><small><?php echo htmlspecialchars($m['description']); ?></small></td>
<td><code><?php echo htmlspecialchars($m['slug']); ?></code></td>
<td>
<button class="btn btn-edit" onclick='editModifier(<?php echo json_encode($m, JSON_HEX_APOS); ?>)'>Modifier</button>
<a href="?tab=modifiers&delete_modifier=<?php echo $m['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer ce modificateur ?')">Supprimer</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php elseif ($tab === 'statuses'): ?>
<h3 style="color: #88c0d0;">Statuts / États</h3>
<div style="display: flex; gap: 30px; align-items: flex-start;">
<!-- LEFT: Status Management -->
<div style="flex: 1;">
<div class="form-card">
<h4>Ajouter / Modifier un Statut</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 du Statut</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>
<div class="color-group">
<input type="color" id="st_color_picker" class="color-picker-input" oninput="document.getElementById('st_color').value = this.value">
<input type="text" name="color" id="st_color" required placeholder="#ef4444" oninput="document.getElementById('st_color_picker').value = this.value">
</div>
</div>
<div class="form-group" style="flex: 0 0 100px;">
<label>Clignotement</label>
<label class="switch">
<input type="checkbox" name="is_blinking" id="st_is_blinking">
<span class="slider"></span>
</label>
</div>
</div>
<div class="form-group">
<label>Description</label>
<textarea name="description" id="st_desc" rows="2"></textarea>
</div>
<button type="submit" class="btn btn-add">ENREGISTRER LE STATUT</button>
<button type="button" class="btn" style="background: #4c566a; color: #fff;" 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>
<?php
$c = $s['color'];
$isBlink = strpos($c, ';blink') !== false;
$pureColor = str_replace(';blink', '', $c);
?>
<td><div class="<?php echo $isBlink ? 'blink-effect' : ''; ?>" style="width: 20px; height: 20px; background: <?php echo $pureColor; ?>; border: 1px solid #fff;"></div></td>
<td><strong><?php echo htmlspecialchars($s["name"]); ?></strong></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); ?>)'>Modifier</button>
<a href="?tab=statuses&delete_status=<?php echo $s['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer ce statut ?')">Supprimer</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<!-- RIGHT: Rules Management -->
<div style="flex: 1.5;">
<!-- PROFILE MANAGEMENT -->
<div class="form-card" style="border-color: #ebcb8b; margin-bottom: 20px;">
<h4 style="color: #ebcb8b;"><i class="fa-solid fa-layer-group"></i> PROFILS / GROUPES DE RÈGLES</h4>
<form method="POST" id="profileForm" style="display: flex; gap: 10px; align-items: flex-end;">
<input type="hidden" name="action" value="upsert_status_profile">
<input type="hidden" name="id" id="prof_id" value="0">
<div class="form-group" style="flex: 1; margin-bottom: 0;">
<label>Nom du Profil</label>
<input type="text" name="name" id="prof_name" required placeholder="Ex: Planètes Spéciales">
</div>
<div class="form-group" style="flex: 1; margin-bottom: 0;">
<label>Slug</label>
<input type="text" name="slug" id="prof_slug" required placeholder="Ex: planetes_speciales">
</div>
<button type="submit" class="btn btn-add" style="margin-bottom: 0;">ENREGISTRER</button>
<button type="button" class="btn" style="background: #4c566a; color: #fff; margin-bottom: 0;" onclick="resetProfileForm()">ANNULER</button>
</form>
<div style="margin-top: 15px; display: flex; flex-wrap: wrap; gap: 10px;">
<?php foreach ($status_profiles_list as $p): ?>
<div style="background: rgba(235, 203, 139, 0.1); border: 1px solid #ebcb8b; padding: 5px 10px; border-radius: 4px; display: flex; align-items: center; gap: 10px;">
<strong><?php echo htmlspecialchars($p["name"]); ?></strong> (<code><?php echo htmlspecialchars($p['slug']); ?></code>)
<div style="display: flex; gap: 5px;">
<i class="fa-solid fa-pen-to-square" style="cursor: pointer; color: #ebcb8b;" onclick='editProfile(<?php echo json_encode($p, JSON_HEX_APOS); ?>)'></i>
<a href="?tab=statuses&delete_status_profile=<?php echo $p['id']; ?>" onclick="return confirm('Supprimer ce profil ?')" style="color: #bf616a;"><i class="fa-solid fa-trash"></i></a>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<div class="form-card" style="border-color: #88c0d0;">
<h4 style="color: #88c0d0;"><i class="fa-solid fa-gears"></i> CONFIGURATION DES RÈGLES</h4>
<form method="POST" id="ruleForm">
<input type="hidden" name="action" value="upsert_status_rule">
<input type="hidden" name="id" id="rule_id" value="0">
<div style="display: flex; gap: 15px; margin-bottom: 15px;">
<div class="form-group" style="flex: 1.5;">
<label>Nom de la règle</label>
<input type="text" name="name" id="rule_name" required placeholder="Ex: Occupation ennemie">
</div>
<div class="form-group" style="flex: 1;">
<label>Profile / Groupe</label>
<select name="profile_id" id="rule_profile_id" required>
<?php foreach ($status_profiles_list as $p): ?>
<option value="<?php echo $p['id']; ?>"><?php echo htmlspecialchars($p["name"]); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="form-group" style="flex: 1;">
<label>Statut à appliquer</label>
<select name="status_id" id="rule_status_id" required>
<?php foreach ($statuses_list as $s): ?>
<option value="<?php echo $s['id']; ?>"><?php echo htmlspecialchars($s["name"]); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="form-group" style="flex: 0.5;">
<label>Priorité</label>
<input type="number" name="priority" id="rule_priority" value="0">
</div>
</div>
<div style="background: rgba(0,0,0,0.2); padding: 15px; border-radius: 4px; border: 1px solid #334155; margin-bottom: 15px;">
<div style="display: flex; gap: 20px; align-items: stretch;">
<!-- COLONNE ORBITALE -->
<div style="flex: 1; display: flex; flex-direction: column; gap: 15px; padding-right: 15px; border-right: 1px dashed #334155;">
<div style="font-size: 11px; color: #88c0d0; font-weight: bold; text-align: center; border-bottom: 1px solid #334155; padding-bottom: 5px; margin-bottom: 5px;">EN ORBITE</div>
<div class="form-group" style="margin-bottom: 0;">
<label style="font-size: 10px;">Nombre de factions</label>
<div style="display: flex; gap: 5px;">
<select name="orbital_count_op" id="rule_orb_op" style="width: 70px;">
<option value="">-</option>
<option value="=">=</option>
<option value=">">></option>
<option value="<"><</option>
<option value=">=">>=</option>
<option value="<="><=</option>
</select>
<input type="number" name="orbital_count_val" id="rule_orb_val" placeholder="0">
</div>
</div>
<div class="form-group" style="margin-bottom: 0;">
<label style="font-size: 10px;">Filtre Dominance</label>
<div class="ms-container" id="ms_orb">
<div class="ms-display" onclick="toggleMS('ms_orb_list')">Toutes / Peu importe</div>
<div class="ms-dropdown" id="ms_orb_list">
<label class="ms-item"><input type="checkbox" value="none" onchange="updateMSLabel('ms_orb')"> Aucune (Vide)</label>
<?php foreach($factions_list as $f): if($f["name"] !== 'Aucune'): ?>
<label class="ms-item"><input type="checkbox" value="<?php echo $f['id']; ?>" name="orbital_dominance[]" onchange="updateMSLabel('ms_orb')"> <?php echo htmlspecialchars($f["name"]); ?></label>
<?php endif; endforeach; ?>
</div>
</div>
</div>
</div>
<!-- COLONNE COMBINAISON (MILIEU) -->
<div style="flex: 0 0 100px; display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 10px; background: rgba(136, 192, 208, 0.05); border-radius: 8px; border: 1px solid rgba(136, 192, 208, 0.2); padding: 10px;">
<label style="font-size: 10px; color: #88c0d0; font-weight: bold; text-transform: uppercase;">Combinaison</label>
<select name="combine_mode" id="rule_combine" style="width: 100%; text-align: center; font-weight: bold; color: #ebcb8b; background: #2e3440; border-color: #88c0d0;">
<option value="OR">OU</option>
<option value="AND">ET</option>
</select>
<div style="font-size: 9px; color: #d8dee9; text-align: center; opacity: 0.7;">(Orbital) [?] (Sol)</div>
</div>
<!-- COLONNE SOL -->
<div style="flex: 1; display: flex; flex-direction: column; gap: 15px; padding-left: 15px; border-left: 1px dashed #334155;">
<div style="font-size: 11px; color: #88c0d0; font-weight: bold; text-align: center; border-bottom: 1px solid #334155; padding-bottom: 5px; margin-bottom: 5px;">AU SOL</div>
<div class="form-group" style="margin-bottom: 0;">
<label style="font-size: 10px;">Nombre de factions</label>
<div style="display: flex; gap: 5px;">
<select name="terrestrial_count_op" id="rule_terr_op" style="width: 70px;">
<option value="">-</option>
<option value="=">=</option>
<option value=">">></option>
<option value="<"><</option>
<option value=">=">>=</option>
<option value="<="><=</option>
</select>
<input type="number" name="terrestrial_count_val" id="rule_terr_val" placeholder="0">
</div>
</div>
<div class="form-group" style="margin-bottom: 0;">
<label style="font-size: 10px;">Filtre Dominance</label>
<div class="ms-container" id="ms_terr">
<div class="ms-display" onclick="toggleMS('ms_terr_list')">Toutes / Peu importe</div>
<div class="ms-dropdown" id="ms_terr_list">
<label class="ms-item"><input type="checkbox" value="none" onchange="updateMSLabel('ms_terr')"> Aucune (Vide)</label>
<?php foreach($factions_list as $f): if($f["name"] !== 'Aucune'): ?>
<label class="ms-item"><input type="checkbox" value="<?php echo $f['id']; ?>" name="terrestrial_dominance[]" onchange="updateMSLabel('ms_terr')"> <?php echo htmlspecialchars($f["name"]); ?></label>
<?php endif; endforeach; ?>
</div>
</div>
</div>
</div>
</div>
<div style="display: flex; align-items: center; gap: 10px; padding-top: 15px; margin-top: 15px; border-top: 1px solid #334155;">
<input type="checkbox" name="is_empty_case" id="rule_empty" style="width: auto;">
<label for="rule_empty" style="margin-bottom: 0; color: #ebcb8b;">Cas "CASE VIDE" (Aucune faction nulle part)</label>
</div>
</div>
<button type="submit" class="btn btn-add">ENREGISTRER LA RÈGLE</button>
<button type="button" class="btn" style="background: #4c566a; color: #fff;" onclick="resetRuleForm()">ANNULER</button>
</form>
</div>
<table>
<thead><tr><th>Profile</th><th>Priorité</th><th>Nom / Condition</th><th>Statut</th><th>Actions</th></tr></thead>
<tbody>
<?php foreach ($status_rules_list as $r): ?>
<tr>
<td><span style="background: #3b4252; padding: 2px 6px; border-radius: 4px; font-size: 10px;"><?php echo htmlspecialchars($r['profile_name'] ?: 'Standard'); ?></span></td>
<td><code><?php echo $r['priority']; ?></code></td>
<td>
<strong><?php echo htmlspecialchars($r["name"]); ?></strong><br>
<small style="color: #8c92a3; font-size: 10px;">
<?php
$orb_conds = [];
if($r['orbital_count_op']) $orb_conds[] = "Factions " . $r['orbital_count_op'] . " " . $r['orbital_count_val'];
if($r['orbital_dominance']) $orb_conds[] = "IN (" . $r['orbital_dominance'] . ")";
$terr_conds = [];
if($r['terrestrial_count_op']) $terr_conds[] = "Factions " . $r['terrestrial_count_op'] . " " . $r['terrestrial_count_val'];
if($r['terrestrial_dominance']) $terr_conds[] = "IN (" . $r['terrestrial_dominance'] . ")";
$final_parts = [];
if ($r['is_empty_case']) $final_parts[] = "Case Vide";
$orb_str = !empty($orb_conds) ? "Orbital (" . implode(' AND ', $orb_conds) . ")" : "";
$terr_str = !empty($terr_conds) ? "Ground (" . implode(' AND ', $terr_conds) . ")" : "";
if ($orb_str && $terr_str) {
$sep = ($r['combine_mode'] == 'AND') ? ' AND ' : ' OR ';
$final_parts[] = $orb_str . $sep . $terr_str;
} elseif ($orb_str) {
$final_parts[] = $orb_str;
} elseif ($terr_str) {
$final_parts[] = $terr_str;
}
echo !empty($final_parts) ? implode(' AND ', $final_parts) : '<em>Toujours vrai</em>';
?>
</small>
</td>
<td><span style="color: <?php echo str_replace(';blink','', $statuses_list[array_search($r['status_id'], array_column($statuses_list, 'id'))]['color'] ?? '#fff'); ?>; font-weight: bold;"><i class="fa-solid fa-circle" style="font-size: 8px;"></i> <?php echo htmlspecialchars($r['status_name']); ?></span></td>
<td>
<button class="btn btn-edit" onclick='editRule(<?php echo json_encode($r, JSON_HEX_APOS); ?>)'>Modifier</button>
<a href="?tab=statuses&delete_status_rule=<?php echo $r['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer cette règle ?')">Supprimer</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<?php elseif ($tab === 'settlement_types'): ?>
<h3 style="color: #88c0d0;">Lieux et points dintérêt</h3>
<div class="form-card">
<h4>Ajouter / Modifier un Lieu et point dintérêt</h4>
<form method="POST" id="settlementTypeForm">
<input type="hidden" name="action" value="upsert_settlement_type">
<input type="hidden" name="id" id="set_t_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="set_t_name" required placeholder="Ex: Ville, Avant-poste...">
</div>
<div class="form-group" style="flex: 1;">
<label>Slug</label>
<input type="text" name="slug" id="set_t_slug" required placeholder="Ex: ville, avant_poste...">
</div>
</div>
<div class="form-group">
<label>Description</label>
<textarea name="description" id="set_t_desc" rows="2"></textarea>
</div>
<button type="submit" class="btn btn-add">ENREGISTRER</button>
<button type="button" class="btn" style="background: #4c566a; color: #fff;" onclick="resetSettlementTypeForm()">ANNULER</button>
</form>
</div>
<table>
<thead><tr><th>Nom</th><th>Slug</th><th>Description</th><th>Actions</th></tr></thead>
<tbody>
<?php foreach ($settlement_types_list as $st): ?>
<tr>
<td><strong><?php echo htmlspecialchars($st["name"]); ?></strong></td>
<td><code><?php echo htmlspecialchars($st['slug']); ?></code></td>
<td><small><?php echo htmlspecialchars($st['description']); ?></small></td>
<td>
<button class="btn btn-edit" onclick='editSettlementType(<?php echo json_encode($st, JSON_HEX_APOS); ?>)'>Modifier</button>
<a href="?tab=settlement_types&delete_settlement_type=<?php echo $st['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer ce type ?')">Supprimer</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php elseif ($tab === 'factions'): ?>
<h3 style="color: #88c0d0;">Gestion des Factions</h3>
<div class="form-card">
<h4>Ajouter / Modifier une Faction</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 de la Faction</label>
<input type="text" name="name" id="fac_name" required placeholder="Ex: Fédération, Empire...">
</div>
<div class="form-group" style="flex: 1;">
<label>Slug</label>
<input type="text" name="slug" id="fac_slug" required placeholder="Ex: federation, empire...">
</div>
<div class="form-group" style="flex: 1;">
<label>Couleur</label>
<div class="color-group">
<input type="color" id="fac_color_picker" class="color-picker-input" oninput="document.getElementById('fac_color').value = this.value">
<input type="text" name="color" id="fac_color" required placeholder="#808080" oninput="document.getElementById('fac_color_picker').value = this.value">
</div>
</div>
<div class="form-group" style="flex: 1;">
<label>Icône (FontAwesome)</label>
<input type="text" name="fa_icon" id="fac_fa_icon" placeholder="Ex: fa-users">
</div>
<div class="form-group" style="flex: 1;">
<label>PNG (Prioritaire)</label>
<input type="file" name="image" accept="image/png">
</div>
</div>
<div class="form-group">
<label style="font-size: 12px; color: #8c92a3;">Alliances (Réciprocité automatique)</label>
<div style="background: #0f172a; border: 1px solid #334155; padding: 10px; max-height: 150px; overflow-y: auto; display: flex; flex-wrap: wrap; gap: 10px; margin-top: 5px;">
<?php foreach ($factions_list as $potential_ally): ?>
<label class="alliance-label" style="font-size: 11px; display: flex; align-items: center; gap: 5px; cursor: pointer;" data-id="<?php echo $potential_ally['id']; ?>">
<input type="checkbox" name="alliances[]" value="<?php echo $potential_ally['id']; ?>" class="alliance-checkbox" data-id="<?php echo $potential_ally['id']; ?>">
<span style="padding: 2px 8px; border-radius: 4px; background: #334155; color: #fff;">
<?php echo htmlspecialchars($potential_ally["name"]); ?>
</span>
</label>
<?php endforeach; ?>
</div>
</div>
<button type="submit" class="btn btn-add">ENREGISTRER LA FACTION</button>
<button type="button" class="btn" style="background: #4c566a; color: #fff;" onclick="resetFactionForm()">ANNULER</button>
</form>
</div>
<table>
<thead><tr><th>Couleur</th><th>Visuel</th><th>Nom</th><th>Slug</th><th>Alliances</th><th>Actions</th></tr></thead>
<tbody>
<?php foreach ($factions_list as $f): ?>
<tr>
<td><div style="width: 25px; height: 25px; border-radius: 50%; background: <?php echo htmlspecialchars($f['color'] ?? '#808080'); ?>; border: 1px solid #334155;"></div></td>
<td style="text-align: center;">
<?php if (!empty($f["image_url"])): ?>
<img src="<?php echo htmlspecialchars($f["image_url"]); ?>?v=<?php echo time(); ?>" style="max-width: 40px; max-height: 40px;">
<?php elseif (!empty($f['fa_icon'])): ?>
<i class="fa-solid <?php echo htmlspecialchars($f['fa_icon']); ?> fa-lg" style="color: <?php echo htmlspecialchars($f['color'] ?? '#fff'); ?>;"></i>
<?php else: ?>
<i class="fa-solid fa-flag fa-lg" style="color: <?php echo htmlspecialchars($f['color'] ?? '#4c566a'); ?>;"></i>
<?php endif; ?>
</td>
<td><strong><?php echo htmlspecialchars($f["name"]); ?></strong></td>
<td><code><?php echo htmlspecialchars($f['slug']); ?></code></td>
<td>
<?php
$stmt = $db->prepare("SELECT f.name FROM factions f JOIN faction_alliances fa ON (f.id = fa.faction_id_1 OR f.id = fa.faction_id_2) WHERE (fa.faction_id_1 = ? OR fa.faction_id_2 = ?) AND f.id != ?");
$stmt->execute([$f['id'], $f['id'], $f['id']]);
$allies = $stmt->fetchAll(PDO::FETCH_COLUMN);
if(empty($allies)) echo '<span style="color: #4c566a;">Aucune</span>';
foreach($allies as $ally) echo '<span class="modifier-tag tag-bonus" style="font-size: 9px;">' . htmlspecialchars($ally) . '</span>';
?>
</td>
<td>
<button class="btn btn-edit" onclick='editFaction(<?php echo json_encode($f, JSON_HEX_APOS); ?>)'>Modifier</button>
<a href="?tab=factions&delete_faction=<?php echo $f['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer cette faction ?')">Supprimer</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php elseif ($tab === 'resources'): ?>
<h3 style="color: #88c0d0;">Gestion des Ressources</h3>
<div class="form-card">
<h4>Ajouter / Modifier une Ressource</h4>
<form method="POST" id="resourceForm" 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 de la Ressource</label>
<input type="text" name="name" id="res_name" required placeholder="Ex: Crédits">
</div>
<div class="form-group" style="flex: 1;">
<label>Slug</label>
<input type="text" name="slug" id="res_slug" required placeholder="Ex: credits">
</div>
<div class="form-group" style="flex: 1;">
<label>Icône (FontAwesome)</label>
<input type="text" name="icon" id="res_icon" placeholder="Ex: fa-coins">
</div>
<div class="form-group" style="flex: 1;">
<label>Image (PNG/JPG)</label>
<input type="file" name="image" accept="image/*">
</div>
</div>
<div style="display: flex; gap: 20px; align-items: center;">
<div class="form-group" style="flex: 2;">
<label>Description</label>
<textarea name="description" id="res_desc" rows="1"></textarea>
</div>
<div class="form-group" style="flex: 1;">
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer;">
<input type="checkbox" name="show_in_header" id="res_show_header" value="1" style="width: auto;"> Afficher dans le header global
</label>
</div>
</div>
<button type="submit" class="btn btn-add">ENREGISTRER</button>
<button type="button" class="btn" style="background: #4c566a; color: #fff;" onclick="resetResourceForm()">ANNULER</button>
</form>
</div>
<table>
<thead><tr><th>Visuel</th><th>Header</th><th>Nom</th><th>Slug</th><th>Actions</th></tr></thead>
<tbody>
<?php foreach ($resources_list as $r): ?>
<tr>
<td style="text-align: center;">
<?php if (!empty($r["image_url"])): ?>
<img src="<?php echo htmlspecialchars($r["image_url"]); ?>?v=<?php echo time(); ?>" style="max-width: 30px; max-height: 30px;">
<?php elseif (!empty($r['icon'])): ?>
<i class="fa-solid <?php echo htmlspecialchars($r['icon']); ?> fa-lg"></i>
<?php endif; ?>
</td>
<td style="text-align: center;">
<?php if ($r['show_in_header']): ?>
<i class="fa-solid fa-check" style="color: #a3be8c;"></i>
<?php endif; ?>
</td>
<td><strong><?php echo htmlspecialchars($r["name"]); ?></strong></td>
<td><code><?php echo htmlspecialchars($r['slug']); ?></code></td>
<td>
<button class="btn btn-edit" onclick='editResource(<?php echo json_encode($r, JSON_HEX_APOS); ?>)'>Modifier</button>
<a href="?tab=resources&delete_resource=<?php echo $r['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer cette ressource ?')">Supprimer</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php elseif ($tab === 'lootboxes'): ?>
<h3 style="color: #88c0d0;">Système de Lootboxes</h3>
<div class="form-card">
<h4>Ajouter / Modifier une Lootbox</h4>
<form method="POST" id="lootboxForm">
<input type="hidden" name="action" value="upsert_lootbox">
<input type="hidden" name="id" id="lb_id" value="0">
<div style="display: flex; gap: 20px;">
<div class="form-group" style="flex: 1;">
<label>Nom de la Box</label>
<input type="text" name="name" id="lb_name" required>
</div>
<div class="form-group" style="flex: 1;">
<label>Slug</label>
<input type="text" name="slug" id="lb_slug" required>
</div>
</div>
<div class="form-group">
<label>Description</label>
<textarea name="description" id="lb_desc" rows="2"></textarea>
</div>
<div style="display: flex; gap: 30px; margin-top: 20px;">
<!-- Configuration des Tirages -->
<div style="flex: 1;">
<h5 style="color: #ebcb8b;">Nombre de tirages (Probabilités)</h5>
<div id="rollsContainer">
<div class="sub-form-header">
<div style="flex: 1;">Nb Tirages</div>
<div style="flex: 1;">Probabilité (%)</div>
<div class="btn-del-row-placeholder"></div>
</div>
</div>
<button type="button" class="btn" style="background: #4c566a; color: #fff; margin-top: 5px;" onclick="addRollRow()">+ AJOUTER NB TIRAGE</button>
</div>
<!-- Configuration du Loot -->
<div style="flex: 2;">
<h5 style="color: #88c0d0;">Objets possibles dans la box</h5>
<div id="itemsContainer">
<div class="sub-form-header">
<div style="flex: 1;">Ressource (Slug)</div>
<div style="flex: 1;">Probabilité (%)</div>
<div style="flex: 1;">Quantité (Min/Max)</div>
<div style="flex: 1;">Garanti ?</div>
<div class="btn-del-row-placeholder"></div>
</div>
</div>
<button type="button" class="btn" style="background: #4c566a; color: #fff; margin-top: 5px;" onclick="addItemRow()">+ AJOUTER OBJET AU LOOT</button>
</div>
</div>
<div style="margin-top: 25px;">
<button type="submit" class="btn btn-add">ENREGISTRER LA LOOTBOX</button>
<button type="button" class="btn" style="background: #4c566a; color: #fff;" onclick="resetLootboxForm()">ANNULER</button>
</div>
</form>
</div>
<table>
<thead><tr><th>Nom</th><th>Slug</th><th>Tirages Possibles</th><th>Nombre d'items</th><th>Actions</th></tr></thead>
<tbody>
<?php foreach ($lootboxes_list as $lb): ?>
<tr>
<td><strong><?php echo htmlspecialchars($lb["name"]); ?></strong></td>
<td><code><?php echo htmlspecialchars($lb['slug']); ?></code></td>
<td style="font-size: 11px;">
<?php foreach($lb['rolls'] as $r) echo $r['roll_count'] . " (" . $r['probability'] . "%) "; ?>
</td>
<td><?php echo count($lb['items']); ?></td>
<td>
<button class="btn btn-edit" onclick='editLootbox(<?php echo json_encode($lb, JSON_HEX_APOS); ?>)'>Modifier</button>
<a href="?tab=lootboxes&delete_lootbox=<?php echo $lb['id']; ?>" class="btn btn-del" onclick="return confirm('Supprimer cette lootbox ?')">Supprimer</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php elseif ($tab === 'project_logs'): ?>
<h3 style="color: #88c0d0;">Journal de Bord du Projet</h3>
<div class="form-card">
<h4>Nouvelle Entrée</h4>
<form method="POST" id="logForm">
<input type="hidden" name="action" value="upsert_project_log">
<input type="hidden" name="id" id="log_id" value="0">
<div style="display: flex; gap: 20px;">
<div class="form-group" style="flex: 1;">
<label>Version</label>
<input type="text" name="version" id="log_version" required placeholder="Ex: 0.1.0">
</div>
<div class="form-group" style="flex: 3;">
<label>Titre</label>
<input type="text" name="title" id="log_title" required placeholder="Résumé des changements">
</div>
</div>
<div class="form-group">
<label>Contenu (Détails)</label>
<textarea name="content" id="log_content" rows="4"></textarea>
</div>
<button type="submit" class="btn btn-add">PUBLIER</button>
<button type="button" class="btn" style="background: #4c566a; color: #fff;" onclick="resetLogForm()">ANNULER</button>
</form>
</div>
<?php foreach ($project_logs_list as $log): ?>
<div style="background: #0a0f1d; border: 1px solid #2d3545; padding: 20px; margin-bottom: 20px; position: relative;">
<div style="display: flex; justify-content: space-between; align-items: flex-start;">
<div>
<span style="background: #ebcb8b; color: #000; padding: 2px 8px; border-radius: 4px; font-weight: bold; font-size: 12px;"><?php echo htmlspecialchars($log['version']); ?></span>
<h4 style="display: inline; margin-left: 10px; color: #88c0d0;"><?php echo htmlspecialchars($log['title']); ?></h4>
</div>
<div style="font-size: 12px; color: #4c566a;">
<i class="fa-solid fa-calendar-day"></i> <?php echo date('d/m/Y H:i', strtotime($log['created_at'])); ?>
</div>
</div>
<div style="margin-top: 15px; font-size: 14px; line-height: 1.6; color: #d8dee9; white-space: pre-line;">
<?php echo htmlspecialchars($log['content']); ?>
</div>
<div style="margin-top: 15px; border-top: 1px solid #1a202c; padding-top: 10px; text-align: right;">
<button class="btn btn-edit" style="padding: 4px 10px; font-size: 10px;" onclick='editLog(<?php echo json_encode($log, JSON_HEX_APOS); ?>)'>Modifier</button>
<a href="?tab=project_logs&delete_project_log=<?php echo $log['id']; ?>" class="btn btn-del" style="padding: 4px 10px; font-size: 10px;" onclick="return confirm('Supprimer cette entrée ?')">Supprimer</a>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<script>
function syncSlug(v,t){const e=document.getElementById(t);if(e){e.value=v.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g,'').replace(/[^a-z0-9]+/g,'-').replace(/^-+|-+$/g,'');} if(typeof checkUnitFormValidity==='function')checkUnitFormValidity();}
function checkUnitFormValidity(){const n=document.getElementById('unit_name')?.value,s=document.getElementById('unit_slug')?.value,g=document.getElementById('unit_grid_data')?.value,b=document.getElementById('unit_submit_btn');if(b){const v=n&&s&&g&&g!=='[]'&&g!=='';b.disabled=!v;b.style.opacity=v?'1':'0.5';}}
function editUnit(data) {
resetUnitForm();
document.getElementById('unit_id').value = data.id;
document.getElementById('unit_name').value = data.name;
document.getElementById('unit_slug').value = data.slug;
document.getElementById('unit_faction_id').value = data.faction_id || "";
document.getElementById('unit_points_per_hit').value = data.points_per_hit;
document.getElementById('unit_can_be_destroyed').checked = data.can_be_destroyed == 1;
document.getElementById('unit_can_be_captured').checked = data.can_be_captured == 1;
document.getElementById('unit_bonus_destruction').value = data.bonus_destruction;
document.getElementById('unit_bonus_capture').value = data.bonus_capture;
document.getElementById('unit_grid_data').value = data.grid_data;
setUnitGridFromData(data.grid_data);
if (data.rewards) {
data.rewards.forEach(r => {
addUnitRewardRow(r.action_type, r.resource_id, r.amount);
});
}
if(typeof checkUnitFormValidity==='function')checkUnitFormValidity();
window.scrollTo(0,0);
}
function resetUnitForm() {
document.getElementById('unitForm').reset();
document.getElementById('unit_id').value = 0;
document.getElementById('unit_grid_data').value = "";
document.getElementById('unitRewardsContainer').innerHTML = `
<div class="sub-form-header">
<div style="flex: 1;">Action</div>
<div style="flex: 1;">Ressource</div>
<div style="flex: 1;">Quantité</div>
<div class="btn-del-row-placeholder"></div>
</div>`;
const cells = document.querySelectorAll('.unit-cell');
cells.forEach(c => c.classList.remove('active'));
if(typeof checkUnitFormValidity==='function')checkUnitFormValidity();
}
function addUnitRewardRow(action = 'destroy', resId = '', amount = 0) {
const container = document.getElementById('unitRewardsContainer');
const row = document.createElement('div');
row.className = 'sub-form-row';
let resOptions = '';
<?php foreach ($resources_list as $res): ?>
resOptions += '<option value="<?php echo $res['id']; ?>" ' + (resId == <?php echo $res['id']; ?> ? 'selected' : '') + '><?php echo addslashes($res['name']); ?></option>';
<?php endforeach; ?>
row.innerHTML = `
<select name="reward_action[]" style="flex: 1;">
<option value="destroy" ${action === 'destroy' ? 'selected' : ''}>Destruction</option>
<option value="capture" ${action === 'capture' ? 'selected' : ''}>Capture</option>
</select>
<select name="reward_resource_id[]" style="flex: 1;">
<option value="">-- Ressource --</option>
${resOptions}
</select>
<input type="number" name="reward_amount[]" value="${amount}" style="flex: 1;" placeholder="Qté">
<div class="btn-del-row" onclick="this.parentElement.remove()">×</div>
`;
container.appendChild(row);
}
function createUnitGrid() {
const grid = document.getElementById('unitGrid');
if (!grid) return;
for (let i = 0; i < 36; i++) {
const cell = document.createElement('div');
cell.className = 'unit-cell';
cell.dataset.index = i;
cell.onclick = function() {
this.classList.toggle('active');
updateUnitGridData();
};
grid.appendChild(cell);
}
}
function updateUnitGridData() {
const activeCells = [];
document.querySelectorAll('.unit-cell.active').forEach(c => {
activeCells.push(parseInt(c.dataset.index));
});
document.getElementById("unit_grid_data").value = JSON.stringify(activeCells);
if(typeof checkUnitFormValidity==='function')checkUnitFormValidity();
}
function setUnitGridFromData(json) {
const cells = document.querySelectorAll('.unit-cell');
cells.forEach(c => c.classList.remove('active'));
try {
const activeIndices = JSON.parse(json);
activeIndices.forEach(idx => {
const cell = document.querySelector(`.unit-cell[data-index="${idx}"]`);
if (cell) cell.classList.add('active');
});
} catch(e) {}
}
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_icon').value = data.icon;
document.getElementById('obj_desc').value = data.description;
document.getElementById('obj_orbital_enabled').checked = (data.orbital_control_enabled == 1);
document.getElementById('obj_terrestrial_enabled').checked = (data.terrestrial_control_enabled == 1);
document.getElementById('obj_profile_id').value = data.status_profile_id || "";
// Reset checkboxes
document.querySelectorAll('.modifier-checkbox').forEach(cb => cb.checked = false);
if (data.modifier_ids) {
data.modifier_ids.forEach(mid => {
const cb = document.querySelector(`.modifier-checkbox[data-id="${mid}"]`);
if (cb) cb.checked = true;
});
}
window.scrollTo(0, 0);
}
function resetObjectForm() {
document.getElementById('objectForm').reset();
document.getElementById('obj_id').value = 0;
document.querySelectorAll('.modifier-checkbox').forEach(cb => cb.checked = false);
}
function editModifier(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_desc').value = data.description;
window.scrollTo(0, 0);
}
function resetModifierForm() {
document.getElementById('modifierForm').reset();
document.getElementById('mod_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;
let color = data.color;
let isBlinking = false;
if (color.indexOf(';blink') !== -1) {
isBlinking = true;
color = color.replace(';blink', '');
}
document.getElementById('st_color').value = color;
document.getElementById('st_color_picker').value = color;
document.getElementById('st_is_blinking').checked = isBlinking;
document.getElementById('st_desc').value = data.description;
window.scrollTo(0, 0);
}
function resetStatusForm() {
document.getElementById('statusForm').reset();
document.getElementById('st_id').value = 0;
}
function editProfile(data) {
document.getElementById('prof_id').value = data.id;
document.getElementById('prof_name').value = data.name;
document.getElementById('prof_slug').value = data.slug;
window.scrollTo(0, 0);
}
function resetProfileForm() {
document.getElementById('profileForm').reset();
document.getElementById('prof_id').value = 0;
}
function editRule(data) {
document.getElementById('rule_id').value = data.id;
document.getElementById('rule_name').value = data.name;
document.getElementById('rule_status_id').value = data.status_id;
document.getElementById('rule_profile_id').value = data.profile_id;
document.getElementById('rule_priority').value = data.priority;
document.getElementById('rule_orb_op').value = data.orbital_count_op || "";
document.getElementById('rule_orb_val').value = data.orbital_count_val !== null ? data.orbital_count_val : "";
document.getElementById('rule_terr_op').value = data.terrestrial_count_op || "";
document.getElementById('rule_terr_val').value = data.terrestrial_count_val !== null ? data.terrestrial_count_val : "";
document.getElementById('rule_combine').value = data.combine_mode || "OR";
document.getElementById('rule_empty').checked = data.is_empty_case == 1;
// Reset MS lists
resetMS('ms_orb');
resetMS('ms_terr');
if (data.orbital_dominance) {
const ids = data.orbital_dominance.split(',');
ids.forEach(id => {
const cb = document.querySelector(`#ms_orb_list input[value="${id}"]`);
if (cb) cb.checked = true;
});
updateMSLabel('ms_orb');
}
if (data.terrestrial_dominance) {
const ids = data.terrestrial_dominance.split(',');
ids.forEach(id => {
const cb = document.querySelector(`#ms_terr_list input[value="${id}"]`);
if (cb) cb.checked = true;
});
updateMSLabel('ms_terr');
}
window.scrollTo(0, 0);
}
function resetRuleForm() {
document.getElementById('ruleForm').reset();
document.getElementById('rule_id').value = 0;
resetMS('ms_orb');
resetMS('ms_terr');
}
function toggleMS(id) {
const dropdown = document.getElementById(id);
dropdown.style.display = dropdown.style.display === 'block' ? 'none' : 'block';
}
function resetMS(containerId) {
document.querySelectorAll(`#${containerId}_list input`).forEach(cb => cb.checked = false);
updateMSLabel(containerId);
}
function updateMSLabel(containerId) {
const container = document.getElementById(containerId);
const checkboxes = container.querySelectorAll('.ms-dropdown input:checked');
const display = container.querySelector('.ms-display');
if (checkboxes.length === 0) {
display.innerText = "Toutes / Peu importe";
} else if (checkboxes.length === 1) {
const text = checkboxes[0].parentElement.innerText.trim();
display.innerText = text;
} else {
display.innerText = checkboxes.length + " sélectionnées";
}
}
// Close MS dropdowns when clicking outside
document.addEventListener('click', function(e) {
if (!e.target.closest('.ms-container')) {
document.querySelectorAll('.ms-dropdown').forEach(d => d.style.display = 'none');
}
});
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_color').value = data.color || "#808080";
document.getElementById('fac_color_picker').value = data.color || "#808080";
document.getElementById('fac_fa_icon').value = data.fa_icon || "";
document.querySelectorAll('.alliance-checkbox').forEach(cb => cb.checked = false);
if (data.alliance_ids) {
data.alliance_ids.forEach(id => {
const cb = document.querySelector(`.alliance-checkbox[data-id="${id}"]`);
if (cb) cb.checked = true;
});
}
window.scrollTo(0, 0);
}
function resetFactionForm() {
document.getElementById('factionForm').reset();
document.getElementById('fac_id').value = 0;
document.querySelectorAll('.alliance-checkbox').forEach(cb => cb.checked = false);
}
function editLevel(data) {
document.getElementById('level_id').value = data.id;
document.getElementById('level_name').value = data.name;
document.getElementById('level_slug').value = data.slug;
document.getElementById('level_resource_id').value = data.resource_id;
document.getElementById('level_required_quantity').value = data.required_quantity;
window.scrollTo(0, 0);
}
function resetLevelForm() {
document.getElementById('levelForm').reset();
document.getElementById('level_id').value = 0;
}
function editRank(data) {
document.getElementById('rank_id').value = data.id;
document.getElementById('rank_name').value = data.name;
document.getElementById('rank_slug').value = data.slug;
document.getElementById('rank_type').value = data.user_type;
document.getElementById('rank_min').value = data.min_level;
document.getElementById('rank_max').value = data.max_level;
updateRankFields();
window.scrollTo(0,0);
}
function resetRankForm() {
document.getElementById('rankForm').reset();
document.getElementById('rank_id').value = 0;
updateRankFields();
}
function updateRankFields() {
const rankTypeEl = document.getElementById('rank_type'); if (!rankTypeEl) return; const type = rankTypeEl.value;
const lvlGrp = document.getElementById('rank_min').parentElement.parentElement;
if (type === 'utilisateur') {
lvlGrp.style.display = 'flex';
} else {
lvlGrp.style.display = 'none';
}
}
function editResource(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_desc').value = data.description;
document.getElementById('res_show_header').checked = data.show_in_header == 1;
window.scrollTo(0, 0);
}
function resetResourceForm() {
document.getElementById('resourceForm').reset();
document.getElementById('res_id').value = 0;
}
function editLootbox(data) {
document.getElementById('lb_id').value = data.id;
document.getElementById('lb_name').value = data.name;
document.getElementById('lb_slug').value = data.slug;
document.getElementById('lb_desc').value = data.description;
document.getElementById('rollsContainer').innerHTML = `
<div class="sub-form-header">
<div style="flex: 1;">Nb Tirages</div>
<div style="flex: 1;">Probabilité (%)</div>
<div class="btn-del-row-placeholder"></div>
</div>`;
if (data.rolls) {
data.rolls.forEach(r => addRollRow(r.roll_count, r.probability));
}
document.getElementById('itemsContainer').innerHTML = `
<div class="sub-form-header">
<div style="flex: 1;">Ressource (Slug)</div>
<div style="flex: 1;">Probabilité (%)</div>
<div style="flex: 1;">Quantité (Min/Max)</div>
<div style="flex: 1;">Garanti ?</div>
<div class="btn-del-row-placeholder"></div>
</div>`;
if (data.items) {
data.items.forEach(i => addItemRow(i.resource_slug, i.probability, i.quantity_min, i.quantity_max, i.is_guaranteed));
}
window.scrollTo(0, 0);
}
function resetLootboxForm() {
document.getElementById('lootboxForm').reset();
document.getElementById('lb_id').value = 0;
document.getElementById('rollsContainer').innerHTML = '';
document.getElementById('itemsContainer').innerHTML = '';
}
function addRollRow(count = 1, prob = 0) {
const row = document.createElement('div');
row.className = 'sub-form-row';
row.innerHTML = `
<input type="number" name="rolls_count[]" value="${count}" style="flex: 1;">
<input type="number" step="0.01" name="rolls_prob[]" value="${prob}" style="flex: 1;">
<div class="btn-del-row" onclick="this.parentElement.remove()">×</div>
`;
document.getElementById('rollsContainer').appendChild(row);
}
function addItemRow(slug = '', prob = 0, min = 1, max = 1, guaranteed = 0) {
const row = document.createElement('div');
row.className = 'sub-form-row';
let options = '<option value="">(Aléatoire)</option>';
const resList = <?php echo json_encode($resources_list); ?>;
resList.forEach(r => {
options += `<option value="${r.slug}" ${r.slug === slug ? 'selected' : ''}>${r.name}</option>`;
});
row.innerHTML = `
<select name="item_slug[]" style="flex: 1.5;">${options}</select>
<input type="number" step="0.01" name="item_prob[]" value="${prob}" style="flex: 1;">
<div style="flex: 1.5; display: flex; gap: 2px;">
<input type="number" name="item_qmin[]" value="${min}" style="width: 50%;">
<input type="number" name="item_qmax[]" value="${max}" style="width: 50%;">
</div>
<div style="flex: 1; text-align: center;">
<input type="checkbox" name="item_is_guaranteed[]" value="1" ${guaranteed == 1 ? 'checked' : ''} onchange="this.previousElementSibling.value = this.checked ? 1 : 0">
<input type="hidden" name="item_is_guaranteed_val[]" value="${guaranteed}">
</div>
<div class="btn-del-row" onclick="this.parentElement.remove()">×</div>
`;
document.getElementById('itemsContainer').appendChild(row);
}
function editLog(data) {
document.getElementById('log_id').value = data.id;
document.getElementById('log_version').value = data.version;
document.getElementById('log_title').value = data.title;
document.getElementById('log_content').value = data.content;
window.scrollTo(0, 0);
}
function resetLogForm() {
document.getElementById('logForm').reset();
document.getElementById('log_id').value = 0;
}
function editTitle(data) {
document.getElementById('title_id').value = data.id;
document.getElementById('title_name').value = data.name;
document.getElementById('title_slug').value = data.slug;
document.getElementById('title_allowed_type').value = data.allowed_user_type;
document.getElementById('title_req_level').value = data.required_level;
document.getElementById('title_color').value = data.color || "#ffffff";
window.scrollTo(0,0);
}
function resetTitleForm() {
document.getElementById('titleForm').reset();
document.getElementById('title_id').value = 0;
}
function editBadge(data) {
document.getElementById('badge_id').value = data.id;
document.getElementById('badge_name').value = data.name;
document.getElementById('badge_slug').value = data.slug;
document.getElementById('badge_allowed_type').value = data.allowed_user_type;
document.getElementById('badge_req_level').value = data.required_level;
if (data.image_url) {
document.getElementById('badge_preview').src = data.image_url;
document.getElementById('badge_preview_container').style.display = 'block';
} else {
document.getElementById('badge_preview_container').style.display = 'none';
}
window.scrollTo(0,0);
}
function resetBadgeForm() {
document.getElementById('badgeForm').reset();
document.getElementById('badge_id').value = 0;
document.getElementById('badge_preview_container').style.display = 'none';
}
document.addEventListener("DOMContentLoaded", function() {
updateRankFields();
if (document.getElementById('tab') === 'units' || <?php echo $tab === 'units' ? 'true' : 'false'; ?>) {
createUnitGrid();
}
});
</script>
</body>
</html>