use leptos::prelude::*; use leptos_router::hooks::{use_navigate, use_query_map}; use web_sys::SubmitEvent; use crate::{ api::{self, SearchResults}, components::{AccountPreview, BlockPreview, TransactionPreview}, }; const RECENT_BLOCKS_LIMIT: u64 = 10; /// Main page component #[component] pub fn MainPage() -> impl IntoView { let query_map = use_query_map(); let navigate = use_navigate(); // Read search query from URL parameter let url_query = move || query_map.read().get("q").unwrap_or_default(); let (search_query, set_search_query) = signal(url_query()); // Sync search input with URL parameter Effect::new(move || { set_search_query.set(url_query()); }); // Search results resource based on URL query parameter let search_resource = Resource::new(url_query, |query| async move { if query.is_empty() { return None; } match api::search(query).await { Ok(result) => Some(result), Err(e) => { log::error!("Search error: {}", e); None } } }); // Load recent blocks on mount let recent_blocks_resource = Resource::new( || (), |_| async { match api::get_latest_block_id().await { Ok(last_id) => { api::get_blocks( std::cmp::max(last_id.saturating_sub(RECENT_BLOCKS_LIMIT) as u32, 1), RECENT_BLOCKS_LIMIT as u32, ) .await } Err(err) => Err(err), } }, ); // Handle search - update URL parameter let on_search = move |ev: SubmitEvent| { ev.prevent_default(); let query = search_query.get(); if query.is_empty() { navigate("?", Default::default()); return; } navigate( &format!("?q={}", urlencoding::encode(&query)), Default::default(), ); }; view! {