diff --git a/backend/src/handlers.rs b/backend/src/handlers.rs index 7f0c57d..db42caa 100644 --- a/backend/src/handlers.rs +++ b/backend/src/handlers.rs @@ -39,11 +39,24 @@ pub async fn get_calendar_events( return Ok(Json(vec![])); // No calendars found } - // Fetch events from the first calendar - let calendar_path = &calendar_paths[0]; - let events = client.fetch_events(calendar_path) - .await - .map_err(|e| ApiError::Internal(format!("Failed to fetch events: {}", e)))?; + // Fetch events from all calendars + let mut all_events = Vec::new(); + for calendar_path in &calendar_paths { + match client.fetch_events(calendar_path).await { + Ok(mut events) => { + // Set calendar_path for each event to identify which calendar it belongs to + for event in &mut events { + event.calendar_path = Some(calendar_path.clone()); + } + all_events.extend(events); + }, + Err(e) => { + // Log the error but continue with other calendars + eprintln!("Failed to fetch events from calendar {}: {}", calendar_path, e); + } + } + } + let events = all_events; // Filter events by month if specified let filtered_events = if let (Some(year), Some(month)) = (params.year, params.month) { @@ -80,11 +93,23 @@ pub async fn refresh_event( return Ok(Json(None)); // No calendars found } - // Fetch the specific event by UID from the first calendar - let calendar_path = &calendar_paths[0]; - let event = client.fetch_event_by_uid(calendar_path, &uid) - .await - .map_err(|e| ApiError::Internal(format!("Failed to fetch event: {}", e)))?; + // Search for the specific event by UID across all calendars + let mut found_event = None; + for calendar_path in &calendar_paths { + match client.fetch_event_by_uid(calendar_path, &uid).await { + Ok(Some(mut event)) => { + event.calendar_path = Some(calendar_path.clone()); + found_event = Some(event); + break; + }, + Ok(None) => continue, // Event not found in this calendar + Err(e) => { + eprintln!("Failed to fetch event from calendar {}: {}", calendar_path, e); + continue; + } + } + } + let event = found_event; Ok(Json(event)) } diff --git a/src/app.rs b/src/app.rs index b83a65a..3345f2c 100644 --- a/src/app.rs +++ b/src/app.rs @@ -273,11 +273,12 @@ pub fn App() -> Html { reminder_str, recurrence_str, event_data.recurrence_days, - None // Let backend use first available calendar + event_data.selected_calendar ).await { Ok(_) => { web_sys::console::log_1(&"Event created successfully".into()); - // Refresh the page to show the new event + // Trigger a page reload to refresh events from all calendars + // TODO: This could be improved to do a more targeted refresh web_sys::window().unwrap().location().reload().unwrap(); } Err(err) => { @@ -542,6 +543,7 @@ pub fn App() -> Html { move |_| create_event_modal_open.set(false) })} on_create={on_event_create} + available_calendars={user_info.as_ref().map(|ui| ui.calendars.clone()).unwrap_or_default()} /> diff --git a/src/components/create_event_modal.rs b/src/components/create_event_modal.rs index 50a628a..704ce7b 100644 --- a/src/components/create_event_modal.rs +++ b/src/components/create_event_modal.rs @@ -1,6 +1,7 @@ use yew::prelude::*; use web_sys::{HtmlInputElement, HtmlTextAreaElement, HtmlSelectElement}; use chrono::{NaiveDate, NaiveTime}; +use crate::services::calendar_service::CalendarInfo; #[derive(Properties, PartialEq)] pub struct CreateEventModalProps { @@ -8,6 +9,7 @@ pub struct CreateEventModalProps { pub selected_date: Option, pub on_close: Callback<()>, pub on_create: Callback, + pub available_calendars: Vec, } #[derive(Clone, PartialEq, Debug)] @@ -88,6 +90,7 @@ pub struct EventCreationData { pub reminder: ReminderType, pub recurrence: RecurrenceType, pub recurrence_days: Vec, // [Sun, Mon, Tue, Wed, Thu, Fri, Sat] for weekly recurrence + pub selected_calendar: Option, // Calendar path } impl Default for EventCreationData { @@ -114,6 +117,7 @@ impl Default for EventCreationData { reminder: ReminderType::default(), recurrence: RecurrenceType::default(), recurrence_days: vec![false; 7], // [Sun, Mon, Tue, Wed, Thu, Fri, Sat] - all false by default + selected_calendar: None, } } } @@ -123,18 +127,25 @@ pub fn create_event_modal(props: &CreateEventModalProps) -> Html { let event_data = use_state(|| EventCreationData::default()); // Initialize with selected date if provided - use_effect_with((props.selected_date, props.is_open), { + use_effect_with((props.selected_date, props.is_open, props.available_calendars.clone()), { let event_data = event_data.clone(); - move |(selected_date, is_open)| { + move |(selected_date, is_open, available_calendars)| { if *is_open { - if let Some(date) = selected_date { + let mut data = if let Some(date) = selected_date { let mut data = (*event_data).clone(); data.start_date = *date; data.end_date = *date; - event_data.set(data); + data } else { - event_data.set(EventCreationData::default()); + EventCreationData::default() + }; + + // Set default calendar to the first available one + if data.selected_calendar.is_none() && !available_calendars.is_empty() { + data.selected_calendar = Some(available_calendars[0].path.clone()); } + + event_data.set(data); } || () } @@ -164,6 +175,18 @@ pub fn create_event_modal(props: &CreateEventModalProps) -> Html { }) }; + let on_calendar_change = { + let event_data = event_data.clone(); + Callback::from(move |e: Event| { + if let Some(select) = e.target_dyn_into::() { + let mut data = (*event_data).clone(); + let value = select.value(); + data.selected_calendar = if value.is_empty() { None } else { Some(value) }; + event_data.set(data); + } + }) + }; + let on_description_input = { let event_data = event_data.clone(); Callback::from(move |e: InputEvent| { @@ -420,6 +443,31 @@ pub fn create_event_modal(props: &CreateEventModalProps) -> Html { /> +
+ + +
+