use std::str::FromStr as _; use indexer_service_protocol::{BedrockStatus, Block, BlockBody, BlockHeader, BlockId, HashType}; use leptos::prelude::*; use leptos_router::{components::A, hooks::use_params_map}; use crate::{api, components::TransactionPreview, format_utils}; #[derive(Clone, PartialEq, Eq)] enum BlockIdOrHash { BlockId(BlockId), Hash(HashType), } /// Block page component #[component] pub fn BlockPage() -> impl IntoView { let params = use_params_map(); let block_resource = Resource::new( move || { let id_str = params.read().get("id").unwrap_or_default(); // Try to parse as block ID (number) if let Ok(block_id) = id_str.parse::() { return Some(BlockIdOrHash::BlockId(block_id)); } // Try to parse as block hash (hex string) if let Ok(hash) = HashType::from_str(&id_str) { return Some(BlockIdOrHash::Hash(hash)); } None }, |block_id_or_hash| async move { match block_id_or_hash { Some(BlockIdOrHash::BlockId(id)) => api::get_block_by_id(id).await, Some(BlockIdOrHash::Hash(hash)) => api::get_block_by_hash(hash).await, None => Err(leptos::prelude::ServerFnError::ServerError( "Invalid block ID or hash".to_owned(), )), } }, ); view! {
"Loading block..."
}> {move || { block_resource .get() .map(|result| match result { Ok(blk) => { let Block { header: BlockHeader { block_id, prev_block_hash, hash, timestamp, signature, }, body: BlockBody { transactions, }, bedrock_status, bedrock_parent_id: _, } = blk; let hash_str = hash.to_string(); let prev_hash = prev_block_hash.to_string(); let timestamp_str = format_utils::format_timestamp(timestamp); let signature_str = signature.to_string(); let status = match &bedrock_status { BedrockStatus::Pending => "Pending", BedrockStatus::Safe => "Safe", BedrockStatus::Finalized => "Finalized", }; view! {

"Block Information"

"Block ID: " {block_id.to_string()}
"Hash: " {hash_str}
"Previous Block Hash: " {prev_hash}
"Timestamp: " {timestamp_str}
"Status: " {status}
"Signature: " {signature_str}
"Transaction Count: " {transactions.len().to_string()}

"Transactions"

{if transactions.is_empty() { view! {
"No transactions"
} .into_any() } else { view! {
{transactions .into_iter() .map(|tx| view! { }) .collect::>()}
} .into_any() }}
} .into_any() } Err(e) => { view! {

"Error"

{format!("Failed to load block: {e}")}

} .into_any() } }) }} } }