Skip to content

Commit

Permalink
Merge pull request #68 from TravelMemories/Frontend
Browse files Browse the repository at this point in the history
Page navigation and basic log in/out
  • Loading branch information
dxrgrabowski authored Jan 6, 2024
2 parents 5152582 + 52a7317 commit 35cf8bf
Show file tree
Hide file tree
Showing 15 changed files with 286 additions and 75 deletions.
22 changes: 19 additions & 3 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,31 @@
import React from "react";
import Home from "./pages/Home";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import HomePage from "./pages/HomePage";
import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom";
import Navbar from "./components/navbar/Navbar";
import YourMemoriesPage from "./pages/YourMemoriesPage";
import PublicMemoriesPage from "./pages/PublicMemoriesPage";
import ProfilePage from "./pages/ProfilePage";

import { useUserContext } from "./context/UserContext";
import NewMemoryPage from "./pages/NewMemoryPage";

function App() {
const { isLoggedIn } = useUserContext();
return (
<div className="relative">
<BrowserRouter>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route
path="/"
element={isLoggedIn ? <NewMemoryPage /> : <HomePage />}
/>
{isLoggedIn && (
<Route path="/memories" element={<YourMemoriesPage />} />
)}
<Route path="/public-memories" element={<PublicMemoriesPage />} />
{isLoggedIn && <Route path="/profile" element={<ProfilePage />} />}
<Route path="*" element={<Navigate to="/" />} />
</Routes>
</BrowserRouter>
</div>
Expand Down
22 changes: 22 additions & 0 deletions frontend/src/components/navbar/LoginButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from "react";
import { motion } from "framer-motion";
import { useUserContext } from "../../context/UserContext";
function LoginButton() {
const { isLoggedIn, LogIn, LogOut } = useUserContext();
return (
<motion.button
className="bg-action-400 whitespace-nowrap px-4 py-1 rounded-2xl tracking-tight text-background-50 shadow-md hover:bg-action-500 transition-colors"
animate={{ scale: 1 }}
whileHover={{ scale: 1.03 }}
whileTap={{ scale: 1.01 }}
onClick={() => {
if (isLoggedIn) LogOut();
else LogIn();
}}
>
{isLoggedIn ? "Log out" : "Log in"}
</motion.button>
);
}

export default LoginButton;
155 changes: 95 additions & 60 deletions frontend/src/components/navbar/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { motion, useInView } from "framer-motion";
import { NavLink } from "react-router-dom";
import { RxHamburgerMenu } from "react-icons/rx";
import { GoX } from "react-icons/go";
import { useUserContext } from "../../context/UserContext";
import LoginButton from "./LoginButton";
import RegisterButton from "./RegisterButton";

function Navbar() {
//const [navbarButtons, setNavbarButtons] = useState<NavbarButtonProps[]>([
Expand All @@ -14,12 +17,8 @@ function Navbar() {
route: "/memories",
},
{
text: "Society",
route: "/society",
},
{
text: "Destinations",
route: "/destinations",
text: "Discover",
route: "/public-memories",
},
{
text: "Profile",
Expand All @@ -39,71 +38,107 @@ function Navbar() {
if (isMobileMenuOpen && !isInView) setIsMobileMenuOpen(false);
}, [isInView, isMobileMenuOpen]);

const { isLoggedIn } = useUserContext();

return (
<nav className="sticky flex items-center top-0 left-0 right-0 z-50 font-primary w-full border-b bg-white px-4 sm:px-6 lg:px-3 xl:px-6 py-4 sm:py-3">
<motion.div
animate={{ scale: 1 }}
whileHover={{
scale: 1.01,
}}
transition={{ duration: 0.2 }}
<nav className="sticky flex items-center top-0 left-0 right-0 z-50 font-primary w-full border-b text-primary-950 bg-background-50 py-4 sm:py-3">
<div
className={`flex items-center flex-grow ${
isLoggedIn ? "max-w-[80%]" : "max-w-[97%] sm:max-w-[80%]"
} mx-auto`}
>
{/* Travel memories logo */}
<motion.div
animate={{ scaleX: 1 }}
whileHover={{
scaleX: 1.01,
}}
transition={{ duration: 0.2 }}
>
<NavLink
to={"/"}
className="group flex justify-center items-center gap-2 lg:gap-4 cursor-pointer"
>
<SlGlobe className="text-2xl lg:text-4xl group-hover:rotate-12 transition-transform" />
<p className=" sm:text-lg lg:text-2xl font-bold">Travel Memories</p>
</NavLink>
</motion.div>
{/* New memory button */}
{/* {isLoggedIn && (
<NavLink
to={"/"}
className="hidden sm:flex justify-center items-center gap-2 xl:gap-4 cursor-pointer"
to={"/new-memory"}
className="absolute left-1/2 translate-x-[-50%]"
>
<SlGlobe className="text-2xl lg:text-3xl xl:text-4xl" />
<p className="text-lg lg:text-xl font-bold xl:text-2xl">
Travel Memories
</p>
<motion.div className="whitespace-nowrap text-xl text-center bg-action-400 text-background-50 font-bold py-2 px-8 rounded-full shadow-sm border border-background-100 origin-center transition cursor-pointer hover:scale-105 hover:bg-action-500 active:scale-100 sm:text-base xl:text-xl">
NEW MEMORY
</motion.div>
</NavLink>
</motion.div>
<NavLink
to={"/new-memory"}
className="absolute left-1/2 translate-x-[-50%]"
>
<motion.div className="whitespace-nowrap text-xl text-center bg-primary-400 text-white font-bold py-2 px-8 rounded-full shadow-sm border border-primary-200 origin-center transition cursor-pointer hover:scale-105 hover:bg-primary-500 active:scale-100 sm:text-base xl:text-xl">
NEW MEMORY
</motion.div>
</NavLink>
<ul className="hidden lg:flex gap-4 items-center justify-center w-auto ml-auto xl:gap-10 xl:text-lg">
{navbarButtons.map((button, index) => (
<NavbarButton key={index} text={button.text} route={button.route} />
))}
</ul>
<motion.button
ref={ref}
className="ml-auto text-3xl lg:hidden cursor-pointer"
whileHover={{ scaleY: 1.1 }}
onClick={toggleMobileMenu}
>
<RxHamburgerMenu />
</motion.button>
{isInView && isMobileMenuOpen && (
<motion.div className="absolute w-screen h-screen top-0 left-0 bg-black/40 z-50 overflow-hidden">
<motion.ul
initial={{ x: 500 }}
animate={{ x: 0 }}
transition={{ duration: 0.1 }}
className="absolute right-0 top-0 h-full w-1/2 bg-white shadow-md p-4 flex flex-col items-end text-2xl gap-4"
>
<motion.button
className="cursor-pointer text-4xl"
whileHover={{ scale: 1.1 }}
onClick={toggleMobileMenu}
>
<GoX />
</motion.button>
{navbarButtons.map((button, index) => (
)} */}
{/* Button list */}
<ul
className={`hidden lg:flex items-center justify-center w-auto ml-auto ${
isLoggedIn ? "gap-10" : "gap-6"
} text-lg`}
>
{/* Navigation buttons */}
{isLoggedIn &&
navbarButtons.map((button, index) => (
<NavbarButton
key={index}
text={button.text}
route={button.route}
/>
))}
</motion.ul>
</motion.div>
)}
<LoginButton />
{!isLoggedIn && <RegisterButton />}
</ul>
{!isLoggedIn && (
<div className="lg:hidden flex items-center justify-center ml-auto gap-2">
<LoginButton />
<RegisterButton />
</div>
)}
{/* Hamburger menu button */}
<motion.button
ref={ref}
className={`ml-auto text-3xl ${
isLoggedIn ? "lg:hidden" : "hidden"
} cursor-pointer`}
whileHover={{ scaleY: 1.1 }}
onClick={toggleMobileMenu}
>
<RxHamburgerMenu />
</motion.button>
{/* Hamburger menu */}
{isInView && isMobileMenuOpen && (
<motion.div className="absolute w-screen h-screen top-0 left-0 bg-black/40 z-50 overflow-hidden">
<motion.ul
initial={{ x: 500 }}
animate={{ x: 0 }}
transition={{ duration: 0.1 }}
className="absolute right-0 top-0 h-full w-1/2 bg-background-50 shadow-md p-4 flex flex-col items-end text-2xl gap-4 text-right"
>
<motion.button
className="cursor-pointer text-4xl"
whileHover={{ scale: 1.1 }}
onClick={toggleMobileMenu}
>
<GoX />
</motion.button>
{isLoggedIn &&
navbarButtons.map((button, index) => (
<NavbarButton
key={index}
text={button.text}
route={button.route}
/>
))}
<LoginButton />
{!isLoggedIn && <RegisterButton />}
</motion.ul>
</motion.div>
)}
</div>
</nav>
);
}
Expand Down
23 changes: 23 additions & 0 deletions frontend/src/components/navbar/RegisterButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from "react";
import { motion } from "framer-motion";
import { useUserContext } from "../../context/UserContext";

function RegisterButton() {
const { isLoggedIn, LogIn, LogOut } = useUserContext();
return (
<motion.button
className="bg-background-50 px-4 py-1 rounded-2xl tracking-tight text-primary-950 shadow-md hover:bg-background-100 transition-colors"
animate={{ scale: 1 }}
whileHover={{ scale: 1.03 }}
whileTap={{ scale: 1.01 }}
onClick={() => {
if (isLoggedIn) LogOut();
else LogIn();
}}
>
Register
</motion.button>
);
}

export default RegisterButton;
31 changes: 31 additions & 0 deletions frontend/src/context/UserContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React, { ReactNode, createContext, useContext, useState } from "react";

interface UserContextProviderProps {
children: ReactNode;
}
interface UserContextProps {
isLoggedIn: boolean;
LogIn: () => void;
LogOut: () => void;
}
const UserContext = createContext({} as UserContextProps);

export function useUserContext() {
return useContext(UserContext);
}

export function UserContextProvider({ children }: UserContextProviderProps) {
const [isLoggedIn, setIsLoggedIn] = useState(false);

const LogIn = () => {
setIsLoggedIn(true);
};
const LogOut = () => {
setIsLoggedIn(false);
};
return (
<UserContext.Provider value={{ isLoggedIn, LogIn, LogOut }}>
{children}
</UserContext.Provider>
);
}
2 changes: 1 addition & 1 deletion frontend/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
@tailwind utilities;

body {
@apply bg-primary-200 font-primary;
@apply bg-primary-50 font-primary;
}
5 changes: 4 additions & 1 deletion frontend/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { UserContextProvider } from "./context/UserContext";

const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<React.StrictMode>
<App />
<UserContextProvider>
<App />
</UserContextProvider>
</React.StrictMode>
);
1 change: 1 addition & 0 deletions frontend/src/model/UserData.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export interface UserData {}
10 changes: 5 additions & 5 deletions frontend/src/pages/Home.tsx → frontend/src/pages/HomePage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react";
import { motion } from "framer-motion";

function Home() {
function HomePage() {
const transitionDelay = 0.7;
const buttonAnimationVariants = {
initial: { scale: 0 },
Expand All @@ -26,7 +26,7 @@ function Home() {
Capture Your Travel Memories
</motion.h1>
<motion.p
className="text-xl sm:text-2xl tracking-normal text-center mx-auto text-black/80 cursor-default sm:max-w-[70%] xl:max-w-[50%]"
className="text-xl sm:text-2xl tracking-normal text-center mx-auto text-primary-950/80 cursor-default sm:max-w-[70%] xl:max-w-[50%]"
variants={heroAnimationVariants}
initial="initial"
animate="animate"
Expand All @@ -44,7 +44,7 @@ function Home() {
transition={{ delay: 3 * transitionDelay, duration: 0.4 }}
>
<motion.button
className="bg-primary-500 px-10 py-4 text-xl rounded-2xl tracking-tight font-bold text-white shadow-md"
className="bg-action-400 px-10 py-4 text-xl rounded-2xl tracking-tight font-bold text-background-50 shadow-md"
variants={buttonAnimationVariants}
initial="initial"
animate="animate"
Expand All @@ -54,7 +54,7 @@ function Home() {
Get Started
</motion.button>
<motion.button
className=" bg-white px-10 py-4 text-xl rounded-2xl tracking-tight font-bold text-black shadow-md"
className=" bg-background-50 px-10 py-4 text-xl rounded-2xl tracking-tight font-bold text-primary-950 shadow-md"
variants={buttonAnimationVariants}
initial="initial"
animate="animate"
Expand All @@ -68,4 +68,4 @@ function Home() {
);
}

export default Home;
export default HomePage;
7 changes: 7 additions & 0 deletions frontend/src/pages/LoginPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from "react";

function LoginPage() {
return <div>LoginPage</div>;
}

export default LoginPage;
7 changes: 7 additions & 0 deletions frontend/src/pages/NewMemoryPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from "react";

function NewMemoryPage() {
return <div>NewMemoryPage</div>;
}

export default NewMemoryPage;
7 changes: 7 additions & 0 deletions frontend/src/pages/ProfilePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from "react";

function ProfilePage() {
return <div>ProfilePage</div>;
}

export default ProfilePage;
Loading

0 comments on commit 35cf8bf

Please sign in to comment.