feat(dash): improved frontend dashboard (#6)
All checks were successful
CI / Format (push) Successful in 6m30s
CI / Clippy (push) Successful in 2m25s
CI / Security Audit (push) Successful in 1m53s
CI / Tests (push) Successful in 2m50s
CI / Deploy (push) Successful in 4s

Co-authored-by: Sharang Parnerkar <parnerkarsharang@gmail.com>
Reviewed-on: #6
This commit was merged in pull request #6.
This commit is contained in:
2026-02-19 11:52:41 +00:00
parent f699976f4d
commit a588be306a
46 changed files with 4960 additions and 261 deletions

67
src/pages/dashboard.rs Normal file
View File

@@ -0,0 +1,67 @@
use dioxus::prelude::*;
use crate::components::{NewsCardView, PageHeader};
use crate::models::NewsCategory;
/// Dashboard page displaying an AI news feed grid with category filters.
///
/// Replaces the previous `OverviewPage`. Shows mock news items
/// that will eventually be sourced from the SearXNG instance.
#[component]
pub fn DashboardPage() -> Element {
let news = use_signal(crate::components::news_card::mock_news);
let mut active_filter = use_signal(|| Option::<NewsCategory>::None);
// Collect filtered news items based on active category filter
let filtered: Vec<_> = {
let items = news.read();
let filter = active_filter.read();
match &*filter {
Some(cat) => items
.iter()
.filter(|n| n.category == *cat)
.cloned()
.collect(),
None => items.clone(),
}
};
// All available filter categories
let categories = [
("All", None),
("LLM", Some(NewsCategory::Llm)),
("Agents", Some(NewsCategory::Agents)),
("Privacy", Some(NewsCategory::Privacy)),
("Infrastructure", Some(NewsCategory::Infrastructure)),
("Open Source", Some(NewsCategory::OpenSource)),
];
rsx! {
section { class: "dashboard-page",
PageHeader {
title: "Dashboard".to_string(),
subtitle: "AI news and updates".to_string(),
}
div { class: "dashboard-filters",
for (label , cat) in categories {
{
let is_active = *active_filter.read() == cat;
let class = if is_active {
"filter-tab filter-tab--active"
} else {
"filter-tab"
};
rsx! {
button { class: "{class}", onclick: move |_| active_filter.set(cat.clone()), "{label}" }
}
}
}
}
div { class: "news-grid",
for card in filtered {
NewsCardView { key: "{card.title}", card }
}
}
}
}
}