diff --git a/src/App.tsx b/src/App.tsx
index be547d9..e3dcd93 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,18 +1,13 @@
-import { FC, useState } from "react";
+import { FC } from "react";
import { PreLoader } from "./components/PreLoader";
import "./index.css";
import MainLayout from "./layouts/MainLayout";
import { AppRouter } from "./router";
import { Router } from "./router/Router";
-import { MealSummary } from "./types/meal";
import { useAuth0 } from "./utils/auth0-spa";
export const App: FC = () => {
const { loading } = useAuth0();
- const [searchString, setSearchString] = useState("");
- const [searchResults, setSearchResults] = useState({
- meals: [] as MealSummary[],
- });
return loading ? (
@@ -20,12 +15,8 @@ export const App: FC = () => {
) : (
-
-
+
+
);
diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx
index 64598f6..27e5033 100644
--- a/src/components/SearchBar.tsx
+++ b/src/components/SearchBar.tsx
@@ -1,30 +1,20 @@
-import React, { ChangeEvent, FC } from "react";
+import React, { ChangeEvent, FC, useState } from "react";
import { Link } from "react-router-dom";
-import { getData } from "../services/api";
-import { MealSummary } from "../types/meal";
+import { useMeal } from "../store/meal";
+import { fetchSearchResults } from "../store/meal/async";
-type Props = {
- searchString: string;
- setSearchString: React.Dispatch>;
- setSearchResults: React.Dispatch<
- React.SetStateAction<{ meals: MealSummary[] }>
- >;
-};
-
-export const SearchBar: FC = ({
- searchString,
- setSearchString,
- setSearchResults,
-}) => {
+export const SearchBar: FC = () => {
+ const { dispatch } = useMeal();
+ const [searchString, setSearchString] = useState("");
const getSearchResults: React.MouseEventHandler = (e) => {
searchString === ""
? e.preventDefault()
- : getData(searchString, setSearchResults, "search");
+ : fetchSearchResults(dispatch, searchString);
};
const clearSearchBar = () => {
setSearchString("");
- setSearchResults({ meals: [] });
+ dispatch({ type: "clearSearchResults" });
};
const handleChange = (e: ChangeEvent) => {
diff --git a/src/containers/Search/components/SearchPage.tsx b/src/containers/Search/components/SearchPage.tsx
index d9f4386..3c460f9 100644
--- a/src/containers/Search/components/SearchPage.tsx
+++ b/src/containers/Search/components/SearchPage.tsx
@@ -6,29 +6,26 @@ import { SearchResult } from "./SearchResult";
type Props = {
searchString: string;
- searchResults: { meals: MealSummary[] };
+ searchResults: MealSummary[];
};
-export const SearchPage: FC = ({ searchString, searchResults }) => {
- const { meals } = searchResults;
- return (
-
- {!meals ? (
-
-
- No results to display, instead there is a picture of my breakfast.
-
-

-
- ) : (
-
-
- {meals.map((meal, i) => (
-
- ))}
-
-
- )}
-
- );
-};
+export const SearchPage: FC = ({ searchString, searchResults }) => (
+
+ {!searchResults ? (
+
+
+ No results to display, instead there is a picture of my breakfast.
+
+

+
+ ) : (
+
+
+ {searchResults.map((meal, i) => (
+
+ ))}
+
+
+ )}
+
+);
diff --git a/src/containers/Search/index.tsx b/src/containers/Search/index.tsx
index 181e596..abb94a1 100644
--- a/src/containers/Search/index.tsx
+++ b/src/containers/Search/index.tsx
@@ -1,12 +1,13 @@
import { FC } from "react";
-import { MealSummary } from "../../types/meal";
+import { useMeal } from "../../store/meal";
import { SearchPage } from "./components/SearchPage";
-type Props = {
- searchString: string;
- searchResults: { meals: MealSummary[] };
+export const Search: FC = () => {
+ const { state } = useMeal();
+ return (
+
+ );
};
-
-export const Search: FC = ({ searchString, searchResults }) => (
-
-);
diff --git a/src/layouts/MainLayout.tsx b/src/layouts/MainLayout.tsx
index c3a6294..5bc05bc 100644
--- a/src/layouts/MainLayout.tsx
+++ b/src/layouts/MainLayout.tsx
@@ -3,21 +3,8 @@ import { Footer } from "../components/Footer";
import { Navbar } from "../components/Navbar";
import { SearchBar } from "../components/SearchBar";
import { SideNav } from "../components/SideNav";
-import { MealSummary } from "../types/meal";
-type Props = {
- searchString: string;
- setSearchString: React.Dispatch>;
- setSearchResults: React.Dispatch<
- React.SetStateAction<{ meals: MealSummary[] }>
- >;
-};
-const MainLayout: FC = ({
- searchString,
- setSearchString,
- setSearchResults,
- children,
-}) => {
+const MainLayout: FC = ({ children }) => {
const [showNav, setShowNav] = useState(false);
const openNavClick: React.MouseEventHandler = (e) => {
@@ -42,12 +29,7 @@ const MainLayout: FC = ({
<>
{children}
diff --git a/src/layouts/PageLayout.tsx b/src/layouts/PageLayout.tsx
index 04e0f1c..9360977 100644
--- a/src/layouts/PageLayout.tsx
+++ b/src/layouts/PageLayout.tsx
@@ -1,8 +1,6 @@
import { FC } from "react";
-type Props = {
- title: string;
-};
+type Props = { title: string };
const PageLayout: FC = ({ title, children }) => (
diff --git a/src/router/AppRouter.tsx b/src/router/AppRouter.tsx
index 9061ea5..260a676 100644
--- a/src/router/AppRouter.tsx
+++ b/src/router/AppRouter.tsx
@@ -3,20 +3,15 @@ import { Redirect, Route, Switch } from "react-router-dom";
import { buttonURL } from "../constants";
import { Categories } from "../containers/Categories";
import { Category } from "../containers/Category";
+import { Contact } from "../containers/Contact";
import { Home } from "../containers/Home";
import { Meal } from "../containers/Meal";
+import { NotFound } from "../containers/NotFound";
import { Profile } from "../containers/Profile";
import { Search } from "../containers/Search";
-import { Contact } from "../containers/Contact";
-import { NotFound } from "../containers/NotFound";
-import { MealSummary } from "../types/meal";
import { PrivateRoute } from "./PrivateRoute";
-type Props = {
- searchString: string;
- searchResults: { meals: MealSummary[] };
-};
-const AppRouter: FC
= ({ searchString, searchResults }) => (
+const AppRouter: FC = () => (
@@ -37,7 +32,7 @@ const AppRouter: FC = ({ searchString, searchResults }) => (
-
+
diff --git a/src/store/meal/async.ts b/src/store/meal/async.ts
index df09e01..c1c7727 100644
--- a/src/store/meal/async.ts
+++ b/src/store/meal/async.ts
@@ -23,3 +23,20 @@ export const fetchMeal = async (dispatch: Dispatch, id: string) => {
dispatch({ type: "setMeal", payload: meal.meals });
};
+
+export const fetchSearchResults = async (
+ dispatch: Dispatch,
+ searchString: string
+) => {
+ //TODO: refactor to use Meal client
+ const URI = createURI(searchString, "search");
+
+ const meals = await fetch(URI)
+ .then((response) => response.json())
+ .catch((error) => console.warn(error + "url:" + URI));
+
+ dispatch({
+ type: "setSearchResults",
+ payload: { search: meals.meals, searchString },
+ });
+};
diff --git a/src/store/meal/index.tsx b/src/store/meal/index.tsx
index b98ae56..9e2a068 100644
--- a/src/store/meal/index.tsx
+++ b/src/store/meal/index.tsx
@@ -1,10 +1,21 @@
//https://kentcdodds.com/blog/how-to-use-react-context-effectively
import { createContext, FC, useContext, useReducer } from "react";
-import { MealApi } from "../../types/meal";
+import { MealApi, MealSummary } from "../../types/meal";
import { appReducer, Dispatch } from "./reducer";
-export type AppState = { meals: MealApi[] };
+export type AppState = {
+ meals: MealApi[];
+ search: MealSummary[];
+ searchString: string;
+};
+
+const initState = {
+ meals: [] as MealApi[],
+ search: [] as MealSummary[],
+ searchString: "",
+};
+
type ContextType = { state: AppState; dispatch: Dispatch } | undefined;
const AppContext = createContext(undefined);
@@ -18,7 +29,7 @@ export const useMeal = () => {
};
export const AppProvider: FC = ({ children }) => {
- const [state, dispatch] = useReducer(appReducer, { meals: [] as MealApi[] });
+ const [state, dispatch] = useReducer(appReducer, initState);
const value = { state, dispatch };
return {children};
};
diff --git a/src/store/meal/reducer.ts b/src/store/meal/reducer.ts
index 9f3174e..f21c8d9 100644
--- a/src/store/meal/reducer.ts
+++ b/src/store/meal/reducer.ts
@@ -3,13 +3,15 @@ import { AppState } from "./index";
export const appReducer = (state: AppState, action: Action) => {
switch (action.type) {
case "setMeal":
- return { meals: action.payload };
- case "fetchMeal":
- return { meals: state.meals };
- case "fetchRandomMeal":
- return { meals: state.meals };
- case "toggleFav":
- return { meals: state.meals };
+ return { ...state, meals: action.payload };
+ case "setSearchResults":
+ return {
+ ...state,
+ search: action.payload.search,
+ searchString: action.payload.searchString,
+ };
+ case "clearSearchResults":
+ return { ...state, search: [] };
default: {
throw new Error(`Unhandled action type: ${action.type}`);
}
@@ -18,6 +20,7 @@ export const appReducer = (state: AppState, action: Action) => {
export type Action = {
payload?: any;
- type: "setMeal" | "fetchMeal" | "fetchRandomMeal" | "toggleFav";
+ type: "setMeal" | "setSearchResults" | "clearSearchResults";
};
+
export type Dispatch = (action: Action) => void;