"use client";
import { type CSSProperties, type ReactNode } from "react";
import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { GripVertical, MoreHorizontal, Star } from "lucide-react";
import { cn } from "@/lib/utils";
import { type CandidateRow, type StageKey } from "@/lib/schema";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
/**
* Pane 2 のステージグループ用、ドラッグ可能な候補者行。
*
* - 行全体クリック = 候補者を選択(onSelect 経由)
* - 左端のグリップだけが drag listener を持つ。`MoreHorizontal` メニューや
* 行クリックとは衝突しない(`activationConstraint: distance` でも吸収済み)
* - DragOverlay 描画中は `isDragging` で半透明 + pointer-events 抑止
*
* archived グループの行はドラッグさせないため、本コンポーネントは stage グループ
* 専用。archived は CandidateListPane 側の通常 `
` で描画する。
*/
export function SortableCandidateRow({
cand,
stage,
selected,
onSelect,
actions,
}: {
cand: CandidateRow;
stage: StageKey;
selected: boolean;
onSelect: (id: string) => void;
actions: ReactNode;
}) {
const {
attributes,
listeners,
setNodeRef,
transform,
transition,
isDragging,
} = useSortable({
id: cand.id,
data: { containerId: stage, name: cand.name },
});
const style: CSSProperties = {
transform: CSS.Transform.toString(transform),
transition,
};
return (
}
/>
{actions}
);
}
function ScoreBadge({
avg,
selected,
}: {
avg: number | null;
selected: boolean;
}) {
if (avg === null) {
return (
—
);
}
return (
{avg.toFixed(1)}
);
}