Skip to content

Commit

Permalink
Merge pull request #29 from Matsadura/front-end
Browse files Browse the repository at this point in the history
Badr's FRONT
  • Loading branch information
Matsadura authored Sep 16, 2024
2 parents 9843e8b + a29fa84 commit 8a313d1
Show file tree
Hide file tree
Showing 11 changed files with 475 additions and 181 deletions.
110 changes: 104 additions & 6 deletions client/src/components/MovieCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,102 @@ import { TiHeartFullOutline, TiBookmark, TiEject, TiArrowRight, TiStarFullOutlin
import { LuClock } from "react-icons/lu";
import { MdDateRange } from "react-icons/md";
import { MdLanguage } from "react-icons/md";
import { useState } from 'react';
import {useState, useCallback, useEffect} from 'react';
import axios from 'axios';

export default function MovieCard({userId, movie_id, title, poster, year, rate, popularity, trailer, lang }) {
const [liked, setLiked] = useState(false)
const [save, setSave] = useState(false);
const [order, setOrder] = useState(false);
const [userData, setUserData] = useState({});

const handleLike = useCallback(async () => {
setLiked(prevState => !prevState);
await toggleLike(userId, movie_id, 'liked');
}, [userId, movie_id]);

const handleSave = useCallback(async () => {
setSave(prevState => !prevState);
await toggleSave(userId, movie_id, 'save');
}, [userId, movie_id]);

const handleOrder = useCallback(async () => {
setOrder(prevState => !prevState);
// Implement order logic here
}, []);

const toggleLike = async (userId, movie_id, liked) => {
try {
const apiUrl = process.env.REACT_APP_API_URL;
const token = localStorage.getItem('_token');
const dataToSend = {
user_id: userId,
movie_id: movie_id,
like: liked
};

if (token) {
const response = await axios.post(`${apiUrl}/${userId}/liked`, dataToSend, {
headers: {
Authorization: `Bearer ${token}`,
}
});
console.log("Like response:", response.data);
}
} catch (error) {
console.error("Error toggling like:", error.response?.data || error.message);
}
};

const toggleSave = async (userId, movie_id, save) => {
try {
const apiUrl = process.env.REACT_APP_API_URL;
const token = localStorage.getItem('_token');
const dataToSend = {
user_id: userId,
movie_id: movie_id,
save: save
};

if (token) {
const response = await axios.post(`${apiUrl}/${userId}/save`, dataToSend, {
headers: {
Authorization: `Bearer ${token}`,
}
});
console.log("Save response:", response.data);
}
} catch (error) {
console.error("Error toggling save:", error.response?.data || error.message);
}
};



// const toggleUserMovie = async (userId, movie_id, action) => {
// try {
// const apiUrl = process.env.REACT_APP_API_URL;
// const token = localStorage.getItem('_token');
// const dataToSend = {
// user_id: userId,
// movie_id: movie_id,
// save: action === true ? save : false,
// like: action === true ? liked : false
// };
//
// if (token) {
// const response = await axios.post(`${apiUrl}/${userId}/${action}`, dataToSend, {
// headers: {
// Authorization: `Bearer ${token}`,
// }
// });
// }
// console.log("data", dataToSend);
// } catch (error) {
// console.error(error.response?.data || error.message);
// }
// };

export default function MovieCard({ title, poster, year, rate, popularity, trailer, lang }) {
const [like, setLike] = useState(false);


return <div className='flex justify-start ml-5 mt-5 md:flex-row flex-col md:h-96 h-fit'>
Expand Down Expand Up @@ -60,12 +152,18 @@ export default function MovieCard({ title, poster, year, rate, popularity, trail
{/* This is the buttons side*/}
<div className='bg-secondary rounded-3xl flex flex-col md:h-96 text-white'>
<div className='p-4 flex justify-center gap-4 rounded-3xl bg-secondary'>
<button className={`rounded-2xl ${like ? 'text-red-400' : ''} text-4xl bg-secondary-light p-4 hover:bg-primary hover:shadow-sm hover:shadow-secondary-lighter`} onClick={() => setLike(!like)}><TiHeartFullOutline /></button>
<button className="rounded-2xl text-4xl bg-secondary-light p-4 hover:bg-primary hover:shadow-sm hover:shadow-secondary-lighter"><TiBookmark /></button>
<button
onClick={handleLike}
className={`rounded-2xl ${liked ? 'text-red-400' : ''} text-4xl bg-secondary-light p-4 hover:bg-primary hover:shadow-sm hover:shadow-secondary-lighter`}><TiHeartFullOutline /></button>
<button
onClick={handleSave}
className="rounded-2xl text-4xl bg-secondary-light p-4 hover:bg-primary hover:shadow-sm hover:shadow-secondary-lighter"><TiBookmark /></button>
<button className="rounded-2xl text-4xl bg-secondary-light p-4 hover:bg-primary hover:shadow-sm hover:shadow-secondary-lighter"><TiEject /></button>
</div>
{/* This will be hidden in the movile devices */}
<div className='pb-10 bg-secondary-light rounded-3xl rounded-l-none h-full items-end justify-center hidden md:flex'>
<div
onClick={handleOrder}
className='pb-10 bg-secondary-light rounded-3xl rounded-l-none h-full items-end justify-center hidden md:flex'>
<a href={trailer} className='text-white font-bold text-2xl p-2 px-4 flex justify-center items-center bg-primary hover:bg-green-700 rounded-xl'>Watch trailer <TiArrowRight /></a>
</div>
</div>
Expand Down
94 changes: 83 additions & 11 deletions client/src/components/Navbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,35 @@ import { useNavigate } from "react-router-dom";
const Navbar = () => {
const [activeLink, setActiveLink] = useState("Home");
const { user } = useContext(DataContext);
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const navigate = useNavigate();


const handleClick = (link) => {
setActiveLink(link);
};


const handlePopoverToggle = () => {
setIsPopoverOpen(!isPopoverOpen);
};
const handleLogout = () => {
localStorage.removeItem('_token');
window.location.href = '/';
};
const handleProfileClick = () => {
// Navigate to your profile page
navigate('/users/profile');
};
const handleLikedMoviesClick = () => {
// Navigate to your liked movies page
navigate('/liked-movies');
};
const handleSavedMoviesClick = () => {
// Navigate to your saved movies page
navigate('/saved-movies');
};

return (
<nav className="bg-secondary-dark p-4 flex justify-between items-center shadow-white shadow-b-xl">
{/* Left side - Logo */}
Expand All @@ -22,7 +45,7 @@ const Navbar = () => {
</div>
<div className="flex space-x-4 items-center">
<a
href="#"
href="/"
onClick={() => handleClick("Home")}
className={`text-gray-300 hover:text-white ${
activeLink === "Home" ? "text-white" : ""
Expand Down Expand Up @@ -50,18 +73,67 @@ const Navbar = () => {
<div className="p-2 hover:bg-secondary-light rounded-full">
<CiBookmark className="text-2xl" />
</div>
<div className="p-2 hover:bg-secondary-light rounded-full">
<FaUserCircle className="text-2xl" />
</div>
<div className="relative">
<button
className="p-2 hover:bg-secondary-light rounded-full"
onClick={handlePopoverToggle}
>
<FaUserCircle className="text-2xl"/>
</button>
{(isPopoverOpen || !isPopoverOpen) && (
<div
className={`absolute z-30 text-gray-700 right-0 top-full mt-2 bg-white rounded-lg shadow-md w-48 ${isPopoverOpen ? 'slide-down-animation' : 'slide-up-animation'}`}
>
{isPopoverOpen && (
<ul className="list-none p-2">
<li
className="hover:bg-gray-100 p-2 rounded-md cursor-pointer"
onClick={handleProfileClick}
>
Profile
</li>
<li
className="hover:bg-gray-100 p-2 rounded-md cursor-pointer"
onClick={handleLikedMoviesClick}
>
Liked Movies
</li>
<li
className="hover:bg-gray-100 p-2 rounded-md cursor-pointer"
onClick={handleSavedMoviesClick}
>
Saved Movies
</li>
<li
className="hover:bg-gray-100 p-2 rounded-md cursor-pointer"
onClick={handleLogout}
>
Logout
</li>
</ul>
)}
</div>
)}
</div>
</>
) : (
<button
onClick={() => navigate("/auth")}
className="p-2 hover:bg-secondary-light rounded-full
font-bold w-20 bg-indigo-700 text-black"
>
login
</button>
<div className="flex gap-3">
<button
onClick={() => navigate("/auth")}
className="p-2 text-white hover:text-black bg-transparent hover:bg-primary border-2 border-white transition-all ease-in-out duration-500 rounded-full
font-bold w-20 bg-indigo-700"
>
Login
</button>
<button
onClick={() => navigate("/auth")}
className="p-2 text-white hover:text-black bg-transparent hover:bg-primary border-2 border-white transition-all ease-in-out duration-500 rounded-full
font-bold w-20 bg-indigo-700"
>
Register
</button>
</div>

)}
</div>
</nav>
Expand Down
3 changes: 3 additions & 0 deletions client/src/components/PrivateRoute.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export const PrivateRoute = ({ open = false, element: Element }) => {
const [isLoading, setIsLoading] = useState(true);
const { setAuth, setUser, isAuthenticated } = useContext(DataContext);
const token = localStorage.getItem("_token");
if (!token && open) {
return <Element/>
}
const headers = {
headers: {
Authorization: `Bearer ${token}`,
Expand Down
30 changes: 30 additions & 0 deletions client/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,34 @@ body {
scrollbar-width: none;
-ms-overflow-style: none;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

@keyframes slideUp {
from {
opacity: 1;
transform: translateY(0px);
}
to {
opacity: 0;
transform: translateY(-10px);
}
}

.slide-down-animation {
animation: slideDown 1s ease-in-out forwards;
}

.slide-up-animation {
animation: slideUp 1s ease-in-out forwards;
}


8 changes: 5 additions & 3 deletions client/src/main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ContextProvider } from "./components/Context.jsx";
import { PrivateRoute } from "./components/PrivateRoute.jsx";
import AuthPage from "./scenes/AuthPage.jsx";
import About from "./scenes/About.jsx";
import UserProfile from "./scenes/UserProfile.jsx";

createRoot(document.getElementById("root")).render(
// <App />
Expand All @@ -17,9 +18,10 @@ createRoot(document.getElementById("root")).render(
path="/"
element={<PrivateRoute open={true} element={HomePage} />}
/>
<Route path="/AllMovies" element={<AllMoviesPage />} />
<Route path="/auth" element={<AuthPage />} />
<Route path="/about" element={<About />} />
<Route path="/AllMovies" element={<PrivateRoute open={true} element={AllMoviesPage} />} />
<Route path="/auth" element={<AuthPage />} />
<Route path="/users/profile" element={<PrivateRoute element={UserProfile} />} />
<Route path="/about" element={<About />} />
</Routes>
</Router>
</ContextProvider>
Expand Down
Loading

0 comments on commit 8a313d1

Please sign in to comment.