Major Features: - Replace single ReminderType enum with Vec<VAlarm> throughout stack - Add comprehensive alarm management UI with AlarmList and AddAlarmModal components - Support relative (15min before, 2hrs after) and absolute (specific date/time) triggers - Display reminder icons in both month and week calendar views - RFC 5545 compliant VALARM implementation using calendar-models library Frontend Changes: - Create AlarmList component for displaying configured reminders - Create AddAlarmModal with full alarm configuration (trigger, timing, description) - Update RemindersTab to use new alarm management interface - Replace old ReminderType dropdown with modern multi-alarm system - Add reminder icons to event displays in month/week views - Fix event title ellipsis behavior in week view with proper CSS constraints Backend Changes: - Update all request/response models to use Vec<VAlarm> instead of String - Remove EventReminder conversion logic, pass VAlarms directly through - Maintain RFC 5545 compliance for CalDAV server compatibility UI/UX Improvements: - Improved basic details tab layout (calendar/repeat side-by-side, All Day checkbox repositioned) - Simplified reminder system to single notification type for user clarity - Font Awesome icons throughout instead of emojis for consistency - Clean modal styling with proper button padding and hover states - Removed non-standard custom message fields for maximum CalDAV compatibility 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
116 lines
3.5 KiB
Rust
116 lines
3.5 KiB
Rust
use super::{types::*, AlarmList, AddAlarmModal};
|
|
use calendar_models::VAlarm;
|
|
use yew::prelude::*;
|
|
|
|
#[function_component(RemindersTab)]
|
|
pub fn reminders_tab(props: &TabProps) -> Html {
|
|
let data = &props.data;
|
|
|
|
// Modal state
|
|
let is_modal_open = use_state(|| false);
|
|
let editing_index = use_state(|| None::<usize>);
|
|
|
|
// Add alarm callback
|
|
let on_add_alarm = {
|
|
let is_modal_open = is_modal_open.clone();
|
|
let editing_index = editing_index.clone();
|
|
Callback::from(move |_| {
|
|
editing_index.set(None);
|
|
is_modal_open.set(true);
|
|
})
|
|
};
|
|
|
|
// Edit alarm callback
|
|
let on_alarm_edit = {
|
|
let is_modal_open = is_modal_open.clone();
|
|
let editing_index = editing_index.clone();
|
|
Callback::from(move |index: usize| {
|
|
editing_index.set(Some(index));
|
|
is_modal_open.set(true);
|
|
})
|
|
};
|
|
|
|
// Delete alarm callback
|
|
let on_alarm_delete = {
|
|
let data = data.clone();
|
|
Callback::from(move |index: usize| {
|
|
let mut current_data = (*data).clone();
|
|
if index < current_data.alarms.len() {
|
|
current_data.alarms.remove(index);
|
|
data.set(current_data);
|
|
}
|
|
})
|
|
};
|
|
|
|
// Close modal callback
|
|
let on_modal_close = {
|
|
let is_modal_open = is_modal_open.clone();
|
|
let editing_index = editing_index.clone();
|
|
Callback::from(move |_| {
|
|
is_modal_open.set(false);
|
|
editing_index.set(None);
|
|
})
|
|
};
|
|
|
|
// Save alarm callback
|
|
let on_alarm_save = {
|
|
let data = data.clone();
|
|
let is_modal_open = is_modal_open.clone();
|
|
let editing_index = editing_index.clone();
|
|
Callback::from(move |alarm: VAlarm| {
|
|
let mut current_data = (*data).clone();
|
|
|
|
if let Some(index) = *editing_index {
|
|
// Edit existing alarm
|
|
if index < current_data.alarms.len() {
|
|
current_data.alarms[index] = alarm;
|
|
}
|
|
} else {
|
|
// Add new alarm
|
|
current_data.alarms.push(alarm);
|
|
}
|
|
|
|
data.set(current_data);
|
|
is_modal_open.set(false);
|
|
editing_index.set(None);
|
|
})
|
|
};
|
|
|
|
// Get initial alarm for editing
|
|
let initial_alarm = (*editing_index).and_then(|index| {
|
|
data.alarms.get(index).cloned()
|
|
});
|
|
|
|
html! {
|
|
<div class="tab-panel">
|
|
<div class="form-group">
|
|
<div class="alarm-management-header">
|
|
<h5>{"Event Reminders"}</h5>
|
|
<button
|
|
class="add-alarm-button"
|
|
onclick={on_add_alarm}
|
|
type="button"
|
|
>
|
|
<i class="fas fa-plus"></i>
|
|
{" Add Reminder"}
|
|
</button>
|
|
</div>
|
|
<p class="form-help-text">{"Configure multiple reminders with custom timing and notification types"}</p>
|
|
</div>
|
|
|
|
<AlarmList
|
|
alarms={data.alarms.clone()}
|
|
on_alarm_delete={on_alarm_delete}
|
|
on_alarm_edit={on_alarm_edit}
|
|
/>
|
|
|
|
<AddAlarmModal
|
|
is_open={*is_modal_open}
|
|
editing_index={*editing_index}
|
|
initial_alarm={initial_alarm}
|
|
on_close={on_modal_close}
|
|
on_save={on_alarm_save}
|
|
/>
|
|
</div>
|
|
}
|
|
} |