150 lines
4.6 KiB
Rust
150 lines
4.6 KiB
Rust
use chrono::{Datelike, Days, Months, NaiveDate};
|
|
use common::ron_api;
|
|
use gloo::storage::{LocalStorage, Storage};
|
|
use ron::ser::{to_string_pretty, PrettyConfig};
|
|
use serde::{Deserialize, Serialize};
|
|
use thiserror::Error;
|
|
|
|
use crate::{calendar, request};
|
|
|
|
#[derive(Error, Debug)]
|
|
pub enum Error {
|
|
#[error("Request error: {0}")]
|
|
Request(#[from] request::Error),
|
|
}
|
|
|
|
type Result<T> = std::result::Result<T, Error>;
|
|
|
|
#[derive(Clone, Copy)]
|
|
pub struct RecipeScheduler {
|
|
is_local: bool,
|
|
}
|
|
|
|
pub enum ScheduleRecipeResult {
|
|
Ok,
|
|
RecipeAlreadyScheduledAtThisDate,
|
|
}
|
|
|
|
impl From<ron_api::ScheduleRecipeResult> for ScheduleRecipeResult {
|
|
fn from(api_res: ron_api::ScheduleRecipeResult) -> Self {
|
|
match api_res {
|
|
ron_api::ScheduleRecipeResult::Ok => Self::Ok,
|
|
ron_api::ScheduleRecipeResult::RecipeAlreadyScheduledAtThisDate => {
|
|
Self::RecipeAlreadyScheduledAtThisDate
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
|
struct ScheduledRecipesStore {
|
|
recipe_id: i64,
|
|
date: NaiveDate,
|
|
}
|
|
|
|
fn build_key(year: i32, month: u32) -> String {
|
|
format!("scheduled_recipes-{}-{}", year, month)
|
|
}
|
|
|
|
fn load_scheduled_recipes(year: i32, month: u32) -> Vec<ScheduledRecipesStore> {
|
|
LocalStorage::get::<Vec<ScheduledRecipesStore>>(build_key(year, month)).unwrap_or_default()
|
|
}
|
|
|
|
fn save_scheduled_recipes(scheduled_recipes: Vec<ScheduledRecipesStore>, year: i32, month: u32) {
|
|
LocalStorage::set(build_key(year, month), scheduled_recipes).unwrap();
|
|
}
|
|
|
|
impl RecipeScheduler {
|
|
pub fn new(is_local: bool) -> Self {
|
|
Self { is_local }
|
|
}
|
|
|
|
pub async fn get_scheduled_recipes(
|
|
&self,
|
|
start_date: NaiveDate,
|
|
end_date: NaiveDate,
|
|
) -> Result<Vec<(NaiveDate, String, i64)>> {
|
|
if self.is_local {
|
|
let mut recipe_ids_and_dates = vec![];
|
|
let mut current_date = start_date;
|
|
while current_date <= end_date {
|
|
current_date = current_date + Months::new(1);
|
|
for recipe in load_scheduled_recipes(current_date.year(), current_date.month0()) {
|
|
if recipe.date >= start_date && recipe.date <= end_date {
|
|
recipe_ids_and_dates.push(recipe);
|
|
}
|
|
}
|
|
}
|
|
|
|
if recipe_ids_and_dates.is_empty() {
|
|
return Ok(vec![]);
|
|
}
|
|
|
|
let titles: ron_api::Strings = request::get(
|
|
"recipe/get_titles",
|
|
ron_api::Ids {
|
|
ids: recipe_ids_and_dates
|
|
.iter()
|
|
.map(|r| r.recipe_id)
|
|
.collect::<Vec<_>>(),
|
|
},
|
|
)
|
|
.await?;
|
|
|
|
Ok(recipe_ids_and_dates
|
|
.iter()
|
|
.zip(titles.strs.into_iter())
|
|
.map(|(id_and_date, title)| (id_and_date.date, title, id_and_date.recipe_id))
|
|
.collect::<Vec<_>>())
|
|
} else {
|
|
let scheduled_recipes: ron_api::ScheduledRecipes = request::get(
|
|
"calendar/get_scheduled_recipes",
|
|
ron_api::DateRange {
|
|
start_date,
|
|
end_date,
|
|
},
|
|
)
|
|
.await?;
|
|
|
|
Ok(scheduled_recipes.recipes)
|
|
}
|
|
}
|
|
|
|
pub async fn shedule_recipe(
|
|
&self,
|
|
recipe_id: i64,
|
|
date: NaiveDate,
|
|
servings: u32,
|
|
) -> Result<ScheduleRecipeResult> {
|
|
if self.is_local {
|
|
// storage.get(format("scheduled_recipes-{}-{}", )
|
|
// storage.set("asd", "hello").unwrap();
|
|
let mut recipe_ids_and_dates = load_scheduled_recipes(date.year(), date.month0());
|
|
for recipe in recipe_ids_and_dates.iter() {
|
|
if recipe.recipe_id == recipe_id && recipe.date == date {
|
|
return Ok(ScheduleRecipeResult::RecipeAlreadyScheduledAtThisDate);
|
|
}
|
|
}
|
|
recipe_ids_and_dates.push(ScheduledRecipesStore { recipe_id, date });
|
|
save_scheduled_recipes(recipe_ids_and_dates, date.year(), date.month0());
|
|
Ok(ScheduleRecipeResult::Ok)
|
|
} else {
|
|
request::post::<ron_api::ScheduleRecipeResult, _>(
|
|
"calendar/schedule_recipe",
|
|
ron_api::ScheduleRecipe {
|
|
recipe_id,
|
|
date,
|
|
servings,
|
|
},
|
|
)
|
|
.await
|
|
.map_err(Error::from)
|
|
.map(From::<ron_api::ScheduleRecipeResult>::from)
|
|
}
|
|
}
|
|
|
|
// pub async fn remove_scheduled_recipe(
|
|
// &self,
|
|
// recipe_id: i64
|
|
// )
|
|
}
|