From 21aa213ff4144133aa1ece095b698d17e2672749 Mon Sep 17 00:00:00 2001 From: schn33fuchs Date: Tue, 28 Apr 2026 21:23:40 +0200 Subject: [PATCH] Viewing ticket by ID This is now possible by going to /tickets/{id} --- frontend/Cargo.lock | 156 +++++++++++++++++++++++++++++++++++ frontend/Cargo.toml | 2 +- frontend/src/lib.rs | 5 +- frontend/src/pages/ticket.rs | 99 +++++++++++++++++++++- 4 files changed, 257 insertions(+), 5 deletions(-) diff --git a/frontend/Cargo.lock b/frontend/Cargo.lock index 018471f..140ecf6 100644 --- a/frontend/Cargo.lock +++ b/frontend/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + [[package]] name = "bincode" version = "1.3.3" @@ -23,12 +38,36 @@ version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +[[package]] +name = "cc" +version = "1.2.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" +dependencies = [ + "find-msvc-tools", + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "chrono" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link", +] + [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -39,12 +78,24 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + [[package]] name = "fnv" version = "1.0.7" @@ -64,6 +115,7 @@ dependencies = [ name = "frontend" version = "0.1.0" dependencies = [ + "chrono", "gloo 0.12.0", "gloo-net 0.7.0", "serde", @@ -562,6 +614,30 @@ dependencies = [ "itoa", ] +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "implicit-clone" version = "0.6.0" @@ -616,12 +692,27 @@ version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + [[package]] name = "memchr" version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.17.0" @@ -836,6 +927,12 @@ dependencies = [ "serde", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "slab" version = "0.4.12" @@ -1100,6 +1197,65 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + [[package]] name = "winnow" version = "0.5.40" diff --git a/frontend/Cargo.toml b/frontend/Cargo.toml index 1684f68..e41e491 100644 --- a/frontend/Cargo.toml +++ b/frontend/Cargo.toml @@ -23,4 +23,4 @@ gloo-net = "0.7.0" yew-router = "0.20.0" serde_json = "1.0.149" gloo = "0.12.0" - +chrono = { version = "0.4.44", features = ["serde"] } diff --git a/frontend/src/lib.rs b/frontend/src/lib.rs index f6c81f1..feeeee3 100644 --- a/frontend/src/lib.rs +++ b/frontend/src/lib.rs @@ -9,6 +9,8 @@ enum Route { Home, #[at("/ticket")] Ticket, + #[at("/tickets/:id")] + TicketById { id: i32 }, #[not_found] #[at("/404")] NotFound, @@ -18,7 +20,8 @@ fn switch(route: Route) -> Html { match route { Route::Home => html! { }, Route::NotFound => html! { }, - Route::Ticket => html! { }, + Route::Ticket => html! { }, + Route::TicketById { id } => html! { }, } } diff --git a/frontend/src/pages/ticket.rs b/frontend/src/pages/ticket.rs index 642bfb4..0a98672 100644 --- a/frontend/src/pages/ticket.rs +++ b/frontend/src/pages/ticket.rs @@ -1,9 +1,10 @@ use gloo_net::http::Request; use serde::{Deserialize, Serialize}; +use serde_json::json; use wasm_bindgen_futures::spawn_local; use yew::prelude::*; -#[derive(Serialize, Deserialize, Clone, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct TicketCreateScheme { pub category: String, pub betreff: String, @@ -11,8 +12,31 @@ pub struct TicketCreateScheme { pub room: i16, } -#[component(Ticket)] -pub fn ticket_component() -> Html { +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct Ticket { + pub id: i32, + pub category: String, + pub betreff: String, + pub description: String, + pub room: i16, + pub status: String, + pub date: chrono::NaiveDateTime, + pub user_id: i16, +} + +#[derive(Properties, PartialEq)] +pub struct TicketProps { + pub id: i32, +} + +#[derive(Deserialize, Debug)] +pub struct ApiError { + message: String, + status: String, +} + +#[component(SubmitTicket)] +pub fn submit_ticket_component() -> Html { let category = use_state(|| "".to_string()); let betreff = use_state(|| "".to_string()); let description = use_state(|| "".to_string()); @@ -118,3 +142,72 @@ pub fn ticket_component() -> Html { } } + +#[component(ShowTicketByID)] +pub fn show_ticket_by_id_component(props: &TicketProps) -> Html { + let ticket = use_state(|| None::); + let error = use_state(|| None::); + let loading = use_state(|| false); + let id = props.id; + + { + let ticket = ticket.clone(); + let error = error.clone(); + let loading = loading.clone(); + + use_effect_with(id, move |id_ref| { + loading.set(true); + let ticket = ticket.clone(); + let error = error.clone(); + let id = *id_ref; + spawn_local(async move { + let url = format!("http://localhost:8001/api/tickets/{}", id); + match Request::get(&url).send().await { + Ok(response) => { + let status = response.status(); + if status == 200 { + match response.json::().await { + Ok(t) => ticket.set(Some(t)), + Err(err) => error.set(Some(format!("Parse error: {}", err))), + } + } else { + match response.json::().await { + Ok(ae) => error.set(Some(ae.message)), + Err(_) => { + if let Ok(text) = response.text().await { + error.set(Some(text)); + } else { + error.set(Some(format!("Server error: {}", status))); + } + } + } + } + } + Err(err) => error.set(Some(format!("Network error: {}", err))), + } + loading.set(false); + }); + || () + }); + } + + if *loading { + html! {

{ "Loading" }

} + } else if let Some(e) = &*error { + html! {

{ format!("Error: {}", e) }

} + } else if let Some(t) = &*ticket { + html! { +
+

{ format!("Ticket #{}", t.id) }

+

{ "Kategorie: " }{ &t.category }

+

{ "Betreff: " }{ &t.betreff }

+

{ "Beschreibung: " }{ &t.description }

+

{ "Raum: " }{ t.room }

+

{ "Datum: " }{ &t.date }

+

{ "Status: "}{ &t.status }

+
+ } + } else { + html! {

{ "No ticket found." }

} + } +}