peillute/views/home.rs
1//! Home page component for the Peillute application
2//!
3//! This component provides the main user interface for managing users in the system,
4//! including listing existing users, adding new users, and deleting users.
5
6use crate::Route;
7use dioxus::prelude::*;
8
9/// Home page component
10///
11/// Renders the main user management interface with the following features:
12/// - List of existing users with links to their transaction history
13/// - Form for adding new users
14/// - Delete buttons for removing users
15#[component]
16pub fn Home() -> Element {
17 let mut user_input = use_signal(|| "".to_string());
18 let mut users = use_signal(|| Vec::new());
19
20 use_future(move || async move {
21 if let Ok(data) = get_users().await {
22 users.set(data);
23 }
24 });
25
26 rsx! {
27 div { id: "users-list",
28 for item in users.iter() {
29 div { class: "user-card",
30 div { class: "user-content",
31 Link {
32 to: Route::History {
33 name: item.to_string(),
34 },
35 span { class: "user-name", "{item}" }
36 }
37 }
38 {
39 let item_for_delete = item.clone();
40 rsx! {
41 button {
42 r#type: "button",
43 class: "delete-btn",
44 onclick: move |_| {
45 let username = item_for_delete.clone();
46 spawn(async move {
47 if let Ok(_) = delete_user(username).await {
48 if let Ok(data) = get_users().await {
49 users.set(data);
50 }
51 }
52 });
53 },
54 "X"
55 }
56 }
57 }
58 }
59 }
60 }
61 div { id: "add-user-form",
62 form {
63 label { r#for: "fusername", "Enter a new user:" }
64 input {
65 r#type: "text",
66 id: "form-username",
67 r#name: "fusername",
68 placeholder: "New user name",
69 value: user_input,
70 oninput: move |event| user_input.set(event.value()),
71 }
72 button {
73 id: "submit",
74 r#type: "submit",
75 onclick: move |_| async move {
76 if let Ok(_) = add_user(user_input.to_string()).await {
77 user_input.set("".to_string());
78 }
79 if let Ok(data) = get_users().await {
80 users.set(data);
81 }
82 },
83 "Submit"
84 }
85 }
86 }
87 }
88}
89
90/// Server function to retrieve the list of users
91#[server]
92async fn get_users() -> Result<Vec<String>, ServerFnError> {
93 use crate::db;
94 let users = db::get_users()?;
95 Ok(users)
96}
97
98/// Server function to add a new user
99///
100/// Creates a user in the local database and broadcasts the creation
101/// to all nodes in the network.
102#[server]
103async fn add_user(name: String) -> Result<(), ServerFnError> {
104 if name == "" {
105 return Err(ServerFnError::new("User name cannot be empty."));
106 }
107
108 if let Err(e) = crate::control::enqueue_critical(crate::control::CriticalCommands::CreateUser {
109 name: name,
110 })
111 .await
112 {
113 return Err(ServerFnError::new(format!(
114 "Failed to diffuse the create user message: {e}"
115 )));
116 }
117
118 Ok(())
119}
120
121/// Server function to delete a user
122///
123/// Removes a user from the local database.
124#[server]
125async fn delete_user(name: String) -> Result<(), ServerFnError> {
126 use crate::db;
127 db::delete_user(&name)?;
128 Ok(())
129}