Calendar is now displayed on home page and recipes can be scheduled without being logged
This commit is contained in:
parent
ccb1248da3
commit
37721ac3ea
22 changed files with 538 additions and 166 deletions
150
frontend/src/recipe_scheduler.rs
Normal file
150
frontend/src/recipe_scheduler.rs
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
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
|
||||
// )
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue