Autosave: 20260408-162933
This commit is contained in:
parent
f8ced7fba3
commit
761c0bd6af
@ -524,6 +524,8 @@ $current_session_user = isset($_SESSION['user']) ? (string) $_SESSION['user'] :
|
||||
<a href="scmanufactures.php">Manufactures</a>
|
||||
<a href="scvaisseaux.php">Vaisseaux</a>
|
||||
<a href="scpreset.php">Presets Vaisseau</a>
|
||||
<a href="scwebhook.php">SC Webhook</a>
|
||||
<a href="scnotification.php">SC Notification</a>
|
||||
</nav>
|
||||
|
||||
<?php if ($flash_message !== ''): ?>
|
||||
|
||||
BIN
assets/pasted-20260408-155112-5f68f53a.png
Normal file
BIN
assets/pasted-20260408-155112-5f68f53a.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
243
db/scdiscord.php
Normal file
243
db/scdiscord.php
Normal file
@ -0,0 +1,243 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/config.php';
|
||||
|
||||
function scdiscord_bootstrap(): void
|
||||
{
|
||||
static $bootstrapped = false;
|
||||
|
||||
if ($bootstrapped) {
|
||||
return;
|
||||
}
|
||||
|
||||
$db = db();
|
||||
|
||||
$db->exec(
|
||||
"CREATE TABLE IF NOT EXISTS tbl_scwebhooks (
|
||||
cl_scwebhook_id INT(11) NOT NULL AUTO_INCREMENT,
|
||||
cl_scwebhook_name VARCHAR(255) NOT NULL,
|
||||
cl_scwebhook_url TEXT NOT NULL,
|
||||
cl_scwebhook_is_forum TINYINT(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (cl_scwebhook_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci"
|
||||
);
|
||||
|
||||
$db->exec(
|
||||
"CREATE TABLE IF NOT EXISTS tbl_scbanners (
|
||||
cl_scbanner_id INT(11) NOT NULL AUTO_INCREMENT,
|
||||
cl_scbanner_name VARCHAR(255) NOT NULL,
|
||||
cl_scbanner_url TEXT NOT NULL,
|
||||
cl_scbanner_border_color VARCHAR(20) NOT NULL DEFAULT '#ffae00',
|
||||
PRIMARY KEY (cl_scbanner_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci"
|
||||
);
|
||||
|
||||
$columns_stmt = $db->query("SHOW COLUMNS FROM tbl_scbanners LIKE 'cl_scbanner_border_color'");
|
||||
$has_border_color = (bool) $columns_stmt->fetch();
|
||||
if (!$has_border_color) {
|
||||
$db->exec("ALTER TABLE tbl_scbanners ADD COLUMN cl_scbanner_border_color VARCHAR(20) NOT NULL DEFAULT '#ffae00' AFTER cl_scbanner_url");
|
||||
}
|
||||
|
||||
$db->exec(
|
||||
"CREATE TABLE IF NOT EXISTS tbl_scnotifications (
|
||||
cl_scnotification_id INT(11) NOT NULL AUTO_INCREMENT,
|
||||
cl_scnotification_webhook_id INT(11) NOT NULL,
|
||||
cl_scnotification_banner_id INT(11) DEFAULT NULL,
|
||||
cl_scnotification_title VARCHAR(255) NOT NULL DEFAULT '',
|
||||
cl_scnotification_message TEXT NOT NULL,
|
||||
cl_scnotification_payload LONGTEXT NOT NULL,
|
||||
cl_scnotification_response LONGTEXT DEFAULT NULL,
|
||||
cl_scnotification_success TINYINT(1) NOT NULL DEFAULT 0,
|
||||
cl_scnotification_created_by VARCHAR(190) NOT NULL,
|
||||
cl_scnotification_created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (cl_scnotification_id),
|
||||
KEY idx_scnotification_webhook (cl_scnotification_webhook_id),
|
||||
KEY idx_scnotification_banner (cl_scnotification_banner_id),
|
||||
CONSTRAINT fk_scnotification_webhook FOREIGN KEY (cl_scnotification_webhook_id)
|
||||
REFERENCES tbl_scwebhooks (cl_scwebhook_id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE RESTRICT,
|
||||
CONSTRAINT fk_scnotification_banner FOREIGN KEY (cl_scnotification_banner_id)
|
||||
REFERENCES tbl_scbanners (cl_scbanner_id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci"
|
||||
);
|
||||
|
||||
$stmt_existing_red = $db->prepare('SELECT cl_scbanner_id FROM tbl_scbanners WHERE cl_scbanner_name = :name LIMIT 1');
|
||||
$stmt_existing_red->execute(['name' => 'Alerte Rouge']);
|
||||
$existing_red_banner = $stmt_existing_red->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($existing_red_banner) {
|
||||
$stmt_update_red = $db->prepare(
|
||||
'UPDATE tbl_scbanners
|
||||
SET cl_scbanner_border_color = CASE
|
||||
WHEN cl_scbanner_border_color IS NULL OR cl_scbanner_border_color = "" OR cl_scbanner_border_color = "#ffae00"
|
||||
THEN :border_color
|
||||
ELSE cl_scbanner_border_color
|
||||
END
|
||||
WHERE cl_scbanner_id = :id'
|
||||
);
|
||||
$stmt_update_red->execute([
|
||||
'border_color' => '#ff3b30',
|
||||
'id' => $existing_red_banner['cl_scbanner_id'],
|
||||
]);
|
||||
}
|
||||
|
||||
$bootstrapped = true;
|
||||
}
|
||||
|
||||
function scdiscord_mask_webhook_url(string $url): string
|
||||
{
|
||||
$trimmed = trim($url);
|
||||
if ($trimmed === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$length = strlen($trimmed);
|
||||
if ($length <= 24) {
|
||||
return str_repeat('•', max(8, $length));
|
||||
}
|
||||
|
||||
return substr($trimmed, 0, 32) . str_repeat('•', 18) . substr($trimmed, -10);
|
||||
}
|
||||
|
||||
function scdiscord_normalize_hex_color(string $color): string
|
||||
{
|
||||
$candidate = strtoupper(trim($color));
|
||||
if ($candidate === '') {
|
||||
return '#FFAE00';
|
||||
}
|
||||
|
||||
if ($candidate[0] !== '#') {
|
||||
$candidate = '#' . $candidate;
|
||||
}
|
||||
|
||||
if (!preg_match('/^#[0-9A-F]{6}$/', $candidate)) {
|
||||
return '#FFAE00';
|
||||
}
|
||||
|
||||
return $candidate;
|
||||
}
|
||||
|
||||
function scdiscord_hex_to_decimal(string $color): int
|
||||
{
|
||||
return hexdec(ltrim(scdiscord_normalize_hex_color($color), '#'));
|
||||
}
|
||||
|
||||
function scdiscord_build_mentions(bool $notify_here, bool $notify_everyone): array
|
||||
{
|
||||
$parts = [];
|
||||
|
||||
if ($notify_here) {
|
||||
$parts[] = '@here';
|
||||
}
|
||||
|
||||
if ($notify_everyone) {
|
||||
$parts[] = '@everyone';
|
||||
}
|
||||
|
||||
return $parts;
|
||||
}
|
||||
|
||||
function scdiscord_build_thread_name(string $title, string $location, string $start_date): string
|
||||
{
|
||||
$parts = [];
|
||||
|
||||
if ($title !== '') {
|
||||
$parts[] = $title;
|
||||
}
|
||||
|
||||
if ($location !== '') {
|
||||
$parts[] = $location;
|
||||
}
|
||||
|
||||
if ($start_date !== '') {
|
||||
$parts[] = $start_date;
|
||||
}
|
||||
|
||||
$thread_name = trim(implode(' • ', $parts));
|
||||
|
||||
if ($thread_name === '') {
|
||||
$thread_name = 'Notification Discord';
|
||||
}
|
||||
|
||||
return mb_substr($thread_name, 0, 100);
|
||||
}
|
||||
|
||||
function scdiscord_post_webhook(string $webhook_url, array $payload): array
|
||||
{
|
||||
$target_url = $webhook_url;
|
||||
$separator = (str_contains($target_url, '?')) ? '&' : '?';
|
||||
$target_url .= $separator . 'wait=true';
|
||||
|
||||
$json_payload = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
|
||||
if ($json_payload === false) {
|
||||
return [
|
||||
'success' => false,
|
||||
'http_code' => 0,
|
||||
'response' => 'Erreur d\'encodage JSON.',
|
||||
];
|
||||
}
|
||||
|
||||
if (function_exists('curl_init')) {
|
||||
$ch = curl_init($target_url);
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => $json_payload,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
'Content-Type: application/json',
|
||||
'Content-Length: ' . strlen($json_payload),
|
||||
],
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_TIMEOUT => 20,
|
||||
]);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$http_code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$curl_error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ($response === false) {
|
||||
return [
|
||||
'success' => false,
|
||||
'http_code' => $http_code,
|
||||
'response' => $curl_error !== '' ? $curl_error : 'Erreur CURL inconnue.',
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'success' => $http_code >= 200 && $http_code < 300,
|
||||
'http_code' => $http_code,
|
||||
'response' => $response,
|
||||
];
|
||||
}
|
||||
|
||||
$context = stream_context_create([
|
||||
'http' => [
|
||||
'method' => 'POST',
|
||||
'header' => "Content-Type: application/json\r\n",
|
||||
'content' => $json_payload,
|
||||
'timeout' => 20,
|
||||
'ignore_errors' => true,
|
||||
],
|
||||
]);
|
||||
|
||||
$response = @file_get_contents($target_url, false, $context);
|
||||
$http_code = 0;
|
||||
if (isset($http_response_header) && is_array($http_response_header)) {
|
||||
foreach ($http_response_header as $header_line) {
|
||||
if (preg_match('#^HTTP/\S+\s+(\d{3})#', $header_line, $matches)) {
|
||||
$http_code = (int) $matches[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'success' => $response !== false && $http_code >= 200 && $http_code < 300,
|
||||
'http_code' => $http_code,
|
||||
'response' => $response === false ? 'Erreur lors de la requête HTTP.' : $response,
|
||||
];
|
||||
}
|
||||
@ -406,6 +406,8 @@ if ($edit_id > 0) {
|
||||
<a href="scmanufactures.php">Manufactures</a>
|
||||
<a href="scvaisseaux.php">Vaisseaux</a>
|
||||
<a href="scpreset.php">Presets Vaisseau</a>
|
||||
<a href="scwebhook.php">SC Webhook</a>
|
||||
<a href="scnotification.php">SC Notification</a>
|
||||
</nav>
|
||||
|
||||
<?php if ($flash_message !== ''): ?>
|
||||
|
||||
@ -278,6 +278,8 @@ $current_session_user = $_SESSION['user'] ?? '';
|
||||
<a href="scmanufactures.php" class="active">Manufactures</a>
|
||||
<a href="scvaisseaux.php">Vaisseaux</a>
|
||||
<a href="scpreset.php">Presets Vaisseau</a>
|
||||
<a href="scwebhook.php">SC Webhook</a>
|
||||
<a href="scnotification.php">SC Notification</a>
|
||||
</nav>
|
||||
|
||||
<?php if ($flash_message !== ''): ?>
|
||||
|
||||
@ -335,6 +335,8 @@ $current_session_user = $_SESSION['user'] ?? '';
|
||||
<a href="scmanufactures.php">Manufactures</a>
|
||||
<a href="scvaisseaux.php">Vaisseaux</a>
|
||||
<a href="scpreset.php">Presets Vaisseau</a>
|
||||
<a href="scwebhook.php">SC Webhook</a>
|
||||
<a href="scnotification.php">SC Notification</a>
|
||||
</nav>
|
||||
|
||||
<?php if ($flash_message !== ''): ?>
|
||||
|
||||
969
scnotification.php
Normal file
969
scnotification.php
Normal file
@ -0,0 +1,969 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/db/auth.php';
|
||||
require_once __DIR__ . '/db/scdiscord.php';
|
||||
|
||||
auth_start_session();
|
||||
auth_bootstrap();
|
||||
scdiscord_bootstrap();
|
||||
|
||||
if (!auth_is_logged_in()) {
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$db = db();
|
||||
$csrf_token = auth_csrf_token();
|
||||
$flash = auth_flash_get();
|
||||
$flash_type = $flash['type'] ?? '';
|
||||
$flash_message = $flash['message'] ?? '';
|
||||
$current_session_user = $_SESSION['user'] ?? '';
|
||||
$current_session_role = $_SESSION['role'] ?? 'member';
|
||||
$role_label = ($current_session_role === 'admin') ? 'Administrateur' : 'Membre';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$submitted_csrf = (string) ($_POST['csrf_token'] ?? '');
|
||||
if (!auth_validate_csrf($submitted_csrf)) {
|
||||
auth_flash_set('error', 'Jeton CSRF invalide.');
|
||||
header('Location: scnotification.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$_SESSION['scnotification_old'] = $_POST;
|
||||
|
||||
$action = (string) ($_POST['action'] ?? '');
|
||||
if ($action === 'send_notification') {
|
||||
$cl_scnotification_webhook_id = (int) ($_POST['cl_scnotification_webhook_id'] ?? 0);
|
||||
$cl_scnotification_banner_id = (int) ($_POST['cl_scnotification_banner_id'] ?? 0);
|
||||
$use_custom_banner = isset($_POST['cl_scnotification_use_custom_banner']);
|
||||
$cl_scnotification_custom_banner_url = trim((string) ($_POST['cl_scnotification_custom_banner_url'] ?? ''));
|
||||
$notify_here = isset($_POST['cl_scnotification_notify_here']);
|
||||
$notify_everyone = isset($_POST['cl_scnotification_notify_everyone']);
|
||||
$cl_scnotification_title = trim((string) ($_POST['cl_scnotification_title'] ?? ''));
|
||||
$cl_scnotification_message = trim((string) ($_POST['cl_scnotification_message'] ?? ''));
|
||||
$show_footer = isset($_POST['cl_scnotification_show_footer']);
|
||||
$cl_scnotification_footer_text = trim((string) ($_POST['cl_scnotification_footer_text'] ?? ''));
|
||||
$cl_scnotification_footer_icon_url = trim((string) ($_POST['cl_scnotification_footer_icon_url'] ?? ''));
|
||||
$show_reactions = isset($_POST['cl_scnotification_show_reactions']);
|
||||
$show_thread = isset($_POST['cl_scnotification_show_thread']);
|
||||
$show_org = isset($_POST['cl_scnotification_show_org']);
|
||||
$cl_scnotification_org_value = trim((string) ($_POST['cl_scnotification_org_value'] ?? ''));
|
||||
$show_pvp = isset($_POST['cl_scnotification_show_pvp']);
|
||||
$cl_scnotification_pvp_value = trim((string) ($_POST['cl_scnotification_pvp_value'] ?? ''));
|
||||
$include_schedule = isset($_POST['cl_scnotification_include_schedule']);
|
||||
$cl_scnotification_location = trim((string) ($_POST['cl_scnotification_location'] ?? ''));
|
||||
$cl_scnotification_start_date = trim((string) ($_POST['cl_scnotification_start_date'] ?? ''));
|
||||
$cl_scnotification_departure_time = trim((string) ($_POST['cl_scnotification_departure_time'] ?? ''));
|
||||
$include_briefing_time = isset($_POST['cl_scnotification_include_briefing_time']);
|
||||
$cl_scnotification_briefing_time = trim((string) ($_POST['cl_scnotification_briefing_time'] ?? ''));
|
||||
$include_end_date = isset($_POST['cl_scnotification_include_end_date']);
|
||||
$cl_scnotification_end_date = trim((string) ($_POST['cl_scnotification_end_date'] ?? ''));
|
||||
$include_end_time = isset($_POST['cl_scnotification_include_end_time']);
|
||||
$cl_scnotification_end_time = trim((string) ($_POST['cl_scnotification_end_time'] ?? ''));
|
||||
$show_channel_url = isset($_POST['cl_scnotification_show_channel_url']);
|
||||
$cl_scnotification_channel_url = trim((string) ($_POST['cl_scnotification_channel_url'] ?? ''));
|
||||
$show_inventory_url = isset($_POST['cl_scnotification_show_inventory_url']);
|
||||
$cl_scnotification_inventory_url = trim((string) ($_POST['cl_scnotification_inventory_url'] ?? ''));
|
||||
$show_source_url = isset($_POST['cl_scnotification_show_source_url']);
|
||||
$cl_scnotification_source_url = trim((string) ($_POST['cl_scnotification_source_url'] ?? ''));
|
||||
|
||||
if ($cl_scnotification_webhook_id <= 0) {
|
||||
auth_flash_set('error', 'Veuillez sélectionner un webhook Discord.');
|
||||
header('Location: scnotification.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($cl_scnotification_message === '') {
|
||||
auth_flash_set('error', 'Le champ description est obligatoire pour envoyer la notification.');
|
||||
header('Location: scnotification.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt_webhook = $db->prepare('SELECT * FROM tbl_scwebhooks WHERE cl_scwebhook_id = :id LIMIT 1');
|
||||
$stmt_webhook->execute(['id' => $cl_scnotification_webhook_id]);
|
||||
$webhook = $stmt_webhook->fetch();
|
||||
|
||||
if (!$webhook) {
|
||||
auth_flash_set('error', 'Webhook Discord introuvable.');
|
||||
header('Location: scnotification.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$banner = null;
|
||||
if ($cl_scnotification_banner_id > 0) {
|
||||
$stmt_banner = $db->prepare('SELECT * FROM tbl_scbanners WHERE cl_scbanner_id = :id LIMIT 1');
|
||||
$stmt_banner->execute(['id' => $cl_scnotification_banner_id]);
|
||||
$banner = $stmt_banner->fetch();
|
||||
}
|
||||
|
||||
if ($use_custom_banner && $cl_scnotification_custom_banner_url !== '' && !filter_var($cl_scnotification_custom_banner_url, FILTER_VALIDATE_URL)) {
|
||||
auth_flash_set('error', 'L’URL de bannière personnalisée est invalide.');
|
||||
header('Location: scnotification.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
foreach ([
|
||||
'URL canal Discord' => [$show_channel_url, $cl_scnotification_channel_url],
|
||||
'URL inventaire' => [$show_inventory_url, $cl_scnotification_inventory_url],
|
||||
'URL source' => [$show_source_url, $cl_scnotification_source_url],
|
||||
'Icône du footer' => [$show_footer && $cl_scnotification_footer_icon_url !== '', $cl_scnotification_footer_icon_url],
|
||||
] as $label => [$enabled, $value]) {
|
||||
if ($enabled && $value !== '' && !filter_var($value, FILTER_VALIDATE_URL)) {
|
||||
auth_flash_set('error', $label . ' invalide.');
|
||||
header('Location: scnotification.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$mentions = scdiscord_build_mentions($notify_here, $notify_everyone);
|
||||
$banner_image_url = $use_custom_banner && $cl_scnotification_custom_banner_url !== ''
|
||||
? $cl_scnotification_custom_banner_url
|
||||
: (string) ($banner['cl_scbanner_url'] ?? '');
|
||||
$border_color = (string) ($banner['cl_scbanner_border_color'] ?? '#ffae00');
|
||||
|
||||
$fields = [];
|
||||
|
||||
if ($show_org && $cl_scnotification_org_value !== '' && mb_strtolower($cl_scnotification_org_value) !== 'non') {
|
||||
$fields[] = [
|
||||
'name' => 'Tenue d’organisation',
|
||||
'value' => mb_substr($cl_scnotification_org_value, 0, 1024),
|
||||
'inline' => true,
|
||||
];
|
||||
}
|
||||
|
||||
if ($show_pvp && $cl_scnotification_pvp_value !== '' && mb_strtolower($cl_scnotification_pvp_value) !== 'inexistant') {
|
||||
$fields[] = [
|
||||
'name' => 'Risques PvP',
|
||||
'value' => mb_substr($cl_scnotification_pvp_value, 0, 1024),
|
||||
'inline' => true,
|
||||
];
|
||||
}
|
||||
|
||||
if ($include_schedule) {
|
||||
if ($cl_scnotification_location !== '') {
|
||||
$fields[] = ['name' => 'Lieu de ralliement', 'value' => mb_substr($cl_scnotification_location, 0, 1024), 'inline' => false];
|
||||
}
|
||||
if ($cl_scnotification_start_date !== '') {
|
||||
$fields[] = ['name' => 'Date de début', 'value' => mb_substr($cl_scnotification_start_date, 0, 1024), 'inline' => true];
|
||||
}
|
||||
if ($cl_scnotification_departure_time !== '') {
|
||||
$fields[] = ['name' => 'Heure de départ', 'value' => mb_substr($cl_scnotification_departure_time, 0, 1024), 'inline' => true];
|
||||
}
|
||||
if ($include_briefing_time && $cl_scnotification_briefing_time !== '') {
|
||||
$fields[] = ['name' => 'Heure de briefing', 'value' => mb_substr($cl_scnotification_briefing_time, 0, 1024), 'inline' => true];
|
||||
}
|
||||
if ($include_end_date && $cl_scnotification_end_date !== '') {
|
||||
$fields[] = ['name' => 'Date de fin', 'value' => mb_substr($cl_scnotification_end_date, 0, 1024), 'inline' => true];
|
||||
}
|
||||
if ($include_end_time && $cl_scnotification_end_time !== '') {
|
||||
$fields[] = ['name' => 'Heure de fin', 'value' => mb_substr($cl_scnotification_end_time, 0, 1024), 'inline' => true];
|
||||
}
|
||||
}
|
||||
|
||||
if ($show_channel_url && $cl_scnotification_channel_url !== '') {
|
||||
$fields[] = ['name' => 'Canal Discord', 'value' => '[Ouvrir le canal](' . $cl_scnotification_channel_url . ')', 'inline' => false];
|
||||
}
|
||||
|
||||
if ($show_inventory_url && $cl_scnotification_inventory_url !== '') {
|
||||
$fields[] = ['name' => 'Inventaire A.R.I.A', 'value' => '[Consulter l’inventaire](' . $cl_scnotification_inventory_url . ')', 'inline' => false];
|
||||
}
|
||||
|
||||
if ($show_source_url && $cl_scnotification_source_url !== '') {
|
||||
$fields[] = ['name' => 'Source', 'value' => '[Ouvrir la source](' . $cl_scnotification_source_url . ')', 'inline' => false];
|
||||
}
|
||||
|
||||
if ($show_reactions) {
|
||||
$fields[] = ['name' => 'Réactions', 'value' => '👍 / ⏳ / ❓ / 👎', 'inline' => false];
|
||||
}
|
||||
|
||||
$embed = [
|
||||
'description' => mb_substr($cl_scnotification_message, 0, 4096),
|
||||
'color' => scdiscord_hex_to_decimal($border_color),
|
||||
];
|
||||
|
||||
if ($cl_scnotification_title !== '') {
|
||||
$embed['title'] = mb_substr($cl_scnotification_title, 0, 256);
|
||||
}
|
||||
|
||||
if (!empty($fields)) {
|
||||
$embed['fields'] = $fields;
|
||||
}
|
||||
|
||||
if ($banner_image_url !== '') {
|
||||
$embed['image'] = ['url' => $banner_image_url];
|
||||
}
|
||||
|
||||
if ($show_footer && ($cl_scnotification_footer_text !== '' || $cl_scnotification_footer_icon_url !== '')) {
|
||||
$embed['footer'] = [];
|
||||
if ($cl_scnotification_footer_text !== '') {
|
||||
$embed['footer']['text'] = mb_substr($cl_scnotification_footer_text, 0, 2048);
|
||||
}
|
||||
if ($cl_scnotification_footer_icon_url !== '') {
|
||||
$embed['footer']['icon_url'] = $cl_scnotification_footer_icon_url;
|
||||
}
|
||||
}
|
||||
|
||||
$payload = [
|
||||
'embeds' => [$embed],
|
||||
];
|
||||
|
||||
if (!empty($mentions)) {
|
||||
$payload['content'] = implode(' ', $mentions);
|
||||
$payload['allowed_mentions'] = ['parse' => ['everyone']];
|
||||
}
|
||||
|
||||
$is_forum_webhook = ((int) ($webhook['cl_scwebhook_is_forum'] ?? 0) === 1);
|
||||
if ($is_forum_webhook) {
|
||||
$payload['thread_name'] = scdiscord_build_thread_name(
|
||||
$cl_scnotification_title,
|
||||
$cl_scnotification_location,
|
||||
$cl_scnotification_start_date
|
||||
);
|
||||
} elseif ($show_thread) {
|
||||
$embed['fields'][] = [
|
||||
'name' => 'Fil de discussion',
|
||||
'value' => 'Le webhook sélectionné n’est pas de type forum.',
|
||||
'inline' => false,
|
||||
];
|
||||
$payload['embeds'] = [$embed];
|
||||
}
|
||||
|
||||
$result = scdiscord_post_webhook((string) $webhook['cl_scwebhook_url'], $payload);
|
||||
|
||||
$stmt_log = $db->prepare(
|
||||
'INSERT INTO tbl_scnotifications (
|
||||
cl_scnotification_webhook_id,
|
||||
cl_scnotification_banner_id,
|
||||
cl_scnotification_title,
|
||||
cl_scnotification_message,
|
||||
cl_scnotification_payload,
|
||||
cl_scnotification_response,
|
||||
cl_scnotification_success,
|
||||
cl_scnotification_created_by
|
||||
) VALUES (
|
||||
:webhook_id,
|
||||
:banner_id,
|
||||
:title,
|
||||
:message,
|
||||
:payload,
|
||||
:response,
|
||||
:success,
|
||||
:created_by
|
||||
)'
|
||||
);
|
||||
$stmt_log->execute([
|
||||
'webhook_id' => $cl_scnotification_webhook_id,
|
||||
'banner_id' => $cl_scnotification_banner_id > 0 ? $cl_scnotification_banner_id : null,
|
||||
'title' => $cl_scnotification_title,
|
||||
'message' => $cl_scnotification_message,
|
||||
'payload' => json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
|
||||
'response' => (string) ($result['response'] ?? ''),
|
||||
'success' => !empty($result['success']) ? 1 : 0,
|
||||
'created_by' => $current_session_user !== '' ? $current_session_user : 'Inconnu',
|
||||
]);
|
||||
|
||||
if (!empty($result['success'])) {
|
||||
unset($_SESSION['scnotification_old']);
|
||||
auth_flash_set('success', 'Notification Discord envoyée avec succès.');
|
||||
} else {
|
||||
auth_flash_set('error', 'Échec de l’envoi Discord (HTTP ' . (int) ($result['http_code'] ?? 0) . ').');
|
||||
}
|
||||
|
||||
header('Location: scnotification.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$old = $_SESSION['scnotification_old'] ?? [];
|
||||
unset($_SESSION['scnotification_old']);
|
||||
|
||||
$stmt_webhooks = $db->query('SELECT * FROM tbl_scwebhooks ORDER BY cl_scwebhook_name ASC');
|
||||
$webhooks = $stmt_webhooks->fetchAll();
|
||||
|
||||
$stmt_banners = $db->query('SELECT * FROM tbl_scbanners ORDER BY cl_scbanner_name ASC');
|
||||
$banners = $stmt_banners->fetchAll();
|
||||
|
||||
$stmt_recent = $db->query(
|
||||
'SELECT n.cl_scnotification_id,
|
||||
n.cl_scnotification_title,
|
||||
n.cl_scnotification_success,
|
||||
n.cl_scnotification_created_at,
|
||||
n.cl_scnotification_created_by,
|
||||
w.cl_scwebhook_name,
|
||||
b.cl_scbanner_name
|
||||
FROM tbl_scnotifications n
|
||||
JOIN tbl_scwebhooks w ON w.cl_scwebhook_id = n.cl_scnotification_webhook_id
|
||||
LEFT JOIN tbl_scbanners b ON b.cl_scbanner_id = n.cl_scnotification_banner_id
|
||||
ORDER BY n.cl_scnotification_id DESC
|
||||
LIMIT 8'
|
||||
);
|
||||
$recent_notifications = $stmt_recent->fetchAll();
|
||||
|
||||
function scnotification_old_value(array $old, string $key, string $default = ''): string
|
||||
{
|
||||
$value = $old[$key] ?? $default;
|
||||
return is_string($value) ? $value : $default;
|
||||
}
|
||||
|
||||
function scnotification_old_checked(array $old, string $key, bool $default = false): bool
|
||||
{
|
||||
if (empty($old)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return array_key_exists($key, $old);
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SC Notification | R.E.A.C.T. Admin</title>
|
||||
<link rel="stylesheet" type="text/css" href="css/styles.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/default.css">
|
||||
<style>
|
||||
:root {
|
||||
--primary: #f4a31d;
|
||||
--primary-soft: rgba(244, 163, 29, 0.16);
|
||||
--bg: #2b2b2b;
|
||||
--bg-page: #1a1a1a;
|
||||
--card: #565656;
|
||||
--card-deep: #4a4a4a;
|
||||
--field: #454545;
|
||||
--border: rgba(255,255,255,0.08);
|
||||
--text-soft: #d5d5d5;
|
||||
--text-muted: #a9a9a9;
|
||||
--success: #6fe08f;
|
||||
--danger: #ff8a8a;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Electrolize';
|
||||
src: url('fonts/Electrolize-Regular.ttf') format('truetype');
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(180deg, #4a4a4a 0%, var(--bg-page) 100%);
|
||||
font-family: 'Electrolize', sans-serif;
|
||||
color: #f6f6f6;
|
||||
}
|
||||
|
||||
.admin-layout {
|
||||
max-width: 1460px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.admin-topbar, .page-shell, .history-card {
|
||||
background: rgba(53, 53, 53, 0.98);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 14px;
|
||||
box-shadow: 0 14px 38px rgba(0, 0, 0, 0.28);
|
||||
}
|
||||
|
||||
.admin-topbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
padding: 1.4rem 1.8rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.topbar-info h1 {
|
||||
margin: 0;
|
||||
font-size: 1.55rem;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.topbar-info p {
|
||||
margin: 0.35rem 0 0;
|
||||
color: var(--primary);
|
||||
font-size: 0.88rem;
|
||||
}
|
||||
|
||||
.btn-modern {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.4rem;
|
||||
padding: 0.72rem 1.1rem;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--primary);
|
||||
background: transparent;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.82rem;
|
||||
cursor: pointer;
|
||||
transition: 0.22s ease;
|
||||
font-family: 'Electrolize', sans-serif;
|
||||
}
|
||||
|
||||
.btn-modern:hover {
|
||||
background: var(--primary);
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.btn-modern.danger {
|
||||
border-color: #f06a6a;
|
||||
color: #f06a6a;
|
||||
}
|
||||
|
||||
.btn-modern.danger:hover {
|
||||
background: #f06a6a;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
margin-bottom: 1.5rem;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.08);
|
||||
}
|
||||
|
||||
.nav-tabs a {
|
||||
color: #a5a5a5;
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.88rem;
|
||||
}
|
||||
|
||||
.nav-tabs a.active,
|
||||
.nav-tabs a:hover {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.flash {
|
||||
margin-bottom: 1rem;
|
||||
padding: 1rem 1.15rem;
|
||||
border-radius: 10px;
|
||||
border: 1px solid rgba(255,255,255,0.08);
|
||||
background: rgba(255,255,255,0.04);
|
||||
}
|
||||
|
||||
.flash.success { color: var(--success); border-color: rgba(111,224,143,0.28); }
|
||||
.flash.error { color: var(--danger); border-color: rgba(255,138,138,0.28); }
|
||||
|
||||
.page-shell {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
padding: 0.65rem 0.9rem 1rem;
|
||||
font-size: 1.12rem;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.form-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.form-column {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.section-card {
|
||||
background: var(--card);
|
||||
border: 1px solid rgba(0,0,0,0.18);
|
||||
border-radius: 8px;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
margin: 0 0 0.9rem;
|
||||
color: var(--primary);
|
||||
font-size: 1rem;
|
||||
line-height: 1.2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.section-title::before {
|
||||
content: '';
|
||||
width: 3px;
|
||||
height: 18px;
|
||||
background: var(--primary);
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.field-row { margin-bottom: 0.85rem; }
|
||||
.field-row:last-child { margin-bottom: 0; }
|
||||
|
||||
label, .inline-label {
|
||||
display: block;
|
||||
margin-bottom: 0.45rem;
|
||||
font-size: 0.83rem;
|
||||
color: var(--text-soft);
|
||||
}
|
||||
|
||||
.check {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.55rem;
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 0.7rem;
|
||||
color: #ededed;
|
||||
}
|
||||
|
||||
.control,
|
||||
textarea,
|
||||
select,
|
||||
input[type="text"],
|
||||
input[type="url"],
|
||||
input[type="date"],
|
||||
input[type="time"] {
|
||||
width: 100%;
|
||||
padding: 0.8rem 0.85rem;
|
||||
border-radius: 5px;
|
||||
border: 1px solid rgba(255,255,255,0.06);
|
||||
background: var(--field);
|
||||
color: #fff;
|
||||
font-family: 'Electrolize', sans-serif;
|
||||
}
|
||||
|
||||
textarea {
|
||||
min-height: 180px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
input[disabled], select[disabled], textarea[disabled] {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.subgrid-2 {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.8rem;
|
||||
}
|
||||
|
||||
.char-counter {
|
||||
margin-top: 0.3rem;
|
||||
font-size: 0.72rem;
|
||||
color: var(--text-muted);
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.submit-wrap {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.submit-wrap .btn-modern {
|
||||
width: 100%;
|
||||
padding: 0.95rem 1.2rem;
|
||||
background: var(--primary);
|
||||
color: #111;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.submit-wrap .btn-modern:hover {
|
||||
filter: brightness(1.06);
|
||||
}
|
||||
|
||||
.history-card {
|
||||
margin-top: 1.5rem;
|
||||
padding: 1.2rem;
|
||||
}
|
||||
|
||||
.history-card h2 {
|
||||
margin: 0 0 1rem;
|
||||
color: var(--primary);
|
||||
font-size: 1rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.history-list {
|
||||
display: grid;
|
||||
gap: 0.7rem;
|
||||
}
|
||||
|
||||
.history-item {
|
||||
padding: 0.85rem 0.95rem;
|
||||
border-radius: 8px;
|
||||
background: rgba(255,255,255,0.04);
|
||||
border: 1px solid rgba(255,255,255,0.06);
|
||||
}
|
||||
|
||||
.history-meta {
|
||||
margin-top: 0.25rem;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
|
||||
.status-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
padding: 0.2rem 0.55rem;
|
||||
border-radius: 999px;
|
||||
font-size: 0.72rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.status-pill.ok {
|
||||
background: rgba(111,224,143,0.16);
|
||||
color: #a7efba;
|
||||
}
|
||||
|
||||
.status-pill.ko {
|
||||
background: rgba(255,138,138,0.16);
|
||||
color: #ffb0b0;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
padding: 1.2rem;
|
||||
border: 1px dashed rgba(255,255,255,0.12);
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.form-grid, .subgrid-2 { grid-template-columns: 1fr; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="admin-layout">
|
||||
<header class="admin-topbar">
|
||||
<div class="topbar-info">
|
||||
<h1>R.E.A.C.T. SC Notification</h1>
|
||||
<p>Niveau d'accès : <strong><?php echo htmlspecialchars($role_label, ENT_QUOTES, 'UTF-8'); ?></strong> | Session : <strong><?php echo htmlspecialchars($current_session_user, ENT_QUOTES, 'UTF-8'); ?></strong></p>
|
||||
</div>
|
||||
<div class="topbar-actions">
|
||||
<a href="index.php" class="btn-modern">Site</a>
|
||||
<a href="logout.php" class="btn-modern danger">Exit</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<nav class="nav-tabs">
|
||||
<?php if (auth_is_admin()): ?>
|
||||
<a href="admin.php">Utilisateurs</a>
|
||||
<a href="scitems.php">Base d'Objets</a>
|
||||
<a href="scmining.php">Scanner Minage</a>
|
||||
<a href="scmanufactures.php">Manufactures</a>
|
||||
<a href="scvaisseaux.php">Vaisseaux</a>
|
||||
<?php endif; ?>
|
||||
<a href="scpreset.php">Presets Vaisseau</a>
|
||||
<a href="scwebhook.php">SC Webhook</a>
|
||||
<a href="scnotification.php" class="active">SC Notification</a>
|
||||
</nav>
|
||||
|
||||
<?php if ($flash_message !== ''): ?>
|
||||
<div class="flash <?php echo htmlspecialchars($flash_type, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<?php echo htmlspecialchars($flash_message, ENT_QUOTES, 'UTF-8'); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="page-shell">
|
||||
<div class="page-title">Envoi d'une notification sur Discord</div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrf_token, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<input type="hidden" name="action" value="send_notification">
|
||||
|
||||
<div class="form-grid">
|
||||
<div class="form-column">
|
||||
<section class="section-card">
|
||||
<h2 class="section-title">Canal de notification</h2>
|
||||
<div class="field-row">
|
||||
<select class="control" name="cl_scnotification_webhook_id" required>
|
||||
<option value="">Sélectionner un webhook</option>
|
||||
<?php foreach ($webhooks as $webhook): ?>
|
||||
<?php $selected = (string) $webhook['cl_scwebhook_id'] === scnotification_old_value($old, 'cl_scnotification_webhook_id'); ?>
|
||||
<option value="<?php echo (int) $webhook['cl_scwebhook_id']; ?>" <?php echo $selected ? 'selected' : ''; ?>>
|
||||
<?php echo htmlspecialchars($webhook['cl_scwebhook_name'] . (((int) $webhook['cl_scwebhook_is_forum'] === 1) ? ' [forum]' : ''), ENT_QUOTES, 'UTF-8'); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section-card">
|
||||
<h2 class="section-title">Bannière et Couleur de bordure</h2>
|
||||
<div class="field-row">
|
||||
<select class="control" name="cl_scnotification_banner_id" id="cl_scnotification_banner_id">
|
||||
<option value="">Aucune bannière</option>
|
||||
<?php foreach ($banners as $banner): ?>
|
||||
<?php $selected = (string) $banner['cl_scbanner_id'] === scnotification_old_value($old, 'cl_scnotification_banner_id'); ?>
|
||||
<option value="<?php echo (int) $banner['cl_scbanner_id']; ?>" <?php echo $selected ? 'selected' : ''; ?>>
|
||||
<?php echo htmlspecialchars($banner['cl_scbanner_name'] . ' [' . scdiscord_normalize_hex_color((string) ($banner['cl_scbanner_border_color'] ?? '#ffae00')) . ']', ENT_QUOTES, 'UTF-8'); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<label class="check">
|
||||
<input type="checkbox" name="cl_scnotification_use_custom_banner" id="cl_scnotification_use_custom_banner" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_use_custom_banner') ? 'checked' : ''; ?>>
|
||||
<span>Utiliser une bannière personnalisée</span>
|
||||
</label>
|
||||
<div class="field-row">
|
||||
<input type="url" class="control" name="cl_scnotification_custom_banner_url" id="cl_scnotification_custom_banner_url" placeholder="URL personnalisée https://.../png" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_custom_banner_url'), ENT_QUOTES, 'UTF-8'); ?>">
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section-card">
|
||||
<h2 class="section-title">Message</h2>
|
||||
<label class="check">
|
||||
<input type="checkbox" name="cl_scnotification_notify_here" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_notify_here') ? 'checked' : ''; ?>>
|
||||
<span>Notifier avec @here</span>
|
||||
</label>
|
||||
<label class="check">
|
||||
<input type="checkbox" name="cl_scnotification_notify_everyone" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_notify_everyone', true) ? 'checked' : ''; ?>>
|
||||
<span>Notifier avec @everyone</span>
|
||||
</label>
|
||||
<div class="field-row">
|
||||
<label for="cl_scnotification_title">Titre :</label>
|
||||
<input type="text" class="control" id="cl_scnotification_title" name="cl_scnotification_title" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_title'), ENT_QUOTES, 'UTF-8'); ?>">
|
||||
</div>
|
||||
<div class="field-row">
|
||||
<label for="cl_scnotification_message">Description :</label>
|
||||
<textarea id="cl_scnotification_message" name="cl_scnotification_message" maxlength="2500" placeholder="Compatible avec le Markdown Discord..."><?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_message'), ENT_QUOTES, 'UTF-8'); ?></textarea>
|
||||
<div class="char-counter"><span id="messageCount">2500</span> caractères restants</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section-card">
|
||||
<h2 class="section-title">Options Footer</h2>
|
||||
<label class="check">
|
||||
<input type="checkbox" name="cl_scnotification_show_footer" id="cl_scnotification_show_footer" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_show_footer', true) ? 'checked' : ''; ?>>
|
||||
<span>Afficher le footer</span>
|
||||
</label>
|
||||
<div class="field-row">
|
||||
<label for="cl_scnotification_footer_text">Texte du footer :</label>
|
||||
<input type="text" class="control footer-toggle" id="cl_scnotification_footer_text" name="cl_scnotification_footer_text" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_footer_text', 'R.E.A.C.T Initiative'), ENT_QUOTES, 'UTF-8'); ?>">
|
||||
</div>
|
||||
<div class="field-row">
|
||||
<label for="cl_scnotification_footer_icon_url">URL icône footer :</label>
|
||||
<input type="url" class="control footer-toggle" id="cl_scnotification_footer_icon_url" name="cl_scnotification_footer_icon_url" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_footer_icon_url'), ENT_QUOTES, 'UTF-8'); ?>" placeholder="*.png">
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section-card">
|
||||
<h2 class="section-title">Réactions & Fils</h2>
|
||||
<label class="check">
|
||||
<input type="checkbox" name="cl_scnotification_show_reactions" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_show_reactions') ? 'checked' : ''; ?>>
|
||||
<span>Afficher les réactions 👍 / ⏳ / ❓ / 👎</span>
|
||||
</label>
|
||||
<label class="check">
|
||||
<input type="checkbox" name="cl_scnotification_show_thread" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_show_thread', true) ? 'checked' : ''; ?>>
|
||||
<span>Afficher le fil de discussion</span>
|
||||
</label>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="form-column">
|
||||
<section class="section-card">
|
||||
<h2 class="section-title">Tenue d'organisation & PvP</h2>
|
||||
<label class="check">
|
||||
<input type="checkbox" name="cl_scnotification_show_org" id="cl_scnotification_show_org" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_show_org') ? 'checked' : ''; ?>>
|
||||
<span>Afficher la tenue d'organisation</span>
|
||||
</label>
|
||||
<div class="field-row">
|
||||
<select class="control org-toggle" name="cl_scnotification_org_value" id="cl_scnotification_org_value">
|
||||
<?php foreach (['Non', 'Tenue civile', 'Tenue organisation', 'Tenue lourde'] as $option): ?>
|
||||
<option value="<?php echo htmlspecialchars($option, ENT_QUOTES, 'UTF-8'); ?>" <?php echo scnotification_old_value($old, 'cl_scnotification_org_value', 'Non') === $option ? 'selected' : ''; ?>><?php echo htmlspecialchars($option, ENT_QUOTES, 'UTF-8'); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<label class="check">
|
||||
<input type="checkbox" name="cl_scnotification_show_pvp" id="cl_scnotification_show_pvp" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_show_pvp') ? 'checked' : ''; ?>>
|
||||
<span>Afficher les risques PvP</span>
|
||||
</label>
|
||||
<div class="field-row">
|
||||
<select class="control pvp-toggle" name="cl_scnotification_pvp_value" id="cl_scnotification_pvp_value">
|
||||
<?php foreach (['Inexistant', 'Faible', 'Modéré', 'Important', 'Extrême'] as $option): ?>
|
||||
<option value="<?php echo htmlspecialchars($option, ENT_QUOTES, 'UTF-8'); ?>" <?php echo scnotification_old_value($old, 'cl_scnotification_pvp_value', 'Inexistant') === $option ? 'selected' : ''; ?>><?php echo htmlspecialchars($option, ENT_QUOTES, 'UTF-8'); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section-card">
|
||||
<h2 class="section-title">Lieu, Date et Heure</h2>
|
||||
<label class="check">
|
||||
<input type="checkbox" name="cl_scnotification_include_schedule" id="cl_scnotification_include_schedule" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_include_schedule') ? 'checked' : ''; ?>>
|
||||
<span>Inclure date, lieu et heures</span>
|
||||
</label>
|
||||
<div class="field-row">
|
||||
<label for="cl_scnotification_location">Lieu de ralliement :</label>
|
||||
<input type="text" class="control schedule-toggle" id="cl_scnotification_location" name="cl_scnotification_location" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_location'), ENT_QUOTES, 'UTF-8'); ?>">
|
||||
</div>
|
||||
<div class="field-row subgrid-2">
|
||||
<div>
|
||||
<label for="cl_scnotification_start_date">Date de début :</label>
|
||||
<input type="date" class="control schedule-toggle" id="cl_scnotification_start_date" name="cl_scnotification_start_date" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_start_date'), ENT_QUOTES, 'UTF-8'); ?>">
|
||||
</div>
|
||||
<div>
|
||||
<label for="cl_scnotification_departure_time">Heure de départ :</label>
|
||||
<input type="time" class="control schedule-toggle" id="cl_scnotification_departure_time" name="cl_scnotification_departure_time" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_departure_time', '21:30'), ENT_QUOTES, 'UTF-8'); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<label class="check">
|
||||
<input type="checkbox" name="cl_scnotification_include_briefing_time" id="cl_scnotification_include_briefing_time" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_include_briefing_time') ? 'checked' : ''; ?>>
|
||||
<span>Inclure une heure de briefing</span>
|
||||
</label>
|
||||
<div class="field-row">
|
||||
<label for="cl_scnotification_briefing_time">Heure de briefing :</label>
|
||||
<input type="time" class="control briefing-toggle" id="cl_scnotification_briefing_time" name="cl_scnotification_briefing_time" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_briefing_time', '21:00'), ENT_QUOTES, 'UTF-8'); ?>">
|
||||
</div>
|
||||
<label class="check">
|
||||
<input type="checkbox" name="cl_scnotification_include_end_date" id="cl_scnotification_include_end_date" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_include_end_date') ? 'checked' : ''; ?>>
|
||||
<span>Inclure une date de fin</span>
|
||||
</label>
|
||||
<div class="field-row">
|
||||
<label for="cl_scnotification_end_date">Date de fin :</label>
|
||||
<input type="date" class="control enddate-toggle" id="cl_scnotification_end_date" name="cl_scnotification_end_date" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_end_date'), ENT_QUOTES, 'UTF-8'); ?>">
|
||||
</div>
|
||||
<label class="check">
|
||||
<input type="checkbox" name="cl_scnotification_include_end_time" id="cl_scnotification_include_end_time" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_include_end_time') ? 'checked' : ''; ?>>
|
||||
<span>Inclure une heure de fin</span>
|
||||
</label>
|
||||
<div class="field-row">
|
||||
<label for="cl_scnotification_end_time">Heure de fin :</label>
|
||||
<input type="time" class="control endtime-toggle" id="cl_scnotification_end_time" name="cl_scnotification_end_time" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_end_time', '00:00'), ENT_QUOTES, 'UTF-8'); ?>">
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section-card">
|
||||
<h2 class="section-title">URL externes</h2>
|
||||
<label class="check">
|
||||
<input type="checkbox" name="cl_scnotification_show_channel_url" id="cl_scnotification_show_channel_url" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_show_channel_url') ? 'checked' : ''; ?>>
|
||||
<span>Afficher un lien de canal Discord</span>
|
||||
</label>
|
||||
<div class="field-row">
|
||||
<label for="cl_scnotification_channel_url">URL Canal :</label>
|
||||
<input type="url" class="control channelurl-toggle" id="cl_scnotification_channel_url" name="cl_scnotification_channel_url" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_channel_url', 'https://discord.com/channels/...'), ENT_QUOTES, 'UTF-8'); ?>">
|
||||
</div>
|
||||
<label class="check">
|
||||
<input type="checkbox" name="cl_scnotification_show_inventory_url" id="cl_scnotification_show_inventory_url" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_show_inventory_url') ? 'checked' : ''; ?>>
|
||||
<span>Afficher une URL de l'inventaire A.R.I.A</span>
|
||||
</label>
|
||||
<div class="field-row">
|
||||
<label for="cl_scnotification_inventory_url">URL Inventaire :</label>
|
||||
<input type="url" class="control inventoryurl-toggle" id="cl_scnotification_inventory_url" name="cl_scnotification_inventory_url" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_inventory_url', 'https://aria.blackops-agency.fr/...'), ENT_QUOTES, 'UTF-8'); ?>">
|
||||
</div>
|
||||
<label class="check">
|
||||
<input type="checkbox" name="cl_scnotification_show_source_url" id="cl_scnotification_show_source_url" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_show_source_url') ? 'checked' : ''; ?>>
|
||||
<span>Afficher une URL source</span>
|
||||
</label>
|
||||
<div class="field-row">
|
||||
<label for="cl_scnotification_source_url">URL Source :</label>
|
||||
<input type="url" class="control sourceurl-toggle" id="cl_scnotification_source_url" name="cl_scnotification_source_url" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_source_url', 'https://...'), ENT_QUOTES, 'UTF-8'); ?>">
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="submit-wrap">
|
||||
<button type="submit" class="btn-modern">Envoyer</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<section class="history-card">
|
||||
<h2>Historique récent</h2>
|
||||
<?php if (empty($recent_notifications)): ?>
|
||||
<div class="empty-state">Aucune notification n’a encore été envoyée.</div>
|
||||
<?php else: ?>
|
||||
<div class="history-list">
|
||||
<?php foreach ($recent_notifications as $item): ?>
|
||||
<div class="history-item">
|
||||
<div>
|
||||
<strong><?php echo htmlspecialchars($item['cl_scnotification_title'] !== '' ? $item['cl_scnotification_title'] : 'Notification sans titre', ENT_QUOTES, 'UTF-8'); ?></strong>
|
||||
<span class="status-pill <?php echo ((int) $item['cl_scnotification_success'] === 1) ? 'ok' : 'ko'; ?>">
|
||||
<?php echo ((int) $item['cl_scnotification_success'] === 1) ? 'Envoyée' : 'Erreur'; ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="history-meta">
|
||||
Webhook : <strong><?php echo htmlspecialchars($item['cl_scwebhook_name'], ENT_QUOTES, 'UTF-8'); ?></strong>
|
||||
<?php if (!empty($item['cl_scbanner_name'])): ?>
|
||||
| Bannière : <strong><?php echo htmlspecialchars($item['cl_scbanner_name'], ENT_QUOTES, 'UTF-8'); ?></strong>
|
||||
<?php endif; ?>
|
||||
| Par : <strong><?php echo htmlspecialchars($item['cl_scnotification_created_by'], ENT_QUOTES, 'UTF-8'); ?></strong>
|
||||
| Le : <strong><?php echo htmlspecialchars($item['cl_scnotification_created_at'], ENT_QUOTES, 'UTF-8'); ?></strong>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const messageField = document.getElementById('cl_scnotification_message');
|
||||
const messageCount = document.getElementById('messageCount');
|
||||
|
||||
function updateCounter() {
|
||||
const remaining = 2500 - (messageField.value || '').length;
|
||||
messageCount.textContent = remaining;
|
||||
}
|
||||
|
||||
function toggleByCheckbox(checkboxId, selector, invert = false) {
|
||||
const checkbox = document.getElementById(checkboxId);
|
||||
const targets = document.querySelectorAll(selector);
|
||||
if (!checkbox) return;
|
||||
|
||||
const enabled = invert ? !checkbox.checked : checkbox.checked;
|
||||
targets.forEach((target) => {
|
||||
target.disabled = !enabled;
|
||||
});
|
||||
}
|
||||
|
||||
function syncStates() {
|
||||
toggleByCheckbox('cl_scnotification_use_custom_banner', '#cl_scnotification_custom_banner_url');
|
||||
toggleByCheckbox('cl_scnotification_show_footer', '.footer-toggle');
|
||||
toggleByCheckbox('cl_scnotification_show_org', '.org-toggle');
|
||||
toggleByCheckbox('cl_scnotification_show_pvp', '.pvp-toggle');
|
||||
toggleByCheckbox('cl_scnotification_include_schedule', '.schedule-toggle');
|
||||
const scheduleEnabled = document.getElementById('cl_scnotification_include_schedule')?.checked;
|
||||
document.getElementById('cl_scnotification_include_briefing_time').disabled = !scheduleEnabled;
|
||||
document.getElementById('cl_scnotification_include_end_date').disabled = !scheduleEnabled;
|
||||
document.getElementById('cl_scnotification_include_end_time').disabled = !scheduleEnabled;
|
||||
toggleByCheckbox('cl_scnotification_include_briefing_time', '.briefing-toggle');
|
||||
toggleByCheckbox('cl_scnotification_include_end_date', '.enddate-toggle');
|
||||
toggleByCheckbox('cl_scnotification_include_end_time', '.endtime-toggle');
|
||||
if (!scheduleEnabled) {
|
||||
document.querySelectorAll('.briefing-toggle, .enddate-toggle, .endtime-toggle').forEach(el => el.disabled = true);
|
||||
}
|
||||
toggleByCheckbox('cl_scnotification_show_channel_url', '.channelurl-toggle');
|
||||
toggleByCheckbox('cl_scnotification_show_inventory_url', '.inventoryurl-toggle');
|
||||
toggleByCheckbox('cl_scnotification_show_source_url', '.sourceurl-toggle');
|
||||
}
|
||||
|
||||
updateCounter();
|
||||
messageField.addEventListener('input', updateCounter);
|
||||
|
||||
[
|
||||
'cl_scnotification_use_custom_banner',
|
||||
'cl_scnotification_show_footer',
|
||||
'cl_scnotification_show_org',
|
||||
'cl_scnotification_show_pvp',
|
||||
'cl_scnotification_include_schedule',
|
||||
'cl_scnotification_include_briefing_time',
|
||||
'cl_scnotification_include_end_date',
|
||||
'cl_scnotification_include_end_time',
|
||||
'cl_scnotification_show_channel_url',
|
||||
'cl_scnotification_show_inventory_url',
|
||||
'cl_scnotification_show_source_url'
|
||||
].forEach((id) => {
|
||||
const el = document.getElementById(id);
|
||||
if (el) {
|
||||
el.addEventListener('change', syncStates);
|
||||
}
|
||||
});
|
||||
|
||||
syncStates();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -331,6 +331,8 @@ $presets = $stmt_list->fetchAll();
|
||||
<a href="scvaisseaux.php">Vaisseaux</a>
|
||||
<?php endif; ?>
|
||||
<a href="scpreset.php" class="active">Presets Vaisseau</a>
|
||||
<a href="scwebhook.php">SC Webhook</a>
|
||||
<a href="scnotification.php">SC Notification</a>
|
||||
</nav>
|
||||
|
||||
<?php if ($flash_message !== ''): ?>
|
||||
|
||||
@ -289,6 +289,8 @@ $current_session_user = $_SESSION['user'] ?? '';
|
||||
<a href="scmanufactures.php">Manufactures</a>
|
||||
<a href="scvaisseaux.php" class="active">Vaisseaux</a>
|
||||
<a href="scpreset.php">Presets Vaisseau</a>
|
||||
<a href="scwebhook.php">SC Webhook</a>
|
||||
<a href="scnotification.php">SC Notification</a>
|
||||
</nav>
|
||||
|
||||
<?php if ($flash_message !== ''): ?>
|
||||
|
||||
749
scwebhook.php
Normal file
749
scwebhook.php
Normal file
@ -0,0 +1,749 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/db/auth.php';
|
||||
require_once __DIR__ . '/db/scdiscord.php';
|
||||
|
||||
auth_start_session();
|
||||
auth_bootstrap();
|
||||
scdiscord_bootstrap();
|
||||
|
||||
if (!auth_is_admin()) {
|
||||
header('Location: index.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$db = db();
|
||||
$csrf_token = auth_csrf_token();
|
||||
$flash = auth_flash_get();
|
||||
$flash_type = $flash['type'] ?? '';
|
||||
$flash_message = $flash['message'] ?? '';
|
||||
$current_session_user = $_SESSION['user'] ?? '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$submitted_csrf = (string) ($_POST['csrf_token'] ?? '');
|
||||
if (!auth_validate_csrf($submitted_csrf)) {
|
||||
auth_flash_set('error', 'Jeton CSRF invalide.');
|
||||
header('Location: scwebhook.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$action = (string) ($_POST['action'] ?? '');
|
||||
|
||||
if ($action === 'add_webhook' || $action === 'update_webhook') {
|
||||
$webhook_id = (int) ($_POST['webhook_id'] ?? 0);
|
||||
$cl_scwebhook_name = trim((string) ($_POST['cl_scwebhook_name'] ?? ''));
|
||||
$cl_scwebhook_url = trim((string) ($_POST['cl_scwebhook_url'] ?? ''));
|
||||
$cl_scwebhook_is_forum = isset($_POST['cl_scwebhook_is_forum']) ? 1 : 0;
|
||||
|
||||
if ($cl_scwebhook_name === '' || $cl_scwebhook_url === '') {
|
||||
auth_flash_set('error', 'Le nom et l’URL du webhook sont obligatoires.');
|
||||
header('Location: scwebhook.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!filter_var($cl_scwebhook_url, FILTER_VALIDATE_URL)) {
|
||||
auth_flash_set('error', 'L’URL du webhook Discord est invalide.');
|
||||
header('Location: scwebhook.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
if ($action === 'add_webhook') {
|
||||
$stmt = $db->prepare('INSERT INTO tbl_scwebhooks (cl_scwebhook_name, cl_scwebhook_url, cl_scwebhook_is_forum) VALUES (:name, :url, :is_forum)');
|
||||
$stmt->execute([
|
||||
'name' => $cl_scwebhook_name,
|
||||
'url' => $cl_scwebhook_url,
|
||||
'is_forum' => $cl_scwebhook_is_forum,
|
||||
]);
|
||||
auth_flash_set('success', 'Webhook Discord ajouté avec succès.');
|
||||
} else {
|
||||
if ($webhook_id <= 0) {
|
||||
throw new RuntimeException('ID de webhook invalide.');
|
||||
}
|
||||
|
||||
$stmt = $db->prepare('UPDATE tbl_scwebhooks SET cl_scwebhook_name = :name, cl_scwebhook_url = :url, cl_scwebhook_is_forum = :is_forum WHERE cl_scwebhook_id = :id');
|
||||
$stmt->execute([
|
||||
'name' => $cl_scwebhook_name,
|
||||
'url' => $cl_scwebhook_url,
|
||||
'is_forum' => $cl_scwebhook_is_forum,
|
||||
'id' => $webhook_id,
|
||||
]);
|
||||
auth_flash_set('success', 'Webhook Discord mis à jour.');
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
auth_flash_set('error', 'Erreur webhook : ' . $e->getMessage());
|
||||
}
|
||||
|
||||
header('Location: scwebhook.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === 'delete_webhook') {
|
||||
$webhook_id = (int) ($_POST['webhook_id'] ?? 0);
|
||||
|
||||
if ($webhook_id > 0) {
|
||||
try {
|
||||
$stmt_usage = $db->prepare('SELECT COUNT(*) FROM tbl_scnotifications WHERE cl_scnotification_webhook_id = :id');
|
||||
$stmt_usage->execute(['id' => $webhook_id]);
|
||||
$usage_total = (int) $stmt_usage->fetchColumn();
|
||||
|
||||
if ($usage_total > 0) {
|
||||
auth_flash_set('error', 'Suppression refusée : ce webhook est déjà relié à l’historique des notifications.');
|
||||
} else {
|
||||
$stmt = $db->prepare('DELETE FROM tbl_scwebhooks WHERE cl_scwebhook_id = :id');
|
||||
$stmt->execute(['id' => $webhook_id]);
|
||||
auth_flash_set('success', 'Webhook Discord supprimé.');
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
auth_flash_set('error', 'Erreur suppression webhook : ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
header('Location: scwebhook.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === 'add_banner' || $action === 'update_banner') {
|
||||
$banner_id = (int) ($_POST['banner_id'] ?? 0);
|
||||
$cl_scbanner_name = trim((string) ($_POST['cl_scbanner_name'] ?? ''));
|
||||
$cl_scbanner_url = trim((string) ($_POST['cl_scbanner_url'] ?? ''));
|
||||
$cl_scbanner_border_color = scdiscord_normalize_hex_color((string) ($_POST['cl_scbanner_border_color'] ?? ''));
|
||||
|
||||
if ($cl_scbanner_name === '' || $cl_scbanner_url === '') {
|
||||
auth_flash_set('error', 'Le nom et le lien d’image de la bannière sont obligatoires.');
|
||||
header('Location: scwebhook.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!filter_var($cl_scbanner_url, FILTER_VALIDATE_URL)) {
|
||||
auth_flash_set('error', 'L’URL de la bannière est invalide.');
|
||||
header('Location: scwebhook.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
if ($action === 'add_banner') {
|
||||
$stmt = $db->prepare('INSERT INTO tbl_scbanners (cl_scbanner_name, cl_scbanner_url, cl_scbanner_border_color) VALUES (:name, :url, :border_color)');
|
||||
$stmt->execute([
|
||||
'name' => $cl_scbanner_name,
|
||||
'url' => $cl_scbanner_url,
|
||||
'border_color' => $cl_scbanner_border_color,
|
||||
]);
|
||||
auth_flash_set('success', 'Bannière Discord ajoutée avec succès.');
|
||||
} else {
|
||||
if ($banner_id <= 0) {
|
||||
throw new RuntimeException('ID de bannière invalide.');
|
||||
}
|
||||
|
||||
$stmt = $db->prepare('UPDATE tbl_scbanners SET cl_scbanner_name = :name, cl_scbanner_url = :url, cl_scbanner_border_color = :border_color WHERE cl_scbanner_id = :id');
|
||||
$stmt->execute([
|
||||
'name' => $cl_scbanner_name,
|
||||
'url' => $cl_scbanner_url,
|
||||
'border_color' => $cl_scbanner_border_color,
|
||||
'id' => $banner_id,
|
||||
]);
|
||||
auth_flash_set('success', 'Bannière Discord mise à jour.');
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
auth_flash_set('error', 'Erreur bannière : ' . $e->getMessage());
|
||||
}
|
||||
|
||||
header('Location: scwebhook.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === 'delete_banner') {
|
||||
$banner_id = (int) ($_POST['banner_id'] ?? 0);
|
||||
|
||||
if ($banner_id > 0) {
|
||||
try {
|
||||
$stmt = $db->prepare('DELETE FROM tbl_scbanners WHERE cl_scbanner_id = :id');
|
||||
$stmt->execute(['id' => $banner_id]);
|
||||
auth_flash_set('success', 'Bannière Discord supprimée.');
|
||||
} catch (Throwable $e) {
|
||||
auth_flash_set('error', 'Erreur suppression bannière : ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
header('Location: scwebhook.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$stmt_webhooks = $db->query('SELECT * FROM tbl_scwebhooks ORDER BY cl_scwebhook_name ASC');
|
||||
$webhooks = $stmt_webhooks->fetchAll();
|
||||
|
||||
$stmt_banners = $db->query('SELECT * FROM tbl_scbanners ORDER BY cl_scbanner_name ASC');
|
||||
$banners = $stmt_banners->fetchAll();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SC Webhook | R.E.A.C.T. Admin</title>
|
||||
<link rel="stylesheet" type="text/css" href="css/styles.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/default.css">
|
||||
<style>
|
||||
:root {
|
||||
--primary: #f6a21a;
|
||||
--primary-soft: rgba(246, 162, 26, 0.16);
|
||||
--primary-glow: rgba(246, 162, 26, 0.38);
|
||||
--bg-dark: #0d1016;
|
||||
--card-bg: rgba(44, 44, 48, 0.96);
|
||||
--card-bg-secondary: rgba(58, 58, 63, 0.96);
|
||||
--border-glow: rgba(255, 255, 255, 0.08);
|
||||
--danger: #ff6767;
|
||||
--success: #52d273;
|
||||
--muted: #aaaaaa;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Electrolize';
|
||||
src: url('fonts/Electrolize-Regular.ttf') format('truetype');
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(180deg, #262626 0%, #12141b 100%);
|
||||
color: #f4f4f4;
|
||||
font-family: 'Electrolize', sans-serif;
|
||||
}
|
||||
|
||||
.admin-layout {
|
||||
max-width: 1450px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.admin-topbar, .glass-card {
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--border-glow);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 16px 48px rgba(0, 0, 0, 0.28);
|
||||
}
|
||||
|
||||
.admin-topbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
padding: 1.5rem 2rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.topbar-info h1 {
|
||||
margin: 0;
|
||||
font-size: 1.6rem;
|
||||
letter-spacing: 1px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.topbar-info p {
|
||||
margin: 0.35rem 0 0;
|
||||
color: var(--primary);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.btn-modern {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.45rem;
|
||||
padding: 0.75rem 1.1rem;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--primary);
|
||||
background: transparent;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.82rem;
|
||||
cursor: pointer;
|
||||
transition: 0.25s ease;
|
||||
font-family: 'Electrolize', sans-serif;
|
||||
}
|
||||
|
||||
.btn-modern:hover {
|
||||
background: var(--primary);
|
||||
color: #0d1016;
|
||||
box-shadow: 0 0 18px var(--primary-glow);
|
||||
}
|
||||
|
||||
.btn-modern.danger {
|
||||
border-color: var(--danger);
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
.btn-modern.danger:hover {
|
||||
background: var(--danger);
|
||||
color: #fff;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.btn-modern.secondary {
|
||||
border-color: #6e6e6e;
|
||||
color: #d6d6d6;
|
||||
}
|
||||
|
||||
.btn-modern.secondary:hover {
|
||||
background: #6e6e6e;
|
||||
color: #fff;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.btn-mini {
|
||||
padding: 0.45rem 0.8rem;
|
||||
font-size: 0.72rem;
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.08);
|
||||
}
|
||||
|
||||
.nav-tabs a {
|
||||
color: #989898;
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.88rem;
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
.nav-tabs a.active,
|
||||
.nav-tabs a:hover {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.flash {
|
||||
margin-bottom: 1.5rem;
|
||||
padding: 1rem 1.2rem;
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(255,255,255,0.08);
|
||||
background: rgba(255,255,255,0.04);
|
||||
}
|
||||
|
||||
.flash.success { border-color: rgba(82, 210, 115, 0.35); color: #9ef0b4; }
|
||||
.flash.error { border-color: rgba(255, 103, 103, 0.35); color: #ff9d9d; }
|
||||
|
||||
.page-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 420px 1fr;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.stack {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.glass-card {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.glass-card h2 {
|
||||
margin: 0 0 1.25rem;
|
||||
color: var(--primary);
|
||||
font-size: 1.1rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.6px;
|
||||
}
|
||||
|
||||
.section-note {
|
||||
margin: -0.5rem 0 1.2rem;
|
||||
color: var(--muted);
|
||||
font-size: 0.82rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.form-grid {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: block;
|
||||
margin-bottom: 0.5rem;
|
||||
color: #d8d8d8;
|
||||
font-size: 0.82rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
width: 100%;
|
||||
padding: 0.82rem 0.9rem;
|
||||
border-radius: 6px;
|
||||
border: 1px solid rgba(255,255,255,0.08);
|
||||
background: var(--card-bg-secondary);
|
||||
color: #fff;
|
||||
font-family: 'Electrolize', sans-serif;
|
||||
}
|
||||
|
||||
.form-control[type="color"] {
|
||||
min-height: 48px;
|
||||
padding: 0.35rem;
|
||||
}
|
||||
|
||||
.checkbox-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.7rem;
|
||||
color: #e7e7e7;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.list-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.table-wrap {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: 0.9rem 0.75rem;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.08);
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
font-size: 0.88rem;
|
||||
}
|
||||
|
||||
th {
|
||||
color: var(--primary);
|
||||
text-transform: uppercase;
|
||||
font-size: 0.75rem;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.muted {
|
||||
color: var(--muted);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 0.2rem 0.55rem;
|
||||
border-radius: 999px;
|
||||
background: rgba(255,255,255,0.07);
|
||||
font-size: 0.72rem;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.pill.forum {
|
||||
background: rgba(246, 162, 26, 0.18);
|
||||
color: #ffd38c;
|
||||
}
|
||||
|
||||
.banner-preview {
|
||||
width: 120px;
|
||||
max-height: 42px;
|
||||
object-fit: cover;
|
||||
border-radius: 6px;
|
||||
border: 1px solid rgba(255,255,255,0.08);
|
||||
display: block;
|
||||
background: #17191e;
|
||||
}
|
||||
|
||||
.color-chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.45rem;
|
||||
}
|
||||
|
||||
.color-chip::before {
|
||||
content: '';
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 50%;
|
||||
background: var(--chip-color, #ffae00);
|
||||
box-shadow: 0 0 0 2px rgba(255,255,255,0.08);
|
||||
}
|
||||
|
||||
.actions-inline {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.45rem;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
padding: 2rem;
|
||||
border: 1px dashed rgba(255,255,255,0.12);
|
||||
border-radius: 10px;
|
||||
color: #9a9a9a;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
.page-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="admin-layout">
|
||||
<header class="admin-topbar">
|
||||
<div class="topbar-info">
|
||||
<h1>R.E.A.C.T. SC Webhook</h1>
|
||||
<p>Niveau d'accès : <strong>Administrateur</strong> | Session : <strong><?php echo htmlspecialchars($current_session_user, ENT_QUOTES, 'UTF-8'); ?></strong></p>
|
||||
</div>
|
||||
<div class="topbar-actions">
|
||||
<a href="index.php" class="btn-modern">Site</a>
|
||||
<a href="logout.php" class="btn-modern danger">Exit</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<nav class="nav-tabs">
|
||||
<a href="admin.php">Utilisateurs</a>
|
||||
<a href="scitems.php">Base d'Objets</a>
|
||||
<a href="scmining.php">Scanner Minage</a>
|
||||
<a href="scmanufactures.php">Manufactures</a>
|
||||
<a href="scvaisseaux.php">Vaisseaux</a>
|
||||
<a href="scpreset.php">Presets Vaisseau</a>
|
||||
<a href="scwebhook.php" class="active">SC Webhook</a>
|
||||
<a href="scnotification.php">SC Notification</a>
|
||||
</nav>
|
||||
|
||||
<?php if ($flash_message !== ''): ?>
|
||||
<div class="flash <?php echo htmlspecialchars($flash_type, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<?php echo htmlspecialchars($flash_message, ENT_QUOTES, 'UTF-8'); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="page-grid">
|
||||
<aside class="stack">
|
||||
<section class="glass-card">
|
||||
<h2 id="webhookFormTitle">Nouveau webhook Discord</h2>
|
||||
<p class="section-note">Ajoute la nomination du webhook et son URL. Active l’option forum si ce webhook doit créer un fil lors de l’envoi.</p>
|
||||
<form method="post" id="webhookForm" class="form-grid">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrf_token, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<input type="hidden" name="action" id="webhookAction" value="add_webhook">
|
||||
<input type="hidden" name="webhook_id" id="webhookId" value="">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="cl_scwebhook_name">Nomination du webhook</label>
|
||||
<input type="text" id="cl_scwebhook_name" name="cl_scwebhook_name" class="form-control" required placeholder="Ex : news-bops-cig">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="cl_scwebhook_url">Lien du webhook</label>
|
||||
<input type="url" id="cl_scwebhook_url" name="cl_scwebhook_url" class="form-control" required placeholder="https://discord.com/api/webhooks/...">
|
||||
</div>
|
||||
|
||||
<label class="checkbox-row">
|
||||
<input type="checkbox" id="cl_scwebhook_is_forum" name="cl_scwebhook_is_forum" value="1">
|
||||
<span>Webhook de type forum / fil de discussion</span>
|
||||
</label>
|
||||
|
||||
<button type="submit" class="btn-modern" id="webhookSubmitBtn">Ajouter le webhook</button>
|
||||
<button type="button" class="btn-modern secondary" id="webhookCancelBtn" style="display:none;" onclick="resetWebhookForm()">Annuler l’édition</button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section class="glass-card">
|
||||
<h2 id="bannerFormTitle">Nouvelle bannière</h2>
|
||||
<p class="section-note">Chaque bannière stocke un nom, un lien d’image et une couleur de bordure utilisée dans l’embed Discord.</p>
|
||||
<form method="post" id="bannerForm" class="form-grid">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrf_token, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<input type="hidden" name="action" id="bannerAction" value="add_banner">
|
||||
<input type="hidden" name="banner_id" id="bannerId" value="">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="cl_scbanner_name">Nom de la bannière</label>
|
||||
<input type="text" id="cl_scbanner_name" name="cl_scbanner_name" class="form-control" required placeholder="Ex : Alerte Rouge">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="cl_scbanner_url">Lien image</label>
|
||||
<input type="url" id="cl_scbanner_url" name="cl_scbanner_url" class="form-control" required placeholder="https://.../banniere.png">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="cl_scbanner_border_color">Couleur de bordure</label>
|
||||
<input type="color" id="cl_scbanner_border_color" name="cl_scbanner_border_color" class="form-control" value="#ffae00">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn-modern" id="bannerSubmitBtn">Ajouter la bannière</button>
|
||||
<button type="button" class="btn-modern secondary" id="bannerCancelBtn" style="display:none;" onclick="resetBannerForm()">Annuler l’édition</button>
|
||||
</form>
|
||||
</section>
|
||||
</aside>
|
||||
|
||||
<main class="list-grid">
|
||||
<section class="glass-card">
|
||||
<h2>Webhooks Discord enregistrés</h2>
|
||||
<?php if (empty($webhooks)): ?>
|
||||
<div class="empty-state">Aucun webhook configuré pour le moment.</div>
|
||||
<?php else: ?>
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nomination</th>
|
||||
<th>URL</th>
|
||||
<th>Type</th>
|
||||
<th style="text-align:right;">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($webhooks as $webhook): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<strong><?php echo htmlspecialchars($webhook['cl_scwebhook_name'], ENT_QUOTES, 'UTF-8'); ?></strong>
|
||||
</td>
|
||||
<td>
|
||||
<span class="muted"><?php echo htmlspecialchars(scdiscord_mask_webhook_url((string) $webhook['cl_scwebhook_url']), ENT_QUOTES, 'UTF-8'); ?></span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="pill <?php echo ((int) $webhook['cl_scwebhook_is_forum'] === 1) ? 'forum' : ''; ?>">
|
||||
<?php echo ((int) $webhook['cl_scwebhook_is_forum'] === 1) ? 'Forum' : 'Classique'; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="actions-inline">
|
||||
<button
|
||||
type="button"
|
||||
class="btn-modern btn-mini"
|
||||
onclick='editWebhook(<?php echo json_encode([
|
||||
'id' => (int) $webhook['cl_scwebhook_id'],
|
||||
'name' => (string) $webhook['cl_scwebhook_name'],
|
||||
'url' => (string) $webhook['cl_scwebhook_url'],
|
||||
'is_forum' => (int) $webhook['cl_scwebhook_is_forum'],
|
||||
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>)'
|
||||
>Éditer</button>
|
||||
<form method="post" onsubmit="return confirm('Supprimer ce webhook Discord ?');">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrf_token, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<input type="hidden" name="action" value="delete_webhook">
|
||||
<input type="hidden" name="webhook_id" value="<?php echo (int) $webhook['cl_scwebhook_id']; ?>">
|
||||
<button type="submit" class="btn-modern btn-mini danger">Supprimer</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
<section class="glass-card">
|
||||
<h2>Bannières disponibles</h2>
|
||||
<?php if (empty($banners)): ?>
|
||||
<div class="empty-state">Aucune bannière enregistrée pour le moment.</div>
|
||||
<?php else: ?>
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nom</th>
|
||||
<th>Prévisualisation</th>
|
||||
<th>Couleur</th>
|
||||
<th style="text-align:right;">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($banners as $banner): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<strong><?php echo htmlspecialchars($banner['cl_scbanner_name'], ENT_QUOTES, 'UTF-8'); ?></strong>
|
||||
</td>
|
||||
<td>
|
||||
<img class="banner-preview" src="<?php echo htmlspecialchars($banner['cl_scbanner_url'], ENT_QUOTES, 'UTF-8'); ?>" alt="Prévisualisation bannière">
|
||||
</td>
|
||||
<td>
|
||||
<span class="color-chip" style="--chip-color: <?php echo htmlspecialchars(scdiscord_normalize_hex_color((string) ($banner['cl_scbanner_border_color'] ?? '#ffae00')), ENT_QUOTES, 'UTF-8'); ?>;">
|
||||
<?php echo htmlspecialchars(scdiscord_normalize_hex_color((string) ($banner['cl_scbanner_border_color'] ?? '#ffae00')), ENT_QUOTES, 'UTF-8'); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="actions-inline">
|
||||
<button
|
||||
type="button"
|
||||
class="btn-modern btn-mini"
|
||||
onclick='editBanner(<?php echo json_encode([
|
||||
'id' => (int) $banner['cl_scbanner_id'],
|
||||
'name' => (string) $banner['cl_scbanner_name'],
|
||||
'url' => (string) $banner['cl_scbanner_url'],
|
||||
'border_color' => (string) ($banner['cl_scbanner_border_color'] ?? '#ffae00'),
|
||||
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>)'
|
||||
>Éditer</button>
|
||||
<form method="post" onsubmit="return confirm('Supprimer cette bannière ?');">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrf_token, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<input type="hidden" name="action" value="delete_banner">
|
||||
<input type="hidden" name="banner_id" value="<?php echo (int) $banner['cl_scbanner_id']; ?>">
|
||||
<button type="submit" class="btn-modern btn-mini danger">Supprimer</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function editWebhook(webhook) {
|
||||
document.getElementById('webhookFormTitle').textContent = 'Modifier le webhook Discord';
|
||||
document.getElementById('webhookAction').value = 'update_webhook';
|
||||
document.getElementById('webhookId').value = webhook.id || '';
|
||||
document.getElementById('cl_scwebhook_name').value = webhook.name || '';
|
||||
document.getElementById('cl_scwebhook_url').value = webhook.url || '';
|
||||
document.getElementById('cl_scwebhook_is_forum').checked = Number(webhook.is_forum || 0) === 1;
|
||||
document.getElementById('webhookSubmitBtn').textContent = 'Mettre à jour le webhook';
|
||||
document.getElementById('webhookCancelBtn').style.display = 'inline-flex';
|
||||
}
|
||||
|
||||
function resetWebhookForm() {
|
||||
document.getElementById('webhookFormTitle').textContent = 'Nouveau webhook Discord';
|
||||
document.getElementById('webhookAction').value = 'add_webhook';
|
||||
document.getElementById('webhookId').value = '';
|
||||
document.getElementById('cl_scwebhook_name').value = '';
|
||||
document.getElementById('cl_scwebhook_url').value = '';
|
||||
document.getElementById('cl_scwebhook_is_forum').checked = false;
|
||||
document.getElementById('webhookSubmitBtn').textContent = 'Ajouter le webhook';
|
||||
document.getElementById('webhookCancelBtn').style.display = 'none';
|
||||
}
|
||||
|
||||
function editBanner(banner) {
|
||||
document.getElementById('bannerFormTitle').textContent = 'Modifier la bannière';
|
||||
document.getElementById('bannerAction').value = 'update_banner';
|
||||
document.getElementById('bannerId').value = banner.id || '';
|
||||
document.getElementById('cl_scbanner_name').value = banner.name || '';
|
||||
document.getElementById('cl_scbanner_url').value = banner.url || '';
|
||||
document.getElementById('cl_scbanner_border_color').value = banner.border_color || '#ffae00';
|
||||
document.getElementById('bannerSubmitBtn').textContent = 'Mettre à jour la bannière';
|
||||
document.getElementById('bannerCancelBtn').style.display = 'inline-flex';
|
||||
}
|
||||
|
||||
function resetBannerForm() {
|
||||
document.getElementById('bannerFormTitle').textContent = 'Nouvelle bannière';
|
||||
document.getElementById('bannerAction').value = 'add_banner';
|
||||
document.getElementById('bannerId').value = '';
|
||||
document.getElementById('cl_scbanner_name').value = '';
|
||||
document.getElementById('cl_scbanner_url').value = '';
|
||||
document.getElementById('cl_scbanner_border_color').value = '#ffae00';
|
||||
document.getElementById('bannerSubmitBtn').textContent = 'Ajouter la bannière';
|
||||
document.getElementById('bannerCancelBtn').style.display = 'none';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user