brackt/app/components/league/settings/SortableDraftOrderRow.tsx
Chris Parsons b1a1a472f5 Refactor league settings into per-section components (#347)
Extract all settings sections from the monolithic 1009-line route file into
individual components under app/components/league/settings/. Route file drops
to ~300 lines. Separates draft-order dirty state from general settings dirty
state, deduplicates section-change handling, and fixes several bugs found
during review (typo in pointsFor5th, wrong mock in tests, lint violations).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 14:00:35 -07:00

64 lines
1.7 KiB
TypeScript

import { CSS } from "@dnd-kit/utilities";
import { useSortable } from "@dnd-kit/sortable";
import { GripVertical } from "lucide-react";
import { cn } from "~/lib/utils";
export function SortableDraftOrderRow({
teamId,
index,
teamName,
ownerName,
disabled = false,
}: {
teamId: string;
index: number;
teamName: string;
ownerName: string | null;
disabled?: boolean;
}) {
const {
attributes,
listeners,
setNodeRef,
transform,
transition,
isDragging,
} = useSortable({ id: teamId });
return (
<div
ref={setNodeRef}
style={{
transform: CSS.Transform.toString(transform),
transition,
}}
className={cn(
"flex items-center gap-3 rounded-lg border bg-card p-4",
isDragging && "z-10 shadow-lg ring-1 ring-primary/30",
disabled && "opacity-65"
)}
>
<input type="hidden" name="teamOrder" value={teamId} />
<button
type="button"
className={cn(
"flex h-9 w-9 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted",
disabled && "cursor-not-allowed hover:bg-transparent"
)}
aria-label={`Drag ${teamName}`}
disabled={disabled}
{...(disabled ? {} : attributes)}
{...(disabled ? {} : listeners)}
>
<GripVertical className="h-4 w-4" />
</button>
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-primary text-sm font-bold text-primary-foreground">
{index + 1}
</div>
<div className="min-w-0 flex-1">
<p className="truncate font-medium">{teamName}</p>
{ownerName && <p className="truncate text-xs text-muted-foreground">{ownerName}</p>}
</div>
</div>
);
}