use dioxus::prelude::*; use crate::app::Route; use crate::components::page_header::PageHeader; use crate::components::severity_badge::SeverityBadge; use crate::infrastructure::dast::fetch_dast_findings; #[component] pub fn DastFindingsPage() -> Element { let findings = use_resource(|| async { fetch_dast_findings().await.ok() }); rsx! { PageHeader { title: "DAST Findings", description: "Vulnerabilities discovered through dynamic application security testing", } div { class: "card", match &*findings.read() { Some(Some(data)) => { let finding_list = &data.data; if finding_list.is_empty() { rsx! { p { "No DAST findings yet. Run a scan to discover vulnerabilities." } } } else { rsx! { table { class: "table", thead { tr { th { "Severity" } th { "Type" } th { "Title" } th { "Endpoint" } th { "Method" } th { "Exploitable" } } } tbody { for finding in finding_list { { let id = finding.get("_id").and_then(|v| v.get("$oid")).and_then(|v| v.as_str()).unwrap_or("").to_string(); let severity = finding.get("severity").and_then(|v| v.as_str()).unwrap_or("info").to_string(); rsx! { tr { td { SeverityBadge { severity: severity } } td { span { class: "badge", "{finding.get(\"vuln_type\").and_then(|v| v.as_str()).unwrap_or(\"-\")}" } } td { Link { to: Route::DastFindingDetailPage { id: id }, "{finding.get(\"title\").and_then(|v| v.as_str()).unwrap_or(\"-\")}" } } td { code { class: "text-sm", "{finding.get(\"endpoint\").and_then(|v| v.as_str()).unwrap_or(\"-\")}" } } td { "{finding.get(\"method\").and_then(|v| v.as_str()).unwrap_or(\"-\")}" } td { if finding.get("exploitable").and_then(|v| v.as_bool()).unwrap_or(false) { span { class: "badge badge-danger", "Confirmed" } } else { span { class: "badge", "Unconfirmed" } } } } } } } } } } } }, Some(None) => rsx! { p { "Failed to load findings." } }, None => rsx! { p { "Loading..." } }, } } } }