[
  {
    "path": ".gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# production\n/build\n\n# misc\n.DS_Store\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n"
  },
  {
    "path": "README.md",
    "content": "# Hooks Movie App\nThis is the demo application using React Hooks!!!\n\nThe article containing instructions on how to build this app can be found [here](https://www.freecodecamp.org/news/how-to-build-a-movie-search-app-using-react-hooks-24eb72ddfaf7/)\n\n# Getting Started\nThese instructions should get you a copy of the project up and running on your local machine for development and testing purposes.\n\n# Prerequisites\nThings you need to get started:\n- A recent version of Node running on your machine (8.0 or higher), check this [link](https://nodejs.org/en/download/) to download it.\n- A cool text editor, I recommend using either [VSCode](https://code.visualstudio.com/download) or [Atom(with the nuclide plugin)](https://nuclide.io/docs/editor/setup/)\n\n# Installing\nTo get the project running, follow these steps:\n- Create a folder\n-Enter/Navigate into that folder\n```\ncd <folder-name>\n```\n\n- Clone this repository:\n```\ngit clone https://github.com/samie820/hooks-movie-app.git\n```\n\n- Install all the project's dependencies:\n```\nyarn or npm install\n```\n- Once that's done, run the project:\n```\nnpm start or yarn start\n```\n\n# Deployment\nThe app can be deployed using either heroku or Netlify\n\n# Built With\n- Javascript\n- React - (UI library)\n\n# Contribution\nPlease read the [CONTRIBUTING.md](#) file (Soon to be added) to see how you can contribute and add more features to the project.\n\n# Authors\nTODO: Add the Authors\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"movie-app\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"dependencies\": {\n    \"axios\": \"^0.19.0\",\n    \"react\": \"^16.8.2\",\n    \"react-dom\": \"^16.8.2\",\n    \"react-scripts\": \"2.1.1\"\n  },\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test\",\n    \"eject\": \"react-scripts eject\"\n  },\n  \"eslintConfig\": {\n    \"extends\": \"react-app\"\n  },\n  \"browserslist\": [\n    \">0.2%\",\n    \"not dead\",\n    \"not ie <= 11\",\n    \"not op_mini all\"\n  ]\n}\n"
  },
  {
    "path": "public/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <link href=\"%PUBLIC_URL%/favicon.ico\" rel=\"shortcut icon\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n    <meta name=\"theme-color\" content=\"#000000\">\n    <!--\n      manifest.json provides metadata used when your web app is added to the\n      homescreen on Android. See https://developers.google.com/web/fundamentals/web-app-manifest/\n    -->\n    <link href=\"%PUBLIC_URL%/manifest.json\" rel=\"manifest\">\n    <!--\n      Notice the use of %PUBLIC_URL% in the tags above.\n      It will be replaced with the URL of the `public` folder during the build.\n      Only files inside the `public` folder can be referenced from the HTML.\n\n      Unlike \"/favicon.ico\" or \"favicon.ico\", \"%PUBLIC_URL%/favicon.ico\" will\n      work correctly both with client-side routing and a non-root public URL.\n      Learn how to configure a non-root public URL by running `npm run build`.\n    -->\n    <title>Hooked Movie Searcher</title>\n  </head>\n  <body>\n    <noscript>\n      You need to enable JavaScript to run this app.\n    </noscript>\n    <div id=\"root\"></div>\n    <!--\n      This HTML file is a template.\n      If you open it directly in the browser, you will see an empty page.\n\n      You can add webfonts, meta tags, or analytics to this file.\n      The build step will place the bundled scripts into the <body> tag.\n\n      To begin the development, run `npm start` or `yarn start`.\n      To create a production bundle, use `npm run build` or `yarn build`.\n    -->\n  </body>\n</html>\n"
  },
  {
    "path": "public/manifest.json",
    "content": "{\n  \"short_name\": \"React App\",\n  \"name\": \"Create React App Sample\",\n  \"icons\": [\n    {\n      \"src\": \"favicon.ico\",\n      \"sizes\": \"64x64 32x32 24x24 16x16\",\n      \"type\": \"image/x-icon\"\n    }\n  ],\n  \"start_url\": \".\",\n  \"display\": \"standalone\",\n  \"theme_color\": \"#000000\",\n  \"background_color\": \"#ffffff\"\n}\n"
  },
  {
    "path": "src/App.css",
    "content": ".App {\n  text-align: center;\n}\n\n.App-header {\n  background-color: #282c34;\n  height: 70px;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  font-size: calc(10px + 2vmin);\n  color: white;\n  padding: 20px;\n  cursor: pointer;\n}\n\n.spinner {\n  height: 80px;\n  margin: auto;\n}\n\n.App-intro {\n  font-size: large;\n}\n\n/* new css for movie component */\n\n* {\n  box-sizing: border-box;\n}\n\n.movies {\n  display: flex;\n  flex-wrap: wrap;\n  flex-direction: row;\n}\n\n.App-header h2 {\n  margin: 0;\n}\n\n.add-movies {\n  text-align: center;\n}\n\n.add-movies button {\n  font-size: 16px;\n  padding: 8px;\n  margin: 0 10px 30px 10px;\n}\n\n.movie {\n  padding: 5px 25px 10px 25px;\n  max-width: 25%;\n}\n\n.errorMessage {\n  margin: auto;\n  font-weight: bold;\n  color: rgb(161, 15, 15);\n}\n\n.search {\n  display: flex;\n  flex-direction: row;\n  flex-wrap: wrap;\n  justify-content: center;\n  margin-top: 10px;\n}\n\ninput[type=\"submit\"] {\n  padding: 5px;\n  background-color: transparent;\n  color: black;\n  border: 1px solid black;\n  width: 80px;\n  margin-left: 5px;\n  cursor: pointer;\n}\n\ninput[type=\"submit\"]:hover {\n  background-color: #282c34;\n  color: antiquewhite;\n}\n\n.search > input[type=\"text\"]{\n  width: 40%;\n  min-width: 170px;\n}\n\n@media screen and (min-width: 694px) and (max-width: 915px) {\n  .movie {\n    max-width: 33%;\n  }\n}\n\n@media screen and (min-width: 652px) and (max-width: 693px) {\n  .movie {\n    max-width: 50%;\n  }\n}\n\n@media screen and (max-width: 651px) {\n  .movie {\n    max-width: 100%;\n    margin: auto;\n  }\n}"
  },
  {
    "path": "src/components/App.js",
    "content": "import React, { useReducer, useEffect } from \"react\";\n\nimport Header from \"./Header\";\nimport Movie from \"./Movie\";\nimport spinner from \"../assets/ajax-loader.gif\";\nimport Search from \"./Search\";\nimport { initialState, reducer } from \"../store/reducer\";\nimport axios from \"axios\";\n\nconst MOVIE_API_URL = \"https://www.omdbapi.com/?s=man&apikey=4a3b711b\";\n\nconst App = () => {\n  const [state, dispatch] = useReducer(reducer, initialState);\n\n  useEffect(() => {\n    axios.get(MOVIE_API_URL).then(jsonResponse => {\n      dispatch({\n        type: \"SEARCH_MOVIES_SUCCESS\",\n        payload: jsonResponse.data.Search\n      });\n    });\n  }, []);\n\n  // you can add this to the onClick listener of the Header component\n  const refreshPage = () => {\n    window.location.reload();\n  };\n\n  const search = searchValue => {\n    dispatch({\n      type: \"SEARCH_MOVIES_REQUEST\"\n    });\n\n    axios(`https://www.omdbapi.com/?s=${searchValue}&apikey=4a3b711b`).then(\n      jsonResponse => {\n        if (jsonResponse.data.Response === \"True\") {\n          dispatch({\n            type: \"SEARCH_MOVIES_SUCCESS\",\n            payload: jsonResponse.data.Search\n          });\n        } else {\n          dispatch({\n            type: \"SEARCH_MOVIES_FAILURE\",\n            error: jsonResponse.data.Error\n          });\n        }\n      }\n    );\n  };\n\n  const { movies, errorMessage, loading } = state;\n\n  const retrievedMovies =\n    loading && !errorMessage ? (\n      <img className=\"spinner\" src={spinner} alt=\"Loading spinner\" />\n    ) : errorMessage ? (\n      <div className=\"errorMessage\">{errorMessage}</div>\n    ) : (\n      movies.map((movie, index) => (\n        <Movie key={`${index}-${movie.Title}`} movie={movie} />\n      ))\n    );\n\n  return (\n    <div className=\"App\">\n      <div className=\"m-container\">\n        <Header text=\"HOOKED\" />\n\n        <Search search={search} />\n\n        <p className=\"App-intro\">Sharing a few of our favourite movies</p>\n\n        <div className=\"movies\">{retrievedMovies}</div>\n      </div>\n    </div>\n  );\n};\n\nexport default App;\n"
  },
  {
    "path": "src/components/Header.js",
    "content": "import React from \"react\";\n\nconst Header = props => {\n  return (\n    <header className=\"App-header\">\n      <h2>{props.text}</h2>\n    </header>\n  );\n};\n\nexport default Header;\n"
  },
  {
    "path": "src/components/Movie.js",
    "content": "import React from \"react\";\n\nconst DEFAULT_PLACEHOLDER_IMAGE =\n  \"https://m.media-amazon.com/images/M/MV5BMTczNTI2ODUwOF5BMl5BanBnXkFtZTcwMTU0NTIzMw@@._V1_SX300.jpg\";\n\nconst Movie = ({ movie }) => {\n  const poster =\n    movie.Poster === \"N/A\" ? DEFAULT_PLACEHOLDER_IMAGE : movie.Poster;\n  return (\n    <div className=\"movie\">\n      <h2>{movie.Title}</h2>\n      <div>\n        <img\n          width=\"200\"\n          alt={`The movie titled: ${movie.Title}`}\n          src={poster}\n        />\n      </div>\n      <p>({movie.Year})</p>\n    </div>\n  );\n};\n\nexport default Movie;\n"
  },
  {
    "path": "src/components/Search.js",
    "content": "import React, { useState } from \"react\";\n\nconst Search = ({ search }) => {\n  const [searchValue, setSearchValue] = useState(\"\");\n\n  const handleSearchInputChanges = e => {\n    setSearchValue(e.target.value);\n  };\n\n  const resetInputField = () => {\n    setSearchValue(\"\");\n  };\n\n  const callSearchFunction = e => {\n    e.preventDefault();\n    search(searchValue);\n    resetInputField();\n  };\n\n  return (\n    <form className=\"search\">\n      <input\n        value={searchValue}\n        onChange={handleSearchInputChanges}\n        type=\"text\"\n      />\n\n      <input onClick={callSearchFunction} type=\"submit\" value=\"SEARCH\" />\n    </form>\n  );\n};\n\nexport default Search;\n"
  },
  {
    "path": "src/index.css",
    "content": "body {\n  margin: 0;\n  padding: 0;\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\",\n    \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\",\n    sans-serif;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n  font-family: source-code-pro, Menlo, Monaco, Consolas, \"Courier New\",\n    monospace;\n}\n"
  },
  {
    "path": "src/index.js",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport './index.css';\nimport App from './components/App';\n\nReactDOM.render(<App />, document.getElementById('root'));\n"
  },
  {
    "path": "src/store/reducer/index.js",
    "content": "export const initialState = {\n  loading: true,\n  movies: [],\n  errorMessage: null\n};\n\nexport const reducer = (state, action) => {\n  switch (action.type) {\n    case \"SEARCH_MOVIES_REQUEST\":\n      return {\n        ...state,\n        loading: true,\n        errorMessage: null\n      };\n    case \"SEARCH_MOVIES_SUCCESS\":\n      return {\n        ...state,\n        loading: false,\n        movies: action.payload\n      };\n    case \"SEARCH_MOVIES_FAILURE\":\n      return {\n        ...state,\n        loading: false,\n        errorMessage: action.error\n      };\n    default:\n      return state;\n  }\n};\n"
  }
]