757 lines
52 KiB
PHP
757 lines
52 KiB
PHP
<?php
|
||
if(empty($_SESSION['is_admin'])) die("Access Denied");
|
||
|
||
// ── DB Migrations ─────────────────────────────────────────────────────────────
|
||
try { $pdo->exec("ALTER TABLE users ADD COLUMN profile_pic TEXT DEFAULT NULL"); } catch(Exception $e) {}
|
||
try { $pdo->exec("ALTER TABLE users ADD COLUMN waha_endpoint TEXT DEFAULT NULL"); } catch(Exception $e) {}
|
||
try { $pdo->exec("ALTER TABLE users ADD COLUMN waha_chat_id TEXT DEFAULT NULL"); } catch(Exception $e) {}
|
||
try { $pdo->exec("ALTER TABLE users ADD COLUMN waha_session TEXT DEFAULT 'default'"); } catch(Exception $e) {}
|
||
try { $pdo->exec("ALTER TABLE users ADD COLUMN waha_api_key TEXT DEFAULT NULL"); } catch(Exception $e) {}
|
||
try { $pdo->exec("ALTER TABLE users ADD COLUMN waha_template_task TEXT DEFAULT NULL"); } catch(Exception $e) {}
|
||
try { $pdo->exec("ALTER TABLE users ADD COLUMN waha_template_note TEXT DEFAULT NULL"); } catch(Exception $e) {}
|
||
try { $pdo->exec("ALTER TABLE users ADD COLUMN waha_template_password TEXT DEFAULT NULL"); } catch(Exception $e) {}
|
||
try { $pdo->exec("ALTER TABLE users ADD COLUMN waha_template_file TEXT DEFAULT NULL"); } catch(Exception $e) {}
|
||
|
||
try { $pdo->exec("ALTER TABLE groups ADD COLUMN notify_channels TEXT DEFAULT NULL"); } catch(Exception $e) {}
|
||
try { $pdo->exec("ALTER TABLE groups ADD COLUMN waha_endpoint TEXT DEFAULT NULL"); } catch(Exception $e) {}
|
||
try { $pdo->exec("ALTER TABLE groups ADD COLUMN waha_chat_id TEXT DEFAULT NULL"); } catch(Exception $e) {}
|
||
try { $pdo->exec("ALTER TABLE groups ADD COLUMN waha_api_key TEXT DEFAULT NULL"); } catch(Exception $e) {}
|
||
try { $pdo->exec("ALTER TABLE groups ADD COLUMN waha_session TEXT DEFAULT 'default'"); } catch(Exception $e) {}
|
||
try { $pdo->exec("ALTER TABLE groups ADD COLUMN waha_template_task TEXT DEFAULT NULL"); } catch(Exception $e) {}
|
||
try { $pdo->exec("ALTER TABLE groups ADD COLUMN waha_template_note TEXT DEFAULT NULL"); } catch(Exception $e) {}
|
||
try { $pdo->exec("ALTER TABLE groups ADD COLUMN waha_template_password TEXT DEFAULT NULL"); } catch(Exception $e) {}
|
||
try { $pdo->exec("ALTER TABLE groups ADD COLUMN waha_template_file TEXT DEFAULT NULL"); } catch(Exception $e) {}
|
||
try { $pdo->exec("ALTER TABLE groups ADD COLUMN profile_pic TEXT DEFAULT NULL"); } catch(Exception $e) {}
|
||
try {
|
||
$pdo->exec("CREATE TABLE IF NOT EXISTS system_config (k TEXT PRIMARY KEY, v TEXT)");
|
||
$pdo->exec("INSERT OR IGNORE INTO system_config (k, v) VALUES ('completed_days', '7')");
|
||
$pdo->exec("INSERT OR IGNORE INTO system_config (k, v) VALUES ('archived_days', '90')");
|
||
} catch(Exception $e) {}
|
||
|
||
// ── Handle POST ───────────────────────────────────────────────────────────────
|
||
$success_msg = '';
|
||
$error_msg = '';
|
||
|
||
if($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||
if(isset($_POST['create_user'])) {
|
||
$username = trim($_POST['username']);
|
||
$pass = password_hash($_POST['password'], PASSWORD_DEFAULT);
|
||
$is_admin = isset($_POST['is_admin']) ? 1 : 0;
|
||
try {
|
||
$stmt = $pdo->prepare("INSERT INTO users (username, password_hash, is_admin) VALUES (?, ?, ?)");
|
||
$stmt->execute([$username, $pass, $is_admin]);
|
||
$success_msg = "User '{$username}' created successfully!";
|
||
} catch(Exception $e) {
|
||
$error_msg = "Error: Username may already exist.";
|
||
}
|
||
}
|
||
|
||
if(isset($_POST['delete_user'])) {
|
||
$del_id = (int)$_POST['del_user_id'];
|
||
if($del_id != $user_id) {
|
||
$pdo->prepare("DELETE FROM users WHERE id=?")->execute([$del_id]);
|
||
$success_msg = "User deleted.";
|
||
} else {
|
||
$error_msg = "You cannot delete your own account.";
|
||
}
|
||
}
|
||
|
||
if(isset($_POST['toggle_admin'])) {
|
||
$tid = (int)$_POST['toggle_user_id'];
|
||
$newVal = (int)$_POST['new_admin_val'];
|
||
if($tid != $user_id) {
|
||
$pdo->prepare("UPDATE users SET is_admin=? WHERE id=?")->execute([$newVal, $tid]);
|
||
$success_msg = "User admin status updated.";
|
||
}
|
||
}
|
||
|
||
if(isset($_POST['create_group'])) {
|
||
try {
|
||
$name = trim($_POST['group_name']);
|
||
$pic_path = null;
|
||
if(isset($_FILES['group_pic']) && $_FILES['group_pic']['error'] === UPLOAD_ERR_OK) {
|
||
$ext = pathinfo($_FILES['group_pic']['name'], PATHINFO_EXTENSION);
|
||
$pic_path = 'uploads/group_' . time() . '_' . uniqid() . '.' . $ext;
|
||
move_uploaded_file($_FILES['group_pic']['tmp_name'], $pic_path);
|
||
}
|
||
$stmt = $pdo->prepare("INSERT INTO groups (name, profile_pic) VALUES (?, ?)");
|
||
$stmt->execute([$name, $pic_path]);
|
||
$success_msg = "Group '{$name}' created!";
|
||
} catch(Exception $e) {
|
||
$error_msg = "Error: Group name may already exist.";
|
||
}
|
||
}
|
||
|
||
if(isset($_POST['delete_group'])) {
|
||
$gid = (int)$_POST['del_group_id'];
|
||
$pdo->prepare("DELETE FROM groups WHERE id=?")->execute([$gid]);
|
||
$success_msg = "Group deleted.";
|
||
}
|
||
|
||
if(isset($_POST['assign_group'])) {
|
||
$stmt = $pdo->prepare("INSERT OR IGNORE INTO user_groups (user_id, group_id) VALUES (?, ?)");
|
||
$stmt->execute([$_POST['user_id'], $_POST['group_id']]);
|
||
$success_msg = "User assigned to group.";
|
||
}
|
||
|
||
if(isset($_POST['remove_from_group'])) {
|
||
$pdo->prepare("DELETE FROM user_groups WHERE user_id=? AND group_id=?")->execute([$_POST['user_id'], $_POST['group_id']]);
|
||
$success_msg = "User removed from group.";
|
||
}
|
||
|
||
if(isset($_POST['update_user_channels'])) {
|
||
$ch = $_POST['channels'] ?? [];
|
||
$ch_str = is_array($ch) ? implode(',', $ch) : '';
|
||
$waha_ep = trim($_POST['waha_endpoint'] ?? '');
|
||
$waha_cid = trim($_POST['waha_chat_id'] ?? '');
|
||
$waha_ses = trim($_POST['waha_session'] ?? '') ?: 'default';
|
||
$waha_key = trim($_POST['waha_api_key'] ?? '');
|
||
$tpl_task = trim($_POST['waha_template_task'] ?? '');
|
||
$tpl_note = trim($_POST['waha_template_note'] ?? '');
|
||
$tpl_pass = trim($_POST['waha_template_password'] ?? '');
|
||
$tpl_file = trim($_POST['waha_template_file'] ?? '');
|
||
|
||
$stmt = $pdo->prepare("UPDATE users SET notify_channels=?, telegram_id=?, email=?, whatsapp_number=?, waha_endpoint=?, waha_chat_id=?, waha_template_task=?, waha_template_note=?, waha_template_password=?, waha_template_file=?, waha_session=?, waha_api_key=? WHERE id=?");
|
||
$stmt->execute([$ch_str, $_POST['telegram_id'], $_POST['email'], $_POST['whatsapp_number'], $waha_ep ?: null, $waha_cid ?: null, $tpl_task ?: null, $tpl_note ?: null, $tpl_pass ?: null, $tpl_file ?: null, $waha_ses, $waha_key ?: null, $_POST['user_id']]);
|
||
$success_msg = "User notification preferences updated!";
|
||
}
|
||
|
||
if(isset($_POST['update_group_channels'])) {
|
||
$ch = $_POST['channels'] ?? [];
|
||
$ch_str = is_array($ch) ? implode(',', $ch) : '';
|
||
$waha_ep = trim($_POST['waha_endpoint'] ?? '');
|
||
$waha_cid = trim($_POST['waha_chat_id'] ?? '');
|
||
$waha_ses = trim($_POST['waha_session'] ?? '') ?: 'default';
|
||
$waha_key = trim($_POST['waha_api_key'] ?? '');
|
||
$tpl_task = trim($_POST['waha_template_task'] ?? '');
|
||
$tpl_note = trim($_POST['waha_template_note'] ?? '');
|
||
$tpl_pass = trim($_POST['waha_template_password'] ?? '');
|
||
$tpl_file = trim($_POST['waha_template_file'] ?? '');
|
||
$group_id = $_POST['group_id'];
|
||
$name = trim($_POST['group_name'] ?? '');
|
||
|
||
// Handle profile pic update
|
||
$pic_sql = "";
|
||
$pic_params = [];
|
||
if(isset($_POST['remove_pic']) && $_POST['remove_pic'] == '1') {
|
||
$old = query("SELECT profile_pic FROM groups WHERE id=?", [$group_id])->fetch();
|
||
if($old && $old['profile_pic'] && file_exists($old['profile_pic'])) @unlink($old['profile_pic']);
|
||
$pic_sql = ", profile_pic = NULL";
|
||
} elseif(isset($_FILES['group_pic']) && $_FILES['group_pic']['error'] === UPLOAD_ERR_OK) {
|
||
$old = query("SELECT profile_pic FROM groups WHERE id=?", [$group_id])->fetch();
|
||
if($old && $old['profile_pic'] && file_exists($old['profile_pic'])) @unlink($old['profile_pic']);
|
||
$ext = pathinfo($_FILES['group_pic']['name'], PATHINFO_EXTENSION);
|
||
$new_path = 'uploads/group_' . time() . '_' . uniqid() . '.' . $ext;
|
||
move_uploaded_file($_FILES['group_pic']['tmp_name'], $new_path);
|
||
$pic_sql = ", profile_pic = ?";
|
||
$pic_params[] = $new_path;
|
||
}
|
||
|
||
$sql = "UPDATE groups SET notify_channels=?, waha_endpoint=?, waha_chat_id=?, waha_template_task=?, waha_template_note=?, waha_template_password=?, waha_template_file=?, waha_session=?, waha_api_key=?, name=? $pic_sql WHERE id=?";
|
||
try {
|
||
$stmt = $pdo->prepare($sql);
|
||
$stmt->execute(array_merge([$ch_str, $waha_ep ?: null, $waha_cid ?: null, $tpl_task ?: null, $tpl_note ?: null, $tpl_pass ?: null, $tpl_file ?: null, $waha_ses, $waha_key ?: null, $name], $pic_params, [$group_id]));
|
||
$success_msg = "Group settings updated!";
|
||
} catch(Exception $e) {
|
||
$error_msg = "Error: Group name may already exist.";
|
||
}
|
||
}
|
||
|
||
if(isset($_POST['update_sys_config'])) {
|
||
$stmt = $pdo->prepare("UPDATE system_config SET v=? WHERE k=?");
|
||
$stmt->execute([$_POST['completed_days'] ?? 7, 'completed_days']);
|
||
$stmt->execute([$_POST['archived_days'] ?? 90, 'archived_days']);
|
||
$success_msg = "System configuration saved!";
|
||
}
|
||
}
|
||
|
||
// ── Fetch Data ────────────────────────────────────────────────────────────────
|
||
$users = query("SELECT id, username, is_admin, notify_channels, telegram_id, email, whatsapp_number, profile_pic, waha_endpoint, waha_chat_id, waha_template_task, waha_template_note, waha_template_password, waha_template_file, waha_session, waha_api_key FROM users ORDER BY is_admin DESC, username ASC")->fetchAll();
|
||
$all_groups = query("SELECT * FROM groups ORDER BY name")->fetchAll();
|
||
$conf_comp = query("SELECT v FROM system_config WHERE k='completed_days'")->fetchColumn() ?: 7;
|
||
$conf_arch = query("SELECT v FROM system_config WHERE k='archived_days'")->fetchColumn() ?: 90;
|
||
$waha_endpoint = query("SELECT v FROM system_config WHERE k='waha_endpoint'")->fetchColumn() ?: '';
|
||
$waha_chat_id = query("SELECT v FROM system_config WHERE k='waha_chat_id'")->fetchColumn() ?: '';
|
||
$waha_template = query("SELECT v FROM system_config WHERE k='waha_template'")->fetchColumn() ?: '';
|
||
|
||
// Activity stats for admin
|
||
$total_users = count($users);
|
||
$total_groups = count($all_groups);
|
||
$total_tasks = query("SELECT COUNT(*) FROM tasks")->fetchColumn();
|
||
$total_notes = 0; try { $total_notes = query("SELECT COUNT(*) FROM notes")->fetchColumn(); } catch(Exception $e) {}
|
||
$total_passwords = query("SELECT COUNT(*) FROM passwords")->fetchColumn();
|
||
$total_projects = query("SELECT COUNT(*) FROM projects")->fetchColumn();
|
||
|
||
// Activity log (recent, all users)
|
||
$recent_activity = [];
|
||
try {
|
||
$recent_activity = $pdo->query("SELECT al.*, u.username FROM activity_log al LEFT JOIN users u ON al.user_id=u.id ORDER BY al.created_at DESC LIMIT 20")->fetchAll();
|
||
} catch(Exception $e) {}
|
||
|
||
$active_tab = $_GET['tab'] ?? 'overview';
|
||
?>
|
||
|
||
<div class="header" style="margin-bottom:1rem;">
|
||
<h1 style="font-size:1.5rem; font-weight:700;"><i class="fa fa-shield-halved" style="color:var(--primary);"></i> Admin Panel</h1>
|
||
<span style="font-size:0.8rem; background:rgba(var(--primary-rgb),0.1); color:var(--primary); padding:4px 12px; border-radius:20px; font-weight:700;">ADMIN</span>
|
||
</div>
|
||
|
||
<?php if($success_msg): ?>
|
||
<div class="alert" style="background:rgba(16,185,129,0.12); color:#10B981; border:1px solid rgba(16,185,129,0.3); margin-bottom:1rem;"><?= htmlspecialchars($success_msg) ?></div>
|
||
<?php endif; ?>
|
||
<?php if($error_msg): ?>
|
||
<div class="alert" style="margin-bottom:1rem;"><?= htmlspecialchars($error_msg) ?></div>
|
||
<?php endif; ?>
|
||
|
||
<!-- ── Tabs ──────────────────────────────────────────────────────────────── -->
|
||
<div class="admin-tabs">
|
||
<button class="admin-tab <?= $active_tab==='overview'?'active':'' ?>" onclick="switchTab('overview')"><i class="fa fa-chart-line"></i> Overview</button>
|
||
<button class="admin-tab <?= $active_tab==='users'?'active':'' ?>" onclick="switchTab('users')"><i class="fa fa-users"></i> Users</button>
|
||
<button class="admin-tab <?= $active_tab==='groups'?'active':'' ?>" onclick="switchTab('groups')"><i class="fa fa-people-group"></i> Groups</button>
|
||
<button class="admin-tab <?= $active_tab==='channels'?'active':'' ?>" onclick="switchTab('channels')"><i class="fa fa-bell"></i> Notifications</button>
|
||
<button class="admin-tab <?= $active_tab==='config'?'active':'' ?>" onclick="switchTab('config')"><i class="fa fa-gear"></i> System Config</button>
|
||
</div>
|
||
|
||
<!-- ── Overview Tab ──────────────────────────────────────────────────────── -->
|
||
<div class="admin-tab-pane <?= $active_tab==='overview'?'active':'' ?>" id="tab-overview">
|
||
<!-- Stats Grid -->
|
||
<div style="display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:1rem; margin-bottom:1.5rem;">
|
||
<?php
|
||
$stats = [
|
||
['👤','Users',$total_users,'var(--primary)'],
|
||
['👥','Groups',$total_groups,'#10B981'],
|
||
['✅','Tasks',$total_tasks,'#F59E0B'],
|
||
['📝','Notes',$total_notes,'#8B5CF6'],
|
||
['🔐','Passwords',$total_passwords,'#EF4444'],
|
||
['📁','Projects',$total_projects,'#06B6D4'],
|
||
];
|
||
foreach($stats as [$icon,$label,$val,$col]):
|
||
?>
|
||
<div class="db-stat-card" style="border-top:3px solid <?= $col ?>; gap:0.35rem; padding:1rem;">
|
||
<div style="font-size:0.75rem; color:var(--text-light); font-weight:600; text-transform:uppercase;"><?= $label ?></div>
|
||
<div style="font-size:1.8rem; font-weight:700; color:<?= $col ?>;"><?= $icon ?> <?= $val ?></div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
|
||
<!-- Recent Activity -->
|
||
<div class="card">
|
||
<h3 style="font-size:1rem; font-weight:700; margin-bottom:1rem;">🕓 Recent Platform Activity</h3>
|
||
<?php if(empty($recent_activity)): ?>
|
||
<p style="color:var(--text-light); font-size:0.85rem;">No activity recorded yet.</p>
|
||
<?php else: ?>
|
||
<div style="display:flex; flex-direction:column; gap:0.5rem; max-height:320px; overflow-y:auto;">
|
||
<?php
|
||
$aic = ['#4F46E5','#10B981','#F59E0B','#EF4444','#8B5CF6'];
|
||
foreach($recent_activity as $log):
|
||
$t = strtotime($log['created_at']);
|
||
$diff = time()-$t;
|
||
$ago = $diff<60?'just now':($diff<3600?floor($diff/60).'m ago':($diff<86400?floor($diff/3600).'h ago':floor($diff/86400).'d ago'));
|
||
$col = $aic[crc32($log['username']??'')%count($aic)];
|
||
$init = strtoupper(mb_substr($log['username']??'S',0,1));
|
||
?>
|
||
<div class="log-item">
|
||
<div class="log-avatar" style="background:<?= $col ?>; flex-shrink:0;"><?= $init ?></div>
|
||
<div class="log-body">
|
||
<strong><?= htmlspecialchars($log['username']??'System') ?></strong>
|
||
<span class="log-detail"> · <?= htmlspecialchars($log['action']) ?><?= $log['detail']?' — '.htmlspecialchars(mb_substr($log['detail'],0,40)):'' ?></span>
|
||
</div>
|
||
<div class="log-time"><?= $ago ?></div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── Users Tab ─────────────────────────────────────────────────────────── -->
|
||
<div class="admin-tab-pane <?= $active_tab==='users'?'active':'' ?>" id="tab-users">
|
||
<div style="display:grid; grid-template-columns:340px 1fr; gap:1.5rem; align-items:start;">
|
||
<!-- Create User Form -->
|
||
<div class="card">
|
||
<h3 style="font-size:1rem; font-weight:700; margin-bottom:1rem;"><i class="fa fa-user-plus"></i> Create New User</h3>
|
||
<form method="POST">
|
||
<div class="form-group">
|
||
<label>Username</label>
|
||
<input type="text" name="username" class="form-control" placeholder="Enter username" required>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Password</label>
|
||
<input type="password" name="password" class="form-control" placeholder="Set password" required>
|
||
</div>
|
||
<div class="form-group" style="display:flex; align-items:center; gap:0.5rem;">
|
||
<input type="checkbox" name="is_admin" id="new-user-admin" style="width:auto;">
|
||
<label for="new-user-admin" style="margin:0; font-weight:500;">Grant Admin Privileges</label>
|
||
</div>
|
||
<button type="submit" name="create_user" class="btn" style="width:100%;">
|
||
<i class="fa fa-plus"></i> Create User
|
||
</button>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- User Cards -->
|
||
<div>
|
||
<h3 style="font-size:1rem; font-weight:700; margin-bottom:1rem;"><i class="fa fa-users"></i> All Users (<?= $total_users ?>)</h3>
|
||
<div class="admin-user-grid">
|
||
<?php foreach($users as $u):
|
||
$pic = $u['profile_pic'] ?? null;
|
||
$groups_of_u = query("SELECT g.name FROM groups g JOIN user_groups ug ON g.id=ug.group_id WHERE ug.user_id=?", [$u['id']])->fetchAll();
|
||
?>
|
||
<div class="admin-user-card">
|
||
<div class="admin-user-card-header">
|
||
<div class="admin-user-avatar">
|
||
<?php if($pic && file_exists($pic)): ?>
|
||
<img src="<?= htmlspecialchars($pic) ?>" style="width:100%;height:100%;object-fit:cover;border-radius:50%;" alt="">
|
||
<?php else: ?>
|
||
<?= strtoupper(mb_substr($u['username'],0,1)) ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
<div style="flex:1; min-width:0;">
|
||
<div style="font-weight:700; font-size:0.9rem; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;"><?= htmlspecialchars($u['username']) ?></div>
|
||
<div style="margin-top:2px;">
|
||
<span class="<?= $u['is_admin'] ? 'admin-badge-admin' : 'admin-badge-user' ?>">
|
||
<?= $u['is_admin'] ? 'Admin' : 'User' ?>
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div style="font-size:0.75rem; color:var(--text-light); margin-bottom:0.75rem;">
|
||
<?php if($groups_of_u): ?>
|
||
<i class="fa fa-users" style="margin-right:4px;"></i>
|
||
<?= implode(', ', array_map(fn($g)=>htmlspecialchars($g['name']), $groups_of_u)) ?>
|
||
<?php else: ?>
|
||
<span style="font-style:italic;">No groups</span>
|
||
<?php endif; ?>
|
||
</div>
|
||
<!-- Actions -->
|
||
<div style="display:flex; gap:0.4rem; flex-wrap:wrap;">
|
||
<?php if($u['id'] != $user_id): ?>
|
||
<!-- Toggle admin -->
|
||
<form method="POST" style="display:inline;">
|
||
<input type="hidden" name="toggle_user_id" value="<?= $u['id'] ?>">
|
||
<input type="hidden" name="new_admin_val" value="<?= $u['is_admin']?0:1 ?>">
|
||
<button type="submit" name="toggle_admin" class="btn btn-sm btn-secondary" title="<?= $u['is_admin']?'Revoke Admin':'Grant Admin' ?>">
|
||
<i class="fa fa-<?= $u['is_admin']?'user-minus':'user-shield' ?>"></i>
|
||
</button>
|
||
</form>
|
||
<!-- Delete -->
|
||
<form method="POST" style="display:inline;" onsubmit="event.preventDefault(); appConfirm('Delete user <?= htmlspecialchars(addslashes($u['username'])) ?>?').then(y => { if(y) { this.onsubmit=null; this.submit(); } })">
|
||
<input type="hidden" name="del_user_id" value="<?= $u['id'] ?>">
|
||
<button type="submit" name="delete_user" class="btn btn-sm btn-danger" title="Delete user">
|
||
<i class="fa fa-trash"></i>
|
||
</button>
|
||
</form>
|
||
<?php else: ?>
|
||
<span style="font-size:0.75rem; color:var(--primary); font-style:italic; padding:4px 0;">(You)</span>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── Groups Tab ────────────────────────────────────────────────────────── -->
|
||
<div class="admin-tab-pane <?= $active_tab==='groups'?'active':'' ?>" id="tab-groups">
|
||
<div style="display:grid; grid-template-columns:340px 1fr; gap:1.5rem; align-items:start;">
|
||
<!-- Create Group + Assign -->
|
||
<div>
|
||
<div class="card">
|
||
<h3 style="font-size:1rem; font-weight:700; margin-bottom:1.25rem;"><i class="fa fa-folder-plus"></i> Create Group</h3>
|
||
<form method="POST" enctype="multipart/form-data">
|
||
<div class="form-group">
|
||
<label>Group Name</label>
|
||
<input type="text" name="group_name" class="form-control" placeholder="Enter group name" required>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Profile Picture</label>
|
||
<input type="file" name="group_pic" class="form-control" accept="image/*">
|
||
</div>
|
||
<button type="submit" name="create_group" class="btn" style="width:100%"><i class="fa fa-plus"></i> Create Group</button>
|
||
</form>
|
||
</div>
|
||
<div class="card">
|
||
<h3 style="font-size:1rem; font-weight:700; margin-bottom:1rem;"><i class="fa fa-user-plus"></i> Assign User to Group</h3>
|
||
<form method="POST">
|
||
<div class="form-group">
|
||
<label>User</label>
|
||
<select name="user_id" class="form-control" required>
|
||
<option value="">Select user...</option>
|
||
<?php foreach($users as $u): ?><option value="<?= $u['id'] ?>"><?= htmlspecialchars($u['username']) ?></option><?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Group</label>
|
||
<select name="group_id" class="form-control" required>
|
||
<option value="">Select group...</option>
|
||
<?php foreach($all_groups as $g): ?><option value="<?= $g['id'] ?>"><?= htmlspecialchars($g['name']) ?></option><?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
<button type="submit" name="assign_group" class="btn" style="width:100%;"><i class="fa fa-link"></i> Assign</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Groups Breakdown -->
|
||
<div>
|
||
<h3 style="font-size:1rem; font-weight:700; margin-bottom:1rem;"><i class="fa fa-people-group"></i> All Groups (<?= $total_groups ?>)</h3>
|
||
<?php if(!$all_groups): ?>
|
||
<p style="color:var(--text-light);">No groups created yet.</p>
|
||
<?php endif; ?>
|
||
<div style="display:flex; flex-direction:column; gap:1rem;">
|
||
<?php foreach($all_groups as $g):
|
||
$stmt = $pdo->prepare("SELECT u.id, u.username FROM users u JOIN user_groups ug ON u.id=ug.user_id WHERE ug.group_id=?");
|
||
$stmt->execute([$g['id']]);
|
||
$g_users = $stmt->fetchAll();
|
||
?>
|
||
<div class="card" style="margin-bottom:0;">
|
||
<form method="POST" enctype="multipart/form-data">
|
||
<input type="hidden" name="update_group_channels" value="1">
|
||
<input type="hidden" name="group_id" value="<?= $g['id'] ?>">
|
||
<input type="hidden" name="group_name" value="<?= htmlspecialchars($g['name']) ?>">
|
||
<div style="display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:0.75rem;">
|
||
<div style="display:flex; align-items:center; gap:0.75rem;">
|
||
<div class="admin-user-avatar" style="width:42px; height:42px; font-size:1rem;">
|
||
<?php if($g['profile_pic'] && file_exists($g['profile_pic'])): ?>
|
||
<img src="<?= htmlspecialchars($g['profile_pic']) ?>" style="width:100%;height:100%;object-fit:cover;border-radius:50%;">
|
||
<?php else: ?>
|
||
<?= strtoupper(mb_substr($g['name'],0,1)) ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
<div>
|
||
<input type="text" name="group_name" value="<?= htmlspecialchars($g['name']) ?>" class="form-control" style="font-weight:700; font-size:1rem; color:var(--primary); background:transparent; border:none; padding:0; height:auto; width:100%;" onchange="this.form.submit()">
|
||
<div style="font-size:0.75rem; color:var(--text-light);"><?= count($g_users) ?> member<?= count($g_users)!=1?'s':'' ?></div>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex; gap:0.4rem;">
|
||
<label class="btn btn-sm btn-secondary" style="cursor:pointer;" title="Change Picture">
|
||
<i class="fa fa-camera"></i>
|
||
<input type="file" name="group_pic" style="display:none;" onchange="this.form.submit()">
|
||
</label>
|
||
<?php if($g['profile_pic']): ?>
|
||
<button type="submit" name="remove_pic" value="1" class="btn btn-sm btn-secondary" title="Remove Picture" onclick="return confirm('Remove profile picture?')"><i class="fa fa-image-slash"></i></button>
|
||
<?php endif; ?>
|
||
<button type="button" class="btn btn-sm btn-danger" onclick="appConfirm('Delete group <?= htmlspecialchars(addslashes($g['name'])) ?>?').then(y => { if(y) { document.getElementById('del-group-<?= $g['id'] ?>').submit(); } })"><i class="fa fa-trash"></i></button>
|
||
</div>
|
||
</div>
|
||
<!-- Hidden inputs for templates to preserve them when updating from here -->
|
||
<div style="display:none;">
|
||
<input type="text" name="waha_endpoint" value="<?= htmlspecialchars($g['waha_endpoint']??'') ?>">
|
||
<input type="text" name="waha_chat_id" value="<?= htmlspecialchars($g['waha_chat_id']??'') ?>">
|
||
<input type="text" name="waha_session" value="<?= htmlspecialchars($g['waha_session']??'default') ?>">
|
||
<input type="text" name="waha_api_key" value="<?= htmlspecialchars($g['waha_api_key']??'') ?>">
|
||
<textarea name="waha_template_task"><?= htmlspecialchars($g['waha_template_task']??'') ?></textarea>
|
||
<textarea name="waha_template_note"><?= htmlspecialchars($g['waha_template_note']??'') ?></textarea>
|
||
<textarea name="waha_template_password"><?= htmlspecialchars($g['waha_template_password']??'') ?></textarea>
|
||
<textarea name="waha_template_file"><?= htmlspecialchars($g['waha_template_file']??'') ?></textarea>
|
||
<?php $channels = explode(',', $g['notify_channels']??''); foreach($channels as $c): if(!$c) continue; ?>
|
||
<input type="checkbox" name="channels[]" value="<?= $c ?>" checked>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</form>
|
||
<form method="POST" id="del-group-<?= $g['id'] ?>" style="display:none;"><input type="hidden" name="del_group_id" value="<?= $g['id'] ?>"><input type="hidden" name="delete_group" value="1"></form>
|
||
<?php if($g_users): ?>
|
||
<div style="display:flex; flex-wrap:wrap; gap:0.5rem;">
|
||
<?php foreach($g_users as $gu): ?>
|
||
<div style="display:flex; align-items:center; gap:0.35rem; background:rgba(var(--primary-rgb),0.07); border-radius:20px; padding:4px 10px;">
|
||
<span style="font-size:0.8rem; font-weight:600;"><?= htmlspecialchars($gu['username']) ?></span>
|
||
<form method="POST" style="display:inline;">
|
||
<input type="hidden" name="user_id" value="<?= $gu['id'] ?>">
|
||
<input type="hidden" name="group_id" value="<?= $g['id'] ?>">
|
||
<button type="submit" name="remove_from_group" class="btn btn-sm btn-danger" style="padding:1px 5px; font-size:0.7rem; border-radius:10px;" title="Remove from group">×</button>
|
||
</form>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php else: ?>
|
||
<p style="color:var(--text-light); font-size:0.8rem; font-style:italic;">No members yet.</p>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── Notifications Tab ──────────────────────────────────────────────────── -->
|
||
<div class="admin-tab-pane <?= $active_tab==='channels'?'active':'' ?>" id="tab-channels">
|
||
<div class="card">
|
||
<h3 style="font-size:1rem; font-weight:700; margin-bottom:0.5rem;"><i class="fa fa-bell"></i> User Notification Channels</h3>
|
||
<p style="font-size:0.85rem; color:var(--text-light); margin-bottom:1.25rem;">Configure notification channels per user. WAHA settings appear when <strong>WhatsApp</strong> is enabled.</p>
|
||
|
||
<?php foreach($users as $u):
|
||
$chs = explode(',', $u['notify_channels'] ?? '');
|
||
$uid = $u['id'];
|
||
$hasWA = in_array('whatsapp', $chs);
|
||
?>
|
||
<div class="card" style="margin-bottom:1rem; padding:1rem; border:1px solid var(--border);">
|
||
<form method="POST">
|
||
<input type="hidden" name="user_id" value="<?= $uid ?>">
|
||
|
||
<!-- User header row -->
|
||
<div style="display:flex; align-items:center; gap:0.75rem; flex-wrap:wrap;">
|
||
<!-- Avatar -->
|
||
<div style="width:36px;height:36px;border-radius:50%;background:var(--primary);color:#fff;display:flex;align-items:center;justify-content:center;font-size:0.85rem;font-weight:700;flex-shrink:0;overflow:hidden;">
|
||
<?php if(($u['profile_pic']??null) && file_exists($u['profile_pic'])): ?>
|
||
<img src="<?= htmlspecialchars($u['profile_pic']) ?>" style="width:100%;height:100%;object-fit:cover;">
|
||
<?php else: ?>
|
||
<?= strtoupper(mb_substr($u['username'],0,1)) ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<!-- Name & role -->
|
||
<div style="flex:1;">
|
||
<div style="font-weight:700; font-size:0.95rem;"><?= htmlspecialchars($u['username']) ?></div>
|
||
<div><span class="<?= $u['is_admin']?'admin-badge-admin':'admin-badge-user' ?>" style="font-size:0.7rem;"><?= $u['is_admin']?'Admin':'User' ?></span></div>
|
||
</div>
|
||
|
||
<!-- Save button -->
|
||
<button type="submit" name="update_user_channels" class="btn btn-sm"><i class="fa fa-save"></i> Save</button>
|
||
</div>
|
||
|
||
<!-- Channel checkboxes -->
|
||
<div style="display:flex; gap:1rem; flex-wrap:wrap; margin-top:0.85rem; padding-top:0.75rem; border-top:1px dashed var(--border);">
|
||
<?php foreach(['native','email','telegram','whatsapp'] as $ch): ?>
|
||
<label style="display:flex; align-items:center; gap:5px; font-size:0.85rem; cursor:pointer; font-weight:500;">
|
||
<input type="checkbox" name="channels[]" value="<?= $ch ?>"
|
||
<?= in_array($ch,$chs)?'checked':'' ?>
|
||
<?= $ch==='whatsapp' ? "onchange=\"toggleWAHA({$uid}, this.checked)\"" : '' ?>>
|
||
<?php
|
||
$icons = ['native'=>'🔔','email'=>'📧','telegram'=>'✈️','whatsapp'=>'📱'];
|
||
echo $icons[$ch] . ' ' . ucfirst($ch);
|
||
?>
|
||
</label>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
|
||
<!-- Extra fields row -->
|
||
<div style="display:flex; gap:1rem; flex-wrap:wrap; margin-top:0.75rem; align-items:flex-end;">
|
||
<div class="form-group" style="margin:0; min-width:130px;">
|
||
<label style="font-size:0.75rem;">Telegram ID</label>
|
||
<input type="text" name="telegram_id" value="<?= htmlspecialchars($u['telegram_id']??'') ?>" class="form-control" style="padding:0.35rem;" placeholder="@username or ID">
|
||
</div>
|
||
<div class="form-group" style="margin:0; min-width:180px;">
|
||
<label style="font-size:0.75rem;">Email</label>
|
||
<input type="email" name="email" value="<?= htmlspecialchars($u['email']??'') ?>" class="form-control" style="padding:0.35rem;" placeholder="user@example.com">
|
||
</div>
|
||
<div class="form-group" style="margin:0; min-width:140px;">
|
||
<label style="font-size:0.75rem;">WhatsApp Number</label>
|
||
<input type="text" name="whatsapp_number" value="<?= htmlspecialchars($u['whatsapp_number']??'') ?>" class="form-control" style="padding:0.35rem;" placeholder="6281234567890">
|
||
</div>
|
||
</div>
|
||
|
||
<!-- WAHA expandable section -->
|
||
<div id="waha-section-<?= $uid ?>" style="<?= $hasWA ? '' : 'display:none;' ?> margin-top:0.75rem; padding:0.85rem; background:rgba(37,211,102,0.06); border:1px solid rgba(37,211,102,0.25); border-radius:8px;">
|
||
<div style="font-size:0.78rem; font-weight:700; color:#25D366; margin-bottom:0.65rem;"><i class="fab fa-whatsapp"></i> WAHA WhatsApp API Settings</div>
|
||
<div style="display:flex; gap:1rem; flex-wrap:wrap; align-items:flex-end;">
|
||
<div class="form-group" style="margin:0; flex:2; min-width:200px;">
|
||
<label style="font-size:0.75rem;">WAHA Endpoint URL</label>
|
||
<input type="text" name="waha_endpoint" value="<?= htmlspecialchars($u['waha_endpoint']??'') ?>" class="form-control" style="padding:0.35rem;" placeholder="http://localhost:3000/api/sendText">
|
||
</div>
|
||
<div class="form-group" style="margin:0; flex:1; min-width:120px;">
|
||
<label style="font-size:0.75rem;">Session Name</label>
|
||
<input type="text" name="waha_session" value="<?= htmlspecialchars($u['waha_session'] ?? 'default') ?>" class="form-control" style="padding:0.35rem;" placeholder="default">
|
||
</div>
|
||
<div class="form-group" style="margin:0; flex:1; min-width:160px;">
|
||
<label style="font-size:0.75rem;">Chat ID</label>
|
||
<input type="text" name="waha_chat_id" value="<?= htmlspecialchars($u['waha_chat_id']??'') ?>" class="form-control" style="padding:0.35rem;" placeholder="6281234567890@c.us">
|
||
</div>
|
||
<div class="form-group" style="margin:0; flex:1; min-width:160px;">
|
||
<label style="font-size:0.75rem;">API Key <span style="font-weight:400; color:var(--text-light);">(X-Api-Key)</span></label>
|
||
<input type="password" name="waha_api_key" value="<?= htmlspecialchars($u['waha_api_key']??'') ?>" class="form-control" style="padding:0.35rem; font-family:monospace;" placeholder="Leave blank if not required">
|
||
</div>
|
||
</div>
|
||
<div style="margin-top:0.6rem;">
|
||
<label style="font-size:0.75rem;">Message Templates</label>
|
||
<div style="font-size:0.72rem; color:var(--text-light); margin-bottom:8px;">Variables: <code>{action}</code> <code>{module}</code> <code>{item}</code> <code>{user}</code> <code>{attachment_count}</code> <code>{due_date}</code> <code>{created_date}</code> <code>{updated_date}</code> <code>{assignor}</code> <code>{assignee}</code></div>
|
||
<div style="display:grid; grid-template-columns:1fr 1fr; gap:0.75rem;">
|
||
<div class="form-group" style="margin:0;">
|
||
<label style="font-size:0.7rem; color:var(--text-light);">Task</label>
|
||
<textarea name="waha_template_task" class="form-control" rows="2" style="padding:0.35rem; font-size:0.75rem;" placeholder="*Task Alert:* {action} on '{item}' by {user}"><?= htmlspecialchars($u['waha_template_task']??'') ?></textarea>
|
||
</div>
|
||
<div class="form-group" style="margin:0;">
|
||
<label style="font-size:0.7rem; color:var(--text-light);">Note</label>
|
||
<textarea name="waha_template_note" class="form-control" rows="2" style="padding:0.35rem; font-size:0.75rem;" placeholder="*Note Alert:* {action} on '{item}' by {user}"><?= htmlspecialchars($u['waha_template_note']??'') ?></textarea>
|
||
</div>
|
||
<div class="form-group" style="margin:0;">
|
||
<label style="font-size:0.7rem; color:var(--text-light);">Password</label>
|
||
<textarea name="waha_template_password" class="form-control" rows="2" style="padding:0.35rem; font-size:0.75rem;" placeholder="*Password Alert:* {action} on '{item}' by {user}"><?= htmlspecialchars($u['waha_template_password']??'') ?></textarea>
|
||
</div>
|
||
<div class="form-group" style="margin:0;">
|
||
<label style="font-size:0.7rem; color:var(--text-light);">File/Folder</label>
|
||
<textarea name="waha_template_file" class="form-control" rows="2" style="padding:0.35rem; font-size:0.75rem;" placeholder="*File Alert:* {action} on '{item}' by {user}"><?= htmlspecialchars($u['waha_template_file']??'') ?></textarea>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</form>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
|
||
<!-- Group Notification Channels -->
|
||
<div class="card" style="margin-top:2rem;">
|
||
<h3 style="font-size:1rem; font-weight:700; margin-bottom:0.5rem;"><i class="fa fa-users"></i> Group Notification Channels</h3>
|
||
<p style="font-size:0.85rem; color:var(--text-light); margin-bottom:1.25rem;">Configure notification channels for an entire group. WAHA settings appear when <strong>WhatsApp</strong> is enabled.</p>
|
||
|
||
<?php foreach($all_groups as $g):
|
||
$chs = explode(',', $g['notify_channels'] ?? '');
|
||
$gid = $g['id'];
|
||
$hasWA = in_array('whatsapp', $chs);
|
||
?>
|
||
<div class="card" style="margin-bottom:1rem; padding:1rem; border:1px solid var(--border);">
|
||
<form method="POST">
|
||
<input type="hidden" name="update_group_channels" value="1">
|
||
<input type="hidden" name="group_id" value="<?= $gid ?>">
|
||
<input type="hidden" name="group_name" value="<?= htmlspecialchars($g['name']) ?>">
|
||
|
||
<!-- Group header row -->
|
||
<div style="display:flex; align-items:center; gap:0.75rem; flex-wrap:wrap;">
|
||
<div style="width:36px;height:36px;border-radius:50%;background:var(--primary);color:#fff;display:flex;align-items:center;justify-content:center;font-size:0.85rem;font-weight:700;flex-shrink:0;overflow:hidden;">
|
||
<?php if(!empty($g['profile_pic']) && file_exists($g['profile_pic'])): ?>
|
||
<img src="<?= htmlspecialchars($g['profile_pic']) ?>" style="width:100%;height:100%;object-fit:cover;">
|
||
<?php else: ?>
|
||
<?= strtoupper(mb_substr($g['name'],0,1)) ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
<div style="flex:1;">
|
||
<div style="font-weight:700; font-size:0.95rem;"><?= htmlspecialchars($g['name']) ?></div>
|
||
<div><span style="font-size:0.7rem; color:var(--text-light);">Group</span></div>
|
||
</div>
|
||
<button type="submit" name="update_group_channels" class="btn btn-sm"><i class="fa fa-save"></i> Save</button>
|
||
</div>
|
||
|
||
<!-- Channel checkboxes -->
|
||
<div style="display:flex; gap:1rem; flex-wrap:wrap; margin-top:0.85rem; padding-top:0.75rem; border-top:1px dashed var(--border);">
|
||
<label style="display:flex; align-items:center; gap:5px; font-size:0.85rem; cursor:pointer; font-weight:500;">
|
||
<input type="checkbox" name="channels[]" value="whatsapp" <?= $hasWA?'checked':'' ?> onchange="toggleWAHAGroup(<?= $gid ?>, this.checked)">
|
||
📱 WhatsApp
|
||
</label>
|
||
</div>
|
||
|
||
<!-- WAHA expandable section -->
|
||
<div id="waha-group-section-<?= $gid ?>" style="<?= $hasWA ? '' : 'display:none;' ?> margin-top:0.75rem; padding:0.85rem; background:rgba(37,211,102,0.06); border:1px solid rgba(37,211,102,0.25); border-radius:8px;">
|
||
<div style="font-size:0.78rem; font-weight:700; color:#25D366; margin-bottom:0.65rem;"><i class="fab fa-whatsapp"></i> WAHA WhatsApp API Settings</div>
|
||
<div style="display:flex; gap:1rem; flex-wrap:wrap; align-items:flex-end;">
|
||
<div class="form-group" style="margin:0; flex:2; min-width:200px;">
|
||
<label style="font-size:0.75rem;">WAHA Endpoint URL</label>
|
||
<input type="text" name="waha_endpoint" value="<?= htmlspecialchars($g['waha_endpoint']??'') ?>" class="form-control" style="padding:0.35rem;" placeholder="http://localhost:3000/api/sendText">
|
||
</div>
|
||
<div class="form-group" style="margin:0; flex:1; min-width:120px;">
|
||
<label style="font-size:0.75rem;">Session Name</label>
|
||
<input type="text" name="waha_session" value="<?= htmlspecialchars($g['waha_session'] ?? 'default') ?>" class="form-control" style="padding:0.35rem;" placeholder="default">
|
||
</div>
|
||
<div class="form-group" style="margin:0; flex:1; min-width:160px;">
|
||
<label style="font-size:0.75rem;">Chat ID</label>
|
||
<input type="text" name="waha_chat_id" value="<?= htmlspecialchars($g['waha_chat_id']??'') ?>" class="form-control" style="padding:0.35rem;" placeholder="12345678@g.us">
|
||
</div>
|
||
<div class="form-group" style="margin:0; flex:1; min-width:160px;">
|
||
<label style="font-size:0.75rem;">API Key <span style="font-weight:400; color:var(--text-light);">(X-Api-Key)</span></label>
|
||
<input type="password" name="waha_api_key" value="<?= htmlspecialchars($g['waha_api_key']??'') ?>" class="form-control" style="padding:0.35rem; font-family:monospace;" placeholder="Leave blank if not required">
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin-top:0.6rem;">
|
||
<label style="font-size:0.75rem;">Message Templates</label>
|
||
<div style="font-size:0.72rem; color:var(--text-light); margin-bottom:8px;">Variables: <code>{action}</code> <code>{module}</code> <code>{item}</code> <code>{user}</code> <code>{attachment_count}</code> <code>{due_date}</code> <code>{created_date}</code> <code>{updated_date}</code> <code>{assignor}</code> <code>{assignee}</code></div>
|
||
<div style="display:grid; grid-template-columns:1fr 1fr; gap:0.75rem;">
|
||
<div class="form-group" style="margin:0;">
|
||
<label style="font-size:0.7rem; color:var(--text-light);">Task</label>
|
||
<textarea name="waha_template_task" class="form-control" rows="2" style="padding:0.35rem; font-size:0.75rem;" placeholder="*Task Alert:* {action} on '{item}' by {user}"><?= htmlspecialchars($g['waha_template_task']??'') ?></textarea>
|
||
</div>
|
||
<div class="form-group" style="margin:0;">
|
||
<label style="font-size:0.7rem; color:var(--text-light);">Note</label>
|
||
<textarea name="waha_template_note" class="form-control" rows="2" style="padding:0.35rem; font-size:0.75rem;" placeholder="*Note Alert:* {action} on '{item}' by {user}"><?= htmlspecialchars($g['waha_template_note']??'') ?></textarea>
|
||
</div>
|
||
<div class="form-group" style="margin:0;">
|
||
<label style="font-size:0.7rem; color:var(--text-light);">Password</label>
|
||
<textarea name="waha_template_password" class="form-control" rows="2" style="padding:0.35rem; font-size:0.75rem;" placeholder="*Password Alert:* {action} on '{item}' by {user}"><?= htmlspecialchars($g['waha_template_password']??'') ?></textarea>
|
||
</div>
|
||
<div class="form-group" style="margin:0;">
|
||
<label style="font-size:0.7rem; color:var(--text-light);">File/Folder</label>
|
||
<textarea name="waha_template_file" class="form-control" rows="2" style="padding:0.35rem; font-size:0.75rem;" placeholder="*File Alert:* {action} on '{item}' by {user}"><?= htmlspecialchars($g['waha_template_file']??'') ?></textarea>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── System Config Tab ─────────────────────────────────────────────────── -->
|
||
<div class="admin-tab-pane <?= $active_tab==='config'?'active':'' ?>" id="tab-config">
|
||
<div class="card">
|
||
<h3 style="font-size:1rem; font-weight:700; margin-bottom:0.5rem;"><i class="fa fa-gear"></i> Kanban Auto-Archive Settings</h3>
|
||
<p style="font-size:0.85rem; color:var(--text-light); margin-bottom:1.5rem;">Control how long tasks stay in Completed or Archived states before being moved/deleted.</p>
|
||
<form method="POST">
|
||
<div style="display:grid; grid-template-columns:1fr 1fr; gap:1.5rem; max-width:600px;">
|
||
<div class="form-group" style="margin:0;">
|
||
<label>Completed tasks retain for (Days)</label>
|
||
<input type="number" name="completed_days" value="<?= htmlspecialchars($conf_comp) ?>" class="form-control" min="1" max="365">
|
||
<div style="font-size:0.75rem; color:var(--text-light); margin-top:4px;">Default: 7 days (before auto-moving to Archive)</div>
|
||
</div>
|
||
<div class="form-group" style="margin:0;">
|
||
<label>Archived tasks retain for (Days)</label>
|
||
<input type="number" name="archived_days" value="<?= htmlspecialchars($conf_arch) ?>" class="form-control" min="1" max="3650">
|
||
<div style="font-size:0.75rem; color:var(--text-light); margin-top:4px;">Default: 90 days (before permanent deletion)</div>
|
||
</div>
|
||
</div>
|
||
<button type="submit" name="update_sys_config" class="btn" style="margin-top:1.25rem;"><i class="fa fa-save"></i> Save Configuration</button>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- Danger Zone -->
|
||
<div class="card" style="border:1px solid rgba(239,68,68,0.3);">
|
||
<h3 style="font-size:1rem; font-weight:700; margin-bottom:0.5rem; color:#EF4444;"><i class="fa fa-triangle-exclamation"></i> Danger Zone</h3>
|
||
<p style="font-size:0.85rem; color:var(--text-light); margin-bottom:1rem;">These actions are irreversible. Proceed with extreme caution.</p>
|
||
<div style="display:flex; gap:0.75rem; flex-wrap:wrap;">
|
||
<button class="btn btn-danger" onclick="appConfirm('Really purge all archive tasks?').then(y => { if(y) appAlert('Not implemented in this demo.'); })">
|
||
<i class="fa fa-trash"></i> Purge Archived Tasks
|
||
</button>
|
||
<button class="btn btn-danger" onclick="appConfirm('Really clear all activity logs?').then(y => { if(y) appAlert('Not implemented in this demo.'); })">
|
||
<i class="fa fa-eraser"></i> Clear Activity Logs
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
function switchTab(name) {
|
||
document.querySelectorAll('.admin-tab').forEach(t => t.classList.remove('active'));
|
||
document.querySelectorAll('.admin-tab-pane').forEach(p => p.classList.remove('active'));
|
||
document.querySelector(`[onclick="switchTab('${name}')"]`).classList.add('active');
|
||
document.getElementById('tab-'+name).classList.add('active');
|
||
const url = new URL(window.location);
|
||
url.searchParams.set('tab', name);
|
||
history.replaceState({}, '', url);
|
||
}
|
||
|
||
function toggleWAHA(uid, enabled) {
|
||
const section = document.getElementById('waha-section-' + uid);
|
||
if (!section) return;
|
||
if (enabled) {
|
||
section.style.display = 'block';
|
||
section.style.animation = 'fadeIn 0.25s ease';
|
||
} else {
|
||
section.style.display = 'none';
|
||
}
|
||
}
|
||
function toggleWAHAGroup(gid, enabled) {
|
||
const section = document.getElementById('waha-group-section-' + gid);
|
||
if (!section) return;
|
||
if (enabled) {
|
||
section.style.display = 'block';
|
||
section.style.animation = 'fadeIn 0.25s ease';
|
||
} else {
|
||
section.style.display = 'none';
|
||
}
|
||
}
|
||
</script>
|
||
<style>
|
||
@keyframes fadeIn { from { opacity:0; transform:translateY(-6px); } to { opacity:1; transform:none; } }
|
||
</style>
|