3 Commits
Author SHA1 Message Date
TheDiluTek 3915f997da Merge branch 'main' of https://git.raffauf-clan.de/schn33fuchs/ticketsystem 2026-06-18 19:58:46 +02:00
TheDiluTek 9704d5792a njix 2026-06-18 19:58:41 +02:00
schn33fuchs c11309a3a5 Docs 2026-06-17 16:35:26 +02:00
7 changed files with 92 additions and 2 deletions
+4 -2
View File
@@ -32,8 +32,10 @@ use crate::env::Env;
/// - `db`: PostgreSQL connection pool for database access (via `sqlx::PgPool`)
/// - `env`: [`Env`] configuration loaded from environment variables
pub struct AppState {
db: PgPool,
env: Env,
/// PostgreSQL connection pool for all database operations
pub db: PgPool,
/// Environment configuration with secrets and settings
pub env: Env,
}
/// Main application entry point.
+39
View File
@@ -33,15 +33,25 @@ use serde::{Deserialize, Serialize};
/// ```
#[derive(Deserialize, Serialize, Debug, PartialEq)]
pub struct TicketResponse {
/// Unique ticket identifier
pub id: i32,
/// Ticket category/type (e.g., "maintenance", "support")
pub category: String,
/// Ticket subject line
pub betreff: String,
/// Detailed ticket description
pub description: String,
/// Room number associated with the issue
pub room: i16,
/// Current ticket status (e.g., "open", "in_progress", "resolved", "archived")
pub status: String,
/// When the ticket was created (UTC timestamp)
pub date: chrono::DateTime<chrono::Utc>,
/// ID of the user who created the ticket
pub user_id: i16,
/// First name of the ticket creator (denormalized from `User`)
pub user_first_name: String,
/// Last name of the ticket creator (denormalized from `User`)
pub user_last_name: String,
}
@@ -62,11 +72,17 @@ pub struct TicketResponse {
/// Use [`filter_user()`](`crate::handlers::auth::filter_user`) to convert to [`FilteredUser`] for responses.
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone, sqlx::FromRow)]
pub struct User {
/// Unique user identifier
pub id: i16,
/// User's last name
pub last_name: String,
/// User's first name
pub first_name: String,
/// Unique login username (must be unique in the database)
pub username: String,
/// Whether this user has administrator privileges
pub is_admin: bool,
/// Argon2 password hash (NEVER expose to clients)
pub pwd: String,
}
@@ -82,9 +98,13 @@ pub struct User {
/// - `room`: Room number where the issue is located
#[derive(Deserialize, Serialize, Debug)]
pub struct TicketCreateScheme {
/// Ticket category/type
pub category: String,
/// Subject line for the ticket
pub betreff: String,
/// Detailed problem description
pub description: String,
/// Room number where the issue is located
pub room: i16,
}
@@ -97,6 +117,7 @@ pub struct TicketCreateScheme {
/// - `status`: New ticket status (e.g., "open", "in_progress", "resolved")
#[derive(Deserialize, Serialize, Debug)]
pub struct TicketUpdateScheme {
/// New ticket status (e.g., "open", "in_progress", "resolved", "archived")
pub status: String,
}
@@ -113,11 +134,17 @@ pub struct TicketUpdateScheme {
/// - `new_pwd`: New password (empty string = keep existing password)
#[derive(Deserialize, Serialize, Debug)]
pub struct UserUpdateScheme {
/// User ID to update
pub id: i16,
/// Updated user first name
pub first_name: String,
/// Updated user last name
pub last_name: String,
/// Updated login username
pub username: String,
/// New admin privilege status
pub make_admin: bool,
/// New password (empty string = keep existing password)
pub new_pwd: String,
}
@@ -134,10 +161,15 @@ pub struct UserUpdateScheme {
/// - `pwd`: Plain text password (hashed on server)
#[derive(Deserialize, Serialize, Debug, sqlx::FromRow)]
pub struct UserCreateScheme {
/// User's first name
pub first_name: String,
/// User's last name
pub last_name: String,
/// Unique username for login
pub username: String,
/// Whether to grant admin privileges
pub is_admin: bool,
/// Plain text password (hashed on server before storage)
pub pwd: String,
}
@@ -150,7 +182,9 @@ pub struct UserCreateScheme {
/// The password is never stored in plain text - only the Argon2 hash is persisted.
#[derive(Deserialize, Serialize, Debug)]
pub struct LoginScheme {
/// Username for login
pub username: String,
/// Plain text password (verified against stored Argon2 hash)
pub pwd: String,
}
@@ -161,10 +195,15 @@ pub struct LoginScheme {
/// to prevent leaking sensitive data.
#[derive(Debug, Clone, Serialize)]
pub struct FilteredUser {
/// Unique user identifier
pub id: i16,
/// User's first name
pub first_name: String,
/// User's last name
pub last_name: String,
/// Login username
pub username: String,
/// Whether user has admin privileges
pub is_admin: bool,
}
Binary file not shown.
+17
View File
@@ -1,5 +1,22 @@
use yew::prelude::*;
/// A button component that toggles between light and dark theme modes.
///
/// Clicking this button switches the application's theme by modifying the `data-theme` attribute
/// on the document element. The theme preference is applied via CSS variables for consistent styling.
///
/// # Behavior
/// - Reads the current `data-theme` attribute value from the HTML element
/// - Sets `data-theme="dark"` if currently in light mode
/// - Clears the attribute (light mode) if currently in dark mode
/// - Re-renders to reflect the visual changes (typically toggled via CSS)
///
/// # Example Usage
/// ```ignore
/// html! {
/// <ThemeToggle />
/// }
/// ```
#[function_component]
pub fn ThemeToggle() -> Html {
let onclick = {
+4
View File
@@ -1,5 +1,9 @@
use frontend::App;
/// Main entry point for the Yew frontend application.
///
/// Initializes the Yew framework and renders the root [`App`] component into the DOM.
/// This function is typically called automatically by the WebAssembly runtime.
fn main() {
yew::Renderer::<App>::new().render();
}
@@ -0,0 +1,21 @@
body {
/* Formular Styles */
input, textarea, select, button {
width: 100%;
margin-top: 1rem;
padding: 0.75rem;
font-size: 1rem;
border-radius: 0.5rem;
color: white;
border: none;
cursor: pointer;
margin-bottom: 15px;
}
button:hover {
cursor: pointer;
border: none;
transition: all 0.2s ease-in-out;
margin-bottom: 15px;
}
}
@@ -1,6 +1,11 @@
@use "../variables" as *;
@use "../mixins" as *;
:root {
color-scheme: dark light;
}
.sidebar {
width: 260px;
background: var(--color-sidebar);
@@ -178,4 +183,6 @@
pointer-events: auto;
}
}
}