Refactor event modal into standalone component
- Created dedicated EventModal component in src/components/event_modal.rs - Extracted modal logic and styling from calendar component for better separation - Updated data flow to pass full CalendarEvent objects instead of strings - Added PartialEq derive to CalendarEvent for component props - Updated service layer to group events by CalendarEvent objects - Enhanced event click handling to show detailed event information - Modal displays title, description, location, start/end times, and status - Maintained existing modal styling and user interaction patterns 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
use yew::prelude::*;
|
||||
use chrono::{Datelike, Local, NaiveDate, Duration, Weekday};
|
||||
use std::collections::HashMap;
|
||||
use crate::services::calendar_service::CalendarEvent;
|
||||
use crate::components::EventModal;
|
||||
|
||||
#[derive(Properties, PartialEq)]
|
||||
pub struct CalendarProps {
|
||||
#[prop_or_default]
|
||||
pub events: HashMap<NaiveDate, Vec<String>>,
|
||||
pub events: HashMap<NaiveDate, Vec<CalendarEvent>>,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
@@ -13,6 +15,7 @@ pub fn Calendar(props: &CalendarProps) -> Html {
|
||||
let today = Local::now().date_naive();
|
||||
let current_month = use_state(|| today);
|
||||
let selected_day = use_state(|| today);
|
||||
let selected_event = use_state(|| None::<CalendarEvent>);
|
||||
|
||||
let first_day_of_month = current_month.with_day(1).unwrap();
|
||||
let days_in_month = get_days_in_month(*current_month);
|
||||
@@ -100,13 +103,23 @@ pub fn Calendar(props: &CalendarProps) -> Html {
|
||||
<div class="event-indicators">
|
||||
{
|
||||
events.iter().take(2).map(|event| {
|
||||
let event_clone = event.clone();
|
||||
let selected_event_clone = selected_event.clone();
|
||||
let event_click = Callback::from(move |e: MouseEvent| {
|
||||
e.stop_propagation(); // Prevent day selection
|
||||
selected_event_clone.set(Some(event_clone.clone()));
|
||||
});
|
||||
|
||||
let title = event.get_title();
|
||||
html! {
|
||||
<div class="event-box" title={event.clone()}>
|
||||
<div class="event-box"
|
||||
title={title.clone()}
|
||||
onclick={event_click}>
|
||||
{
|
||||
if event.len() > 15 {
|
||||
format!("{}...", &event[..12])
|
||||
if title.len() > 15 {
|
||||
format!("{}...", &title[..12])
|
||||
} else {
|
||||
event.clone()
|
||||
title
|
||||
}
|
||||
}
|
||||
</div>
|
||||
@@ -133,6 +146,17 @@ pub fn Calendar(props: &CalendarProps) -> Html {
|
||||
|
||||
{ render_next_month_days(days_from_prev_month.len(), days_in_month) }
|
||||
</div>
|
||||
|
||||
// Event details modal
|
||||
<EventModal
|
||||
event={(*selected_event).clone()}
|
||||
on_close={{
|
||||
let selected_event_clone = selected_event.clone();
|
||||
Callback::from(move |_| {
|
||||
selected_event_clone.set(None);
|
||||
})
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -203,4 +227,5 @@ fn get_month_name(month: u32) -> &'static str {
|
||||
12 => "December",
|
||||
_ => "Invalid"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user