diff --git a/assets/images/event-banners/rust-africa-hackathon.png b/assets/images/event-banners/rust-africa-hackathon.png new file mode 100644 index 0000000..561d367 Binary files /dev/null and b/assets/images/event-banners/rust-africa-hackathon.png differ diff --git a/data/events.json b/data/events.json index bef1e94..26da65e 100644 --- a/data/events.json +++ b/data/events.json @@ -33,92 +33,98 @@ "event_link": "https://x.com/RustNigeria/status/1893623969258910075", "date": "2025-02-23T09:30:00.000Z", "speakers": [ - { - "image": "assets/images/speakers/mart.jpg", - "name": "Mart", - "portfolio": "https://x.com/mart_cpp" - }, - { - "name": "Bekka", - "image": "assets/images/speakers/bekka.png", - "portfolio": "https://x.com/ayomide_bajo" - } + { + "image": "assets/images/speakers/mart.jpg", + "name": "Mart", + "portfolio": "https://x.com/mart_cpp" + }, + { + "name": "Bekka", + "image": "assets/images/speakers/bekka.png", + "portfolio": "https://x.com/ayomide_bajo" + } ], "tags": ["workshop"] }, - { + { "banner": "/assets/images/event-banners/rust-class-series2.jpg", "name": "Rust class series ", "description": "Join us as we disect Generics, Enums & Grouping Types with Structs.", "event_link": "https://x.com/RustNigeria/status/1885221234567890123", "date": "2025-01-15T10:00:00.000Z", "speakers": [ - { - "name": "Bekka", - "image": "assets/images/speakers/bekka.png", - "portfolio": "https://x.com/ayomide_bajo" - } + { + "name": "Bekka", + "image": "assets/images/speakers/bekka.png", + "portfolio": "https://x.com/ayomide_bajo" + } ], "tags": ["workshop"] }, - { + { "banner": "/assets/images/event-banners/space2.jpg", "name": "How much of Rust is needed for Blockchain ", "description": "how Rust plays a pivotal role in building one of the most cutting-edge technologies of our time.", "event_link": "https://x.com/RustNigeria/status/1871824461579813129", "date": "2024-12-26T18:00:00.000Z", "speakers": [ - { - "name": "seun lanlege", - "image": "assets/images/speakers/sune.jpg", - "portfolio": "https://x.com/seunlanlege" - }, - - { - "name": "japar jam", - "image": "assets/images/speakers/jef.jpg", - "portfolio": "https://x.com/japarjam" - } + { + "name": "seun lanlege", + "image": "assets/images/speakers/sune.jpg", + "portfolio": "https://x.com/seunlanlege" + }, + { + "name": "japar jam", + "image": "assets/images/speakers/jef.jpg", + "portfolio": "https://x.com/japarjam" + } ], "tags": ["webinar"] }, - { + { "banner": "/assets/images/event-banners/space1.jpg", "name": "Beginner approach to learning Rust ", "description": "exciting session with Rust Experts who will break down the learning curve and guide you on your journey from Zero to Hero", "event_link": "https://x.com/RustNigeria/status/1884271805181092189", "date": "2025-01-31T18:00:00.000Z", "speakers": [ - { - "name": "Francesco", - "image": "assets/images/speakers/francesco.jpg", - "portfolio": "https://x.com/FrancescoCiull4" - }, - - { - "name": "chinedu", - "image": "assets/images/speakers/chinedutherustguy.jpg", - "portfolio": "https://x.com/chinedu" - } + { + "name": "Francesco", + "image": "assets/images/speakers/francesco.jpg", + "portfolio": "https://x.com/FrancescoCiull4" + }, + { + "name": "chinedu", + "image": "assets/images/speakers/chinedutherustguy.jpg", + "portfolio": "https://x.com/chinedu" + } ], "tags": ["webinar"] }, - { + { "banner": "/assets/images/event-banners/gitthubwebinar.jpg", "name": "GitHub setup for Rust project", "description": "Ready to supercharge your Rust projects? Join us for an exclusive webinar with MarcoIeni, Infrastructure ", "event_link": "https://www.youtube.com/live/5QSYa5TkKKY", "date": "2024-12-26T18:00:00.000Z", "speakers": [ - { - "name": "marco Ieni", - "image": "assets/images/speakers/marco-ieni.jpg", - "portfolio": "https://x.com/marcoieni" - } - + { + "name": "marco Ieni", + "image": "assets/images/speakers/marco-ieni.jpg", + "portfolio": "https://x.com/marcoieni" + } ], "tags": ["webinar", "workshop"] + }, + { + "banner": "/assets/images/event-banners/rust-africa-hackathon.png", + "name": "The Rust Africa Hackathon 2026", + "description": "5+ tracks, expert judges, real prizes, and a mission to spotlight Africa’s rising influence in the global Rust ecosystem.", + "event_link": "https://rustafrica.org/the-future-is-written-in-rust-rust-africa-hackathon-2026", + "date": "2026-01-03T00:00:00-06:00", + "speakers": [], + "tags": ["hackathon"] } ] diff --git a/data/projects.json b/data/projects.json index 4438420..e376132 100644 --- a/data/projects.json +++ b/data/projects.json @@ -13,5 +13,10 @@ "repo_url": "https://github.com/mahmudsudo/rate_rs", "banner": "https://opengraph.githubassets.com/1/mahmudsudo/rate_rs", "tags": ["crate"] + }, + { + "repo_url": "https://github.com/alob-mtc/runnerq", + "banner": "https://opengraph.githubassets.com/1/alob-mtc/runnerq", + "tags": ["crate"] } ] diff --git a/src/components/cards_list/mod.rs b/src/components/cards_list/mod.rs index feacda3..8348e43 100644 --- a/src/components/cards_list/mod.rs +++ b/src/components/cards_list/mod.rs @@ -23,7 +23,7 @@ use std::fmt::{Debug, Display}; use std::hash::Hash; pub trait CardsListItem: Send + Sync + Clone + PartialEq + Debug + 'static { - type Tag: Display + Clone + Eq + Hash + Sync + Send + Debug + 'static; + type Tag: Display + Clone + Eq + Hash + Sync + Send + Debug + Ord + Copy + 'static; fn get_key(&self) -> String; fn get_tags(&self) -> &Vec; @@ -99,20 +99,17 @@ where let cards_data_memo = Memo::new(move |_| cards_data()); - let tags = move || { + let tags = Memo::new(move |_| { let mut tags_set = HashSet::new(); - for card_item in cards_data_memo().iter() { - let tags = card_item.get_tags(); - - for tag in tags.iter() { - tags_set.insert(tag.clone()); + for card_item in cards_data_memo.get().iter() { + for tag in card_item.get_tags().iter() { + tags_set.insert(*tag); } } - tags_set - }; + }); - let selected_tags: RwSignal> = RwSignal::new(tags()); + let selected_tags: RwSignal> = RwSignal::new(tags.get()); let filtered_data = move || { cards_data_memo() @@ -137,7 +134,7 @@ where let config = cols_by_breakpoint.clone().unwrap_or_default(); let mut count = config.base; - let mut multiplier = 4; + let mut multiplier = 1; if is_sm.get() { if let Some(v) = config.sm { @@ -148,10 +145,13 @@ where if is_md.get() { if let Some(v) = config.md { count = v; - multiplier = 2; } } + if !is_md.get() { + multiplier = 4; + } + if is_lg.get() { if let Some(v) = config.lg { count = v; @@ -187,6 +187,8 @@ where Effect::new(move || selected_tags.set(tags())); + Effect::new(move || set_items_count(count_data().1)); + view! {
@@ -202,57 +204,62 @@ where )) />
+
{move || - tags().iter().enumerate() - .map(|(index, tag)| { - let tag_clone = tag.clone(); - let tag_clone_2 = tag.clone(); - let tag_clone_3 = tag.clone(); - let (bg, text) = get_color_pair(index, 30); - view! { - - } - }).collect_view() + { + + let mut sorted_tags: Vec<_> = tags.get().iter().cloned().collect(); + + sorted_tags.sort(); + + sorted_tags.into_iter().enumerate() + .map(|(index, tag)| { + + let (bg, text) = get_color_pair(index, 30); + view! { + + } + }).collect_view() + } }
- -
- {render_card(ev, idx.get())} -
-
+ style=move || format!("grid-template-columns: repeat({}, 1fr)", count_data.get().0) + class="grid h-full gap-x-4 overflow-x-hidden"> + +
+ {render_card(ev, idx.get())} +
+
-
    - {move || { - let is_empty = page_items().is_empty(); - - if is_empty { - Either::Left( - view! {
    No Data Available for this Selection
    } - ) - } else { - Either::Right( - page_items().into_iter() - .map(|value| - view! { -
  • - {move || { - match value { - PageItem::Ellipsis => Either::Left(view! {
    ...
    }), - PageItem::Page(num) => Either::Right(view! { }) - } - }} -
  • - }).collect_view() - ) - } - }} -
+ {move || { + if total_pages.get() > 1 { + Some( + view! { +
    + {move || { + let is_empty = page_items().is_empty(); + + if is_empty { + Either::Left( + view! {
    No Data Available for this Selection
    } + ) + } else { + Either::Right( + page_items().into_iter() + .map(|value| + view! { +
  • + {move || { + match value { + PageItem::Ellipsis => Either::Left(view! {
    ...
    }), + PageItem::Page(num) => Either::Right(view! { }) + } + }} +
  • + }).collect_view() + ) + } + }} +
+ } + ) + } else { + None + } + }} } } diff --git a/src/types/articles.rs b/src/types/articles.rs index cf7e69a..3631d39 100644 --- a/src/types/articles.rs +++ b/src/types/articles.rs @@ -5,7 +5,7 @@ use crate::components::cards_list::CardsListItem; use crate::types::person::Person; use std::fmt; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd, Copy)] #[serde(rename_all = "snake_case")] pub enum ArticleTags { Technical, diff --git a/src/types/events.rs b/src/types/events.rs index 8933edd..406669a 100644 --- a/src/types/events.rs +++ b/src/types/events.rs @@ -5,13 +5,14 @@ use std::fmt; use crate::components::cards_list::CardsListItem; use crate::types::person::Person; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd, Copy)] #[serde(rename_all = "snake_case")] pub enum EventTags { Workshop, Meetup, Webinar, InPerson, + Hackathon, } impl fmt::Display for EventTags { @@ -21,6 +22,7 @@ impl fmt::Display for EventTags { EventTags::Meetup => "Meetup", EventTags::Webinar => "Webinar", EventTags::InPerson => "In-Person", + EventTags::Hackathon => "Hackathon", }; write!(f, "{}", s) } diff --git a/src/types/projects.rs b/src/types/projects.rs index 7a5114e..b034ff3 100644 --- a/src/types/projects.rs +++ b/src/types/projects.rs @@ -3,14 +3,14 @@ use std::fmt; use crate::components::cards_list::CardsListItem; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd, Copy)] #[serde(rename_all = "snake_case")] pub enum ProjectTags { Wasm, Ai, Blockchain, Leptos, - Crate + Crate, } impl fmt::Display for ProjectTags {