prepare('SELECT id, email, display_name, is_admin FROM livehub_users WHERE id = ? LIMIT 1'); $stmt->execute([$currentUserId]); $currentUser = $stmt->fetch(); if (!$currentUser) { session_unset(); session_destroy(); header('Location: login.php'); exit; } } catch (Exception $e) { http_response_code(500); echo "Error loading current user."; error_log('Admin user load error: ' . $e->getMessage()); exit; } if (!$currentUser['is_admin']) { http_response_code(403); echo "Access denied. Admin only."; exit; } // 2. Resolve room via slug (?room=studio-1) $roomSlug = $_GET['room'] ?? 'studio-1'; $roomSlug = trim($roomSlug); try { $stmt = $pdo->prepare('SELECT id, slug, title, livekit_room FROM livehub_rooms WHERE slug = ? LIMIT 1'); $stmt->execute([$roomSlug]); $room = $stmt->fetch(); if (!$room) { http_response_code(400); echo "Unknown room: " . htmlspecialchars($roomSlug); exit; } } catch (Exception $e) { http_response_code(500); echo "Error loading room."; error_log('Room load error: ' . $e->getMessage()); exit; } $roomId = (int)$room['id']; $errors = []; $successMsg = null; // 3. Handle add/update membership form POST if ($_SERVER['REQUEST_METHOD'] === 'POST') { $email = trim($_POST['user_email'] ?? ''); $role = $_POST['role'] ?? 'listener'; $allowedRoles = ['host','mod','speaker','listener','banned']; if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { $errors[] = 'Invalid email.'; } if (!in_array($role, $allowedRoles, true)) { $errors[] = 'Invalid role.'; } if (!$errors) { try { // Find user by email $stmt = $pdo->prepare('SELECT id, display_name FROM livehub_users WHERE email = ? LIMIT 1'); $stmt->execute([$email]); $user = $stmt->fetch(); if (!$user) { $errors[] = 'User not found with that email.'; } else { $uid = (int)$user['id']; // Upsert membership $stmt = $pdo->prepare( 'INSERT INTO livehub_room_members (room_id, user_id, role) VALUES (?,?,?) ON DUPLICATE KEY UPDATE role = VALUES(role)' ); $stmt->execute([$roomId, $uid, $role]); $successMsg = 'Updated role for ' . htmlspecialchars($user['display_name']) . ' (' . htmlspecialchars($email) . ') to ' . htmlspecialchars($role) . '.'; } } catch (Exception $e) { $errors[] = 'Error saving membership.'; error_log('Membership save error: ' . $e->getMessage()); } } } // 4. Load current members try { $stmt = $pdo->prepare( 'SELECT m.id, u.email, u.display_name, m.role, m.created_at FROM livehub_room_members m JOIN livehub_users u ON u.id = m.user_id WHERE m.room_id = ? ORDER BY FIELD(m.role, "host","mod","speaker","listener","banned"), u.display_name ASC' ); $stmt->execute([$roomId]); $members = $stmt->fetchAll(); } catch (Exception $e) { $members = []; error_log('Membership list error: ' . $e->getMessage()); } ?>
· LiveKit room: No members assigned yet for this room.
| User | Role | Since | |
|---|---|---|---|
Tip:
– Host/Mod/Speaker will get canPublish in their LiveKit token and appear “On Stage”.
– Listener will join as silent and only see “Listeners” grid.
– Banned users will be blocked at the token endpoint and cannot join the room.