valhalla / frontend /src /components /LoginButton.jsx
Dontcryx_07
final
d660fa9
Raw
History Blame Contribute Delete
4.07 kB
/**
* LoginButton — auth entry point for admin controls.
*
* Shows a LOGIN pill when unauthenticated (opens LoginModal) and a user
* dropdown with logout when a session is active.
*
* Architecture: rendered by App.jsx; uses the useAuth context shared with
* InfoBar and RosterManager.
*
* Design: anonymous users can watch; only admins get controls.
*/
import { useState } from "react";
import { useAuth } from "../hooks/useAuth";
import LoginModal from "./LoginModal";
export default function LoginButton() {
const { user, isAuthenticated, loading, login, logout } = useAuth();
const [showModal, setShowModal] = useState(false);
const [showDropdown, setShowDropdown] = useState(false);
if (loading) return null;
const basePill = {
position: "fixed",
bottom: 16,
right: 16,
zIndex: 1500,
fontFamily: "'Space Mono', monospace",
fontSize: 11,
fontWeight: 600,
letterSpacing: "0.08em",
borderRadius: 6,
padding: "7px 16px",
cursor: "pointer",
display: "flex",
alignItems: "center",
gap: 7,
textTransform: "uppercase",
transition: "all 0.15s",
};
if (!isAuthenticated) {
return (
<>
<button
style={{
...basePill,
background: "#1a1a28",
border: "1px solid rgba(212,160,74,0.45)",
color: "#e7bd70",
boxShadow: "0 2px 12px rgba(0,0,0,0.5), inset 0 1px 0 rgba(212,160,74,0.15)",
}}
onClick={() => setShowModal(true)}
title="Admin login"
>
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M15 3h4a2 2 0 012 2v14a2 2 0 01-2 2h-4" />
<polyline points="10 17 15 12 10 7" />
<line x1="15" y1="12" x2="3" y2="12" />
</svg>
LOGIN
</button>
{showModal && <LoginModal onClose={() => setShowModal(false)} onLogin={login} />}
</>
);
}
return (
<div style={{ position: "fixed", bottom: 16, right: 16, zIndex: 1500 }}>
<button
style={{
...basePill,
background: "rgba(212,160,74,0.12)",
border: "1px solid rgba(212,160,74,0.35)",
color: "#e7bd70",
boxShadow: "0 2px 10px rgba(0,0,0,0.4)",
}}
onClick={() => setShowDropdown((v) => !v)}
title="Logged in — click to logout"
>
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<circle cx="12" cy="8" r="5" />
<path d="M20 21a8 8 0 00-16 0" />
</svg>
{user?.name || user?.email}
</button>
{showDropdown && (
<div
style={{
position: "absolute",
bottom: 42,
right: 0,
background: "#111118",
border: "1px solid rgba(212,160,74,0.25)",
borderRadius: 6,
padding: "8px 0",
minWidth: 170,
boxShadow: "0 8px 30px rgba(0,0,0,0.6)",
}}
onMouseLeave={() => setShowDropdown(false)}
>
<div style={{ padding: "6px 14px", fontSize: 10, color: "#888", fontFamily: "'Space Mono', monospace" }}>
{user?.email}
</div>
<div style={{ height: 1, background: "rgba(255,255,255,0.08)", margin: "2px 0" }} />
<button
onClick={() => {
setShowDropdown(false);
logout();
}}
style={{
display: "block",
width: "100%",
textAlign: "left",
padding: "8px 14px",
background: "none",
border: "none",
color: "#ff9494",
cursor: "pointer",
fontSize: 11,
fontFamily: "'Space Mono', monospace",
}}
>
LOGOUT
</button>
</div>
)}
</div>
);
}