From 74e6259e6fe8dfb4f93139f15f5f8997d7652773 Mon Sep 17 00:00:00 2001 From: CMolinaBetancourt Date: Wed, 29 Oct 2025 13:59:54 -0700 Subject: [PATCH 1/3] feat/footer --- src/components/Footer.jsx | 149 ++++++++++++++++++--------- src/components/MobileMenu.jsx | 62 +++++++++++ src/components/Navbar.jsx | 187 +++++++++++++++++++++++++++------- src/pages/Login.jsx | 79 +++++++++++++- 4 files changed, 386 insertions(+), 91 deletions(-) create mode 100644 src/components/MobileMenu.jsx diff --git a/src/components/Footer.jsx b/src/components/Footer.jsx index 6aacf3b..e66a8ed 100644 --- a/src/components/Footer.jsx +++ b/src/components/Footer.jsx @@ -1,7 +1,8 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import { Link } from 'react-router-dom'; -const links = [ +// Links logged out grid +const loggedOutLinks = [ { id: 'home', text: 'Home', href: '/' }, { id: 'dashboard', text: 'Dashboard', href: '/dashboard' }, { id: 'privacy-policy', text: 'Privacy Policy', href: '/privacy-policy' }, @@ -14,67 +15,119 @@ const links = [ { id: 'onboarding', text: 'Onboarding', href: '/onboarding' }, ]; +// Links logged in +const loggedInLinks = [ + { id: 'home', text: 'Home', href: '/' }, + { id: 'privacy-policy', text: 'Privacy Policy', href: '/privacy-policy' }, + { + id: 'terms-of-service', + text: 'Terms of Service', + href: '/terms-of-service', + }, +]; + const Footer = () => { - const getLinkGridClasses = (id) => { + const [isLoggedIn, setIsLoggedIn] = useState( + !!localStorage.getItem('authToken') + ); + + useEffect(() => { + const checkAuth = () => { + setIsLoggedIn(!!localStorage.getItem('authToken')); + }; + + window.addEventListener('storage', checkAuth); + checkAuth(); + + return () => { + window.removeEventListener('storage', checkAuth); + }; + }, []); + + const getLinkClasses = (isLoggedIn) => + `focus:outline-none focus:ring-2 rounded-lg px-2 py-1 transition-colors whitespace-nowrap ${ + isLoggedIn + ? `font-[Poppins] text-xl font-medium text-[#1E1E1E] leading-normal hover:font-bold focus:ring-persianblue ` + : 'font-medium text-xl text-[#1e1e1e] hover:font-bold focus:ring-persianblue' + }`; + + // Grid logged out state + const getLoggedOutGridClasses = (id) => { switch (id) { case 'home': - return 'row-start-1 col-start-1'; + return 'lg:row-start-1 lg:col-start-1'; case 'dashboard': - return 'row-start-1 col-start-2'; + return 'lg:row-start-1 lg:col-start-2'; case 'privacy-policy': - return 'row-start-2 col-start-1'; + return 'lg:row-start-2 lg:col-start-1'; case 'sign-up': - return 'row-start-2 col-start-2'; + return 'lg:row-start-2 lg:col-start-2'; case 'terms-of-service': - return 'row-start-3 col-start-1'; + return 'lg:row-start-3 lg:col-start-1'; default: return ''; } }; return ( - ); }; diff --git a/src/components/MobileMenu.jsx b/src/components/MobileMenu.jsx new file mode 100644 index 0000000..a8dc8c7 --- /dev/null +++ b/src/components/MobileMenu.jsx @@ -0,0 +1,62 @@ +// react +import React from 'react'; +import { AiOutlineClose } from 'react-icons/ai'; +import { RiLayoutHorizontalFill, RiUser3Fill } from 'react-icons/ri'; +import { PiListBulletsFill } from 'react-icons/pi'; + +const MobileMenu = ({ isOpen, toggleMenu }) => { + const navLinks = [ + { name: 'Dashboard', href: '/Dashboard', icon: PiListBulletsFill }, + { + name: 'Detox Challenge', + href: '/DetoxChallenge', + icon: RiLayoutHorizontalFill, + }, + { name: 'Profile', href: '/Profile', icon: RiUser3Fill }, + ]; + + return ( + <> + {/* Side Menu*/} + + + ); +}; + +export default MobileMenu; \ No newline at end of file diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx index b6c8654..8333a0d 100644 --- a/src/components/Navbar.jsx +++ b/src/components/Navbar.jsx @@ -1,52 +1,161 @@ -// react +//react +import React, { useState, useEffect } from 'react'; import { Link } from 'react-router-dom'; -const navbarClass = ` - flex items-center justify-center cursor-pointer transition-all duration-300 ease-in-out - h-14 w-32 md:w-[220px] px-4 md:px-[58px] py-[8px] rounded-[10px] - text-stone-900 text-2xl font-normal font-playfair - bg-transparent - border-4 border-transparent`; +//icons +import { MdOutlineLogin } from 'react-icons/md'; +import { HiMenu } from 'react-icons/hi'; -const Navbar = () => { - return ( -
- - Skip to main content - - -
- - Healie - +//components +import MobileMenu from './MobileMenu'; + +function Navbar() { + const [isMenuOpen, setIsMenuOpen] = useState(false); // mobile menu state + const [isAuthenticated, setIsAuthenticated] = useState(false); // user authentication state + + // check authentication from localstorage + useEffect(() => { + const checkAuth = () => { + const token = localStorage.getItem('authToken'); + setIsAuthenticated(!!token); + }; + checkAuth(); + window.addEventListener('storage', checkAuth); + return () => window.removeEventListener('storage', checkAuth); + }, []); - -
-
+ + +
{ + if (e.key === 'Enter' || e.key === ' ') { + handleLogout(); + } + }} + className="flex justify-start items-center gap-3 cursor-pointer text-stone-900 text-base font-normal font-playfair hover:font-bold focus:outline-none focus:ring-2 focus:ring-persianblue rounded-[5px] p-1 transition-all duration-300 ease-in-out" + role="button" + tabIndex="0" + aria-label="Log out of your account and go to home page" + > + + Log Out + + {/* logout icon */} +
+ + + + ); -}; +} export default Navbar; \ No newline at end of file diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx index f82b779..c41738d 100644 --- a/src/pages/Login.jsx +++ b/src/pages/Login.jsx @@ -1,9 +1,80 @@ +// Login.jsx +import React, { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import Navbar from '../components/Navbar'; +import Footer from '../components/Footer'; + function Login() { + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const navigate = useNavigate(); + + const handleSubmit = (e) => { + e.preventDefault(); + + // Simular login exitoso (sin validación real) + localStorage.setItem('authToken', 'fake-token-123'); + + // Disparar evento para que Navbar y Footer actualicen + window.dispatchEvent(new Event('storage')); + + // Redirigir al dashboard + navigate('/dashboard'); + }; + return ( -
-

Login Page! 🎉

-
+ <> + +
+
+

+ Log In +

+
+
+ + setEmail(e.target.value)} + className="w-full px-4 py-2 border border-stone-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-persianblue" + required + /> +
+
+ + setPassword(e.target.value)} + className="w-full px-4 py-2 border border-stone-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-persianblue" + required + /> +
+ +
+

+ Don't have an account?{' '} + + Sign Up + +

+
+
+