use dioxus::prelude::*; use crate::app::Route; use crate::components::page_header::PageHeader; use crate::infrastructure::repositories::fetch_repositories; #[component] pub fn GraphIndexPage() -> Element { let repos = use_resource(|| async { fetch_repositories(1).await.ok() }); rsx! { PageHeader { title: "Code Knowledge Graph", description: "Select a repository to explore its code graph", } match &*repos.read() { Some(Some(data)) => { let repo_list = &data.data; if repo_list.is_empty() { rsx! { div { class: "card", p { "No repositories found. Add a repository first." } } } } else { rsx! { div { class: "graph-index-grid", for repo in repo_list { { let repo_id = repo.id.map(|id| id.to_hex()).unwrap_or_default(); let name = repo.name.clone(); let url = repo.git_url.clone(); let branch = repo.default_branch.clone(); let findings = repo.findings_count; let findings_label = if findings != 1 { format!("{findings} findings") } else { "1 finding".to_string() }; let updated = { let now = chrono::Utc::now(); let diff = now.signed_duration_since(repo.updated_at); if diff.num_minutes() < 1 { "just now".to_string() } else if diff.num_hours() < 1 { format!("{}m ago", diff.num_minutes()) } else if diff.num_days() < 1 { format!("{}h ago", diff.num_hours()) } else if diff.num_days() < 30 { format!("{}d ago", diff.num_days()) } else { repo.updated_at.format("%Y-%m-%d").to_string() } }; rsx! { Link { to: Route::GraphExplorerPage { repo_id }, class: "graph-repo-card", div { class: "graph-repo-card-header", div { class: "graph-repo-card-icon", "\u{29BB}" } h3 { class: "graph-repo-card-name", "{name}" } } if !url.is_empty() { p { class: "graph-repo-card-url", "{url}" } } div { class: "graph-repo-card-meta", span { class: "graph-repo-card-tag", "\u{E0A0} {branch}" } span { class: "graph-repo-card-tag graph-repo-card-tag-findings", "{findings_label}" } span { class: "graph-repo-card-tag", "Updated {updated}" } } } } } } } } } }, Some(None) => rsx! { div { class: "card", p { "Failed to load repositories." } } }, None => rsx! { div { class: "loading", "Loading repositories..." } }, } } }