using Spry; using Inversion; using Astralis; using Invercargill; using Invercargill.DataStructures; namespace Spry.Users.Components { /** * UserManagementPage - PageComponent orchestrating all user management components. * * This page provides a complete user management interface that includes: * - Permission check: Only accessible with "user-management" permission * - User list with search, filter, and pagination * - User form modal for create/edit operations * - Status messages (success/error alerts) * * Cross-Component Communication: * - Child components trigger actions via "UserManagementPage:ActionName" pattern * - The page handles these actions and updates child components accordingly * - Uses add_globals_from() to share globals with child components * * Required Permission: "user-management" * * Usage: * // Register as a page: * spry_cfg.add_page(new EndpointRoute("/admin/users")); */ public class UserManagementPage : PageComponent { private PermissionService permission_service = inject(); private UserService user_service = inject(); private SessionService session_service = inject(); private ComponentFactory factory = inject(); private HttpContext http_context = inject(); // ========================================================================= // State Properties // ========================================================================= private string? _success_message = null; private string? _error_message = null; private bool _access_denied = false; // ========================================================================= // Component Implementation // ========================================================================= public override string markup { get { return """ User Management - Admin

Access Denied

You do not have permission to access the user management page.

Please contact an administrator if you believe this is an error.

User Management

"""; }} public override async void prepare() throws Error { // Check permission var auth_result = session_service.authenticate_request(http_context, user_service); if (!auth_result.is_authenticated) { _access_denied = true; return; } var current_user = auth_result.user; if (current_user == null) { _access_denied = true; return; } // Check for user-management permission if (!permission_service.has_permission(current_user, PermissionService.USER_MANAGEMENT)) { _access_denied = true; return; } _access_denied = false; // Ensure form is hidden initially var user_form = get_component_child("user-form"); user_form.hide(); } public async override void handle_action(string action) throws Error { // Don't process actions if access is denied if (_access_denied) { return; } var query = http_context.request.query_params; switch (action) { case "CreateUser": handle_create_user(); break; case "EditUser": var user_id = get_query_value(query, "user_id"); handle_edit_user(user_id); break; case "ToggleActive": var user_id = get_query_value(query, "user_id"); yield handle_toggle_active(user_id); break; case "DeleteUser": var user_id = get_query_value(query, "user_id"); yield handle_delete_user(user_id); break; } } // ========================================================================= // Action Handlers // ========================================================================= private void handle_create_user() throws Error { var user_form = get_component_child("user-form"); user_form.show_create(); _success_message = null; _error_message = null; } private void handle_edit_user(string user_id) throws Error { if (user_id.length == 0) { _error_message = "Invalid user ID"; return; } var user = user_service.get_user(user_id); if (user == null) { _error_message = "User not found"; return; } var user_form = get_component_child("user-form"); user_form.set_user(user); _success_message = null; _error_message = null; } private async void handle_toggle_active(string user_id) throws Error { // Note: Current User model doesn't have is_active field // This is a placeholder for future implementation _error_message = "Toggle active functionality not yet implemented"; _success_message = null; // Refresh the list var user_list = get_component_child("user-list"); add_globals_from(user_list); } private async void handle_delete_user(string user_id) throws Error { if (user_id.length == 0) { _error_message = "Invalid user ID"; return; } // Prevent self-deletion var auth_result = session_service.authenticate_request(http_context, user_service); if (auth_result.is_authenticated && auth_result.user != null) { if (auth_result.user.id == user_id) { _error_message = "Cannot delete your own account"; _success_message = null; // Refresh the list var user_list = get_component_child("user-list"); add_globals_from(user_list); return; } } // Delete the user string? delete_error; if (!user_service.delete_user(user_id, out delete_error)) { _error_message = delete_error ?? "Failed to delete user"; _success_message = null; } else { _success_message = "User deleted successfully"; _error_message = null; } // Refresh the list var user_list = get_component_child("user-list"); add_globals_from(user_list); } // ========================================================================= // Private Helpers // ========================================================================= private string get_query_value(Catalogue query, string key) { var value = query.get_any_or_default(key); return value != null ? ((!)value).strip() : ""; } } }