Add weekday selection for weekly recurrence and fix RRULE generation
- Add weekday selection UI for weekly recurring events with checkboxes - Implement BYDAY parameter generation in RRULE based on selected days - Fix missing RRULE generation in iCalendar output - Convert reminder durations to proper EventReminder structs - Add responsive CSS styling for weekday selection interface 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
		| @@ -272,6 +272,7 @@ pub fn App() -> Html { | ||||
|                         event_data.categories, | ||||
|                         reminder_str, | ||||
|                         recurrence_str, | ||||
|                         event_data.recurrence_days, | ||||
|                         None // Let backend use first available calendar | ||||
|                     ).await { | ||||
|                         Ok(_) => { | ||||
|   | ||||
| @@ -87,6 +87,7 @@ pub struct EventCreationData { | ||||
|     pub categories: String, // Comma-separated list | ||||
|     pub reminder: ReminderType, | ||||
|     pub recurrence: RecurrenceType, | ||||
|     pub recurrence_days: Vec<bool>, // [Sun, Mon, Tue, Wed, Thu, Fri, Sat] for weekly recurrence | ||||
| } | ||||
|  | ||||
| impl Default for EventCreationData { | ||||
| @@ -112,6 +113,7 @@ impl Default for EventCreationData { | ||||
|             categories: String::new(), | ||||
|             reminder: ReminderType::default(), | ||||
|             recurrence: RecurrenceType::default(), | ||||
|             recurrence_days: vec![false; 7], // [Sun, Mon, Tue, Wed, Thu, Fri, Sat] - all false by default | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -290,11 +292,29 @@ pub fn create_event_modal(props: &CreateEventModalProps) -> Html { | ||||
|                     "yearly" => RecurrenceType::Yearly, | ||||
|                     _ => RecurrenceType::None, | ||||
|                 }; | ||||
|                 // Reset recurrence days when changing recurrence type | ||||
|                 data.recurrence_days = vec![false; 7]; | ||||
|                 event_data.set(data); | ||||
|             } | ||||
|         }) | ||||
|     }; | ||||
|  | ||||
|     let on_weekday_change = { | ||||
|         let event_data = event_data.clone(); | ||||
|         move |day_index: usize| { | ||||
|             let event_data = event_data.clone(); | ||||
|             Callback::from(move |e: Event| { | ||||
|                 if let Some(input) = e.target_dyn_into::<HtmlInputElement>() { | ||||
|                     let mut data = (*event_data).clone(); | ||||
|                     if day_index < data.recurrence_days.len() { | ||||
|                         data.recurrence_days[day_index] = input.checked(); | ||||
|                         event_data.set(data); | ||||
|                     } | ||||
|                 } | ||||
|             }) | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     let on_start_date_change = { | ||||
|         let event_data = event_data.clone(); | ||||
|         Callback::from(move |e: Event| { | ||||
| @@ -601,6 +621,35 @@ pub fn create_event_modal(props: &CreateEventModalProps) -> Html { | ||||
|                             </select> | ||||
|                         </div> | ||||
|                     </div> | ||||
|  | ||||
|                     // Show weekday selection only when weekly recurrence is selected | ||||
|                     if matches!(data.recurrence, RecurrenceType::Weekly) { | ||||
|                         <div class="form-group"> | ||||
|                             <label>{"Repeat on"}</label> | ||||
|                             <div class="weekday-selection"> | ||||
|                                 { | ||||
|                                     ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] | ||||
|                                         .iter() | ||||
|                                         .enumerate() | ||||
|                                         .map(|(i, day)| { | ||||
|                                             let day_checked = data.recurrence_days.get(i).cloned().unwrap_or(false); | ||||
|                                             let on_change = on_weekday_change(i); | ||||
|                                             html! { | ||||
|                                                 <label key={i} class="weekday-checkbox"> | ||||
|                                                     <input  | ||||
|                                                         type="checkbox"  | ||||
|                                                         checked={day_checked} | ||||
|                                                         onchange={on_change} | ||||
|                                                     /> | ||||
|                                                     <span class="weekday-label">{day}</span> | ||||
|                                                 </label> | ||||
|                                             } | ||||
|                                         }) | ||||
|                                         .collect::<Html>() | ||||
|                                 } | ||||
|                             </div> | ||||
|                         </div> | ||||
|                     } | ||||
|                 </div> | ||||
|                  | ||||
|                 <div class="modal-footer"> | ||||
|   | ||||
| @@ -607,6 +607,7 @@ impl CalendarService { | ||||
|         categories: String, | ||||
|         reminder: String, | ||||
|         recurrence: String, | ||||
|         recurrence_days: Vec<bool>, | ||||
|         calendar_path: Option<String> | ||||
|     ) -> Result<(), String> { | ||||
|         let window = web_sys::window().ok_or("No global window exists")?; | ||||
| @@ -632,6 +633,7 @@ impl CalendarService { | ||||
|             "categories": categories, | ||||
|             "reminder": reminder, | ||||
|             "recurrence": recurrence, | ||||
|             "recurrence_days": recurrence_days, | ||||
|             "calendar_path": calendar_path | ||||
|         }); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Connor Johnstone
					Connor Johnstone