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:
		
							
								
								
									
										101
									
								
								src/components/event_modal.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								src/components/event_modal.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| use yew::prelude::*; | ||||
| use chrono::{DateTime, Utc}; | ||||
| use crate::services::CalendarEvent; | ||||
|  | ||||
| #[derive(Properties, PartialEq)] | ||||
| pub struct EventModalProps { | ||||
|     pub event: Option<CalendarEvent>, | ||||
|     pub on_close: Callback<()>, | ||||
| } | ||||
|  | ||||
| #[function_component] | ||||
| pub fn EventModal(props: &EventModalProps) -> Html { | ||||
|     let close_modal = { | ||||
|         let on_close = props.on_close.clone(); | ||||
|         Callback::from(move |_| { | ||||
|             on_close.emit(()); | ||||
|         }) | ||||
|     }; | ||||
|      | ||||
|     let backdrop_click = { | ||||
|         let on_close = props.on_close.clone(); | ||||
|         Callback::from(move |e: MouseEvent| { | ||||
|             if e.target() == e.current_target() { | ||||
|                 on_close.emit(()); | ||||
|             } | ||||
|         }) | ||||
|     }; | ||||
|  | ||||
|     if let Some(ref event) = props.event { | ||||
|         html! { | ||||
|             <div class="modal-backdrop" onclick={backdrop_click}> | ||||
|                 <div class="modal-content"> | ||||
|                     <div class="modal-header"> | ||||
|                         <h3>{"Event Details"}</h3> | ||||
|                         <button class="modal-close" onclick={close_modal}>{"×"}</button> | ||||
|                     </div> | ||||
|                     <div class="modal-body"> | ||||
|                         <div class="event-detail"> | ||||
|                             <strong>{"Title:"}</strong> | ||||
|                             <span>{event.get_title()}</span> | ||||
|                         </div> | ||||
|                         { | ||||
|                             if let Some(ref description) = event.description { | ||||
|                                 html! { | ||||
|                                     <div class="event-detail"> | ||||
|                                         <strong>{"Description:"}</strong> | ||||
|                                         <span>{description}</span> | ||||
|                                     </div> | ||||
|                                 } | ||||
|                             } else { | ||||
|                                 html! {} | ||||
|                             } | ||||
|                         } | ||||
|                         { | ||||
|                             if let Some(ref location) = event.location { | ||||
|                                 html! { | ||||
|                                     <div class="event-detail"> | ||||
|                                         <strong>{"Location:"}</strong> | ||||
|                                         <span>{location}</span> | ||||
|                                     </div> | ||||
|                                 } | ||||
|                             } else { | ||||
|                                 html! {} | ||||
|                             } | ||||
|                         } | ||||
|                         <div class="event-detail"> | ||||
|                             <strong>{"Start:"}</strong> | ||||
|                             <span>{format_datetime(&event.start, event.all_day)}</span> | ||||
|                         </div> | ||||
|                         { | ||||
|                             if let Some(ref end) = event.end { | ||||
|                                 html! { | ||||
|                                     <div class="event-detail"> | ||||
|                                         <strong>{"End:"}</strong> | ||||
|                                         <span>{format_datetime(end, event.all_day)}</span> | ||||
|                                     </div> | ||||
|                                 } | ||||
|                             } else { | ||||
|                                 html! {} | ||||
|                             } | ||||
|                         } | ||||
|                         <div class="event-detail"> | ||||
|                             <strong>{"Status:"}</strong> | ||||
|                             <span>{&event.status}</span> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         } | ||||
|     } else { | ||||
|         html! {} | ||||
|     } | ||||
| } | ||||
|  | ||||
| fn format_datetime(dt: &DateTime<Utc>, all_day: bool) -> String { | ||||
|     if all_day { | ||||
|         dt.format("%B %d, %Y").to_string() | ||||
|     } else { | ||||
|         dt.format("%B %d, %Y at %I:%M %p").to_string() | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Connor Johnstone
					Connor Johnstone