← back to Epstein Card
components/ui/main-dropdown.tsx
178 lines
"use client";
import { useState, useRef, useEffect } from "react";
interface MainDropdownProps {
options: string[];
placeholder?: string;
value: string;
onChange: (value: string) => void;
label?: string;
}
export function MainDropdown({
options,
placeholder = "Select...",
value,
onChange,
label
}: MainDropdownProps) {
const [isOpen, setIsOpen] = useState(false);
const [customValue, setCustomValue] = useState("");
const [showCustomInput, setShowCustomInput] = useState(false);
const dropdownRef = useRef<HTMLDivElement>(null);
const customInputRef = useRef<HTMLInputElement>(null);
// Take first 3 options as presets
const presetOptions = options.slice(0, 3);
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
setIsOpen(false);
setShowCustomInput(false);
}
}
document.addEventListener("mousedown", handleClickOutside);
return () => document.removeEventListener("mousedown", handleClickOutside);
}, []);
useEffect(() => {
if (showCustomInput && customInputRef.current) {
customInputRef.current.focus();
}
}, [showCustomInput]);
const handleSelect = (selectedValue: string) => {
if (selectedValue === "custom") {
setShowCustomInput(true);
setIsOpen(false);
} else {
onChange(selectedValue);
setIsOpen(false);
setShowCustomInput(false);
}
};
const handleCustomSubmit = () => {
if (customValue.trim()) {
onChange(customValue);
setShowCustomInput(false);
setCustomValue("");
}
};
const displayValue = value || placeholder;
return (
<div className="relative inline-block" ref={dropdownRef}>
{label && (
<div className="text-purple-400 text-sm font-mono mb-1">{label}</div>
)}
<button
type="button"
onClick={() => setIsOpen(!isOpen)}
className={`
bg-black border-2 border-purple-500 text-white px-6 py-3
rounded-lg font-mono text-xl min-w-[250px] text-left
hover:border-purple-400 transition-all hover:shadow-lg
hover:shadow-purple-500/30 ${value ? '' : 'text-gray-400'}
`}
>
{displayValue}
<span className="float-right">▼</span>
</button>
{isOpen && (
<div className="absolute z-50 mt-2 w-full min-w-[350px] rounded-lg border-2 border-purple-500 bg-black shadow-2xl">
<div className="max-h-[300px] overflow-y-auto">
<div className="p-2">
<div className="text-purple-300 text-sm font-mono px-4 py-2 border-b border-purple-700">
🔥 Quick Selections:
</div>
{presetOptions.map((option, index) => (
<button
key={option}
type="button"
onClick={() => handleSelect(option)}
className="w-full text-left px-4 py-3 hover:bg-purple-900/50 text-purple-300 font-mono text-lg transition-colors rounded flex items-center gap-2"
>
<span className="text-yellow-400 font-bold">{index + 1}.</span>
<span className="truncate">{option}</span>
</button>
))}
<div className="border-t border-purple-700 my-2"></div>
<div className="text-purple-300 text-sm font-mono px-4 py-2">
📁 All Options:
</div>
{options.slice(3).map((option) => (
<button
key={option}
type="button"
onClick={() => handleSelect(option)}
className="w-full text-left px-4 py-2 hover:bg-purple-900/30 text-purple-400 font-mono text-base transition-colors rounded truncate"
>
{option}
</button>
))}
<div className="border-t border-purple-700 my-2"></div>
<button
type="button"
onClick={() => handleSelect("custom")}
className="w-full text-left px-4 py-3 hover:bg-yellow-900/30 text-yellow-400 font-mono text-lg transition-colors rounded font-bold"
>
✏️ Enter Custom Category...
</button>
</div>
</div>
</div>
)}
{showCustomInput && (
<div className="absolute z-50 mt-2 w-full min-w-[350px] rounded-lg border-2 border-yellow-500 bg-black shadow-2xl p-4">
<div className="text-yellow-400 font-mono text-lg mb-3 font-bold">
🔓 Enter Classified Category:
</div>
<input
ref={customInputRef}
type="text"
value={customValue}
onChange={(e) => setCustomValue(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') handleCustomSubmit();
if (e.key === 'Escape') {
setShowCustomInput(false);
setCustomValue("");
}
}}
className="w-full bg-gray-900 border-2 border-yellow-500 text-white px-4 py-3 rounded-lg font-mono text-lg focus:outline-none focus:border-yellow-400"
placeholder="Type classified name..."
/>
<div className="flex gap-3 mt-4">
<button
type="button"
onClick={handleCustomSubmit}
className="flex-1 bg-gradient-to-r from-yellow-600 to-yellow-500 hover:from-yellow-500 hover:to-yellow-400 text-black font-bold py-3 rounded-lg transition-all text-lg"
>
🔓 ACCESS
</button>
<button
type="button"
onClick={() => {
setShowCustomInput(false);
setCustomValue("");
}}
className="flex-1 bg-gray-800 hover:bg-gray-700 text-white font-bold py-3 rounded-lg transition-all text-lg"
>
CANCEL
</button>
</div>
</div>
)}
</div>
);
}