use yew::prelude::*; #[derive(Properties, PartialEq)] pub struct CreateCalendarModalProps { pub is_open: bool, pub on_close: Callback<()>, pub on_create: Callback<(String, Option, Option)>, // name, description, color pub available_colors: Vec, } #[function_component] pub fn CreateCalendarModal(props: &CreateCalendarModalProps) -> Html { let calendar_name = use_state(|| String::new()); let description = use_state(|| String::new()); let selected_color = use_state(|| None::); let error_message = use_state(|| None::); let is_creating = use_state(|| false); let on_name_change = { let calendar_name = calendar_name.clone(); Callback::from(move |e: InputEvent| { let input: web_sys::HtmlInputElement = e.target_unchecked_into(); calendar_name.set(input.value()); }) }; let on_description_change = { let description = description.clone(); Callback::from(move |e: InputEvent| { let input: web_sys::HtmlTextAreaElement = e.target_unchecked_into(); description.set(input.value()); }) }; let on_submit = { let calendar_name = calendar_name.clone(); let description = description.clone(); let selected_color = selected_color.clone(); let error_message = error_message.clone(); let is_creating = is_creating.clone(); let on_create = props.on_create.clone(); Callback::from(move |e: SubmitEvent| { e.prevent_default(); let name = (*calendar_name).trim(); if name.is_empty() { error_message.set(Some("Calendar name is required".to_string())); return; } if name.len() > 100 { error_message.set(Some( "Calendar name too long (max 100 characters)".to_string(), )); return; } error_message.set(None); is_creating.set(true); let desc = if (*description).trim().is_empty() { None } else { Some((*description).clone()) }; on_create.emit((name.to_string(), desc, (*selected_color).clone())); }) }; let on_backdrop_click = { let on_close = props.on_close.clone(); Callback::from(move |e: MouseEvent| { // Only close if clicking the backdrop, not the modal content if e.target() == e.current_target() { on_close.emit(()); } }) }; if !props.is_open { return html! {}; } html! {