Advertisement
krle997

Untitled

Nov 25th, 2024
24
0
29 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { get, writable } from "svelte/store";
  2. import { getWithJwt, MealEntityType, serverlessRoutes, sortItems } from "lib";
  3. import { storeUtil } from "../lib/createItemsStore";
  4. import { currentClient } from "./currentClient";
  5. import type { Ingredient, ItemsStore, Meal, Recipe } from "interfaces";
  6. import { user } from "./userStore";
  7.  
  8. interface ActiveMealsStore extends ItemsStore<Meal> {
  9.   filter: {
  10.     detailedView: boolean;
  11.   };
  12. }
  13.  
  14. const activeMealsStoreCreate = () => {
  15.   const { set, subscribe, update } = writable<ActiveMealsStore>({
  16.     items: [],
  17.     count: 0,
  18.     hasMore: false,
  19.     isFetching: false,
  20.     isFetchingMore: false,
  21.     skip: 0,
  22.     searchTimeout: undefined,
  23.     filter: {
  24.       detailedView: false,
  25.     },
  26.   });
  27.  
  28.   const createUrl = (): string => {
  29.     const {
  30.       skip,
  31.       filter: { detailedView },
  32.     } = get({ subscribe });
  33.  
  34.     const params = new URLSearchParams();
  35.  
  36.     // params.append("take", "200");
  37.     // params.append("skip", skip.toString());
  38.     params.append(
  39.       "clientId",
  40.       (get(currentClient).id || get(user).id).toString()
  41.     );
  42.     // params.append("finishedAt", "false");
  43.     console.log(`${serverlessRoutes.MEAL}/active?${params.toString()}`);
  44.     return `${serverlessRoutes.MEAL}/active?${params.toString()}`;
  45.   };
  46.  
  47.   const {
  48.     // add,
  49.     // replace,
  50.     // remove,
  51.     //fetchData,
  52.     fetchMoreData,
  53.     search,
  54.     loadCache,
  55.   } = storeUtil<Meal, ActiveMealsStore>("activeMealsCache", update, createUrl);
  56.  
  57.   const fetchData = async (): Promise<void> => {
  58.     if (!get(user)) {
  59.       return;
  60.     }
  61.  
  62.     update((store) => {
  63.       store.isFetching = true;
  64.       store.skip = 0;
  65.       return store;
  66.     });
  67.  
  68.     try {
  69.       const response = await getWithJwt(createUrl());
  70.       const {items, count} = response.data;
  71.       console.log(items);
  72.       add(items);
  73.  
  74.       update((store) => {
  75.         // store.items = items;
  76.         store.count = count;
  77.         store.hasMore = store.items.length < store.count;
  78.  
  79.         return store;
  80.       });
  81.  
  82.       localStorage.setItem("activeMealsCache", JSON.stringify({items, count}));
  83.     } catch (error) {
  84.       console.error(error);
  85.     } finally {
  86.       update((store) => {
  87.         store.isFetching = false;
  88.         return store;
  89.       });
  90.     }
  91.   };
  92.  
  93.   const calculateHeadersMacros = (): void => {
  94.     let lastHeaderIndex = 0;
  95.  
  96.     update((store) => {
  97.       store.items.forEach((meal, index): void => {
  98.         const { entityType } = meal;
  99.  
  100.         if (entityType === MealEntityType.HEADER) {
  101.           lastHeaderIndex = index;
  102.  
  103.           const header = store.items[lastHeaderIndex];
  104.  
  105.           header.carbs = 0;
  106.           header.protein = 0;
  107.           header.fats = 0;
  108.           header.calories = 0;
  109.         } else if (entityType === MealEntityType.NORMAL) {
  110.           const header = store.items[lastHeaderIndex];
  111.  
  112.           header.carbs = (header.carbs || 0) + (meal.carbs || 0);
  113.           header.protein = (header.protein || 0) + (meal.protein || 0);
  114.           header.fats = (header.fats || 0) + (meal.fats || 0);
  115.           header.calories = (header.calories || 0) + (meal.calories || 0);
  116.         }
  117.       });
  118.  
  119.       return store;
  120.     });
  121.   };
  122.  
  123.   const fetchRecipeIngredients = async (
  124.     mealId: number,
  125.     id: number
  126.   ): Promise<void> => {
  127.     try {
  128.       const response = await getWithJwt(
  129.         `${serverlessRoutes.RECIPE}/${id}/ingredients`
  130.       );
  131.  
  132.       addRecipeIngredients(mealId, id, response.data.ingredients);
  133.     } catch (error) {
  134.       console.error(error);
  135.     }
  136.   };
  137.  
  138.   const getMealIdFromRecipeId = (recipeId: number): number | undefined => {
  139.     const { items } = get({ subscribe });
  140.  
  141.     const meal = items.find((meal): boolean => {
  142.       const recipe = meal.recipes?.find(({ id }): boolean => id === recipeId);
  143.       return recipe ? true : false;
  144.     });
  145.  
  146.     return meal?.id;
  147.   };
  148.  
  149.   const fetchMeal = async (mealId: any): Promise<void> => {
  150.     const { data, error } = await getWithJwt(
  151.       `${serverlessRoutes.MEAL}/${mealId}`
  152.     );
  153.  
  154.     if (error && !data) {
  155.       return console.error(error);
  156.     }
  157.  
  158.     const { recipes, ingredients } = data;
  159.  
  160.     addMealRecipes(mealId, recipes);
  161.     addMealIngredients(mealId, ingredients);
  162.   };
  163.  
  164.   const replace = (meals: Array<Meal>): void => {
  165.     update((store) => {
  166.       meals.forEach((meal): void => {
  167.         const mealIndex = store.items.findIndex(
  168.           ({ id }): boolean => id === meal.id
  169.         );
  170.  
  171.         if (mealIndex === -1) {
  172.           return;
  173.         }
  174.  
  175.         store.items = store.items.with(mealIndex, meal);
  176.       });
  177.  
  178.       store.items.sort(sortItems);
  179.  
  180.       return store;
  181.     });
  182.   };
  183.  
  184.   const remove = (ids: Array<number>): void => {
  185.     update((store) => {
  186.       store.items = store.items.filter(
  187.         (meal): boolean => !ids.includes(meal.id)
  188.       );
  189.       store.items.sort(sortItems);
  190.  
  191.       store.count -= ids.length;
  192.       store.skip -= ids.length;
  193.       store.hasMore = store.items.length < store.count;
  194.  
  195.       return store;
  196.     });
  197.   };
  198.  
  199.   const add = (meals: Array<Meal>): void => {
  200.     update((store) => {
  201.       const map = {};
  202.       const items = [];
  203.  
  204.       meals.forEach((meal) => {
  205.         if (map[meal.mealPlanId]) {
  206.           map[meal.mealPlanId].push(meal);
  207.         } else {
  208.           map[meal.mealPlanId] = [meal];
  209.         }
  210.       });
  211.  
  212.       console.log({map});
  213.  
  214.       Object.keys(map).forEach((mealPlanId) => {
  215.         map[mealPlanId].sort(sortItems);
  216.         items.push(...map[mealPlanId]);
  217.       });
  218.  
  219.       store.items = items;
  220.       // store.items.unshift(...meals);
  221.       // store.items.sort(sortItems);
  222.  
  223.       store.count += meals.length;
  224.       store.skip += meals.length;
  225.       store.hasMore = store.items.length < store.count;
  226.  
  227.       return store;
  228.     });
  229.   };
  230.  
  231.   const calculateMacros = (meal: Meal): void => {
  232.     let ingredientMacros = {
  233.       protein: 0,
  234.       carbs: 0,
  235.       fats: 0,
  236.       calories: 0,
  237.     };
  238.  
  239.     let recipeMacros = {
  240.       protein: 0,
  241.       carbs: 0,
  242.       fats: 0,
  243.       calories: 0,
  244.     };
  245.  
  246.     if (meal.ingredients) {
  247.       ingredientMacros = meal.ingredients.reduce(
  248.         (macro, ingredient) => {
  249.           const { protein, carbs, fats, calories } = ingredient;
  250.  
  251.           macro.protein += protein || 0;
  252.           macro.carbs += carbs || 0;
  253.           macro.fats += fats || 0;
  254.           macro.calories += calories || 0;
  255.  
  256.           return macro;
  257.         },
  258.         {
  259.           protein: 0,
  260.           carbs: 0,
  261.           fats: 0,
  262.           calories: 0,
  263.         }
  264.       );
  265.     }
  266.  
  267.     if (meal.recipes) {
  268.       recipeMacros = meal.recipes.reduce(
  269.         (macro, recipe) => {
  270.           const { protein, carbs, fats, calories } = recipe;
  271.  
  272.           macro.protein += protein || 0;
  273.           macro.carbs += carbs || 0;
  274.           macro.fats += fats || 0;
  275.           macro.calories += calories || 0;
  276.  
  277.           return macro;
  278.         },
  279.         {
  280.           protein: 0,
  281.           carbs: 0,
  282.           fats: 0,
  283.           calories: 0,
  284.         }
  285.       );
  286.     }
  287.  
  288.     meal.protein = ingredientMacros.protein + recipeMacros.protein;
  289.     meal.carbs = ingredientMacros.carbs + recipeMacros.carbs;
  290.     meal.fats = ingredientMacros.fats + recipeMacros.fats;
  291.     meal.calories = ingredientMacros.calories + recipeMacros.calories;
  292.   };
  293.  
  294.   const calculateMacrosMealRecipe = (recipe: Recipe): void => {
  295.     if (!recipe.ingredients) {
  296.       return;
  297.     }
  298.  
  299.     const ingredientMacros = recipe.ingredients.reduce(
  300.       (macro, ingredient) => {
  301.         const { protein, carbs, fats, calories } = ingredient;
  302.  
  303.         macro.protein += protein || 0;
  304.         macro.carbs += carbs || 0;
  305.         macro.fats += fats || 0;
  306.         macro.calories += calories || 0;
  307.  
  308.         return macro;
  309.       },
  310.       {
  311.         protein: 0,
  312.         carbs: 0,
  313.         fats: 0,
  314.         calories: 0,
  315.       }
  316.     );
  317.  
  318.     recipe.protein = ingredientMacros.protein;
  319.     recipe.carbs = ingredientMacros.carbs;
  320.     recipe.fats = ingredientMacros.fats;
  321.     recipe.calories = ingredientMacros.calories;
  322.   };
  323.  
  324.   const addMealIngredients = (
  325.     mealId: number,
  326.     newIngredients: Array<Ingredient>
  327.   ): void => {
  328.     update((store) => {
  329.       const meal = store.items.find(({ id }): boolean => id === mealId);
  330.  
  331.       if (!meal) {
  332.         return store;
  333.       }
  334.  
  335.       if (meal.ingredients) {
  336.         meal.ingredients.push(...newIngredients);
  337.       } else {
  338.         meal.ingredients = newIngredients;
  339.       }
  340.  
  341.       meal.ingredients.sort(sortItems);
  342.       calculateMacros(meal);
  343.  
  344.       return store;
  345.     });
  346.   };
  347.  
  348.   const replaceMealIngredients = (
  349.     mealId: number,
  350.     newIngredients: Array<Ingredient>
  351.   ): void => {
  352.     update((store) => {
  353.       const meal = store.items.find((meal): boolean => meal.id === mealId);
  354.  
  355.       if (!meal || !meal.ingredients) {
  356.         return store;
  357.       }
  358.  
  359.       const { ingredients } = meal;
  360.  
  361.       newIngredients.forEach((newIngredient): void => {
  362.         const ingredientIndex = ingredients.findIndex(
  363.           ({ id }): boolean => id === newIngredient.id
  364.         );
  365.  
  366.         if (ingredientIndex === -1) {
  367.           return;
  368.         }
  369.  
  370.         ingredients.splice(ingredientIndex, 1, newIngredient);
  371.       });
  372.  
  373.       meal.ingredients.sort(sortItems);
  374.       calculateMacros(meal);
  375.  
  376.       return store;
  377.     });
  378.   };
  379.  
  380.   const removeMealIngredients = (
  381.     mealId: number,
  382.     ingredientIds: Array<number>
  383.   ): void => {
  384.     update((store) => {
  385.       const meal = store.items.find(({ id }): boolean => id === mealId);
  386.  
  387.       if (!meal || !meal.ingredients) {
  388.         return store;
  389.       }
  390.  
  391.       const { ingredients } = meal;
  392.  
  393.       meal.ingredients = ingredients.filter(
  394.         ({ id }): boolean => !ingredientIds.includes(id)
  395.       );
  396.  
  397.       meal.ingredients.sort(sortItems);
  398.       calculateMacros(meal);
  399.  
  400.       return store;
  401.     });
  402.   };
  403.  
  404.   const addMealRecipes = (mealId: number, newRecipes: Array<Recipe>): void => {
  405.     update((store) => {
  406.       const meal = store.items.find(({ id }): boolean => id === mealId);
  407.  
  408.       if (!meal) {
  409.         return store;
  410.       }
  411.  
  412.       if (meal.recipes) {
  413.         meal.recipes.push(...newRecipes);
  414.       } else {
  415.         meal.recipes = newRecipes;
  416.       }
  417.  
  418.       meal.recipes.sort(sortItems);
  419.       calculateMacros(meal);
  420.  
  421.       return store;
  422.     });
  423.   };
  424.  
  425.   const replaceMealRecipes = (
  426.     mealId: number,
  427.     newRecipes: Array<Recipe>
  428.   ): void => {
  429.     update((store) => {
  430.       const meal = store.items.find(({ id }): boolean => id === mealId);
  431.  
  432.       if (!meal || !meal.recipes) {
  433.         return store;
  434.       }
  435.  
  436.       const { recipes } = meal;
  437.  
  438.       newRecipes.forEach((newRecipe): void => {
  439.         const recipeIndex = recipes.findIndex(
  440.           ({ id }): boolean => id === newRecipe.id
  441.         );
  442.  
  443.         if (recipeIndex === -1) {
  444.           return;
  445.         }
  446.  
  447.         recipes.splice(recipeIndex, 1, newRecipe);
  448.       });
  449.  
  450.       meal.recipes.sort(sortItems);
  451.       calculateMacros(meal);
  452.  
  453.       return store;
  454.     });
  455.   };
  456.  
  457.   const removeMealRecipes = (
  458.     mealId: number,
  459.     recipeIds: Array<number>
  460.   ): void => {
  461.     update((store) => {
  462.       const meal = store.items.find(({ id }): boolean => id === mealId);
  463.  
  464.       if (!meal || !meal.recipes) {
  465.         return store;
  466.       }
  467.  
  468.       const { recipes } = meal;
  469.  
  470.       meal.recipes = recipes.filter(
  471.         ({ id }): boolean => !recipeIds.includes(id)
  472.       );
  473.  
  474.       meal.recipes.sort(sortItems);
  475.       calculateMacros(meal);
  476.  
  477.       return store;
  478.     });
  479.   };
  480.  
  481.   const addRecipeIngredients = (
  482.     mealId: number,
  483.     recipeId: number,
  484.     newIngredients: Array<Ingredient>
  485.   ): void => {
  486.     update((store) => {
  487.       const meal = store.items.find(({ id }): boolean => id === mealId);
  488.       const recipe = meal?.recipes?.find(({ id }): boolean => id === recipeId);
  489.  
  490.       if (!meal || !recipe) {
  491.         return store;
  492.       }
  493.  
  494.       if (recipe.ingredients) {
  495.         recipe.ingredients.push(...newIngredients);
  496.       } else {
  497.         recipe.ingredients = newIngredients;
  498.       }
  499.  
  500.       recipe.ingredients.sort(sortItems);
  501.       calculateMacrosMealRecipe(recipe);
  502.       calculateMacros(meal);
  503.  
  504.       return store;
  505.     });
  506.   };
  507.  
  508.   const replaceRecipeIngredients = (
  509.     mealId: number,
  510.     recipeId: number,
  511.     newIngredients: Array<Ingredient>
  512.   ): void => {
  513.     update((store) => {
  514.       const meal = store.items.find(({ id }): boolean => id === mealId);
  515.       const recipe = meal?.recipes?.find(({ id }): boolean => id === recipeId);
  516.  
  517.       if (!meal || !recipe || !recipe.ingredients) {
  518.         return store;
  519.       }
  520.  
  521.       const { ingredients } = recipe;
  522.  
  523.       newIngredients.forEach((newIngredient): void => {
  524.         const ingredientIndex = ingredients.findIndex(
  525.           ({ id }): boolean => id === newIngredient.id
  526.         );
  527.  
  528.         if (ingredientIndex === -1) {
  529.           return;
  530.         }
  531.  
  532.         ingredients.splice(ingredientIndex, 1, newIngredient);
  533.       });
  534.  
  535.       recipe.ingredients.sort(sortItems);
  536.       calculateMacrosMealRecipe(recipe);
  537.       calculateMacros(meal);
  538.  
  539.       return store;
  540.     });
  541.   };
  542.  
  543.   const removeRecipeIngredients = (
  544.     mealId: number,
  545.     recipeId: number,
  546.     ingredientIds: Array<number>
  547.   ): void => {
  548.     update((store) => {
  549.       const meal = store.items.find(({ id }): boolean => id === mealId);
  550.       const recipe = meal?.recipes?.find(({ id }): boolean => id === recipeId);
  551.  
  552.       if (!meal || !recipe || !recipe.ingredients) {
  553.         return store;
  554.       }
  555.  
  556.       const { ingredients } = recipe;
  557.  
  558.       recipe.ingredients = ingredients.filter(
  559.         ({ id }): boolean => !ingredientIds.includes(id)
  560.       );
  561.  
  562.       recipe.ingredients.sort(sortItems);
  563.       calculateMacrosMealRecipe(recipe);
  564.       calculateMacros(meal);
  565.  
  566.       return store;
  567.     });
  568.   };
  569.  
  570.   return {
  571.     set,
  572.     subscribe,
  573.     update,
  574.     add,
  575.     replace,
  576.     remove,
  577.     fetchData,
  578.     fetchMoreData,
  579.     search,
  580.     loadCache,
  581.  
  582.     // generateMealMap, // na fetch mora rucno da se zove, zato je exportovano
  583.     calculateHeadersMacros,
  584.     fetchRecipeIngredients,
  585.     fetchMeal,
  586.  
  587.     addMealIngredients,
  588.     replaceMealIngredients,
  589.     removeMealIngredients,
  590.     addMealRecipes,
  591.     replaceMealRecipes,
  592.     removeMealRecipes,
  593.     addRecipeIngredients,
  594.     replaceRecipeIngredients,
  595.     removeRecipeIngredients,
  596.  
  597.     getMealIdFromRecipeId,
  598.   };
  599. };
  600.  
  601. const activeMealsStore = activeMealsStoreCreate();
  602.  
  603. export { activeMealsStore };
  604.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement