exec("ALTER TABLE users 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')"); $pdo->exec("INSERT OR IGNORE INTO system_config (k, v) VALUES ('waha_endpoint', '')"); $pdo->exec("INSERT OR IGNORE INTO system_config (k, v) VALUES ('waha_chat_id', '')"); $pdo->exec("INSERT OR IGNORE INTO system_config (k, v) VALUES ('waha_template', '')"); } 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 { $stmt = $pdo->prepare("INSERT INTO groups (name) VALUES (?)"); $stmt->execute([$_POST['group_name']]); $success_msg = "Group '{$_POST['group_name']}' created!"; } catch(Exception $e) { $error_msg = "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) : ''; $stmt = $pdo->prepare("UPDATE users SET notify_channels=?, telegram_id=?, email=?, whatsapp_number=? WHERE id=?"); $stmt->execute([$ch_str, $_POST['telegram_id'], $_POST['email'], $_POST['whatsapp_number'], $_POST['user_id']]); $success_msg = "User notification preferences updated!"; } 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']); $stmt->execute([$_POST['waha_endpoint'] ?? '', 'waha_endpoint']); $stmt->execute([$_POST['waha_chat_id'] ?? '', 'waha_chat_id']); $stmt->execute([$_POST['waha_template'] ?? '', 'waha_template']); $success_msg = "System configuration saved!"; } } // ── Fetch Data ──────────────────────────────────────────────────────────────── $users = query("SELECT id, username, is_admin, notify_channels, telegram_id, email, whatsapp_number, profile_pic 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'; ?>

Admin Panel

ADMIN

🕓 Recent Platform Activity

No activity recorded yet.

·

Create New User

All Users ()

fetchAll(); ?>
htmlspecialchars($g['name']), $groups_of_u)) ?> No groups
(You)

Create Group

Assign User to Group

All Groups ()

No groups created yet.

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(); ?>
member

No members yet.

User Notification Channels

Configure notification channels (Native, Telegram, Email, WhatsApp) per user.

User Role Channels Telegram ID Email WhatsApp Save

Kanban Auto-Archive Settings

Control how long tasks stay in Completed or Archived states before being moved/deleted.

Default: 7 days (before auto-moving to Archive)
Default: 90 days (before permanent deletion)

WAHA WhatsApp Notifications

Configure centralized WhatsApp notifications globally via WAHA (WhatsApp HTTP API).

The full /api/sendText HTTP API endpoint where WAHA is hosted. Leave blank to disable WhatsApp Notification feature.
The centralized group or destination ID.
Available Variables: {action}, {module}, {item}, {user}

Danger Zone

These actions are irreversible. Proceed with extreme caution.