145 lines
6.7 KiB
TypeScript
145 lines
6.7 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import Link from "next/link";
|
|
import PointsDisplay from "./PointsDisplay";
|
|
|
|
interface NavbarProps {
|
|
user?: {
|
|
username: string;
|
|
points: number;
|
|
avatar?: string;
|
|
};
|
|
}
|
|
|
|
export default function Navbar({ user }: NavbarProps) {
|
|
const [dropdownOpen, setDropdownOpen] = useState(false);
|
|
|
|
const handleLogout = async () => {
|
|
await fetch("/api/auth/logout", { method: "POST" });
|
|
window.location.href = "/";
|
|
};
|
|
|
|
return (
|
|
<nav className="bg-gray-900 border-b border-gray-800 sticky top-0 z-50">
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div className="flex items-center justify-between h-16">
|
|
<div className="flex items-center gap-8">
|
|
<Link href="/" className="flex items-center gap-2">
|
|
<div className="w-10 h-10 bg-gradient-to-br from-yellow-400 to-orange-500 rounded-lg flex items-center justify-center shadow-lg">
|
|
<svg className="w-6 h-6 text-white" fill="currentColor" viewBox="0 0 20 20">
|
|
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
|
|
</svg>
|
|
</div>
|
|
<span className="text-xl font-bold text-white">EarnPlay</span>
|
|
</Link>
|
|
|
|
{user && (
|
|
<div className="hidden md:flex items-center gap-4">
|
|
<Link
|
|
href="/dashboard"
|
|
className="text-gray-300 hover:text-white px-3 py-2 rounded-lg hover:bg-gray-800 transition"
|
|
>
|
|
Home
|
|
</Link>
|
|
<Link
|
|
href="/tasks"
|
|
className="text-gray-300 hover:text-white px-3 py-2 rounded-lg hover:bg-gray-800 transition"
|
|
>
|
|
Tasks
|
|
</Link>
|
|
<Link
|
|
href="/leaderboard"
|
|
className="text-gray-300 hover:text-white px-3 py-2 rounded-lg hover:bg-gray-800 transition"
|
|
>
|
|
Leaderboard
|
|
</Link>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="flex items-center gap-4">
|
|
{user ? (
|
|
<>
|
|
<PointsDisplay points={user.points} size="small" />
|
|
|
|
<div className="relative">
|
|
<button
|
|
onClick={() => setDropdownOpen(!dropdownOpen)}
|
|
className="flex items-center gap-2 bg-gray-800 hover:bg-gray-700 rounded-lg px-3 py-2 transition"
|
|
>
|
|
<div className="w-8 h-8 rounded-full bg-gradient-to-br from-yellow-400 to-orange-500 flex items-center justify-center text-white font-bold">
|
|
{user.username[0].toUpperCase()}
|
|
</div>
|
|
<span className="hidden md:block text-white font-medium">{user.username}</span>
|
|
<svg
|
|
className={`w-4 h-4 text-gray-400 transition ${dropdownOpen ? "rotate-180" : ""}`}
|
|
fill="currentColor"
|
|
viewBox="0 0 20 20"
|
|
>
|
|
<path fillRule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clipRule="evenodd" />
|
|
</svg>
|
|
</button>
|
|
|
|
{dropdownOpen && (
|
|
<div className="absolute right-0 mt-2 w-48 bg-gray-800 border border-gray-700 rounded-lg shadow-xl overflow-hidden">
|
|
<Link
|
|
href="/profile"
|
|
className="block px-4 py-3 text-gray-300 hover:bg-gray-700 hover:text-white transition"
|
|
>
|
|
<div className="flex items-center gap-2">
|
|
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
|
<path fillRule="evenodd" d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z" clipRule="evenodd" />
|
|
</svg>
|
|
Profile
|
|
</div>
|
|
</Link>
|
|
<Link
|
|
href="/badges"
|
|
className="block px-4 py-3 text-gray-300 hover:bg-gray-700 hover:text-white transition"
|
|
>
|
|
<div className="flex items-center gap-2">
|
|
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
|
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
|
|
</svg>
|
|
Badges
|
|
</div>
|
|
</Link>
|
|
<button
|
|
onClick={handleLogout}
|
|
className="block w-full text-left px-4 py-3 text-red-400 hover:bg-gray-700 transition"
|
|
>
|
|
<div className="flex items-center gap-2">
|
|
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
|
<path fillRule="evenodd" d="M3 3a1 1 0 00-1 1v12a1 1 0 102 0V4a1 1 0 00-1-1zm10.293 9.293a1 1 0 001.414 1.414l3-3a1 1 0 000-1.414l-3-3a1 1 0 10-1.414 1.414L14.586 9H7a1 1 0 100 2h7.586l-1.293 1.293z" clipRule="evenodd" />
|
|
</svg>
|
|
Logout
|
|
</div>
|
|
</button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</>
|
|
) : (
|
|
<div className="flex gap-2">
|
|
<Link
|
|
href="/login"
|
|
className="text-gray-300 hover:text-white px-4 py-2 rounded-lg hover:bg-gray-800 transition"
|
|
>
|
|
Sign In
|
|
</Link>
|
|
<Link
|
|
href="/register"
|
|
className="bg-gradient-to-r from-yellow-500 to-orange-500 text-white px-4 py-2 rounded-lg hover:from-yellow-600 hover:to-orange-600 transition transform hover:scale-105"
|
|
>
|
|
Sign Up
|
|
</Link>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
);
|
|
}
|