From 0abe8607987f55318ca269b41ae31d740d624fb8 Mon Sep 17 00:00:00 2001 From: Florian Berthold Date: Tue, 17 Mar 2026 21:34:02 +0100 Subject: [PATCH] Fix companions API (column rename), home search, search URL params MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix companion_relationships column: relationship → companion_type (with AS alias) - Home page search passes query via ?q= URL param - Search page reads ?q= on load and auto-searches --- herbapi-api/src/db/companions.rs | 12 +++++++----- herbapi-ui/src/pages/home.rs | 7 +++++-- herbapi-ui/src/pages/search.rs | 21 ++++++++++++++++++++- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/herbapi-api/src/db/companions.rs b/herbapi-api/src/db/companions.rs index 688b72b..421c631 100644 --- a/herbapi-api/src/db/companions.rs +++ b/herbapi-api/src/db/companions.rs @@ -6,7 +6,7 @@ use super::models::{CompanionRelationship, CompanionWithNames, CreateCompanion}; pub async fn list_all(pool: &PgPool) -> Result> { sqlx::query_as::<_, CompanionWithNames>( - "SELECT cr.id, cr.species_a_id, cr.species_b_id, cr.relationship, + "SELECT cr.id, cr.species_a_id, cr.species_b_id, cr.companion_type AS relationship, cr.mechanism, cr.source_url, cr.created_at, sa.name_scientific AS species_a_scientific, sa.name_de AS species_a_de, @@ -28,9 +28,10 @@ pub async fn list_all(pool: &PgPool) -> Result> { pub async fn list_for_species(pool: &PgPool, species_id: Uuid) -> Result> { sqlx::query_as::<_, CompanionRelationship>( - "SELECT * FROM companion_relationships + "SELECT id, species_a_id, species_b_id, companion_type AS relationship, mechanism, source_url, created_at + FROM companion_relationships WHERE species_a_id = $1 OR species_b_id = $1 - ORDER BY relationship, created_at" + ORDER BY companion_type, created_at" ) .bind(species_id) .fetch_all(pool) @@ -48,8 +49,9 @@ pub async fn create(pool: &PgPool, req: &CreateCompanion) -> Result( - "INSERT INTO companion_relationships (id, species_a_id, species_b_id, relationship, mechanism, source_url) - VALUES ($1, $2, $3, $4::companion_type, $5, $6) RETURNING *" + "INSERT INTO companion_relationships (id, species_a_id, species_b_id, companion_type, mechanism, source_url) + VALUES ($1, $2, $3, $4, $5, $6) + RETURNING id, species_a_id, species_b_id, companion_type AS relationship, mechanism, source_url, created_at" ) .bind(id).bind(a).bind(b).bind(&req.relationship) .bind(&req.mechanism).bind(&req.source_url) diff --git a/herbapi-ui/src/pages/home.rs b/herbapi-ui/src/pages/home.rs index f26464f..aa66d3a 100644 --- a/herbapi-ui/src/pages/home.rs +++ b/herbapi-ui/src/pages/home.rs @@ -53,8 +53,11 @@ pub fn Home() -> Element { oninput: move |e| search_query.set(e.value()), onkeydown: move |e| { if e.key() == Key::Enter { - let nav = navigator(); - nav.push(Route::SearchPage {}); + let q = search_query.read().clone(); + if !q.is_empty() { + let nav = navigator(); + nav.push(format!("/search?q={}", q).as_str()); + } } }, } diff --git a/herbapi-ui/src/pages/search.rs b/herbapi-ui/src/pages/search.rs index df4ff4b..8ef8da6 100644 --- a/herbapi-ui/src/pages/search.rs +++ b/herbapi-ui/src/pages/search.rs @@ -7,9 +7,28 @@ use crate::i18n::{pick_name, t, t_val}; #[component] pub fn SearchPage() -> Element { let lang = use_context::().0; - let mut query = use_signal(|| String::new()); + // Read ?q= from URL on initial load + let initial_q = { + let window = web_sys::window().unwrap(); + let search = window.location().search().unwrap_or_default(); + let params = web_sys::UrlSearchParams::new_with_str(&search).ok(); + params.and_then(|p| p.get("q")).unwrap_or_default() + }; + let has_initial = !initial_q.is_empty(); + let mut query = use_signal(move || initial_q.clone()); let mut results = use_signal(|| None::, String>>); + // Auto-search on load if ?q= was provided + let mut did_initial = use_signal(|| false); + if has_initial && !*did_initial.read() { + did_initial.set(true); + let q = query.read().clone(); + spawn(async move { + let res = api::search(&q, 50).await; + results.set(Some(res)); + }); + } + let trigger_search = move || { let q = query.read().clone(); if !q.is_empty() {