72 lines · 2.6 KB
import { useState } from "react";
import { adminSetSiteAdmin } from "~/fns/admin";
import type { getAdminOverview } from "~/fns/admin";
import { useAction } from "~/hooks/use-action";
import { Button } from "~/ui/Button";
import { ErrorBanner } from "~/ui/Callout";
import { Panel } from "~/ui/Panel";
import { TextLink } from "~/ui/TextLink";

type Admins = Awaited<ReturnType<typeof getAdminOverview>>["siteAdmins"];

const INPUT = "rounded-md border border-kumo-line bg-kumo-base px-2 py-1 text-kumo-strong";

/** Site admins, with grant and revoke. Revoking here (not in the database) also revokes their site-admin deploy tokens. */
export function SiteAdmins({ admins }: { admins: Admins }) {
  const [name, setName] = useState("");
  const action = useAction(adminSetSiteAdmin);
  return (
    <Panel title="Site admins">
      <div className="space-y-3 p-4 text-sm">
        <ErrorBanner message={action.error} />
        <form
          className="flex flex-wrap items-center gap-2"
          onSubmit={async (event) => {
            event.preventDefault();
            const target = name.trim();
            if (!target || !window.confirm(`Make ${target} a site admin? They can see and change everything.`)) return;
            await action.run({ data: { name: target, admin: true } });
            setName("");
          }}
        >
          <input
            aria-label="User name"
            className={INPUT}
            placeholder="user name"
            value={name}
            onChange={(event) => setName(event.target.value)}
          />
          <Button type="submit" size="sm" pending={action.pending}>
            Grant site admin