← 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>
  );
}