Add calendar selection dropdown and fix multi-calendar event display

- Add calendar selection dropdown to event creation modal
- Update EventCreationData to include selected_calendar field
- Pass available calendars from user info to modal component
- Initialize dropdown with first available calendar as default
- Fix backend to fetch events from ALL calendars, not just the first
- Update refresh_event to search across all calendars
- Events created in any calendar now properly display in UI

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Connor Johnstone
2025-08-29 08:45:40 -04:00
parent 7a53228ec8
commit e1578ed11c
3 changed files with 92 additions and 17 deletions

View File

@@ -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<NaiveDate>,
pub on_close: Callback<()>,
pub on_create: Callback<EventCreationData>,
pub available_calendars: Vec<CalendarInfo>,
}
#[derive(Clone, PartialEq, Debug)]
@@ -88,6 +90,7 @@ pub struct EventCreationData {
pub reminder: ReminderType,
pub recurrence: RecurrenceType,
pub recurrence_days: Vec<bool>, // [Sun, Mon, Tue, Wed, Thu, Fri, Sat] for weekly recurrence
pub selected_calendar: Option<String>, // 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::<HtmlSelectElement>() {
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 {
/>
</div>
<div class="form-group">
<label for="event-calendar">{"Calendar"}</label>
<select
id="event-calendar"
class="form-input"
onchange={on_calendar_change}
>
<option value="" selected={data.selected_calendar.is_none()}>{"Select calendar..."}</option>
{
props.available_calendars.iter().map(|calendar| {
let is_selected = data.selected_calendar.as_ref() == Some(&calendar.path);
html! {
<option
key={calendar.path.clone()}
value={calendar.path.clone()}
selected={is_selected}
>
{&calendar.display_name}
</option>
}
}).collect::<Html>()
}
</select>
</div>
<div class="form-group">
<label for="event-description">{"Description"}</label>
<textarea