Skip to content
Open
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
94 changes: 83 additions & 11 deletions frontend/src/components/Navbar.jsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,40 @@

import { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { PlusIcon, Sun, Moon, LogOut } from "lucide-react";
import { PlusIcon, Sun, Moon, LogOut, X } from "lucide-react";
import { useAuth } from "../context/AuthContext";
import { useTheme } from "../context/ThemeContext";

const Navbar = () => {
const { user, logout } = useAuth();
const { theme, toggleTheme } = useTheme();

const [showLogoutConfirm, setShowLogoutConfirm] = useState(false);

const closeLogoutConfirm = () => setShowLogoutConfirm(false);

const handleConfirmLogout = () => {
setShowLogoutConfirm(false);
logout();
};

// Dismiss the confirmation modal with the Esc key while it is open.
useEffect(() => {
if (!showLogoutConfirm) return;
const handleKeyDown = (e) => {
if (e.key === "Escape") setShowLogoutConfirm(false);
};
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, [showLogoutConfirm]);

return (
<header className="bg-white dark:bg-gray-900 border-b border-gray-200 dark:border-gray-700 sticky top-0 z-50">
<div className="mx-auto max-w-6xl px-4 py-3">
<div className="flex items-center justify-between">
{/* Logo */}
<Link
to="/"
<Link
to="/"
className="text-2xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent"
>
ThinkBoard
Expand All @@ -34,15 +54,15 @@ const Navbar = () => {
{/* Auth Buttons */}
{user ? (
<div className="flex items-center gap-2">
<Link
to="/create"
<Link
to="/create"
className="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors"
>
<PlusIcon size={16} />
<span>New Note</span>
</Link>
<button
onClick={logout}
onClick={() => setShowLogoutConfirm(true)}
className="inline-flex items-center gap-2 px-4 py-2 border border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-850 text-gray-700 dark:text-gray-300 font-medium rounded-lg transition-colors"
>
<LogOut size={16} />
Expand All @@ -51,14 +71,14 @@ const Navbar = () => {
</div>
) : (
<div className="flex items-center gap-2">
<Link
to="/login"
<Link
to="/login"
className="px-4 py-2 text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white transition-colors"
>
Login
</Link>
<Link
to="/signup"
<Link
to="/signup"
className="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors"
>
Sign Up
Expand All @@ -68,8 +88,60 @@ const Navbar = () => {
</div>
</div>
</div>

{/* Logout Confirmation Modal */}
{showLogoutConfirm && (
<div
className="fixed inset-0 z-[100] flex items-center justify-center bg-black/60 backdrop-blur-sm p-4"
onClick={closeLogoutConfirm}
role="dialog"
aria-modal="true"
aria-labelledby="logout-modal-title"
>
<div
className="relative w-full max-w-sm bg-white dark:bg-gray-800 rounded-xl shadow-2xl border border-gray-200 dark:border-gray-700 p-6"
onClick={(e) => e.stopPropagation()}
>
{/* Close Button */}
<button
onClick={closeLogoutConfirm}
className="absolute top-3 right-3 p-1.5 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"
aria-label="Close"
>
<X size={18} />
</button>

<h3
id="logout-modal-title"
className="text-lg font-bold text-gray-900 dark:text-white mb-2"
>
Log out?
</h3>
<p className="text-sm text-gray-500 dark:text-gray-400 mb-6">
Are you sure you want to log out? You&apos;ll need to log back in to
access your notes.
</p>

<div className="flex justify-end gap-3">
<button
onClick={closeLogoutConfirm}
className="px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 font-medium rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"
>
Cancel
</button>
<button
onClick={handleConfirmLogout}
className="inline-flex items-center gap-2 px-4 py-2 bg-red-600 hover:bg-red-700 text-white font-medium rounded-lg transition-colors"
>
<LogOut size={16} />
Logout
</button>
</div>
</div>
</div>
)}
</header>
);
};

export default Navbar;
export default Navbar;