use leptos::prelude::*; use leptos::task::spawn_local; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct User { pub id: String, pub email: String, pub name: String, pub status: UserStatus, pub roles: Vec, pub groups: Vec, pub created_at: String, pub last_login: Option, pub mfa_enabled: bool, } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum UserStatus { Active, Inactive, Suspended, PendingVerification, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Role { pub id: String, pub name: String, pub description: String, pub permissions: Vec, pub parent_role: Option, pub children: Vec, pub level: u32, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Group { pub id: String, pub name: String, pub description: String, pub members: Vec, pub parent_group: Option, pub children: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Permission { pub id: String, pub name: String, pub description: String, pub resource: String, pub action: String, pub category: String, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AccessReviewCampaign { pub id: String, pub name: String, pub description: String, pub schedule: String, pub reviewers: Vec, pub status: String, pub due_date: String, } #[component] pub fn UsersPage() -> impl IntoView { let (active_tab, set_active_tab) = signal("users".to_string()); let (users, set_users) = signal(Vec::::new()); let (roles, set_roles) = signal(Vec::::new()); let (groups, set_groups) = signal(Vec::::new()); let (permissions, set_permissions) = signal(Vec::::new()); let (selected_user, set_selected_user) = signal(None::); let (show_user_modal, set_show_user_modal) = signal(false); let (show_role_hierarchy, set_show_role_hierarchy) = signal(false); let (show_bulk_operations, set_show_bulk_operations) = signal(false); // Load initial data Effect::new(move |_| { spawn_local(async move { // Mock data - in real app, fetch from API let mock_users = vec![ User { id: "u1".to_string(), email: "admin@example.com".to_string(), name: "System Admin".to_string(), status: UserStatus::Active, roles: vec!["admin".to_string()], groups: vec!["admins".to_string()], created_at: "2024-01-01".to_string(), last_login: Some("2024-01-15".to_string()), mfa_enabled: true, }, User { id: "u2".to_string(), email: "user@example.com".to_string(), name: "Regular User".to_string(), status: UserStatus::Active, roles: vec!["user".to_string()], groups: vec!["users".to_string()], created_at: "2024-01-10".to_string(), last_login: Some("2024-01-14".to_string()), mfa_enabled: false, }, ]; let mock_roles = vec![ Role { id: "admin".to_string(), name: "Administrator".to_string(), description: "Full system access".to_string(), permissions: vec!["*".to_string()], parent_role: None, children: vec!["operator".to_string()], level: 0, }, Role { id: "operator".to_string(), name: "Operator".to_string(), description: "Infrastructure management".to_string(), permissions: vec!["infra:*".to_string()], parent_role: Some("admin".to_string()), children: vec!["user".to_string()], level: 1, }, Role { id: "user".to_string(), name: "User".to_string(), description: "Basic access".to_string(), permissions: vec!["read:*".to_string()], parent_role: Some("operator".to_string()), children: vec![], level: 2, }, ]; set_users.set(mock_users); set_roles.set(mock_roles); }); }); view! {
// Header

"User Management"

// Tab Navigation
// Content Area
{move || match active_tab.get().as_str() { "users" => view! { }.into(), "roles" => view! { }.into(), "groups" => view! { }.into(), "permissions" => view! { }.into(), "reviews" => view! { }.into(), _ => view! {
"Unknown tab"
}.into(), }}
// User Modal {move || if show_user_modal.get() { view! { }.into() } else { view! {
}.into() }} // Role Hierarchy Modal {move || if show_role_hierarchy.get() { view! { }.into() } else { view! {
}.into() }} // Bulk Operations Modal {move || if show_bulk_operations.get() { view! { }.into() } else { view! {
}.into() }}
} } #[component] fn UsersTab( users: ReadSignal>, set_selected_user: WriteSignal>, set_show_user_modal: WriteSignal, ) -> impl IntoView { let (search_term, set_search_term) = signal(String::new()); let (status_filter, set_status_filter) = signal("all".to_string()); let filtered_users = Memo::new(move |_| { let search = search_term.get().to_lowercase(); let status = status_filter.get(); users.get().into_iter().filter(|user| { let matches_search = search.is_empty() || user.name.to_lowercase().contains(&search) || user.email.to_lowercase().contains(&search); let matches_status = status == "all" || format!("{:?}", user.status).to_lowercase() == status; matches_search && matches_status }).collect::>() }); view! {
// Search and Filters
// Users Table
{move || { filtered_users.get().into_iter().map(|user| { let user_clone = user.clone(); let user_clone2 = user.clone(); view! { } }).collect::>() }}
"Name" "Email" "Status" "Roles" "MFA" "Last Login" "Actions"
{&user.name} {&user.email}
"badge-success", UserStatus::Inactive => "badge-warning", UserStatus::Suspended => "badge-error", UserStatus::PendingVerification => "badge-info", } )}> {format!("{:?}", user.status)}
{user.roles.into_iter().map(|role| { view! {
{role}
} }).collect::>()}
{if user.mfa_enabled { view! {
"Enabled"
} } else { view! {
"Disabled"
} }}
{user.last_login.unwrap_or_else(|| "Never".to_string())}
} } #[component] fn RolesTab(roles: ReadSignal>) -> impl IntoView { view! {
{move || { roles.get().into_iter().map(|role| { view! {

{&role.name}

{&role.description}

"Permissions: "
{role.permissions.into_iter().map(|perm| { view! {
{perm}
} }).collect::>()}
{role.parent_role.as_ref().map(|parent| { view! {
"Inherits from: " {parent}
} })}
} }).collect::>() }}
} } #[component] fn GroupsTab(groups: ReadSignal>) -> impl IntoView { view! {
"Group management coming soon..."
} } #[component] fn PermissionsTab(permissions: ReadSignal>) -> impl IntoView { view! {
} } #[component] fn AccessReviewsTab() -> impl IntoView { view! {
"Access review campaigns coming soon..."
} } #[component] fn UserModal( user: ReadSignal>, show: ReadSignal, set_show: WriteSignal, roles: Vec, groups: Vec, ) -> impl IntoView { let (name, set_name) = signal(String::new()); let (email, set_email) = signal(String::new()); let (selected_roles, set_selected_roles) = signal(Vec::::new()); Effect::new(move |_| { if let Some(u) = user.get() { set_name.set(u.name); set_email.set(u.email); set_selected_roles.set(u.roles); } else { set_name.set(String::new()); set_email.set(String::new()); set_selected_roles.set(Vec::new()); } }); view! {
} } #[component] fn RoleHierarchyModal( roles: Vec, show: ReadSignal, set_show: WriteSignal, ) -> impl IntoView { view! {
} } #[component] fn RoleHierarchyViewer(roles: Vec) -> impl IntoView { // Sort roles by level for hierarchy display let mut sorted_roles = roles; sorted_roles.sort_by_key(|r| r.level); view! {
{sorted_roles.into_iter().map(|role| { let indent = role.level * 24; // 24px per level view! {
{&role.name}
{&role.description}
{role.permissions.into_iter().take(3).map(|perm| { view! {
{perm}
} }).collect::>()} {if role.permissions.len() > 3 { view! {
{"+"}{role.permissions.len() - 3}{" more"}
}.into() } else { view! {
}.into() }}
} }).collect::>()}
} } #[component] fn PermissionMatrix() -> impl IntoView { let resources = vec!["Users", "Roles", "Infrastructure", "Workflows", "Policies"]; let actions = vec!["Read", "Write", "Delete", "Execute", "Admin"]; let roles = vec!["Admin", "Operator", "User"]; view! {
{roles.iter().map(|role| { let role = role.clone(); view! { } }).collect::>()} {resources.into_iter().flat_map(|resource| { actions.iter().map({ let resource = resource.clone(); move |action| { view! { {roles.iter().map(|role| { let role = role.clone(); view! { } }).collect::>()} } } }).collect::>() }).collect::>()}
"Resource" "Action"{role}
{&resource} {action}
} } #[component] fn BulkOperationsModal( show: ReadSignal, set_show: WriteSignal, ) -> impl IntoView { let (operation_type, set_operation_type) = signal("import".to_string()); view! {
} }