Refined docs and stuff

Docs link to each other and are generally better
This commit is contained in:
2026-05-20 12:50:00 +02:00
parent 0db9b76cad
commit 721e43c380
14 changed files with 256 additions and 159 deletions

View File

@@ -4,6 +4,29 @@ use yew::prelude::*;
use yew_router::prelude::*;
#[macro_export]
/// Removes surrounding double quotes from a string.
///
/// This macro takes an expression that evaluates to a string and returns a new `String`
/// with any leading or trailing double quotes removed. It's useful for cleaning up
/// string data that might be inadvertently wrapped in quotes, such as JSON string values.
///
/// # Arguments
///
/// * `$str`: An expression that can be converted into a string slice (`&str`).
///
/// # Examples
///
/// ```rust
/// use your_crate::dequote; // Assuming `dequote` is re-exported or in scope
///
/// let quoted_string = "\"hello world\"";
/// let dequoted_string = dequote!(quoted_string);
/// assert_eq!(dequoted_string, "hello world");
///
/// let already_clean = "no quotes";
/// let dequoted_clean = dequote!(already_clean);
/// assert_eq!(dequoted_clean, "no quotes");
/// ```
macro_rules! dequote {
($str:expr) => {
$str.trim_matches('"').to_string()

View File

@@ -29,7 +29,7 @@ pub struct AdminSetupScheme {
/// a form to create the first admin user. Key functionality:
///
/// - **Admin Check**: On mount, verifies if an admin already exists by calling `/api/check-admin`.
/// If an admin is found, the user is redirected to the login page (`crate::Route::Login`).
/// If an admin is found, the user is redirected to the login page ([`crate::Route::Login`]).
/// - **Form Fields**: Collects `first_name`, `last_name`, `username`, `password`, and `confirm_password`.
/// - **Form Validation**:
/// - Ensures password fields are not empty.

View File

@@ -7,6 +7,11 @@ use wasm_bindgen_futures::spawn_local;
use yew::prelude::*;
use yew_router::prelude::*;
/// The key used to store and retrieve the sidebar's expansion state in `LocalStorage`.
///
/// This constant ensures consistency when accessing the stored state across different
/// parts of the application. The value associated with this key in `LocalStorage`
/// will be a serialized [`SidebarExpandState`] object.
const STORAGE_KEY: &str = "sidebar_state";
/// Represents the expansion state of collapsible menus within the sidebar.

View File

@@ -102,6 +102,14 @@ pub struct UserProps {
pub id: i16,
}
/// Represents an error response from the API.
///
/// This struct is used to deserialize error messages received from the backend API.
/// It typically contains a human-readable message and an internal status code.
///
/// # Fields
/// - `message`: A `String` containing a description of the error.
/// - `_status`: An internal status code or message, often ignored in frontend display.
#[derive(Deserialize, Debug)]
struct ApiError {
message: String,

View File

@@ -24,6 +24,15 @@ struct TicketPartial {
user_id: i16,
}
/// A partial representation of a user, containing only the fields necessary for statistical analysis.
///
/// This struct is used to efficiently retrieve and process user data for diagnostics
/// without fetching the full user details.
///
/// # Fields
/// - `id`: The unique identifier of the user.
/// - `first_name`: The first name of the user.
/// - `last_name`: The last name of the user.
#[derive(Debug, Deserialize, Clone, PartialEq)]
struct UserPartial {
id: i16,
@@ -37,12 +46,20 @@ struct UserPartial {
/// for calculating and visualizing ticket distribution per room.
///
/// # Fields
/// - `tickets`: A vector of `TicketPartial` containing ticket data relevant for room totals.
/// - `tickets`: A vector of [`TicketPartial`] containing ticket data relevant for room totals.
#[derive(Properties, PartialEq)]
struct RoomTotalsProps {
tickets: Vec<TicketPartial>,
}
/// Properties for components that display user-wise ticket totals.
///
/// This struct passes a list of partial user data and partial ticket data to a component
/// responsible for calculating and visualizing ticket distribution per user.
///
/// # Fields
/// - `users`: A vector of [`UserPartial`] containing user data relevant for user totals.
/// - `tickets`: A vector of [`TicketPartial`] containing ticket data relevant for user totals.
#[derive(Properties, PartialEq)]
struct UserTotalProps {
users: Vec<UserPartial>,
@@ -79,7 +96,7 @@ fn weekday_index(dt: &DateTime<Utc>) -> usize {
/// the total count of tickets submitted on that day.
///
/// # Arguments
/// - `tickets`: A slice of `TicketPartial` items to count.
/// - `tickets`: A slice of [`TicketPartial`] items to count.
///
/// # Returns
/// An array `[usize; 7]` with ticket counts for each weekday.
@@ -93,12 +110,12 @@ fn count_by_weekday(tickets: &[TicketPartial]) -> [usize; 7] {
/// Calculates the occurrences of each weekday within the date range covered by the tickets.
///
/// This function determines the minimum and maximum dates from the provided `TicketPartial`
/// This function determines the minimum and maximum dates from the provided [`TicketPartial`]
/// slice and then counts how many times each weekday occurs within that inclusive date range.
/// This is useful for normalizing ticket counts against the number of available days for each weekday.
///
/// # Arguments
/// - `partials`: A slice of `TicketPartial` items defining the date range.
/// - `partials`: A slice of [`TicketPartial`] items defining the date range.
///
/// # Returns
/// An array `[usize; 7]` where each element represents the number of times a
@@ -147,7 +164,8 @@ fn day_counts(partials: &[TicketPartial]) -> [usize; 7] {
/// Converts a numerical room representation back into a human-readable string format.
///
/// This function is the inverse of the room parsing logic in `SubmitTicket` component.
/// This function is the inverse of the room parsing logic in
/// [`SubmitTicket`](`crate::pages::ticket::SubmitTicket`) component.
/// It converts negative numbers back to "K" prefixed rooms, numbers >= 1000 back to "D" prefixed rooms,
/// and other numbers to their string representation.
///
@@ -318,12 +336,12 @@ pub fn ticket_count_component() -> Html {
///
/// # State
/// Uses `use_state` hooks to manage:
/// - `tickets`: A vector of `TicketPartial` for statistical analysis.
/// - `tickets`: A vector of [`TicketPartial`] for statistical analysis.
/// - `error`: Any error message from API calls.
/// - `loading`: A boolean indicating if data is being fetched.
///
/// # Functionality
/// - Fetches all tickets (as `TicketPartial`) from `/api/tickets`.
/// - Fetches all tickets (as [`TicketPartial`]) from `/api/tickets`.
/// - Calculates:
/// - `counts`: Number of tickets submitted on each weekday.
/// - `occ`: Number of occurrences of each weekday in the ticket date range.
@@ -465,7 +483,7 @@ pub fn submit_stats_component() -> Html {
/// A component that displays the total number of tickets per room.
///
/// This component takes a list of `TicketPartial` items and calculates the
/// This component takes a list of [`TicketPartial`] items and calculates the
/// total number of tickets for each room. It then displays these totals
/// in a sorted list with a bar chart visualization.
///
@@ -477,7 +495,7 @@ pub fn submit_stats_component() -> Html {
/// - **Sorts Results**: Displays rooms sorted by ticket count in descending order.
/// - **Visualizes Data**: Renders a bar chart where the width of each bar is
/// proportional to the ticket count for that room, relative to the room with the maximum tickets.
/// - **Room Formatting**: Uses the `parse_room` function to display room numbers
/// - **Room Formatting**: Uses the [`parse_room`] function to display room numbers
/// in a human-readable format.
///
/// # Example
@@ -522,6 +540,30 @@ fn room_total_component(props: &RoomTotalsProps) -> Html {
}
}
/// A component that displays the total number of tickets per user.
///
/// This component takes lists of [`UserPartial`] and [`TicketPartial`] items to calculate
/// and display the total number of tickets submitted by each user.
/// The results are presented in a sorted list with a bar chart visualization.
///
/// # Props
/// - `users`: A `Vec<UserPartial>` containing partial user data.
/// - `tickets`: A `Vec<TicketPartial>` containing partial ticket data for analysis.
///
/// # Functionality
/// - **Maps User Names**: Creates a map from user IDs to their first and last names for display.
/// - **Calculates Totals**: Aggregates ticket counts for each user.
/// - **Sorts Results**: Displays users sorted by their ticket count in descending order.
/// - **Visualizes Data**: Renders a bar chart where the width of each bar is proportional
/// to the ticket count for that user, relative to the user with the maximum tickets.
/// - **Name Formatting**: Uses the [`dequote!`] macro to clean up user names before display.
///
/// # Example
/// ```rust
/// html! {
/// <UserTotal users={my_user_partials} tickets={my_ticket_partials} />
/// }
/// ```
#[component(UserTotal)]
fn user_total_component(props: &UserTotalProps) -> Html {
let name_map: HashMap<i16, (String, String)> = props