brackt/app/components/league/settings/HistoryDangerSection.tsx
Chris Parsons 05fe1493a3
Refactor league settings into per-section components (#379)
* 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>

* Fix Stop hook loop: suppress output on typecheck success

The Stop hook was producing stdout on every run, causing Claude Code to
feed it back as context and rewake the model each turn. Now emits a
systemMessage JSON only on failure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Typescript fix

* Remove type asserting

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 14:19:50 -07:00

134 lines
5.5 KiB
TypeScript

import { Activity, RotateCcw, ShieldAlert } from "lucide-react";
import { Form, Link } from "react-router";
import { Button } from "~/components/ui/button";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "~/components/ui/alert-dialog";
import { cn } from "~/lib/utils";
import { SettingsSection, SettingsStatusPill } from "./SettingsSection";
export function HistoryDangerSection({
active,
league,
season,
isAdmin,
isDeleteDialogOpen,
onDeleteDialogOpenChange,
navigationState,
}: {
active: boolean;
league: { id: string; name: string };
season: { id: string } | null;
isAdmin: boolean;
isDeleteDialogOpen: boolean;
onDeleteDialogOpenChange: (open: boolean) => void;
navigationState: "idle" | "loading" | "submitting";
}) {
return (
<SettingsSection
id="history-danger"
icon={ShieldAlert}
title="History & Danger"
description="Audit history is informational. Reset and delete actions are intentionally separated from normal settings."
status={<SettingsStatusPill tone="warning">Careful</SettingsStatusPill>}
className={cn("border-destructive/40", !active && "hidden")}
>
<div className="space-y-3">
<div className="flex flex-col gap-4 rounded-lg border p-4 sm:flex-row sm:items-center sm:justify-between">
<div className="flex min-w-0 items-start gap-3">
<Activity className="mt-0.5 h-5 w-5 shrink-0 text-muted-foreground" />
<div>
<h3 className="font-semibold">Audit Log</h3>
<p className="mt-1 text-sm text-muted-foreground">View the full history of commissioner actions for this season.</p>
</div>
</div>
<Button variant="outline" className="sm:w-44" asChild>
<Link to={`/leagues/${league.id}/audit-log`}>View Audit Log</Link>
</Button>
</div>
{isAdmin && season && (
<div className="flex flex-col gap-4 rounded-lg border border-destructive/30 p-4 sm:flex-row sm:items-center sm:justify-between">
<div className="flex min-w-0 items-start gap-3">
<RotateCcw className="mt-0.5 h-5 w-5 shrink-0 text-destructive" />
<div>
<h3 className="font-semibold">Reset Draft</h3>
<p className="mt-1 text-sm text-muted-foreground">
Delete all picks, queues, and timers. Draft order is preserved.
</p>
</div>
</div>
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="destructive" className="sm:w-44">
Reset Draft
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Reset the draft?</AlertDialogTitle>
<AlertDialogDescription>
This deletes all draft picks, queues, and timers, then returns the season to pre-draft. This cannot be undone.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<Form method="post">
<input type="hidden" name="intent" value="reset-draft" />
<AlertDialogAction type="submit" className="bg-destructive hover:bg-destructive/90">
Reset Draft
</AlertDialogAction>
</Form>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</div>
)}
<div className="flex flex-col gap-4 rounded-lg border border-destructive/30 p-4 sm:flex-row sm:items-center sm:justify-between">
<div className="flex min-w-0 items-start gap-3">
<ShieldAlert className="mt-0.5 h-5 w-5 shrink-0 text-destructive" />
<div>
<h3 className="font-semibold">Delete League</h3>
<p className="mt-1 text-sm text-muted-foreground">
Permanently delete this league and all associated data.
</p>
</div>
</div>
<AlertDialog open={isDeleteDialogOpen} onOpenChange={onDeleteDialogOpenChange}>
<AlertDialogTrigger asChild>
<Button variant="destructive" className="sm:w-44" disabled={navigationState === "submitting"}>
Delete League
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
<AlertDialogDescription>
This permanently deletes <strong>{league.name}</strong> and all associated data including seasons, teams, and commissioners.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<Form method="post">
<input type="hidden" name="intent" value="delete" />
<AlertDialogAction type="submit" className="bg-destructive hover:bg-destructive/90">
Delete League
</AlertDialogAction>
</Form>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</div>
</div>
</SettingsSection>
);
}