frontend/pages/basic_pages.rs
1use gloo_net::http::Request;
2use wasm_bindgen_futures::spawn_local;
3use yew::prelude::*;
4use yew_router::prelude::*;
5
6/// Removes surrounding double quotes from a string.
7///
8/// This macro takes an expression that evaluates to a string and returns a new `String`
9/// with any leading or trailing double quotes removed. It's useful for cleaning up
10/// string data that might be inadvertently wrapped in quotes, such as JSON string values.
11///
12/// # Arguments
13///
14/// * `$str`: An expression that can be converted into a string slice (`&str`).
15///
16/// # Examples
17///
18/// ```rust
19/// use your_crate::dequote; // Assuming `dequote` is re-exported or in scope
20///
21/// let quoted_string = "\"hello world\"";
22/// let dequoted_string = dequote!(quoted_string);
23/// assert_eq!(dequoted_string, "hello world");
24///
25/// let already_clean = "no quotes";
26/// let dequoted_clean = dequote!(already_clean);
27/// assert_eq!(dequoted_clean, "no quotes");
28/// ```
29macro_rules! dequote {
30 ($str:expr) => {
31 $str.trim_matches('"').to_string()
32 };
33}
34
35/// The main home page component of the application.
36///
37/// This component displays different content based on whether the logged-in user
38/// is an administrator. It fetches the user's admin status from the
39/// `/api/users/current` endpoint upon initialization.
40///
41/// # Behavior
42/// - **Loading**: Displays "Loading..." while fetching user data.
43/// - **Admin User**: Renders the `TicketCount` utility component.
44/// - **Non-Admin User**: Renders the `TicketCount` utility component.
45///
46/// # Example
47/// ```rust
48/// html! {
49/// <Home />
50/// }
51/// ```
52#[component(Home)]
53pub fn home_component() -> Html {
54 let name = use_state(|| "".to_string());
55 {
56 let name = name.clone();
57 use_effect_with((), move |_| {
58 spawn_local(async move {
59 let response = Request::get("/api/users/current")
60 .credentials(web_sys::RequestCredentials::Include)
61 .send()
62 .await;
63
64 match response {
65 Ok(resp) if resp.status() == 200 => {
66 let user_data: serde_json::Value = resp.json().await.unwrap_or_default();
67 let name_value = format!(
68 "{} {}",
69 dequote!(user_data["data"]["first_name"].to_string()),
70 dequote!(user_data["data"]["last_name"].to_string())
71 );
72 name.set(name_value);
73 }
74 _ => name.set("Unknown".to_string()),
75 }
76 });
77 || ()
78 });
79 }
80
81 html! {
82 <div class="rundbg home">
83 <crate::utilities::TicketCount/>
84
85 <p class="login-status">{ "Sie sind angemeldet als: " }</p>
86 <p class="name">{ &*name }</p>
87 </div>
88 }
89}
90
91/// A basic component displayed when a requested route does not match any defined paths (404 error).
92///
93/// It provides a simple message indicating that the page was not found and includes
94/// a link to navigate back to the home page.
95///
96/// # Example
97/// ```rust
98/// html! {
99/// <NotFound />
100/// }
101/// ```
102#[component(NotFound)]
103pub fn not_found_component() -> Html {
104 let message = "404 Nicht gefunden";
105 html! {
106 <div>
107 <h1>{&message}</h1>
108 <Link<crate::Route> to={crate::Route::Home}>{ "Zurück zum Start" }</Link<crate::Route>>
109 </div>
110 }
111}
112
113/// A component displayed when a user attempts to access a page for which they do not have sufficient permissions.
114///
115/// It informs the user about the access restriction and provides instructions to contact
116/// a specific person ("Herr Winter") if they believe this is an error.
117/// It also includes a link to return to the home page.
118///
119/// # Example
120/// ```rust
121/// html! {
122/// <PermissionDenied />
123/// }
124/// ```
125#[component(PermissionDenied)]
126pub fn denied_component() -> Html {
127 html! {
128 <div>
129 <h1>{ "Sie haben nicht die benötigten Rechte um diese Seite aufzurufen" }</h1>
130 <h3>{ "Wenn sie denken, dass dies ein Fehler ist kontaktieren sie Herrn Winter" }</h3>
131 <Link<crate::Route> to={crate::Route::Home}>{ "Zurück zum Start" }</Link<crate::Route>>
132 </div>
133 }
134}
135
136#[component(Icon)]
137pub fn icon_component() -> Html {
138 html! {
139 <img src="assets/csg.png" class="csg-icon" />
140 }
141}