77 lines
3.6 KiB
JavaScript
77 lines
3.6 KiB
JavaScript
import React, { useState } from 'react'
|
|
import SearchBar from '../Search/SearchBar'
|
|
|
|
const DEFAULT_AVATAR = 'https://files.skinbase.org/default/avatar_default.webp'
|
|
|
|
export default function Topbar({ user = null }) {
|
|
const [menuOpen, setMenuOpen] = useState(false)
|
|
|
|
return (
|
|
<header className="fixed top-0 left-0 right-0 h-16 bg-neutral-900 border-b border-neutral-800 z-50">
|
|
<div className="h-full px-5 flex items-center justify-between gap-4">
|
|
<div className="flex items-center gap-4">
|
|
<button aria-label="Toggle menu" className="md:hidden text-neutral-200 hover:text-sky-400">
|
|
<i className="fas fa-bars text-lg" aria-hidden="true"></i>
|
|
</button>
|
|
<a href="/" className="text-sky-400 font-semibold text-xl">Skinbase</a>
|
|
</div>
|
|
|
|
<div className="hidden md:block flex-1 max-w-xl">
|
|
<SearchBar />
|
|
</div>
|
|
|
|
<div className="flex items-center gap-3 sm:gap-4">
|
|
<a href="/forum" className="hidden sm:inline text-sm text-neutral-300 hover:text-sky-400 transition-colors">Forum</a>
|
|
|
|
{user ? (
|
|
<div className="relative">
|
|
<button
|
|
onClick={() => setMenuOpen(o => !o)}
|
|
className="flex items-center gap-2 rounded-lg px-2 py-1 hover:bg-white/5 transition-colors"
|
|
aria-label="User menu"
|
|
>
|
|
<img
|
|
src={user.avatarUrl || DEFAULT_AVATAR}
|
|
alt={user.displayName}
|
|
className="w-7 h-7 rounded-full object-cover ring-1 ring-white/10"
|
|
onError={(e) => { e.currentTarget.src = DEFAULT_AVATAR }}
|
|
/>
|
|
<span className="hidden sm:inline text-sm text-white/90">{user.displayName}</span>
|
|
<i className="fas fa-chevron-down text-xs text-white/50" aria-hidden="true"></i>
|
|
</button>
|
|
|
|
{menuOpen && (
|
|
<div className="absolute right-0 mt-2 w-48 rounded-lg bg-neutral-800 border border-neutral-700 shadow-xl overflow-hidden z-50">
|
|
<a href={`/@${user.username}`} className="flex items-center gap-2 px-4 py-2 text-sm hover:bg-white/5">
|
|
<img
|
|
src={user.avatarUrl || DEFAULT_AVATAR}
|
|
alt={user.displayName}
|
|
className="w-6 h-6 rounded-full object-cover"
|
|
onError={(e) => { e.currentTarget.src = DEFAULT_AVATAR }}
|
|
/>
|
|
<span className="truncate">{user.displayName}</span>
|
|
</a>
|
|
<div className="border-t border-neutral-700" />
|
|
<a href={user.uploadUrl} className="block px-4 py-2 text-sm hover:bg-white/5">Upload</a>
|
|
<a href="/studio/artworks" className="block px-4 py-2 text-sm hover:bg-white/5">Studio</a>
|
|
<a href="/dashboard" className="block px-4 py-2 text-sm hover:bg-white/5">Dashboard</a>
|
|
<div className="border-t border-neutral-700" />
|
|
<a href="/logout" className="block px-4 py-2 text-sm text-red-400 hover:bg-white/5"
|
|
onClick={(e) => { e.preventDefault(); document.getElementById('logout-form')?.submit() }}>
|
|
Sign out
|
|
</a>
|
|
</div>
|
|
)}
|
|
</div>
|
|
) : (
|
|
<a href="/login" className="text-sm text-neutral-300 hover:text-sky-400 transition-colors">
|
|
<i className="fas fa-user" aria-hidden="true"></i>
|
|
</a>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</header>
|
|
)
|
|
}
|
|
|