Files
smart-rgb/frontend/src/shared/components/game/Menu.tsx
2025-10-16 00:02:34 -05:00

100 lines
3.7 KiB
TypeScript

import { useState } from "react";
import { Menu, X } from "lucide-react";
import { cn } from "@/lib/utils";
import "./Menu.css";
interface GameMenuProps {
onExit: () => void;
onSettings?: () => void;
}
export function GameMenu({ onExit, onSettings }: GameMenuProps) {
const [isOpen, setIsOpen] = useState(false);
const [showConfirmation, setShowConfirmation] = useState(false);
const [isClosing, setIsClosing] = useState(false);
const closeConfirmation = () => {
setIsClosing(true);
setTimeout(() => {
setShowConfirmation(false);
setIsClosing(false);
}, 200);
};
return (
<div className="fixed top-4 right-4 z-999 no-drag block-game-input">
{/* Hamburger/Close Button */}
<button
className="bg-[rgba(15,23,42,0.75)] border-none rounded-md text-white p-2 cursor-pointer flex items-center justify-center transition-colors duration-150 ease-[ease] hover:bg-[rgba(15,23,42,0.9)]"
onClick={() => setIsOpen((prev) => !prev)}
>
{isOpen ? <X size={20} /> : <Menu size={20} />}
</button>
{/* Dropdown Menu */}
{isOpen && (
<div className="absolute top-[calc(100%+0.5rem)] right-0 bg-[rgba(15,23,42,0.75)] rounded-md min-w-[140px] overflow-hidden">
<button
className={cn(
"w-full bg-transparent border-none text-white py-1.5 px-4 text-right cursor-pointer font-inter transition-[background-color] duration-150 ease-[ease] hover:bg-[rgba(255,255,255,0.06)]",
onSettings && "border-t border-white/10",
)}
onClick={() => {
setShowConfirmation(true);
setIsClosing(false);
setIsOpen(false);
}}
>
Exit
</button>
</div>
)}
{/* Confirmation Dialog */}
{showConfirmation && (
<div
className={cn(
"fixed inset-0 bg-[rgba(0,0,0,0.5)] flex items-center justify-center z-[1000]",
isClosing ? "animate-[fadeOut_0.2s_ease-out_forwards]" : "animate-[fadeIn_0.2s_ease-out]",
)}
onClick={closeConfirmation}
>
<div
className={cn(
"bg-zinc-900 rounded-lg p-8 min-w-[300px] max-w-[400px] shadow-lg shadow-zinc-950/50",
isClosing ? "animate-[slideDown_0.2s_ease-out_forwards]" : "animate-[slideUp_0.2s_ease-out]",
)}
onClick={(e) => e.stopPropagation()}
>
<h3 className="my-0 mb-4 text-white text-xl font-inter font-semibold">Are you sure?</h3>
<p className="my-0 mb-6 text-white/80 font-inter leading-normal text-pretty">
You will not be able to return to this game after exiting.
</p>
<div className="flex gap-3 justify-end">
<button
className="border-none rounded-md text-white px-5 cursor-pointer font-inter transition-colors duration-150 ease-in-out bg-white/10 hover:bg-white/15"
onClick={closeConfirmation}
>
Nevermind
</button>
<button
className="border-none rounded-md text-white px-5 cursor-pointer font-inter transition-[background-color] duration-150 ease-[ease] bg-red-500 font-medium hover:bg-red-400"
onClick={() => {
setIsClosing(true);
setTimeout(() => {
setShowConfirmation(false);
setIsClosing(false);
onExit();
}, 200);
}}
>
I'm sure
</button>
</div>
</div>
</div>
)}
</div>
);
}