Complete drag-to-create event functionality with proper timezone handling
Integrate drag-to-create functionality with the full event creation pipeline: - Connect WeekView drag events to CreateEventModal via callback chain - Add event creation request callback through Calendar → RouteHandler → App - Implement proper timezone conversion throughout the entire flow - Fix pixels_to_time calculation (1px = 1 minute, not complex formula) - Add initial_start_time/initial_end_time props to CreateEventModal - Convert local times to UTC in both event creation and update functions - Ensure modal displays correct local times while backend receives UTC - Support both temporary drag events and real server events in modal The complete flow now works: drag selection → modal with correct times → proper UTC conversion → backend storage → correct display in calendar. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
		| @@ -3,7 +3,7 @@ use chrono::{Datelike, Local, NaiveDate, Duration}; | ||||
| use std::collections::HashMap; | ||||
| use web_sys::MouseEvent; | ||||
| use crate::services::calendar_service::{CalendarEvent, UserInfo}; | ||||
| use crate::components::{EventModal, ViewMode, CalendarHeader, MonthView, WeekView}; | ||||
| use crate::components::{EventModal, ViewMode, CalendarHeader, MonthView, WeekView, CreateEventModal, EventCreationData}; | ||||
| use gloo_storage::{LocalStorage, Storage}; | ||||
|  | ||||
| #[derive(Properties, PartialEq)] | ||||
| @@ -21,6 +21,8 @@ pub struct CalendarProps { | ||||
|     pub on_calendar_context_menu: Option<Callback<(web_sys::MouseEvent, NaiveDate)>>, | ||||
|     #[prop_or_default] | ||||
|     pub view: ViewMode, | ||||
|     #[prop_or_default] | ||||
|     pub on_create_event_request: Option<Callback<EventCreationData>>, | ||||
| } | ||||
|  | ||||
| #[function_component] | ||||
| @@ -58,6 +60,10 @@ pub fn Calendar(props: &CalendarProps) -> Html { | ||||
|     }); | ||||
|     let selected_event = use_state(|| None::<CalendarEvent>); | ||||
|      | ||||
|     // State for create event modal | ||||
|     let show_create_modal = use_state(|| false); | ||||
|     let create_event_data = use_state(|| None::<(chrono::NaiveDate, chrono::NaiveTime, chrono::NaiveTime)>); | ||||
|      | ||||
|     // Handle view mode changes - adjust current_date format when switching between month/week | ||||
|     { | ||||
|         let current_date = current_date.clone(); | ||||
| @@ -143,6 +149,18 @@ pub fn Calendar(props: &CalendarProps) -> Html { | ||||
|             let _ = LocalStorage::set("calendar_selected_date", new_selected.format("%Y-%m-%d").to_string()); | ||||
|         }) | ||||
|     }; | ||||
|      | ||||
|     // Handle drag-to-create event | ||||
|     let on_create_event = { | ||||
|         let show_create_modal = show_create_modal.clone(); | ||||
|         let create_event_data = create_event_data.clone(); | ||||
|         Callback::from(move |(_date, start_datetime, end_datetime): (NaiveDate, chrono::NaiveDateTime, chrono::NaiveDateTime)| { | ||||
|             // For drag-to-create, we don't need the temporary event approach | ||||
|             // Instead, just pass the local times directly via initial_time props | ||||
|             create_event_data.set(Some((start_datetime.date(), start_datetime.time(), end_datetime.time()))); | ||||
|             show_create_modal.set(true); | ||||
|         }) | ||||
|     }; | ||||
|  | ||||
|     html! { | ||||
|         <div class={classes!("calendar", match props.view { ViewMode::Week => Some("week-view"), _ => None })}> | ||||
| @@ -190,6 +208,7 @@ pub fn Calendar(props: &CalendarProps) -> Html { | ||||
|                             user_info={props.user_info.clone()} | ||||
|                             on_event_context_menu={props.on_event_context_menu.clone()} | ||||
|                             on_calendar_context_menu={props.on_calendar_context_menu.clone()} | ||||
|                             on_create_event={Some(on_create_event)} | ||||
|                         /> | ||||
|                     }, | ||||
|                 } | ||||
| @@ -205,6 +224,47 @@ pub fn Calendar(props: &CalendarProps) -> Html { | ||||
|                     }) | ||||
|                 }} | ||||
|             /> | ||||
|              | ||||
|             // Create event modal | ||||
|             <CreateEventModal | ||||
|                 is_open={*show_create_modal} | ||||
|                 selected_date={create_event_data.as_ref().map(|(date, _, _)| *date)} | ||||
|                 event_to_edit={None} | ||||
|                 available_calendars={props.user_info.as_ref().map(|info| info.calendars.clone()).unwrap_or_default()} | ||||
|                 initial_start_time={create_event_data.as_ref().map(|(_, start_time, _)| *start_time)} | ||||
|                 initial_end_time={create_event_data.as_ref().map(|(_, _, end_time)| *end_time)} | ||||
|                 on_close={{ | ||||
|                     let show_create_modal = show_create_modal.clone(); | ||||
|                     let create_event_data = create_event_data.clone(); | ||||
|                     Callback::from(move |_| { | ||||
|                         show_create_modal.set(false); | ||||
|                         create_event_data.set(None); | ||||
|                     }) | ||||
|                 }} | ||||
|                 on_create={{ | ||||
|                     let show_create_modal = show_create_modal.clone(); | ||||
|                     let create_event_data = create_event_data.clone(); | ||||
|                     let on_create_event_request = props.on_create_event_request.clone(); | ||||
|                     Callback::from(move |event_data: EventCreationData| { | ||||
|                         show_create_modal.set(false); | ||||
|                         create_event_data.set(None); | ||||
|                          | ||||
|                         // Emit the create event request to parent | ||||
|                         if let Some(callback) = &on_create_event_request { | ||||
|                             callback.emit(event_data); | ||||
|                         } | ||||
|                     }) | ||||
|                 }} | ||||
|                 on_update={{ | ||||
|                     let show_create_modal = show_create_modal.clone(); | ||||
|                     let create_event_data = create_event_data.clone(); | ||||
|                     Callback::from(move |(_original_event, _updated_data): (CalendarEvent, EventCreationData)| { | ||||
|                         show_create_modal.set(false); | ||||
|                         create_event_data.set(None); | ||||
|                         // TODO: Handle actual event update | ||||
|                     }) | ||||
|                 }} | ||||
|             /> | ||||
|         </div> | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Connor Johnstone
					Connor Johnstone