Skip to content

Commit

Permalink
Merge pull request #28 from Matsadura/front-end
Browse files Browse the repository at this point in the history
Front end
  • Loading branch information
Badr-Annabi authored Sep 15, 2024
2 parents cf3014e + 2a6555b commit 9843e8b
Show file tree
Hide file tree
Showing 27 changed files with 984 additions and 323 deletions.
29 changes: 16 additions & 13 deletions client/index.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="https://cdn-icons-png.flaticon.com/128/14090/14090460.png" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Gothic+A1:wght@400;500;700&display=swap" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Clinema</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>

<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Gothic+A1:wght@400;500;700&display=swap" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Clinema</title>
</head>

<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>

</html>
Binary file added client/public/favicon.ico
Binary file not shown.
14 changes: 0 additions & 14 deletions client/src/App.jsx

This file was deleted.

15 changes: 15 additions & 0 deletions client/src/components/Context.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createContext, useState } from "react";
import React from "react";

export const DataContext = createContext();

export const ContextProvider = ({ children }) => {
const [isAuthenticated, setAuth] = useState(false);
const [user, setUser] = useState(null);

return (
<DataContext.Provider value={{ setAuth, setUser, isAuthenticated, user }}>
{children}
</DataContext.Provider>
);
};
1 change: 0 additions & 1 deletion client/src/components/LocationComponent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const LocationComponent = () => {
axios.get(`http://localhost:5000/api/weather?lat=${latitude}&lon=${longitude}`)
.then(response => {
setWeatherData(response.data);
console.log("Weather data:", response.data);
})
.catch(err => {
console.error("Error fetching weather data:", err);
Expand Down
17 changes: 13 additions & 4 deletions client/src/components/MovieList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const MovieList = () => {
const [detailedMovies, setDetailedMovies] = useState({});
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
// const navigate = useNavigate();
const navigate = useNavigate();


// Fetch movie data based on weather location
Expand All @@ -26,7 +26,6 @@ const MovieList = () => {

if (response.data && Array.isArray(response.data.suggestions)) {
setMovies(response.data.suggestions);
// navigate('/AllMovies', {state: { suggestions }});
fetchDetailedMovies(response.data.suggestions);
} else {
throw new Error("Unexpected response structure");
Expand Down Expand Up @@ -77,15 +76,25 @@ const MovieList = () => {
}
};

const handleSeeAllClick = () => {
if (movies.length > 0) {
navigate('/AllMovies', { state: { suggestions: movies } });
} else {
console.log('No movies available');
}
}

return (
<div className="h-screen flex flex-col space-y-4 p-4">
{loading && <p>Loading movie information...</p>}
{error && <p className="text-red-500">{error}</p>}
<h1 className="flex justify-center text-3xl text-white font-semibold mt-4">Your Movies Based On Your Local Weather</h1>
<div className="flex justify-end">
<button
className="mb-6 group group-hover:before:duration-500 group-hover:after:duration-500 after:duration-500 hover:border-rose-300 hover:before:[box-shadow:_20px_20px_20px_30px_#a21caf] duration-500 before:duration-500 hover:duration-500 underline underline-offset-2 hover:after:-right-8 hover:before:right-12 hover:before:-bottom-8 hover:before:blur hover:underline hover:underline-offset-4 origin-left hover:decoration-2 hover:text-rose-300 relative bg-neutral-800 h-10 w-40 border text-left p-3 text-gray-50 text-base font-bold rounded-lg overflow-hidden before:absolute before:w-12 before:h-12 before:content[''] before:right-1 before:top-1 before:z-10 before:bg-violet-500 before:rounded-full before:blur-lg after:absolute after:z-10 after:w-20 after:h-20 after:content[''] after:bg-rose-300 after:right-8 after:top-3 after:rounded-full after:blur-lg">
See All
className="mb-6 group group-hover:before:duration-500 group-hover:after:duration-500 after:duration-500 hover:border-rose-300 hover:before:[box-shadow:_20px_20px_20px_30px_#a21caf] duration-500 before:duration-500 hover:duration-500 underline underline-offset-2 hover:after:-right-8 hover:before:right-12 hover:before:-bottom-8 hover:before:blur hover:underline hover:underline-offset-4 origin-left hover:decoration-2 hover:text-rose-300 relative bg-neutral-800 h-10 w-40 border text-left p-3 text-gray-50 text-base font-bold rounded-lg overflow-hidden before:absolute before:w-12 before:h-12 before:content[''] before:right-1 before:top-1 before:z-10 before:bg-violet-500 before:rounded-full before:blur-lg after:absolute after:z-10 after:w-20 after:h-20 after:content[''] after:bg-rose-300 after:right-8 after:top-3 after:rounded-full after:blur-lg"
onClick={handleSeeAllClick}
>
Show All
</button>
</div>
{!loading && !error && (
Expand Down
103 changes: 59 additions & 44 deletions client/src/components/Navbar.jsx
Original file line number Diff line number Diff line change
@@ -1,56 +1,71 @@
import {useState} from "react";
import { useContext, useState } from "react";
import { CiBookmark } from "react-icons/ci";
import { FaUserCircle } from "react-icons/fa";
import clinema from "../images/Clinema.png"; // Adjust this depending on the location of Navbar.jsx


import { DataContext } from "./Context";
import { useNavigate } from "react-router-dom";

const Navbar = () => {
const [activeLink, setActiveLink] = useState("Home");
const [activeLink, setActiveLink] = useState("Home");
const { user } = useContext(DataContext);
const navigate = useNavigate();

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

return (
<nav className="bg-secondary-dark p-4 flex justify-between items-center shadow-white shadow-b-xl">
{/* Left side - Logo */}
<div className="text-white text-lg font-bold">
<img
src={clinema}
alt="Clinema"
className="w-32 h-auto"
/>
</div>
<div className="flex space-x-4 items-center">
<a href="#"
onClick={() => handleClick("Home")}
className={`text-gray-300 hover:text-white ${activeLink === "Home" ? "text-white" : ""}`}
>
Home
</a>
<a
href="/about"
onClick={() => handleClick("About us")}
className={`text-gray-300 hover:text-white ${activeLink === "About us" ? "text-white" : ""}`}
>
About us
</a>
return (
<nav className="bg-secondary-dark p-4 flex justify-between items-center shadow-white shadow-b-xl">
{/* Left side - Logo */}
<div className="text-white text-lg font-bold">
<img src={clinema} alt="Clinema" className="w-32 h-auto" />
</div>
<div className="flex space-x-4 items-center">
<a
href="#"
onClick={() => handleClick("Home")}
className={`text-gray-300 hover:text-white ${
activeLink === "Home" ? "text-white" : ""
}`}
>
Home
</a>
<a
href="/about"
onClick={() => handleClick("About us")}
className={`text-gray-300 hover:text-white ${
activeLink === "About us" ? "text-white" : ""
}`}
>
About us
</a>
</div>
{/*Right side - Home*/}
<div className="flex space-x-4 items-center text-white">
{/*<div className="relative p-2 hover:bg-secondary-light rounded-full">*/}
{/* <CiHome className="text-2xl text-green-400"/>*/}
{/*</div>*/}
{user ? (
<>
<div className="p-2 hover:bg-secondary-light rounded-full">
<CiBookmark className="text-2xl" />
</div>
{/*Right side - Home*/}
<div className="flex space-x-4 items-center text-white">
{/*<div className="relative p-2 hover:bg-secondary-light rounded-full">*/}
{/* <CiHome className="text-2xl text-green-400"/>*/}
{/*</div>*/}
<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="p-2 hover:bg-secondary-light rounded-full">
<FaUserCircle className="text-2xl" />
</div>
</nav>
);
</>
) : (
<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>
</nav>
);
};

export default Navbar;
40 changes: 40 additions & 0 deletions client/src/components/PrivateRoute.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, { useEffect, useState } from "react";
import { DataContext } from "./Context";
import { useContext } from "react";
import { Navigate } from "react-router-dom";
import { request } from "../tools/requestModule";

export const PrivateRoute = ({ open = false, element: Element }) => {
const [isLoading, setIsLoading] = useState(true);
const { setAuth, setUser, isAuthenticated } = useContext(DataContext);
const token = localStorage.getItem("_token");
const headers = {
headers: {
Authorization: `Bearer ${token}`,
},
};

useEffect(() => {
request("/auth_validate", headers)
.then((res) => {
if (res.status === 200) {
setUser(res.data);
setAuth(true);
} else {
setAuth(false);
setUser(null);
}
})
.finally(() => {
setIsLoading(false);
});
}, []);

if (isLoading) return null;

if (open) {
return <Element />;
}

return isAuthenticated ? <Element /> : <Navigate to="/auth" />;
};
Loading

0 comments on commit 9843e8b

Please sign in to comment.