Calendar (WIP)

This commit is contained in:
Greg Burri 2025-01-29 14:37:25 +01:00
parent 9d3f9e9c60
commit 79a0aeb1b8
24 changed files with 613 additions and 231 deletions

View file

@ -1,100 +1,144 @@
use std::{
ops::{AddAssign, SubAssign},
sync::{
atomic::{AtomicI32, AtomicU32, Ordering},
Arc,
},
use std::sync::{
atomic::{AtomicI32, AtomicU32, Ordering},
Arc, Mutex,
};
use chrono::{offset::Local, Datelike, Days, NaiveDate, Weekday};
use chrono::{offset::Local, DateTime, Datelike, Days, Months, NaiveDate, Weekday};
use common::ron_api;
use gloo::{console::log, events::EventListener};
use wasm_bindgen::prelude::*;
use wasm_bindgen_futures::spawn_local;
use web_sys::Element;
use crate::utils::{by_id, SelectorExt};
use crate::{
request,
utils::{by_id, selector, SelectorExt},
};
pub fn setup(calendar: &Element) {
struct CalendarStateInternal {
current_date: DateTime<Local>,
selected_date: DateTime<Local>,
}
#[derive(Clone)]
struct CalendarState {
internal_state: Arc<Mutex<CalendarStateInternal>>,
}
impl CalendarState {
pub fn new() -> Self {
let current_date = Local::now();
Self {
internal_state: Arc::new(Mutex::new(CalendarStateInternal {
current_date,
selected_date: current_date,
})),
}
}
pub fn to_next_month(&self) -> DateTime<Local> {
let mut locker = self.internal_state.lock().unwrap();
let new_date = locker
.current_date
.checked_add_months(Months::new(1))
.unwrap();
locker.current_date = new_date;
new_date
}
pub fn to_previous_month(&self) -> DateTime<Local> {
let mut locker = self.internal_state.lock().unwrap();
let new_date = locker
.current_date
.checked_sub_months(Months::new(1))
.unwrap();
locker.current_date = new_date;
new_date
}
pub fn get_current_date(&self) -> DateTime<Local> {
self.internal_state.lock().unwrap().current_date
}
pub fn get_selected_date(&self) -> DateTime<Local> {
self.internal_state.lock().unwrap().selected_date
}
}
pub fn setup(calendar: Element) {
let prev: Element = calendar.selector(".prev");
let next: Element = calendar.selector(".next");
let current_month = Arc::new(AtomicU32::new(Local::now().month()));
let current_year = Arc::new(AtomicI32::new(Local::now().year()));
let state = CalendarState::new();
display_month(calendar, Local::now().year(), Local::now().month());
display_month(&calendar, state.get_current_date());
let calendar_clone = calendar.clone();
let current_month_clone = current_month.clone();
let current_year_clone = current_year.clone();
let state_clone = state.clone();
EventListener::new(&prev, "click", move |_event| {
let mut m = current_month_clone.load(Ordering::Relaxed) - 1;
if m == 0 {
current_year_clone.fetch_sub(1, Ordering::Relaxed);
m = 12
}
current_month_clone.store(m, Ordering::Relaxed);
display_month(
&calendar_clone,
current_year_clone.load(Ordering::Relaxed),
m,
);
let m = state_clone.to_previous_month();
display_month(&calendar_clone, m);
})
.forget();
let calendar_clone = calendar.clone();
let current_month_clone = current_month.clone();
let current_year_clone = current_year.clone();
let state_clone = state.clone();
EventListener::new(&next, "click", move |_event| {
let mut m = current_month_clone.load(Ordering::Relaxed) + 1;
if m == 13 {
current_year_clone.fetch_add(1, Ordering::Relaxed);
m = 1
}
current_month_clone.store(m, Ordering::Relaxed);
display_month(
&calendar_clone,
current_year_clone.load(Ordering::Relaxed),
m,
);
let m = state_clone.to_next_month();
display_month(&calendar_clone, m);
})
.forget();
// now.weekday()
// let days: Element = calendar.selector(".days");
// let state_clone = state.clone();
// EventListener::new(&days, "click", move |event| {
// log!(event);
// let target: Element = event.target().unwrap().dyn_into().unwrap();
// if
// })
// .forget();
// console!(now.to_string());
// let calendar_clone = calendar.clone();
// let current_month_clone = current_month.clone();
// let current_year_clone = current_year.clone();
// EventListener::new(&next, "click", move |_event| {
// let mut m = current_month_clone.load(Ordering::Relaxed) + 1;
// if m == 13 {
// current_year_clone.fetch_add(1, Ordering::Relaxed);
// m = 1
// }
// current_month_clone.store(m, Ordering::Relaxed);
// display_month(
// &calendar_clone,
// current_year_clone.load(Ordering::Relaxed),
// m,
// );
// })
// .forget();
}
// fn translate_month(month: u32) -> &'static str {
// match
// }
fn display_month(calendar: &Element, year: i32, month: u32) {
log!(year, month);
const NB_CALENDAR_ROW: u64 = 5;
fn display_month(calendar: &Element, date: DateTime<Local>) {
calendar
.selector::<Element>(".year")
.set_inner_html(&year.to_string());
.set_inner_html(&date.year().to_string());
for (i, m) in calendar
.selector_all::<Element>(".month")
.into_iter()
.enumerate()
{
if i as u32 + 1 == month {
if i as u32 + 1 == date.month() {
m.set_class_name("month current");
} else {
m.set_class_name("month");
}
}
// calendar
// .selector::<Element>(".month")
// .set_inner_html(&month.to_string());
let mut current = date;
let mut current = NaiveDate::from_ymd_opt(year, month, 1).unwrap();
// let mut day = Local:: ;
while (current - Days::new(1)).month() == month {
while (current - Days::new(1)).month() == date.month() {
current = current - Days::new(1);
}
@ -102,20 +146,46 @@ fn display_month(calendar: &Element, year: i32, month: u32) {
current = current - Days::new(1);
}
for i in 0..7 {
for j in 0..5 {
let li: Element = by_id(&format!("day-{}{}", i, j));
li.set_inner_html(&current.day().to_string());
let first_day = current;
if current == Local::now().date_naive() {
li.set_class_name("current-month today");
} else if current.month() == month {
li.set_class_name("current-month");
for i in 0..7 {
for j in 0..NB_CALENDAR_ROW {
let day_element: Element = by_id(&format!("day-{}{}", i, j));
let day_content: Element = day_element.selector(".number");
day_content.set_inner_html(&current.day().to_string());
if current == Local::now() {
day_element.set_class_name("current-month today");
} else if current.month() == date.month() {
day_element.set_class_name("current-month");
} else {
li.set_class_name("");
day_element.set_class_name("");
}
current = current + Days::new(1);
}
}
spawn_local(async move {
let scheduled_recipes: ron_api::ScheduledRecipes = request::get(
"calendar/get_scheduled_recipes",
[
("start_date", first_day.date_naive().to_string()),
(
"end_date",
(first_day + Days::new(NB_CALENDAR_ROW * 7))
.date_naive()
.to_string(),
),
],
)
.await
.unwrap();
for recipe in scheduled_recipes.recipes {
log!(recipe.1);
}
// create_tag_elements(recipe_id, &tags.tags);
});
}