acceptation regles

This commit is contained in:
Flatlogic Bot 2026-02-16 00:26:21 +00:00
parent f41686b17d
commit 79d65ef265
8 changed files with 299 additions and 6 deletions

59
api_v1_accept_rules.php Normal file
View File

@ -0,0 +1,59 @@
<?php
header('Content-Type: application/json');
require_once 'auth/session.php';
requireLogin();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$json = json_decode(file_get_contents('php://input'), true);
$channel_id = $json['channel_id'] ?? 0;
$user_id = $_SESSION['user_id'];
if (!$channel_id) {
echo json_encode(['success' => false, 'error' => 'ID de canal manquant']);
exit;
}
// Fetch channel details to get rules_role_id
$stmt = db()->prepare("SELECT * FROM channels WHERE id = ? AND type = 'rules'");
$stmt->execute([$channel_id]);
$channel = $stmt->fetch();
if (!$channel) {
echo json_encode(['success' => false, 'error' => 'Canal de règles introuvable']);
exit;
}
if (empty($channel['rules_role_id'])) {
echo json_encode(['success' => false, 'error' => 'Aucun rôle n\'est configuré pour ce canal']);
exit;
}
$role_id = $channel['rules_role_id'];
try {
db()->beginTransaction();
// 1. Record acceptance
$stmtAcc = db()->prepare("INSERT IGNORE INTO rule_acceptances (user_id, channel_id) VALUES (?, ?)");
$stmtAcc->execute([$user_id, $channel_id]);
// 2. Assign role
// Check if user already has this role
$stmtRoleCheck = db()->prepare("SELECT 1 FROM user_roles WHERE user_id = ? AND role_id = ?");
$stmtRoleCheck->execute([$user_id, $role_id]);
if (!$stmtRoleCheck->fetch()) {
$stmtRole = db()->prepare("INSERT INTO user_roles (user_id, role_id) VALUES (?, ?)");
$stmtRole->execute([$user_id, $role_id]);
}
db()->commit();
echo json_encode(['success' => true]);
} catch (Exception $e) {
db()->rollBack();
echo json_encode(['success' => false, 'error' => 'Erreur lors de l\'attribution du rôle : ' . $e->getMessage()]);
}
exit;
}
echo json_encode(['success' => false, 'error' => 'Méthode non autorisée']);

View File

@ -56,6 +56,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$icon = $_POST['icon'] ?? null;
if ($icon === '') $icon = null;
$category_id = !empty($_POST['category_id']) ? (int)$_POST['category_id'] : null;
$rules_role_id = !empty($_POST['rules_role_id']) ? (int)$_POST['rules_role_id'] : null;
// Check if user has permission to manage channels
$stmt = db()->prepare("SELECT server_id FROM channels WHERE id = ?");
@ -67,8 +68,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Allow spaces, accents and mixed case
$name = trim($name);
// Explicitly exclude position from update to prevent jumping to bottom
$stmt = db()->prepare("UPDATE channels SET name = ?, type = ?, status = ?, allow_file_sharing = ?, message_limit = ?, icon = ?, category_id = ? WHERE id = ?");
$stmt->execute([$name, $type, $status, $allow_file_sharing, $message_limit, $icon, $category_id, $channel_id]);
$stmt = db()->prepare("UPDATE channels SET name = ?, type = ?, status = ?, allow_file_sharing = ?, message_limit = ?, icon = ?, category_id = ?, rules_role_id = ? WHERE id = ?");
$stmt->execute([$name, $type, $status, $allow_file_sharing, $message_limit, $icon, $category_id, $rules_role_id, $channel_id]);
}
header('Location: index.php?server_id=' . $server_id . '&channel_id=' . $channel_id);
exit;
@ -103,6 +104,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$icon = $_POST['icon'] ?? null;
if ($icon === '') $icon = null;
$category_id = !empty($_POST['category_id']) ? (int)$_POST['category_id'] : null;
$rules_role_id = !empty($_POST['rules_role_id']) ? (int)$_POST['rules_role_id'] : null;
// Get next position
$stmtPos = db()->prepare("SELECT MAX(position) as max_pos FROM channels WHERE server_id = ?");
@ -110,8 +112,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$maxPos = $stmtPos->fetch();
$nextPos = ($maxPos['max_pos'] ?? -1) + 1;
$stmt = db()->prepare("INSERT INTO channels (server_id, name, type, allow_file_sharing, message_limit, icon, category_id, position) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$server_id, $name, $type, $allow_file_sharing, $message_limit, $icon, $category_id, $nextPos]);
$stmt = db()->prepare("INSERT INTO channels (server_id, name, type, allow_file_sharing, message_limit, icon, category_id, position, rules_role_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$server_id, $name, $type, $allow_file_sharing, $message_limit, $icon, $category_id, $nextPos, $rules_role_id]);
$channel_id = db()->lastInsertId();
header('Location: index.php?server_id=' . $server_id . '&channel_id=' . $channel_id);

50
api_v1_withdraw_rules.php Normal file
View File

@ -0,0 +1,50 @@
<?php
header('Content-Type: application/json');
require_once 'auth/session.php';
requireLogin();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$json = json_decode(file_get_contents('php://input'), true);
$channel_id = $json['channel_id'] ?? 0;
$user_id = $_SESSION['user_id'];
if (!$channel_id) {
echo json_encode(['success' => false, 'error' => 'ID de canal manquant']);
exit;
}
// Fetch channel details to get rules_role_id
$stmt = db()->prepare("SELECT * FROM channels WHERE id = ? AND type = 'rules'");
$stmt->execute([$channel_id]);
$channel = $stmt->fetch();
if (!$channel) {
echo json_encode(['success' => false, 'error' => 'Canal de règles introuvable']);
exit;
}
$role_id = $channel['rules_role_id'];
try {
db()->beginTransaction();
// 1. Remove acceptance record
$stmtAcc = db()->prepare("DELETE FROM rule_acceptances WHERE user_id = ? AND channel_id = ?");
$stmtAcc->execute([$user_id, $channel_id]);
// 2. Remove role if it was configured
if ($role_id) {
$stmtRole = db()->prepare("DELETE FROM user_roles WHERE user_id = ? AND role_id = ?");
$stmtRole->execute([$user_id, $role_id]);
}
db()->commit();
echo json_encode(['success' => true]);
} catch (Exception $e) {
db()->rollBack();
echo json_encode(['success' => false, 'error' => 'Erreur lors du retrait : ' . $e->getMessage()]);
}
exit;
}
echo json_encode(['success' => false, 'error' => 'Méthode non autorisée']);

View File

@ -1023,9 +1023,16 @@ document.addEventListener('DOMContentLoaded', () => {
modal.querySelector('#edit-channel-limit').value = btn.dataset.limit || '';
modal.querySelector('#edit-channel-status').value = btn.dataset.status || '';
modal.querySelector('#edit-channel-icon').value = btn.dataset.icon || '';
modal.querySelector('#edit-channel-rules-role').value = btn.dataset.rulesRole || '';
modal.querySelector('#edit-channel-category-id').value = btn.dataset.category || '';
modal.querySelector('#delete-channel-id').value = channelId;
// Toggle rules role visibility
const rulesRoleContainer = document.getElementById('edit-channel-rules-role-container');
if (rulesRoleContainer) {
rulesRoleContainer.style.display = (channelType === 'rules') ? 'block' : 'none';
}
// Reset delete zone
document.getElementById('delete-confirm-zone').style.display = 'none';
@ -1950,18 +1957,94 @@ document.addEventListener('DOMContentLoaded', () => {
}
});
// Rules Acceptance
document.getElementById('accept-rules-btn')?.addEventListener('click', async () => {
const btn = document.getElementById('accept-rules-btn');
btn.disabled = true;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span> Traitement...';
try {
const resp = await fetch('api_v1_accept_rules.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ channel_id: window.activeChannelId })
});
const data = await resp.json();
if (data.success) {
const container = document.getElementById('rules-acceptance-container');
container.innerHTML = '<div class="alert alert-success d-inline-block"><i class="fa-solid fa-check-circle me-2"></i> Vous avez accepté les règles.</div>';
// Reload roles in members list if possible, or just reload page
setTimeout(() => location.reload(), 1500);
} else {
alert(data.error || 'Erreur lors de l\'acceptation');
btn.disabled = false;
btn.innerHTML = '<i class="fa-solid fa-check me-2"></i> J\'accepte les règles';
}
} catch (e) {
console.error(e);
btn.disabled = false;
btn.innerHTML = '<i class="fa-solid fa-check me-2"></i> J\'accepte les règles';
}
});
document.getElementById('withdraw-rules-btn')?.addEventListener('click', async () => {
if (!confirm('Êtes-vous sûr de vouloir retirer votre acceptation des règles ? Vous perdrez le rôle associé.')) return;
const btn = document.getElementById('withdraw-rules-btn');
btn.disabled = true;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span> Traitement...';
try {
const resp = await fetch('api_v1_withdraw_rules.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ channel_id: window.activeChannelId })
});
const data = await resp.json();
if (data.success) {
location.reload();
} else {
alert(data.error || 'Erreur lors du retrait');
btn.disabled = false;
btn.innerHTML = '<i class="fa-solid fa-undo me-1"></i> Retirer mon acceptation';
}
} catch (e) {
console.error(e);
btn.disabled = false;
btn.innerHTML = '<i class="fa-solid fa-undo me-1"></i> Retirer mon acceptation';
}
});
// Channel Selection Type
const addChannelBtns = document.querySelectorAll('.add-channel-btn');
addChannelBtns.forEach(btn => {
btn.addEventListener('click', () => {
const type = btn.dataset.type;
const select = document.getElementById('channel-type-select');
const select = document.getElementById('add-channel-type'); // Corrected ID from index.php
if (select) {
select.value = type === 'voice' ? 'voice' : 'chat';
select.value = type === 'voice' ? 'voice' : (type || 'chat');
// Trigger change to update visibility
select.dispatchEvent(new Event('change'));
}
});
});
const addChannelTypeSelect = document.getElementById('add-channel-type');
addChannelTypeSelect?.addEventListener('change', (e) => {
const container = document.getElementById('add-channel-rules-role-container');
if (container) {
container.style.display = (e.target.value === 'rules') ? 'block' : 'none';
}
});
const editChannelTypeSelect = document.getElementById('edit-channel-type');
editChannelTypeSelect?.addEventListener('change', (e) => {
const container = document.getElementById('edit-channel-rules-role-container');
if (container) {
container.style.display = (e.target.value === 'rules') ? 'block' : 'none';
}
});
// User Settings - Avatar Search
const avatarSearchBtn = document.getElementById('search-avatar-btn');
const avatarSearchQuery = document.getElementById('avatar-search-query');

View File

@ -0,0 +1,12 @@
-- Add rules_role_id to channels and create rule_acceptances table
ALTER TABLE channels ADD COLUMN rules_role_id INT NULL;
CREATE TABLE IF NOT EXISTS rule_acceptances (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
channel_id INT NOT NULL,
accepted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY user_channel (user_id, channel_id),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (channel_id) REFERENCES channels(id) ON DELETE CASCADE
);

View File

@ -6,3 +6,6 @@
2026-02-15 23:39:45 - Server: 1 - Orders: [{"id":"11","position":0,"category_id":null},{"id":"12","position":1,"category_id":null},{"id":"10","position":2,"category_id":null},{"id":"1","position":3,"category_id":"10"},{"id":"6","position":4,"category_id":"10"},{"id":"2","position":5,"category_id":"10"},{"id":"9","position":6,"category_id":null},{"id":"3","position":7,"category_id":null}]
2026-02-15 23:40:11 - Server: 1 - Orders: [{"id":"11","position":0,"category_id":null},{"id":"12","position":1,"category_id":null},{"id":"10","position":2,"category_id":null},{"id":"1","position":3,"category_id":"10"},{"id":"6","position":4,"category_id":"10"},{"id":"2","position":5,"category_id":"10"},{"id":"13","position":6,"category_id":null},{"id":"9","position":7,"category_id":null},{"id":"3","position":8,"category_id":null}]
2026-02-15 23:40:20 - Server: 1 - Orders: [{"id":"11","position":0,"category_id":null},{"id":"12","position":1,"category_id":null},{"id":"10","position":2,"category_id":null},{"id":"1","position":3,"category_id":"10"},{"id":"6","position":4,"category_id":"10"},{"id":"2","position":5,"category_id":"10"},{"id":"14","position":6,"category_id":null},{"id":"13","position":7,"category_id":null},{"id":"9","position":8,"category_id":null},{"id":"3","position":9,"category_id":null}]
2026-02-16 00:15:14 - Server: 1 - Orders: [{"id":"11","position":0,"category_id":null},{"id":"12","position":1,"category_id":null},{"id":"10","position":2,"category_id":null},{"id":"1","position":3,"category_id":"10"},{"id":"6","position":4,"category_id":"10"},{"id":"15","position":5,"category_id":"10"},{"id":"2","position":6,"category_id":"10"},{"id":"14","position":7,"category_id":null},{"id":"13","position":8,"category_id":null},{"id":"9","position":9,"category_id":null},{"id":"3","position":10,"category_id":null}]
2026-02-16 00:17:23 - Server: 1 - Orders: [{"id":"11","position":0,"category_id":null},{"id":"12","position":1,"category_id":null},{"id":"10","position":2,"category_id":null},{"id":"1","position":3,"category_id":"10"},{"id":"6","position":4,"category_id":"10"},{"id":"15","position":5,"category_id":"10"},{"id":"2","position":6,"category_id":"10"},{"id":"14","position":7,"category_id":null},{"id":"13","position":8,"category_id":null},{"id":"9","position":9,"category_id":null},{"id":"3","position":10,"category_id":null}]
2026-02-16 00:17:31 - Server: 1 - Orders: [{"id":"11","position":0,"category_id":null},{"id":"12","position":1,"category_id":null},{"id":"10","position":2,"category_id":null},{"id":"1","position":3,"category_id":"10"},{"id":"6","position":4,"category_id":"10"},{"id":"15","position":5,"category_id":"10"},{"id":"2","position":6,"category_id":"10"},{"id":"14","position":7,"category_id":null},{"id":"13","position":8,"category_id":null},{"id":"9","position":9,"category_id":null},{"id":"3","position":10,"category_id":null}]

View File

@ -201,6 +201,11 @@ if ($is_dm_view) {
");
$stmt->execute([$active_server_id, $active_server_id, $active_server_id, $active_server_id]);
$members = $stmt->fetchAll();
// Fetch all server roles
$stmt = db()->prepare("SELECT * FROM roles WHERE server_id = ? ORDER BY position DESC");
$stmt->execute([$active_server_id]);
$server_roles = $stmt->fetchAll();
}
// SEO & Env tags
@ -349,6 +354,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
data-limit="0"
data-status=""
data-icon="<?php echo htmlspecialchars($c['icon'] ?? ''); ?>"
data-rules-role="<?php echo $c['rules_role_id'] ?? ''; ?>"
data-category="<?php echo $c['category_id'] ?? ''; ?>">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33 1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82 1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
</span>
@ -390,6 +396,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
data-limit="<?php echo $c['message_limit']; ?>"
data-status="<?php echo htmlspecialchars($c['status'] ?? ''); ?>"
data-icon="<?php echo htmlspecialchars($c['icon'] ?? ''); ?>"
data-rules-role="<?php echo $c['rules_role_id'] ?? ''; ?>"
data-category="<?php echo $c['category_id'] ?? ''; ?>">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33 1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82 1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
</span>
@ -425,6 +432,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
data-limit="0"
data-status=""
data-icon="<?php echo htmlspecialchars($item['icon'] ?? ''); ?>"
data-rules-role="<?php echo $item['rules_role_id'] ?? ''; ?>"
data-category=""
data-theme="">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33 1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82 1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
@ -608,6 +616,31 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
</div>
<button class="btn btn-primary mt-3" id="add-rule-btn">+ Ajouter une règle</button>
<?php endif; ?>
<?php if (!empty($active_channel['rules_role_id'])): ?>
<?php
$stmtAcc = db()->prepare("SELECT 1 FROM rule_acceptances WHERE user_id = ? AND channel_id = ?");
$stmtAcc->execute([$current_user_id, $active_channel_id]);
$has_accepted = $stmtAcc->fetch();
?>
<div class="mt-5 pt-4 border-top border-secondary text-center" id="rules-acceptance-container">
<?php if ($has_accepted): ?>
<div class="alert alert-success d-inline-block">
<i class="fa-solid fa-check-circle me-2"></i> Vous avez accepté les règles.
</div>
<div class="mt-2">
<button class="btn btn-sm btn-outline-danger" id="withdraw-rules-btn">
<i class="fa-solid fa-undo me-1"></i> Retirer mon acceptation
</button>
</div>
<?php else: ?>
<p class="text-muted mb-3">Veuillez accepter les règles pour obtenir l'accès complet.</p>
<button class="btn btn-lg btn-success px-5" id="accept-rules-btn">
<i class="fa-solid fa-check me-2"></i> J'accepte les règles
</button>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php elseif($channel_type === 'forum'): ?>
<div class="forum-container p-4">
@ -1138,6 +1171,15 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
<option value="fa-terminal">⌨️ Bot</option>
</select>
</div>
<div class="mb-3" id="add-channel-rules-role-container" style="display: none;">
<label class="form-label text-uppercase fw-bold" style="font-size: 0.7em; color: var(--text-muted);">Role granted upon acceptance</label>
<select name="rules_role_id" class="form-select bg-dark text-white border-secondary">
<option value="">No role assigned</option>
<?php foreach($server_roles as $role): ?>
<option value="<?php echo $role['id']; ?>"><?php echo htmlspecialchars($role['name']); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" name="allow_file_sharing" id="add-channel-files" value="1" checked>
<label class="form-check-label text-white" for="add-channel-files">Allow File Sharing</label>
@ -1243,6 +1285,15 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
<option value="fa-terminal">⌨️ Bot</option>
</select>
</div>
<div class="mb-3" id="edit-channel-rules-role-container" style="display: none;">
<label class="form-label text-uppercase fw-bold" style="font-size: 0.7em; color: var(--text-muted);">Role granted upon acceptance</label>
<select name="rules_role_id" id="edit-channel-rules-role" class="form-select bg-dark text-white border-secondary">
<option value="">No role assigned</option>
<?php foreach($server_roles as $role): ?>
<option value="<?php echo $role['id']; ?>"><?php echo htmlspecialchars($role['name']); ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
</div>

View File

@ -61,3 +61,36 @@
2026-02-15 23:59:43 - GET /?fl_project=38443 - POST: []
2026-02-16 00:02:15 - GET /index.php?server_id=1&channel_id=11 - POST: []
2026-02-16 00:02:20 - GET /index.php?server_id=1&channel_id=11 - POST: []
2026-02-16 00:06:51 - GET /?fl_project=38443 - POST: []
2026-02-16 00:11:43 - GET /?fl_project=38443 - POST: []
2026-02-16 00:13:38 - GET /index.php?server_id=1&channel_id=11 - POST: []
2026-02-16 00:13:47 - GET /index.php?server_id=1&channel_id=11 - POST: []
2026-02-16 00:13:53 - GET /index.php?server_id=1&channel_id=11 - POST: []
2026-02-16 00:14:45 - GET /index.php?server_id=1&channel_id=11 - POST: []
2026-02-16 00:15:11 - GET /index.php?server_id=1&channel_id=15 - POST: []
2026-02-16 00:15:42 - GET /index.php?server_id=1&channel_id=11 - POST: []
2026-02-16 00:15:56 - GET /index.php?server_id=1&channel_id=11 - POST: []
2026-02-16 00:16:00 - GET /index.php?server_id=1&channel_id=11 - POST: []
2026-02-16 00:16:00 - GET /index.php?server_id=1&channel_id=11 - POST: []
2026-02-16 00:17:19 - GET /index.php?server_id=1&channel_id=15 - POST: []
2026-02-16 00:17:27 - GET /index.php?server_id=1&channel_id=15 - POST: []
2026-02-16 00:17:35 - GET /index.php?server_id=1&channel_id=6 - POST: []
2026-02-16 00:17:46 - GET /index.php?server_id=1&channel_id=15 - POST: []
2026-02-16 00:17:58 - GET /index.php?server_id=1&channel_id=6 - POST: []
2026-02-16 00:18:04 - GET /index.php?server_id=1&channel_id=15 - POST: []
2026-02-16 00:18:12 - GET /index.php?server_id=1&channel_id=6 - POST: []
2026-02-16 00:18:15 - GET /index.php?server_id=1&channel_id=1 - POST: []
2026-02-16 00:18:17 - GET /index.php?server_id=1&channel_id=15 - POST: []
2026-02-16 00:18:19 - GET /index.php?server_id=1&channel_id=2 - POST: []
2026-02-16 00:18:25 - GET /index.php?server_id=1&channel_id=1 - POST: []
2026-02-16 00:18:27 - GET /index.php?server_id=1&channel_id=11 - POST: []
2026-02-16 00:19:28 - GET /?fl_project=38443 - POST: []
2026-02-16 00:23:03 - GET /index.php?server_id=1&channel_id=11 - POST: []
2026-02-16 00:23:08 - GET /index.php?server_id=1&channel_id=11 - POST: []
2026-02-16 00:23:14 - GET /index.php?server_id=1&channel_id=11 - POST: []
2026-02-16 00:23:19 - GET /index.php?server_id=1&channel_id=11 - POST: []
2026-02-16 00:24:37 - GET /index.php?server_id=1&channel_id=1 - POST: []
2026-02-16 00:24:58 - GET /index.php?server_id=1&channel_id=1 - POST: []
2026-02-16 00:25:16 - GET /index.php?server_id=1&channel_id=6 - POST: []
2026-02-16 00:25:18 - GET /index.php?server_id=1&channel_id=15 - POST: []
2026-02-16 00:25:27 - GET /index.php?server_id=1&channel_id=2 - POST: []