Tuesday, November 26, 2024
Google search engine
HomeLanguagesMovie Web Application with ReactJS

Movie Web Application with ReactJS

This article covers how to make a fully responsive and sleek Movie App with React. React is a JavaScript framework provided by Facebook and is used to build fully-featured web applications. 

We will be following the below steps for creating our application:

Step 1: Creating the project: We will start by creating a new react project using the create-react-app tool. You can use the following command for creating one with the desired name. Please ensure that Node and npm are installed on the system.

npx create-react-app movie-app

Project Structure: We will then delete all the files that are not necessary. The file structure after deleting the files is given below:

Step 2: Open the “src” folder and select the App.js file and add the following code to it.

App.js




import React, { useState } from "react";
import axios from "axios";
import Search from "./components/Search";
import Results from "./components/Results";
import Detail from "./components/Detail";
import "./App.css";
  
function App() {
  const [state, setState] = useState({
    s: "sherlock",
    results: [],
    selected: {},
  });
  
  
  const searchInput = (e) => {
    let s = e.target.value;
  
    setState((prevState) => {
      return { ...prevState, s: s };
    });
  };
  
  const search = (e) => {
    if (e.key === "Enter") {
      axios(apiurl + "&s=" + state.s).then(({ data }) => {
        let results = data.Search;
  
        console.log(results);
  
        setState((prevState) => {
          return { ...prevState, results: results };
        });
      });
    }
  };
  
  const openDetail = (id) => {
    axios(apiurl + "&i=" + id).then(({ data }) => {
      let result = data;
  
      setState((prevState) => {
        return { ...prevState, selected: result };
      });
    });
  };
  
  const closeDetail = () => {
    setState((prevState) => {
      return { ...prevState, selected: {} };
    });
  };
  
  return (
    <div className="App">
      <header className="App-header">
        <h1>Movie Mania</h1>
      </header>
      <main>
        <Search searchInput={searchInput} search={search} />
  
        <Results results={state.results} openDetail={openDetail} />
  
        {typeof state.selected.Title != "undefined" ? (
          <Detail selected={state.selected} closeDetail={closeDetail} />
        ) : (
          false
        )}
      </main>
    </div>
  );
}
  
export default App;


App.css




* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
  
body {
  font-family: "montserrat", sans-serif;
  background: linear-gradient(to right, #000428, #004e92);
}
  
header {
  width: 100%;
  padding-top: 2rem;
  padding-bottom: 1rem;
}
  
header h1 {
  color: #ffffff;
  font-size: 4rem;
  font-weight: 700;
  text-align: center;
}
  
main {
  width: 100%;
  max-width: 90%;
  margin: 0 auto;
}
  
.results {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  /* margin: 0 -15px; */
}
  
.results .result {
  width: 20%;
  min-width: 250px;
  background: #000000;
  max-height: 500px;
  /* padding: 15px; */
  margin: 20px 25px;
  display: flex;
  flex-direction: column;
  cursor: pointer;
}
  
.results .not-found {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  margin: 2rem 0.5rem;
}
  
.results .not-found h2 {
  color: #ffffff;
}
  
.results .result img {
  /* display: block; */
  width: 100%;
  padding: 10px 2px;
  margin: 0 auto;
  height: 350px;
  width: 230px;
}
  
.results .result h3 {
  color: #fff;
  font-size: 20px;
  font-weight: 600;
  width: 100%;
  text-align: center;
  padding: 1rem;
  background: #272829;
  flex: 1 100%;
  transition: 0.4s ease-out;
}
  
.result:hover {
  box-shadow: 0 0 8px 3px #eaf0f7;
  /* background: #dfd8d8; */
}
  
.results .result h3:hover {
  background: #fff;
  color: #223343;
  box-shadow: 0 0 8px 3px #4484c4;
}
  
.detail {
  margin: 3rem 5rem;
  overflow-y: scroll;
}
  
.detail .content .rating {
  margin-left: 2rem;
  font-size: 1.5rem;
  margin-bottom: 0;
  margin-top: 1rem;
  padding-bottom: 0;
}
  
.detail .content {
  display: block;
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  max-width: 15000px;
  /* max-height: 600px; */
  padding: 25px;
  background: #000000;
  color: #fff;
  overflow-y: scroll;
}
  
.detail .content h2 {
  font-size: 3rem;
  padding: 2rem;
  padding-top: 0;
  padding-bottom: 0.5rem;
  font-weight: 600;
}
  
.detail .content span {
  font-size: 1.4rem;
  margin-left: 2rem;
  margin-bottom: 3rem;
  font-weight: 300;
  color: #ffffff;
}
  
.detail .content .rating {
  margin-bottom: 30px;
}
  
.detail .content .about {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -15px 30px;
}
  
.detail .content .about img {
  flex: 1 1 50%;
  max-width: 300px;
  opacity: none;
  padding: 0 15px;
  margin-left: 2rem;
  margin-top: 1rem;
}
  
.detail .content .about p {
  flex: 1 50%;
  padding: 15px 25px;
  margin-top: 3rem;
  font-size: 1.5rem;
}
  
.detail .content .close {
  /* display: inline-block; */
  padding: 15px 30px;
  font-size: 18px;
  /* margin-top: 3rem;
  margin-right: 2rem;
  margin-bottom: 1rem; */
  font-weight: 700;
  background: #223343;
  color: #fff;
  /* border-radius: 8px; */
  border: none;
  outline: none;
  appearance: none;
  cursor: pointer;
  transition: 0.4s ease-out;
  
  width: 100%;
  display: flex;
  margin: auto;
  margin-top: 5rem;
  justify-content: center;
  align-items: center;
  border-radius: 5px;
}
  
.detail .content button:hover {
  background: #4484c4;
}
  
.detail .content .about .close:hover {
  background: #223343;
}
  
@media screen and (max-width: 1015px) {
  .results {
    justify-content: center;
    align-items: center;
  }
  
  .detail .content .close {
    width: 100%;
    display: flex;
    margin: auto;
    justify-content: center;
    align-items: center;
    border-radius: 5px;
  }
}
  
@media screen and (max-width: 683px) {
  .results {
    justify-content: center;
    align-items: center;
  }
  
  .results .result {
    margin: 10px;
    justify-content: center;
    align-items: center;
  }
}
  
@media screen and (max-width: 643px) {
  .results .result {
    margin: 15px;
  }
}
  
@media screen and (max-width: 638px) {
  .results .result {
    margin: 8px;
  }
}
  
@media screen and (max-width: 410px) {
  header h1 {
    font-size: 2.9rem;
  }
  
  .results {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }
  
  .detail {
    overflow-y: scroll;
  }
  
  .detail .content .close {
    width: 100%;
    display: flex;
    margin: auto;
    justify-content: center;
    align-items: center;
    border-radius: 5px;
  }
  
  .detail .content span {
    margin-left: 0.5rem;
    font-style: italic;
    font-weight: bold;
  }
  
  .detail .content h2 {
    padding-left: 0.5rem;
    font-size: 2.1rem;
    margin-bottom: 0.5rem;
    font-weight: 100;
  }
  
  .detail .content .rating {
    margin-left: 0.5rem;
    font-weight: bold;
  }
  
  .detail .content .about img {
    margin-left: 0.5rem;
  }
}


 

Step 3: Make a new folder named Components in your src folder. In the src folder, make files – Detail.js, Result.js, Results.js, Search.js, and Search.css

Step 4: Now add the following codes in the respective files.

Detail.js




import React from "react";
  
function Detail({ selected, closeDetail }) {
  return (
    <section className="detail">
      <div className="content">
        <h2>{selected.Title}</h2>
        <span>{selected.Year}</span>
        <p className="rating">Rating: {selected.imdbRating}</p>
  
        <div className="about">
          <img src={selected.Poster} alt="" />
            
<p>{selected.Plot}</p>
  
        </div>
        <button className="close" onClick={closeDetail}>
          Close
        </button>
      </div>
    </section>
  );
}
  
export default Detail;


Result.js




import React from "react";
  
function Result({ result, openDetail }) {
  return (
    <div className="result" onClick=
        {() => openDetail(result.imdbID)}>
      <img src={result.Poster} />
      <h3>{result.Title}</h3>
    </div>
  );
}
  
export default Result;


Results.js




import React from "react";
import Result from "./Result";
  
function Results({ results, openDetail }) {
  return (
    <section className="results">
      {typeof results != "undefined" ? (
        results.map((result) => (
          <Result key={result.imdbID} result
              ={result} openDetail={openDetail} />
        ))
      ) : (
        <div className="not-found">
          <h2>Sorry.. Movie not found in the database.</h2>
          <h2>
              Try checking the name you input 
            or search for another movie.
          </h2>
        </div>
      )}
    </section>
  );
}
  
export default Results;


Search.js




import React from "react";
import "./Search.css";
  
function Search({ searchInput, search }) {
  return (
    <div className="search-bar">
      <input
        type="text"
        placeholder="Search for a Movie..."
        className="search"
        onChange={searchInput}
        onKeyPress={search}
      />
    </div>
  );
}
  
export default Search;


Search.css




.search-bar {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 1rem 0;
}
  
.search {
  width: 60%;
  display: block;
  padding: 15px;
  border: none;
  outline: none;
  background: none;
  background-color: #fff;
  border-radius: 8px;
  color: dimgrey;
  font-size: 20px;
  font-weight: 300;
  transition: 0.4s ease-out;
}
  
.search:focus {
  box-shadow: 0 0 8px 3px #4484c4;
}
  
@media screen and (max-width: 685px) {
  .search {
    width: 75%;
  }
}
  
@media screen and (max-width: 410px) {
  .search {
    width: 85%;
  }
}


Step 5: Running and Building the application: We can run this application by using the following command. This will start React’s development server that can be used for debugging our application.

npm run start

Output: You will see the following output on your browser screen.

Whether you’re preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape, neveropen Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we’ve already empowered, and we’re here to do the same for you. Don’t miss out – check it out now!

RELATED ARTICLES

Most Popular

Recent Comments