Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 2 additions & 15 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion client/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ScanAFlower from './pages/scanAFlower';
import FlowerGallery from './pages/flowerGallery';
import DiscoverPage from './pages/discoverPage';
import IndividualFlowerPage from './pages/individualFlowerPage';
import AuthPage from './pages/AuthPage';
import NavBar from './components/NavBar';
import Footer from './components/Footer';

Expand All @@ -28,7 +29,8 @@ const App = () => {
{ path: '/dictionary', element: <FlowerDictionary /> },
{ path: '/scan', element: <ScanAFlower /> },
{ path: '/gallery', element: <FlowerGallery /> },
{ path: '/gallery/:flowerId', element: <IndividualFlowerPage flowers={flowers} /> }
{ path: '/gallery/:flowerId', element: <IndividualFlowerPage flowers={flowers} /> },
{ path: '/login', element: <AuthPage /> }

]);

Expand Down
87 changes: 87 additions & 0 deletions client/src/Pages_css/AuthPage.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
.auth-page {
min-height: 70vh;
display: flex;
justify-content: center;
align-items: center;
padding: 40px 16px;
}

.auth-card {
width: 100%;
max-width: 420px;
background-color: #ffffff;
border: 1px solid #d9d9d9;
border-radius: 12px;
padding: 28px;
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
}

.auth-card h1 {
margin: 0 0 8px;
color: #373d3f;
text-align: center;
}

.auth-subtitle {
text-align: center;
color: #555;
margin-bottom: 24px;
}

.auth-form {
display: flex;
flex-direction: column;
gap: 12px;
}

.auth-form label {
font-weight: 600;
color: #373d3f;
}

.auth-form input {
padding: 12px;
border: 1px solid #bdbdbd;
border-radius: 8px;
font-size: 1rem;
}

.auth-form button {
margin-top: 12px;
padding: 12px;
border: none;
border-radius: 8px;
background-color: #373d3f;
color: white;
font-size: 1rem;
cursor: pointer;
}

.auth-form button:hover {
background-color: #4f5a5d;
}

.auth-form button:disabled {
opacity: 0.7;
cursor: not-allowed;
}

.auth-message {
color: #b00020;
font-size: 0.9rem;
margin: 4px 0;
}

.auth-toggle {
width: 100%;
margin-top: 18px;
background: none;
border: none;
color: #2a7abf;
cursor: pointer;
font-size: 0.95rem;
}

.auth-toggle:hover {
text-decoration: underline;
}
15 changes: 15 additions & 0 deletions client/src/components/NavBar.css
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,18 @@
padding: 4px;
line-height: 1;
}
.navbar-auth-button {
font-family: Avenir, "Century Gothic", sans-serif;
font-size: 0.95rem;
color: #373D3F;
background: none;
border: none;
cursor: pointer;
padding: 4px 2px;
border-bottom: 2px solid transparent;
}

.navbar-auth-button:hover {
color: #2a7abf;
border-bottom-color: #2a7abf;
}
39 changes: 37 additions & 2 deletions client/src/components/NavBar.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
import { NavLink, useNavigate } from 'react-router';
import { useState } from 'react';
import { useEffect, useState } from 'react';
import './NavBar.css';

const NavBar = () => {
const [query, setQuery] = useState('');
const [user, setUser] = useState(null);
const navigate = useNavigate();

useEffect(() => {
const loadUser = () => {
const savedUser = localStorage.getItem('flowerhuntUser');
setUser(savedUser ? JSON.parse(savedUser) : null);
};

loadUser();

window.addEventListener('authChanged', loadUser);

return () => {
window.removeEventListener('authChanged', loadUser);
};
}, []);

const handleSearch = (e) => {
e.preventDefault();
if (query.trim()) {
Expand All @@ -14,17 +30,36 @@ const NavBar = () => {
}
};

const handleLogout = () => {
localStorage.removeItem('flowerhuntToken');
localStorage.removeItem('flowerhuntUser');
setUser(null);
navigate('/');
};

return (
<nav className="navbar">
<NavLink to="/" className="navbar-brand">
🌸 FlowerHunt
</NavLink>

<ul className="navbar-links">
<li><NavLink to="/discover">Discover Flowers</NavLink></li>
<li><NavLink to="/dictionary">Flower Dictionary</NavLink></li>
<li><NavLink to="/scan">Scan-A-Flower</NavLink></li>
<li><NavLink to="/gallery">Flower Gallery</NavLink></li>

{user ? (
<li>
<button className="navbar-auth-button" onClick={handleLogout}>
Logout
</button>
</li>
) : (
<li><NavLink to="/login">Login</NavLink></li>
)}
</ul>

<form className="navbar-search" onSubmit={handleSearch}>
<input
type="text"
Expand All @@ -40,4 +75,4 @@ const NavBar = () => {
);
};

export default NavBar;
export default NavBar;
Loading