2026-05-05 14:19:50 -07:00
|
|
|
import { ClipboardList } from "lucide-react";
|
|
|
|
|
import { Label } from "~/components/ui/label";
|
|
|
|
|
import { Button } from "~/components/ui/button";
|
|
|
|
|
import { cn } from "~/lib/utils";
|
|
|
|
|
import { SportIcon } from "~/components/league/SportIcon";
|
|
|
|
|
import { SettingsSection, SettingsStatusPill } from "./SettingsSection";
|
|
|
|
|
|
|
|
|
|
type SportsSeason = {
|
|
|
|
|
id: string;
|
|
|
|
|
name: string;
|
|
|
|
|
sport: { id: string; name: string; slug: string; type: string; iconUrl: string | null };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const BRACKT_SLUG = "brackt";
|
|
|
|
|
|
|
|
|
|
export function SportsSection({
|
|
|
|
|
active,
|
|
|
|
|
canEditSports,
|
|
|
|
|
selectedSports,
|
|
|
|
|
displaySportsSeasons,
|
|
|
|
|
onSportToggle,
|
|
|
|
|
onClearAll,
|
|
|
|
|
}: {
|
|
|
|
|
active: boolean;
|
|
|
|
|
canEditSports: boolean;
|
|
|
|
|
selectedSports: Set<string>;
|
|
|
|
|
displaySportsSeasons: SportsSeason[];
|
|
|
|
|
onSportToggle: (id: string) => void;
|
|
|
|
|
onClearAll: () => void;
|
|
|
|
|
}) {
|
|
|
|
|
return (
|
|
|
|
|
<SettingsSection
|
|
|
|
|
id="sports"
|
|
|
|
|
icon={ClipboardList}
|
|
|
|
|
title="Sports"
|
|
|
|
|
description="Manage draftable sports seasons for this league. Sports lock when the draft starts."
|
|
|
|
|
status={<SettingsStatusPill tone={canEditSports ? "success" : "locked"}>{canEditSports ? "Editable" : "Locked"}</SettingsStatusPill>}
|
|
|
|
|
className={active ? undefined : "hidden"}
|
|
|
|
|
>
|
|
|
|
|
<div className="space-y-4">
|
|
|
|
|
<div className="flex items-center justify-between gap-3">
|
|
|
|
|
<Label>{selectedSports.size} selected</Label>
|
|
|
|
|
{canEditSports && selectedSports.size > 0 && (
|
|
|
|
|
<Button type="button" variant="ghost" size="sm" onClick={onClearAll}>
|
|
|
|
|
Clear all
|
|
|
|
|
</Button>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
<div className="space-y-2">
|
|
|
|
|
{displaySportsSeasons.length > 0 ? (
|
|
|
|
|
displaySportsSeasons.map((ss) => {
|
|
|
|
|
const selected = selectedSports.has(ss.id);
|
|
|
|
|
return (
|
|
|
|
|
<label
|
|
|
|
|
key={ss.id}
|
|
|
|
|
htmlFor={`sport-${ss.id}`}
|
|
|
|
|
className={cn(
|
|
|
|
|
"mb-2 flex cursor-pointer items-center gap-3 rounded-md border p-3 text-sm transition-colors last:mb-0",
|
|
|
|
|
selected ? "border-primary bg-primary/10 text-primary" : "border-border bg-background hover:border-primary/50",
|
|
|
|
|
!canEditSports && "cursor-not-allowed opacity-65"
|
|
|
|
|
)}
|
|
|
|
|
>
|
2026-05-07 23:06:49 -07:00
|
|
|
<input
|
2026-05-05 14:19:50 -07:00
|
|
|
id={`sport-${ss.id}`}
|
2026-05-07 23:06:49 -07:00
|
|
|
type="checkbox"
|
2026-05-05 14:19:50 -07:00
|
|
|
name="sportsSeasons"
|
|
|
|
|
value={ss.id}
|
|
|
|
|
checked={selected}
|
2026-05-07 23:06:49 -07:00
|
|
|
onChange={() => onSportToggle(ss.id)}
|
2026-05-05 14:19:50 -07:00
|
|
|
disabled={!canEditSports}
|
2026-05-07 23:06:49 -07:00
|
|
|
className="sr-only"
|
2026-05-05 14:19:50 -07:00
|
|
|
/>
|
|
|
|
|
<SportIcon sport={ss.sport} />
|
2026-05-07 10:09:45 -07:00
|
|
|
<span className="min-w-0 flex-1 overflow-hidden">
|
2026-05-05 14:19:50 -07:00
|
|
|
<span className="block truncate font-medium">
|
2026-05-15 16:04:07 -07:00
|
|
|
{ss.sport.slug === BRACKT_SLUG ? "Brackt" : ss.name}
|
2026-05-05 14:19:50 -07:00
|
|
|
</span>
|
|
|
|
|
</span>
|
|
|
|
|
</label>
|
|
|
|
|
);
|
|
|
|
|
})
|
|
|
|
|
) : (
|
|
|
|
|
<p className="p-3 text-sm text-muted-foreground">No sports seasons available.</p>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</SettingsSection>
|
|
|
|
|
);
|
|
|
|
|
}
|