Skip to content

Commit

Permalink
Merge pull request #7 from Git-abby/genreNavs
Browse files Browse the repository at this point in the history
chore: Genre navbars implemented
  • Loading branch information
Git-abby authored Dec 17, 2024
2 parents 1899862 + 8bff387 commit 30bf04e
Show file tree
Hide file tree
Showing 13 changed files with 291 additions and 52 deletions.
15 changes: 7 additions & 8 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Route, Routes } from "react-router-dom";
import "./App.css";
// This is default export
import MovieCard from "./components/MovieCard";
import Home from "./components/pages/Home";
import Favorites from "./components/pages/Favorites";
import NavBar from "./components/NavBar";
Expand All @@ -12,29 +11,29 @@ import Footer from "./components/Footer";
import NotFound from "./components/pages/NotFound";
import Login from "./components/pages/Login";
import SignUp from "./components/pages/SignUp";
import ByGenreMovies from "./components/pages/ByGenreMovies";
// it we do named export we had to wrap function name here in {} like {MovieCard}

// A compo is just any fun() in JS that returns some kind of JSX CODE
// Starts with CAPITAL letter
function App() {
const movieNumber = 2;

return (
// <> </> React Fragment = empty HTML tag
<MovieProvider>
<NavBar />
<main className="main bg-gray-1 dark:bg-dark">
<Routes>
<Route path="/signin" element={<Login />} />
<Route path="/signup" element={<SignUp />} />
<Route path="/home" element={<Home />} />
<Route path="/favorites" element={<Favorites />} />
<Route path="/about" element={<About />} />
<Route path="/movie/:movieId" element={<SingleMovie />} />
<Route path="/signin" element={<Login />} />
<Route path="/signup" element={<SignUp />} />
<Route path="/404" element={<NotFound/>} />
<Route path="/genre/:genreId" element={<ByGenreMovies />} />
<Route path="/about" element={<About />} />
<Route path="/404" element={<NotFound />} />
</Routes>
</main>
<Footer/>
<Footer />
</MovieProvider>
);
}
Expand Down
42 changes: 42 additions & 0 deletions frontend/src/components/GenresNavbar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { useEffect, useState } from "react";
import { getAllGenres, getMoviesByGenre } from "../services/api";

// Styling
import "../css/GenresNavbar.css";
import { useNavigate } from "react-router-dom";

function GenresNavbar() {
// For navigating routes
const navigate = useNavigate();

// To store genres
const [genres, setGenres] = useState([]);

useEffect(() => {
const fetchGenres = async () => {
const data = await getAllGenres();

setGenres(data.genres);
console.log(genres);
};
fetchGenres();
}, []);

const onGenreClick = async (genre_id) => {
navigate(`genre/${genre_id}`);
};
return (
<div className="genres-navbar">
{genres.map((genre) => (
<button
key={genre.id}
className="genre-button"
onClick={() => onGenreClick(genre.id)}>
{genre.name}
</button>
))}
</div>
);
}

export default GenresNavbar;
12 changes: 12 additions & 0 deletions frontend/src/components/GoogleButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from "react";
import '../css/GoogleButton.css'

function GoogleButton({onclickFunction}) {
return (
<button type="button" onClick={onclickFunction} className="login-with-google-btn">
Sign in with Google
</button>
);
}

export default GoogleButton;
93 changes: 59 additions & 34 deletions frontend/src/components/NavBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,22 @@ import PersonIcon from "@mui/icons-material/Person";
import { onAuthStateChanged, signOut } from "firebase/auth";
import { auth } from "../services/firebase";
import { useEffect, useState } from "react";
import { getAllGenres } from "../services/api";
import GenresNavbar from "./GenresNavbar";

function NavBar() {
// TO store user info
const [user, setUser] = useState(null);

//Mouse effect for user
const [showMenu, setShowMenu] = useState(false);
// Mouse Effect on Genres
const [showGenres, setShowGenres] = useState(false);

// TO navigate
const navigate = useNavigate();

console.log(showGenres);
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
if (currentUser) {
Expand All @@ -31,51 +39,68 @@ function NavBar() {
const handleLogout = () => {
signOut(auth)
.then(() => {
navigate("/signin");
console.log("User logged out");
})
.catch((error) => {
console.error("Logour Error", error.message);
});
};
return (
<div className="navbar bg-gray-1 dark:bg-dark">
<div className="navbar-brand">
<Link to="/home">GitFlix</Link>
</div>
<div className="navbar-links">
<Link to="/favorites" className="nav-link">
Favorites
</Link>
<Link to="/about" className="nav-link">
About
</Link>
<div>
<Link
className="nav-link"
onMouseEnter={() => setShowMenu(true)}
onMouseLeave={() => setShowMenu(false)}
style={{ position: "relative" }}>
<ul>
<li>
<PersonIcon />
</li>
</ul>
{showMenu && user && (
<div className="dropdown-menu">
<p className="user-display-name">
{user && user ? user.displayName || user.email : "Guest"}
</p>
{user && (
<button className="logout-button" onClick={handleLogout}>
Logout
</button>
<>
<div className="navbar bg-gray-1 dark:bg-dark">
<div className="navbar-brand">
<Link to="/home">GitFlix</Link>
</div>
<div className="navbar-links">
{user && (
<>
<Link
className="nav-link"
onClick={() => setShowGenres(!showGenres)}>
Genres
</Link>
<Link to="/favorites" className="nav-link">
Favorites
</Link>
</>
)}

<Link to="/about" className="nav-link">
About
</Link>
<div>
{user && (
<Link
className="nav-link"
onMouseEnter={() => setShowMenu(true)}
onMouseLeave={() => setShowMenu(false)}
style={{ position: "relative" }}>
<ul>
<li>
<PersonIcon />
</li>
</ul>

{showMenu && user && (
<div className="dropdown-menu">
<p className="user-display-name">
{user && user ? user.displayName || user.email : "Guest"}
</p>
{user && (
<button className="logout-button" onClick={handleLogout}>
Logout
</button>
)}
</div>
)}
</div>
</Link>
)}
</Link>
</div>
</div>
</div>
</div>
{showGenres && <GenresNavbar />}
</>
);
}

Expand Down
44 changes: 44 additions & 0 deletions frontend/src/components/pages/ByGenreMovies.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import { getMoviesByGenre } from "../../services/api";
import MovieCard from "../MovieCard";

// Styling
import "../../css/ByGenreMovies.css"

function ByGenreMovies() {
// Getting genreId from UseParam through route we setup
const { genreId } = useParams();

// movie and loading state
const [loading, setLoading] = useState(true);
const [movies, setMovies] = useState([]);

useEffect(() => {
const fetchMovies = async () => {
setLoading(true);
const data = await getMoviesByGenre(genreId);
// console.log(data);
setMovies(data);
setLoading(false);
};

fetchMovies();
}, [genreId]);
console.log(genreId);
return (
<div>
{loading ? (
<p>Loading movies...</p>
) : (
<div className="movies-container">
{movies.map((movie) => (
<MovieCard key={movie.id} movie={movie} />
))}
</div>
)}
</div>
);
}

export default ByGenreMovies;
46 changes: 39 additions & 7 deletions frontend/src/components/pages/Login.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import React, { useState } from "react";
import { auth } from "../../services/firebase";
import { signInWithEmailAndPassword } from "firebase/auth";
import {
signInWithEmailAndPassword,
signInWithPopup,
GoogleAuthProvider,
} from "firebase/auth";

import { ToastContainer, toast } from "react-toastify";
import { Link, useNavigate } from "react-router-dom";
import GoogleButton from "../GoogleButton";

function Login() {
const navigate = useNavigate();
const [username, setUserName] = useState("");
const [password, setPassword] = useState("");

// LOGIN FUNCTION (HELPS TO SIGN IN WITH EMAIL AND PASSWORD)
const loginWithEmailPassword = async (e) => {
e.preventDefault();

Expand All @@ -32,7 +38,32 @@ function Login() {
}
}
};
// console.log(username, password);

const provider = new GoogleAuthProvider();

// LOGIN WITH GOOGLE
const handleGoogleSignIn = () => {
signInWithPopup(auth, provider)
.then((result) => {
const credential = GoogleAuthProvider.credentialFromResult(result);
const token = credential.accessToken;
// The signed-in user info.
const user = result.user;
navigate("/home");
})
.catch((error) => {
// Handle Errors here.
const errorCode = error.code;
const errorMessage = error.message;
// The email of the user's account used.
const email = error.customData.email;
// The AuthCredential type that was used.
const credential = GoogleAuthProvider.credentialFromError(error);
console.log(error);
toast.error(errorMessage);
});
};

return (
<section className="bg-gray-1 py-20 lg:py-[120px] dark:bg-dark">
<ToastContainer
Expand All @@ -51,11 +82,11 @@ function Login() {
<div className="container mx-auto">
<div className="-mx-4 flex flex-wrap">
<div className="w-full px-4">
<div className="relative mx-auto max-w-[525px] overflow-hidden rounded-lg bg-white px-10 py-8 text-center sm:px-12 md:px-[60px] dark:bg-dark-2">
<div className="relative flex flex-col gap-y-5 mx-auto max-w-[525px] overflow-hidden rounded-lg bg-white px-10 py-8 text-center sm:px-12 md:px-[60px] dark:bg-dark-2">
<div className="mb-5 text-center md:mb-5">
<a className="mx-auto inline-block max-w-[160px] text-2xl text-white">
<p className="mx-auto inline-block max-w-[160px] text-2xl text-white">
GitFlix
</a>
</p>
</div>
<form onSubmit={loginWithEmailPassword}>
<div className="mb-6">
Expand All @@ -76,21 +107,22 @@ function Login() {
className="w-full rounded-md border border-stroke bg-transparent px-5 py-3 text-base text-body-color outline-none focus:border-primary focus-visible:shadow-none dark:border-dark-3 dark:text-white"
/>
</div>
<div className="mb-10">
<div className="mb-0">
<input
type="submit"
value="Login"
className="w-full cursor-pointer rounded-md border border-primary bg-primary px-5 py-3 text-base font-medium text-white transition hover:bg-opacity-90"
/>
</div>
</form>
<GoogleButton onclickFunction={handleGoogleSignIn} />
<div className="flex flex-col justify-center items-center">
<a className="mb-2 inline-block text-base text-dark hover:text-primary hover:underline dark:text-white">
Forget Password?
</a>
<div>
<span className="text-base text-body-color dark:text-dark-6 pr-1.5">
Not a member yet?
Not a member yet?
</span>
<Link to={"/signUp"} className="text-primary hover:underline">
Sign Up
Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/pages/SingleMovie.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const SingleMovie = () => {
<p>
<strong>Overview: </strong> {movie.overview}
</p>

</div>
</div>
);
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/css/ByGenreMovies.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

.movies-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 20px;
padding: 20px;
}

Empty file.
Loading

0 comments on commit 30bf04e

Please sign in to comment.