import { useQueryClient } from "@tanstack/react-query";
import { useState } from "react";
import { adminSetSignupCap } from "~/fns/admin";
import type { getAdminOverview } from "~/fns/admin";
import { useAction } from "~/hooks/use-action";
import { WAITLIST_INVITE_HOURS } from "~/lib/waitlist";
import { Button } from "~/ui/Button";
import { ErrorBanner } from "~/ui/Callout";
import { compactInputClass } from "~/ui/Field";
import { Panel } from "~/ui/Panel";
import { WAITLIST_KEY, WaitlistTable } from "./WaitlistTable";
type Waitlist = Awaited<ReturnType<typeof getAdminOverview>>["waitlist"];
/** Caps how many user accounts may exist; raising it invites people off the waitlist, oldest first. */
export function SignupCapControls({ waitlist }: { waitlist: Waitlist }) {
const [cap, setCap] = useState(waitlist.cap === null ? "" : String(waitlist.cap));
const save = useAction(adminSetSignupCap);
const queryClient = useQueryClient();
const parsed = cap.trim() === "" ? null : Number(cap);
const valid = parsed === null || (Number.isInteger(parsed) && parsed >= 1);
const changed = parsed !== waitlist.cap;
return (
<Panel title="Sign-up cap">
<div className="space-y-3 p-4 text-sm">
<p className="text-kumo-subtle">
{waitlist.users} users
{waitlist.cap === null ? ", no cap" : ` of ${waitlist.cap}`} · {waitlist.waiting} waiting · {waitlist.invited}{" "}
invited (holding a seat for {WAITLIST_INVITE_HOURS} hours)
</p>
<ErrorBanner message={save.error} />
<form
className="flex flex-wrap items-center gap-2"
onSubmit={async (event) => {
event.preventDefault();
if (!valid || !changed) return;
if (await save.run({ data: { cap: parsed } })) {
await queryClient.invalidateQueries({ queryKey: WAITLIST_KEY });
}
}}