Vectrum
Sign In
65 lines · 2.1 KB · TypeScript
"use client";

import { useActionState, useId, useState } from "react";
import type { FormState } from "@/app/actions/types";
import { CommitDialog } from "./commit-dialog";
import { TrashIcon } from "./icons";
import { Box, Button, ButtonLink, RefChip } from "./ui";

/**
 * Deleting a file: the question on an alert-dialog plate (what is lost, Cancel, then the red cap that
 * names the action), which opens the commit dialog to record the deletion.
 */
export function DeleteFileForm({
  action,
  branch,
  baseSha,
  path,
  cancelHref,
}: {
  action: (prev: FormState, formData: FormData) => Promise<FormState>;
  branch: string;
  baseSha: string;
  path: string;
  cancelHref: string;
}) {
  const formId = useId();
  const [state, formAction, pending] = useActionState(action, undefined);
  const [dialogOpen, setDialogOpen] = useState(false);
  const filename = path.split("/").pop();

  return (
    <form id={formId} action={formAction} className="mx-auto mt-6 max-w-md">
      <input type="hidden" name="path" value={path} />
      <Box className="flex flex-col gap-3.5 p-5">
        <div className="flex items-center gap-3">
          <span className="icon-tile size-9 shrink-0 rounded-row text-red! [&_svg]:size-4">
            <TrashIcon />
          </span>
          <h1 className="min-w-0 truncate type-title text-ink">Delete {filename}?</h1>
        </div>
        <p className="type-body text-ink2">
          <code className="font-mono text-ink">{path}</code> will be removed from <RefChip>{branch}</RefChip>. It stays in the
          history.
        </p>
        <div className="flex justify-end gap-2">
          <ButtonLink href={cancelHref}>Cancel</ButtonLink>
          <Button type="button" variant="danger" icon={<TrashIcon />} onClick={() => setDialogOpen(true)}>
            Commit deletion…
          </Button>
        </div>
      </Box>
      <CommitDialog
        formId={formId}
        branch={branch}
        baseSha={baseSha}
        defaultMessage={`Delete ${filename}`}
        pending={pending}
        error={state?.error}
        open={dialogOpen}
        onOpenChange={setDialogOpen}
        danger
      />
    </form>
  );
}