Implement calendar context menu with event creation modal

- Add CalendarContextMenu component for right-click on calendar days
- Add CreateEventModal component with comprehensive event creation form
- Integrate context menu detection to avoid conflicts between event/calendar menus
- Add form validation and date/time selection with all-day toggle
- Connect modal through component hierarchy from app to calendar

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Connor Johnstone
2025-08-28 22:20:22 -04:00
parent 7e62e3b7e3
commit 5c966b2571
6 changed files with 480 additions and 3 deletions

View File

@@ -3,6 +3,7 @@ use chrono::{Datelike, Local, NaiveDate, Duration, Weekday};
use std::collections::HashMap;
use crate::services::calendar_service::{CalendarEvent, UserInfo};
use crate::components::EventModal;
use wasm_bindgen::JsCast;
#[derive(Properties, PartialEq)]
pub struct CalendarProps {
@@ -15,6 +16,8 @@ pub struct CalendarProps {
pub user_info: Option<UserInfo>,
#[prop_or_default]
pub on_event_context_menu: Option<Callback<(web_sys::MouseEvent, CalendarEvent)>>,
#[prop_or_default]
pub on_calendar_context_menu: Option<Callback<(web_sys::MouseEvent, NaiveDate)>>,
}
#[function_component]
@@ -115,9 +118,34 @@ pub fn Calendar(props: &CalendarProps) -> Html {
let on_click = Callback::from(move |_| {
selected_day_clone.set(date);
});
let on_context_menu = {
let on_calendar_context_menu = props.on_calendar_context_menu.clone();
Callback::from(move |e: MouseEvent| {
// Only show context menu if we're not right-clicking on an event
if let Some(target) = e.target() {
if let Ok(element) = target.dyn_into::<web_sys::Element>() {
// Check if the click is on an event box or inside one
let mut current = Some(element);
while let Some(el) = current {
if el.class_name().contains("event-box") {
return; // Don't show calendar context menu on events
}
current = el.parent_element();
}
}
}
e.prevent_default();
e.stop_propagation();
if let Some(callback) = &on_calendar_context_menu {
callback.emit((e, date));
}
})
};
html! {
<div class={classes!(classes)} onclick={on_click}>
<div class={classes!(classes)} onclick={on_click} oncontextmenu={on_context_menu}>
<div class="day-number">{day}</div>
{
if !events.is_empty() {