All files / components/LegacyHomePage LegacyAssessmentSelect.tsx

100% Statements 17/17
100% Branches 19/19
100% Functions 9/9
100% Lines 14/14

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120                                    143x 143x     143x   143x 32x 11x       5x     32x 32x     143x     11x                                                                                                               14x     6x 6x                                      
// Frozen copy for LegacyHomePage only. LegacyHomePage is the "touchstone
// ground truth" preserving the original prototype designer's UX research;
// it must not be affected by refactors to the shared Scaffold components.
// Do not consolidate this with main/components/Scaffold/AssessmentSelect.
import { useState, useEffect, useRef } from "react";
import type { Assessment } from "../../api/legacyClient";
 
interface AssessmentSelectProps {
  assessments: Assessment[];
  selectedAssessmentId: string;
  onSelect: (id: string) => void;
}
 
export default function LegacyAssessmentSelect({
  assessments,
  selectedAssessmentId,
  onSelect,
}: AssessmentSelectProps) {
  const [isOpen, setIsOpen] = useState(false);
  const containerRef = useRef<HTMLDivElement>(null);
 
  const selectedName =
    assessments.find((a) => a.id === selectedAssessmentId)?.name ?? "";
 
  useEffect(() => {
    const handler = (e: MouseEvent) => {
      if (
        containerRef.current &&
        !containerRef.current.contains(e.target as Node)
      ) {
        setIsOpen(false);
      }
    };
    document.addEventListener("mousedown", handler, true);
    return () => document.removeEventListener("mousedown", handler, true);
  }, []);
 
  return (
    <div ref={containerRef} style={{ position: "relative", minWidth: 200 }}>
      <div
        onClick={() => setIsOpen((o) => !o)}
        style={{
          width: "100%",
          height: 28,
          padding: "0px 10px",
          fontFamily: "Helvetica, Arial, sans-serif",
          fontSize: 13,
          background: "#ffffff",
          color: selectedAssessmentId ? "#1E293B" : "#94A3B8",
          border: "1px solid #000000",
          borderRadius: 6,
          cursor: "pointer",
          boxSizing: "border-box",
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          userSelect: "none",
        }}
      >
        <span>{selectedName || "Select assessment…"}</span>
        <svg
          width="12"
          height="12"
          viewBox="0 0 24 24"
          fill="none"
          stroke="#94A3B8"
          strokeWidth="2"
          strokeLinecap="round"
          strokeLinejoin="round"
          style={{
            flexShrink: 0,
            transform: isOpen ? "rotate(180deg)" : "none",
            transition: "transform 0.15s",
          }}
        >
          <polyline points="6 9 12 15 18 9" />
        </svg>
      </div>
 
      {isOpen && assessments.length > 0 && (
        <div
          style={{
            position: "absolute",
            top: "calc(100% + 4px)",
            left: 0,
            right: 0,
            background: "#fff",
            border: "1px solid #E2E8F0",
            borderRadius: 6,
            boxShadow: "0 4px 16px rgba(0,0,0,0.1)",
            zIndex: 100,
            maxHeight: 260,
            overflowY: "auto",
          }}
        >
          {assessments.map((a, i) => (
            <div
              key={a.id}
              onMouseDown={() => {
                onSelect(a.id);
                setIsOpen(false);
              }}
              className={
                "dropdown-option" +
                (a.id === selectedAssessmentId ? " is-selected" : "")
              }
              style={{
                borderBottom:
                  i < assessments.length - 1 ? "1px solid #F1F5F9" : "none",
              }}
            >
              {a.name}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}