diff --git a/frontend/src/components/calendar.rs b/frontend/src/components/calendar.rs index 0c5cc23..8fdd529 100644 --- a/frontend/src/components/calendar.rs +++ b/frontend/src/components/calendar.rs @@ -3,7 +3,7 @@ use crate::components::{ }; use crate::models::ical::VEvent; use crate::services::{calendar_service::{UserInfo, ExternalCalendar}, CalendarService}; -use chrono::{Datelike, Duration, Local, NaiveDate}; +use chrono::{Datelike, Duration, Local, NaiveDate, Weekday}; use gloo_storage::{LocalStorage, Storage}; use std::collections::HashMap; use web_sys::MouseEvent; @@ -111,6 +111,7 @@ pub fn Calendar(props: &CalendarProps) -> Html { use_effect_with((*current_date, view.clone(), external_events.len(), props.user_info.clone()), move |(date, _view, _external_len, user_info)| { let auth_token: Option = LocalStorage::get("auth_token").ok(); let date = *date; // Clone the date to avoid lifetime issues + let view_mode = _view.clone(); // Clone the view mode to avoid lifetime issues let external_events = external_events.clone(); // Clone external events to avoid lifetime issues let user_info = user_info.clone(); // Clone user_info to avoid lifetime issues @@ -136,17 +137,53 @@ pub fn Calendar(props: &CalendarProps) -> Html { String::new() }; - let current_year = date.year(); - let current_month = date.month(); + // Determine which months to fetch based on view mode + let months_to_fetch = match view_mode { + ViewMode::Month => { + // For month view, just fetch the current month + vec![(date.year(), date.month())] + } + ViewMode::Week => { + // For week view, calculate the week bounds and fetch all months that intersect + let start_of_week = get_start_of_week(date); + let end_of_week = start_of_week + Duration::days(6); + + let mut months = vec![(start_of_week.year(), start_of_week.month())]; + + // If the week spans into a different month, add that month too + if end_of_week.month() != start_of_week.month() || end_of_week.year() != start_of_week.year() { + months.push((end_of_week.year(), end_of_week.month())); + } + + months + } + }; - match calendar_service - .fetch_events_for_month_vevent( - &token, - &password, - current_year, - current_month, - ) - .await + // Fetch events for all required months + let mut all_events = Vec::new(); + for (year, month) in months_to_fetch { + match calendar_service + .fetch_events_for_month_vevent( + &token, + &password, + year, + month, + ) + .await + { + Ok(mut month_events) => { + all_events.append(&mut month_events); + } + Err(err) => { + error.set(Some(format!("Failed to load events for {}-{}: {}", year, month, err))); + loading.set(false); + return; + } + } + } + + // Process the combined events + match Ok(all_events) as Result, String> { Ok(vevents) => { // Filter CalDAV events based on calendar visibility @@ -602,3 +639,18 @@ pub fn Calendar(props: &CalendarProps) -> Html { } } + +// Helper function to calculate the start of the week (Sunday) for a given date +fn get_start_of_week(date: NaiveDate) -> NaiveDate { + let weekday = date.weekday(); + let days_from_sunday = match weekday { + Weekday::Sun => 0, + Weekday::Mon => 1, + Weekday::Tue => 2, + Weekday::Wed => 3, + Weekday::Thu => 4, + Weekday::Fri => 5, + Weekday::Sat => 6, + }; + date - Duration::days(days_from_sunday) +}