Fix timezone handling for drag-and-drop and recurring event updates
- Fix double timezone conversion in drag-and-drop that caused 4-hour time shifts - Frontend now sends local times instead of UTC to backend for proper conversion - Add missing timezone parameter to update_series method to fix recurring event updates - Update both event modal and drag-and-drop paths to include timezone information - Maintain RFC 5545 compliance with proper timezone conversion in backend 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -759,6 +759,7 @@ pub fn App() -> Html {
|
||||
params.17, // calendar_path
|
||||
scope,
|
||||
event_data_for_update.occurrence_date.map(|d| d.format("%Y-%m-%d").to_string()), // occurrence_date
|
||||
params.20, // timezone
|
||||
)
|
||||
.await
|
||||
} else {
|
||||
@@ -789,6 +790,7 @@ pub fn App() -> Html {
|
||||
vec![], // exception_dates - empty for simple updates
|
||||
None, // update_action - None for regular updates
|
||||
None, // until_date - None for regular updates
|
||||
params.20, // timezone
|
||||
)
|
||||
.await
|
||||
};
|
||||
@@ -875,6 +877,7 @@ pub fn App() -> Html {
|
||||
params.18, // recurrence_count
|
||||
params.19, // recurrence_until
|
||||
params.17, // calendar_path
|
||||
params.20, // timezone
|
||||
)
|
||||
.await;
|
||||
match create_result {
|
||||
@@ -915,7 +918,7 @@ pub fn App() -> Html {
|
||||
chrono::NaiveDateTime,
|
||||
chrono::NaiveDateTime,
|
||||
bool,
|
||||
Option<chrono::DateTime<chrono::Utc>>,
|
||||
Option<chrono::NaiveDateTime>,
|
||||
Option<String>,
|
||||
Option<String>,
|
||||
)| {
|
||||
@@ -954,30 +957,13 @@ pub fn App() -> Html {
|
||||
String::new()
|
||||
};
|
||||
|
||||
// Convert local naive datetime to UTC before sending to backend
|
||||
use chrono::TimeZone;
|
||||
let local_tz = chrono::Local;
|
||||
|
||||
let start_utc = local_tz.from_local_datetime(&new_start)
|
||||
.single()
|
||||
.unwrap_or_else(|| {
|
||||
// Fallback for ambiguous times (DST transitions)
|
||||
local_tz.from_local_datetime(&new_start).earliest().unwrap()
|
||||
})
|
||||
.with_timezone(&chrono::Utc);
|
||||
|
||||
let end_utc = local_tz.from_local_datetime(&new_end)
|
||||
.single()
|
||||
.unwrap_or_else(|| {
|
||||
// Fallback for ambiguous times (DST transitions)
|
||||
local_tz.from_local_datetime(&new_end).earliest().unwrap()
|
||||
})
|
||||
.with_timezone(&chrono::Utc);
|
||||
|
||||
let start_date = start_utc.format("%Y-%m-%d").to_string();
|
||||
let start_time = start_utc.format("%H:%M").to_string();
|
||||
let end_date = end_utc.format("%Y-%m-%d").to_string();
|
||||
let end_time = end_utc.format("%H:%M").to_string();
|
||||
// Send local times to backend, which will handle timezone conversion
|
||||
let start_date = new_start.format("%Y-%m-%d").to_string();
|
||||
let start_time = new_start.format("%H:%M").to_string();
|
||||
let end_date = new_end.format("%Y-%m-%d").to_string();
|
||||
let end_time = new_end.format("%H:%M").to_string();
|
||||
|
||||
// Convert existing event data to string formats for the API
|
||||
let status_str = match original_event.status {
|
||||
@@ -1062,6 +1048,14 @@ pub fn App() -> Html {
|
||||
original_event.calendar_path.clone(),
|
||||
scope.clone(),
|
||||
occurrence_date,
|
||||
{
|
||||
// Get timezone offset
|
||||
let date = js_sys::Date::new_0();
|
||||
let timezone_offset = date.get_timezone_offset(); // Minutes from UTC
|
||||
let hours = -(timezone_offset as i32) / 60; // Convert to hours, negate for proper sign
|
||||
let minutes = (timezone_offset as i32).abs() % 60;
|
||||
format!("{:+03}:{:02}", hours, minutes) // Format as +05:00 or -04:00
|
||||
},
|
||||
)
|
||||
.await,
|
||||
)
|
||||
@@ -1113,6 +1107,14 @@ pub fn App() -> Html {
|
||||
Some("this_and_future".to_string())
|
||||
},
|
||||
until_date,
|
||||
{
|
||||
// Get timezone offset
|
||||
let date = js_sys::Date::new_0();
|
||||
let timezone_offset = date.get_timezone_offset(); // Minutes from UTC
|
||||
let hours = -(timezone_offset as i32) / 60; // Convert to hours, negate for proper sign
|
||||
let minutes = (timezone_offset as i32).abs() % 60;
|
||||
format!("{:+03}:{:02}", hours, minutes) // Format as +05:00 or -04:00
|
||||
},
|
||||
)
|
||||
.await
|
||||
};
|
||||
@@ -1597,7 +1599,7 @@ pub fn App() -> Html {
|
||||
};
|
||||
|
||||
// Get the occurrence date from the clicked event
|
||||
let occurrence_date = Some(event.dtstart.date_naive().format("%Y-%m-%d").to_string());
|
||||
let occurrence_date = Some(event.dtstart.date().format("%Y-%m-%d").to_string());
|
||||
|
||||
web_sys::console::log_1(&format!("🔄 Delete action: {}", action_str).into());
|
||||
web_sys::console::log_1(&format!("🔄 Event UID: {}", event.uid).into());
|
||||
|
||||
Reference in New Issue
Block a user