Implement last used calendar tracking with localStorage and database sync
- Add database migration for last_used_calendar field in user preferences - Update backend models and handlers to support last_used_calendar persistence - Modify frontend preferences service with update_last_used_calendar() method - Implement automatic saving of selected calendar on event creation - Add localStorage fallback for offline usage and immediate UI response - Update create event modal to default to last used calendar for new events - Clean up unused imports from event form components 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
		| @@ -413,6 +413,21 @@ pub fn App() -> Html { | ||||
|         let auth_token = auth_token.clone(); | ||||
|         Callback::from(move |event_data: EventCreationData| { | ||||
|             web_sys::console::log_1(&format!("Creating event: {:?}", event_data).into()); | ||||
|              | ||||
|             // Save the selected calendar as the last used calendar | ||||
|             if let Some(ref calendar_path) = event_data.selected_calendar { | ||||
|                 let _ = LocalStorage::set("last_used_calendar", calendar_path); | ||||
|                  | ||||
|                 // Also sync to backend asynchronously | ||||
|                 let calendar_path_for_sync = calendar_path.clone(); | ||||
|                 wasm_bindgen_futures::spawn_local(async move { | ||||
|                     let preferences_service = crate::services::preferences::PreferencesService::new(); | ||||
|                     if let Err(e) = preferences_service.update_last_used_calendar(&calendar_path_for_sync).await { | ||||
|                         web_sys::console::warn_1(&format!("Failed to sync last used calendar to backend: {}", e).into()); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|              | ||||
|             create_event_modal_open.set(false); | ||||
|  | ||||
|             if let Some(_token) = (*auth_token).clone() { | ||||
|   | ||||
| @@ -2,6 +2,7 @@ use crate::components::event_form::*; | ||||
| use crate::components::EditAction; | ||||
| use crate::models::ical::VEvent; | ||||
| use crate::services::calendar_service::CalendarInfo; | ||||
| use gloo_storage::{LocalStorage, Storage}; | ||||
| use yew::prelude::*; | ||||
|  | ||||
| #[derive(Properties, PartialEq)] | ||||
| @@ -57,7 +58,25 @@ pub fn create_event_modal(props: &CreateEventModalProps) -> Html { | ||||
|  | ||||
|                 // Set default calendar | ||||
|                 if data.selected_calendar.is_none() && !available_calendars.is_empty() { | ||||
|                     data.selected_calendar = Some(available_calendars[0].path.clone()); | ||||
|                     // For new events, try to use the last used calendar | ||||
|                     if event_to_edit.is_none() { | ||||
|                         // Try to get last used calendar from localStorage | ||||
|                         if let Ok(last_used_calendar) = LocalStorage::get::<String>("last_used_calendar") { | ||||
|                             // Check if the last used calendar is still available | ||||
|                             if available_calendars.iter().any(|cal| cal.path == last_used_calendar) { | ||||
|                                 data.selected_calendar = Some(last_used_calendar); | ||||
|                             } else { | ||||
|                                 // Fall back to first available calendar | ||||
|                                 data.selected_calendar = Some(available_calendars[0].path.clone()); | ||||
|                             } | ||||
|                         } else { | ||||
|                             // No last used calendar, use first available | ||||
|                             data.selected_calendar = Some(available_calendars[0].path.clone()); | ||||
|                         } | ||||
|                     } else { | ||||
|                         // For editing existing events, keep the current calendar as default | ||||
|                         data.selected_calendar = Some(available_calendars[0].path.clone()); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 // Set edit scope if provided | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| use super::types::*; | ||||
| // Types are already imported from super::types::* | ||||
| use wasm_bindgen::JsCast; | ||||
| use web_sys::{HtmlInputElement, HtmlSelectElement}; | ||||
| use web_sys::HtmlSelectElement; | ||||
| use yew::prelude::*; | ||||
|  | ||||
| #[function_component(AdvancedTab)] | ||||
|   | ||||
| @@ -1,7 +1,5 @@ | ||||
| use crate::models::ical::VEvent; | ||||
| use crate::services::calendar_service::CalendarInfo; | ||||
| use chrono::{Datelike, Local, NaiveDate, NaiveTime, TimeZone, Utc}; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use chrono::{Local, NaiveDate, NaiveTime}; | ||||
| use yew::prelude::*; | ||||
|  | ||||
| #[derive(Clone, PartialEq, Debug)] | ||||
|   | ||||
| @@ -24,10 +24,6 @@ pub use create_calendar_modal::CreateCalendarModal; | ||||
| pub use create_event_modal::CreateEventModal; | ||||
| // Re-export event form types for backwards compatibility | ||||
| pub use event_form::EventCreationData; | ||||
| pub use event_form::{ | ||||
|     EventClass as EventFormClass, EventCreationData as EventFormData, EventStatus as EventFormStatus,  | ||||
|     RecurrenceType as EventFormRecurrenceType, ReminderType as EventFormReminderType, | ||||
| }; | ||||
| pub use event_context_menu::{DeleteAction, EditAction, EventContextMenu}; | ||||
| pub use event_modal::EventModal; | ||||
| pub use login::Login; | ||||
|   | ||||
| @@ -12,6 +12,7 @@ pub struct UserPreferences { | ||||
|     pub calendar_view_mode: Option<String>, | ||||
|     pub calendar_theme: Option<String>, | ||||
|     pub calendar_colors: Option<String>, | ||||
|     pub last_used_calendar: Option<String>, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Serialize)] | ||||
| @@ -22,6 +23,7 @@ pub struct UpdatePreferencesRequest { | ||||
|     pub calendar_view_mode: Option<String>, | ||||
|     pub calendar_theme: Option<String>, | ||||
|     pub calendar_colors: Option<String>, | ||||
|     pub last_used_calendar: Option<String>, | ||||
| } | ||||
|  | ||||
| #[allow(dead_code)] | ||||
| @@ -61,6 +63,7 @@ impl PreferencesService { | ||||
|             calendar_view_mode: None, | ||||
|             calendar_theme: None, | ||||
|             calendar_colors: None, | ||||
|             last_used_calendar: None, | ||||
|         }); | ||||
|          | ||||
|         // Update the specific field | ||||
| @@ -95,6 +98,7 @@ impl PreferencesService { | ||||
|             calendar_view_mode: preferences.calendar_view_mode.clone(), | ||||
|             calendar_theme: preferences.calendar_theme.clone(), | ||||
|             calendar_colors: preferences.calendar_colors.clone(), | ||||
|             last_used_calendar: preferences.last_used_calendar.clone(), | ||||
|         }; | ||||
|          | ||||
|         self.sync_preferences(&session_token, &request).await | ||||
| @@ -156,6 +160,7 @@ impl PreferencesService { | ||||
|             calendar_view_mode: LocalStorage::get::<String>("calendar_view_mode").ok(), | ||||
|             calendar_theme: LocalStorage::get::<String>("calendar_theme").ok(), | ||||
|             calendar_colors: LocalStorage::get::<String>("calendar_colors").ok(), | ||||
|             last_used_calendar: LocalStorage::get::<String>("last_used_calendar").ok(), | ||||
|         }; | ||||
|          | ||||
|         // Only migrate if we have some preferences to migrate | ||||
| @@ -164,6 +169,7 @@ impl PreferencesService { | ||||
|             || request.calendar_view_mode.is_some() | ||||
|             || request.calendar_theme.is_some() | ||||
|             || request.calendar_colors.is_some() | ||||
|             || request.last_used_calendar.is_some() | ||||
|         { | ||||
|             self.sync_preferences(&session_token, &request).await?; | ||||
|              | ||||
| @@ -177,4 +183,24 @@ impl PreferencesService { | ||||
|          | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     /// Update the last used calendar and sync with backend | ||||
|     pub async fn update_last_used_calendar(&self, calendar_path: &str) -> Result<(), String> { | ||||
|         // Get session token | ||||
|         let session_token = LocalStorage::get::<String>("session_token") | ||||
|             .map_err(|_| "No session token found".to_string())?; | ||||
|          | ||||
|         // Create minimal update request with only the last used calendar | ||||
|         let request = UpdatePreferencesRequest { | ||||
|             calendar_selected_date: None, | ||||
|             calendar_time_increment: None, | ||||
|             calendar_view_mode: None, | ||||
|             calendar_theme: None, | ||||
|             calendar_colors: None, | ||||
|             last_used_calendar: Some(calendar_path.to_string()), | ||||
|         }; | ||||
|          | ||||
|         // Sync to backend | ||||
|         self.sync_preferences(&session_token, &request).await | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Connor Johnstone
					Connor Johnstone