diff --git a/package-lock.json b/package-lock.json
index 6d5623ee..d519cba8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "diet-diary",
- "version": "2.29.8",
+ "version": "2.30.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "diet-diary",
- "version": "2.29.8",
+ "version": "2.30.0",
"workspaces": [
"packages/parser"
],
diff --git a/package.json b/package.json
index 6a448fe4..9b626f7d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "diet-diary",
- "version": "2.29.8",
+ "version": "2.30.0",
"private": true,
"homepage": ".",
"dependencies": {
diff --git a/src/app/reducers.ts b/src/app/reducers.ts
index 83673f8f..61a1054a 100644
--- a/src/app/reducers.ts
+++ b/src/app/reducers.ts
@@ -6,7 +6,8 @@ import summaryType from "../features/day-page/summaryTypeSlice";
import targetState from "../features/target/targetStateSlice";
import savedMeals from "../features/saved-meal/savedMealsSlice";
import showSavedMeals from "../features/day-page/showSavedMealsSlice";
-import warning from "../features/warning/warningSlice"
+import warning from "../features/warning/warningSlice";
+import savedMealState from "../features/saved-meal/savedMealStateSlice";
export default combineReducers(
@@ -19,5 +20,6 @@ export default combineReducers(
savedMeals,
showSavedMeals,
warning,
+ savedMealState,
}
)
diff --git a/src/app/selectors.ts b/src/app/selectors.ts
index 4f406ca8..0ae885e3 100644
--- a/src/app/selectors.ts
+++ b/src/app/selectors.ts
@@ -12,6 +12,7 @@ export const targetStateSelector = (state: RootState) => state.targetState;
export const savedMealsSelector = (state: RootState) => state.savedMeals;
export const showSavedMealsSelector = (state: RootState) => state.showSavedMeals;
export const warningSelector = (state: RootState) => state.warning;
+export const savedMealStateSelector = (state: RootState) => state.savedMealState;
export const targetSelector = createSelector(
targetStateSelector,
diff --git a/src/components/saved-meal/SavedMealCardsOffcanvas.tsx b/src/components/saved-meal/SavedMealCardsOffcanvas.tsx
index d29e3f27..ccf9c829 100644
--- a/src/components/saved-meal/SavedMealCardsOffcanvas.tsx
+++ b/src/components/saved-meal/SavedMealCardsOffcanvas.tsx
@@ -1,5 +1,6 @@
import _ from "lodash";
import Offcanvas from "react-bootstrap/Offcanvas";
+import SearchTermInput from "../../features/saved-meal/SearchTermInput";
import { Food } from "../../model/Food";
import { SavedMealCards } from "./SavedMealCards";
@@ -16,8 +17,9 @@ function SavedMealCardsOffcanvas(props: Props) {
Saved Meals
+
Total: {_.size(props.meals)}
-
+
);
diff --git a/src/components/saved-meal/SearchTermInput.tsx b/src/components/saved-meal/SearchTermInput.tsx
new file mode 100644
index 00000000..e322db1d
--- /dev/null
+++ b/src/components/saved-meal/SearchTermInput.tsx
@@ -0,0 +1,17 @@
+import Form from "react-bootstrap/Form";
+
+interface Props {
+ searchTerm: string;
+ update: (s: string) => void;
+}
+
+export const SearchTermInput = (props: Props) => (
+
props.update(e.target.value)}
+ />
+
+)
diff --git a/src/features/saved-meal/SavedMealCardsOffcanvas.ts b/src/features/saved-meal/SavedMealCardsOffcanvas.ts
index 4ad5b806..e000c752 100644
--- a/src/features/saved-meal/SavedMealCardsOffcanvas.ts
+++ b/src/features/saved-meal/SavedMealCardsOffcanvas.ts
@@ -1,6 +1,6 @@
import _ from "lodash";
import { connect } from "react-redux";
-import { savedMealsSelector, showSavedMealsSelector } from "../../app/selectors";
+import { savedMealsSelector, savedMealStateSelector, showSavedMealsSelector } from "../../app/selectors";
import { AppDispatch, RootState } from "../../app/store";
import SavedMealCardsOffcanvas from "../../components/saved-meal/SavedMealCardsOffcanvas";
import { Food } from "../../model/Food";
@@ -10,9 +10,20 @@ function indexedMeals(meals: { foods: Food[] }[]) {
return _.map(meals, (m, index) => ({ index: index, foods: m.foods }));
}
+function hasTerm(meal: { foods: Food[] }, term: string): boolean {
+ const found = _.find(meal.foods, food => _.lowerCase(food.description).includes(term));
+ return found ? true : false;
+}
+
+function filterMeals(state: RootState) {
+ const searchTerm = _.lowerCase(savedMealStateSelector(state).searchTerm);
+ const meals = indexedMeals(savedMealsSelector(state));
+ return _.filter(meals, m => hasTerm(m, searchTerm));
+}
+
const mapStateToProps = (state: RootState) => ({
show: showSavedMealsSelector(state),
- meals: indexedMeals(savedMealsSelector(state)),
+ meals: filterMeals(state),
})
const mapDispatchToProps = (dispatch: AppDispatch) => ({
diff --git a/src/features/saved-meal/SearchTermInput.ts b/src/features/saved-meal/SearchTermInput.ts
new file mode 100644
index 00000000..a8463224
--- /dev/null
+++ b/src/features/saved-meal/SearchTermInput.ts
@@ -0,0 +1,15 @@
+import { connect } from "react-redux";
+import { savedMealStateSelector } from "../../app/selectors";
+import { AppDispatch, RootState } from "../../app/store";
+import { SearchTermInput } from "../../components/saved-meal/SearchTermInput";
+import { updateSearchTerm } from "./savedMealStateSlice";
+
+const mapStateToProps = (state: RootState) => ({
+ searchTerm: savedMealStateSelector(state).searchTerm,
+})
+
+const mapDispatchToProps = (dispatch: AppDispatch) => ({
+ update: (newTerm: string) => dispatch(updateSearchTerm(newTerm)),
+})
+
+export default connect(mapStateToProps, mapDispatchToProps)(SearchTermInput);
\ No newline at end of file
diff --git a/src/features/saved-meal/savedMealStateSlice.ts b/src/features/saved-meal/savedMealStateSlice.ts
new file mode 100644
index 00000000..c9adc375
--- /dev/null
+++ b/src/features/saved-meal/savedMealStateSlice.ts
@@ -0,0 +1,27 @@
+import { createSlice, PayloadAction } from "@reduxjs/toolkit";
+import { addSavedMeal } from "../day-page/mealStatesSlice";
+import { hide } from "../day-page/showSavedMealsSlice";
+
+interface SavedMealState {
+ searchTerm: string;
+}
+
+const savedMealStateSlice = createSlice({
+ name: "searchTerm",
+ initialState: { searchTerm: "" } as SavedMealState,
+ reducers: {
+ updateSearchTerm(state, action: PayloadAction) {
+ state.searchTerm = action.payload;
+ },
+ },
+ extraReducers: (builder) => {
+ builder.addCase(addSavedMeal, (state) => {
+ state.searchTerm = "";
+ }).addCase(hide, (state) => {
+ state.searchTerm = "";
+ });
+ }
+});
+
+export const { updateSearchTerm } = savedMealStateSlice.actions;
+export default savedMealStateSlice.reducer;
\ No newline at end of file