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

import { useActionState } from "react";
import { Checkbox } from "@unlocalhosted/metalui";
import type { FormState } from "@/app/actions/types";
import { PullRequestIcon } from "@/components/icons";
import { TextareaField, TextField } from "@/components/settings-fields";
import { PlateBody, PlateFooter } from "@/components/settings-plate";
import { Alert, Button } from "@/components/ui";

export function CreatePullForm({
  action,
  head,
  headRepo,
  base,
  title,
  body,
}: {
  action: (prev: FormState, formData: FormData) => Promise<FormState>;
  head: string;
  /** The fork the head branch is on ("owner/name"), when it isn't the repository's own. */
  headRepo: string | null;
  base: string;
  title: string;
  body: string;
}) {
  const [state, formAction, pending] = useActionState(action, undefined);
  return (
    <form action={formAction}>
      <input type="hidden" name="head" value={head} />
      {headRepo && <input type="hidden" name="head_repo" value={headRepo} />}
      <input type="hidden" name="base" value={base} />
      <PlateBody>
        <TextField label="Title" name="title" required maxLength={256} defaultValue={title} />
        <TextareaField
          label="Description"
          name="body"
          minRows={6}
          maxRows={20}
          defaultValue={body}
          placeholder="What changes, and why. “Fixes #12” links an issue: it closes when this is merged."
          description="Markdown is supported."
        />
        <label className="flex cursor-pointer items-start gap-3">
          <Checkbox name="draft" className="mt-px" />
          <span className="flex flex-col gap-0.5">
            <span className="type-title text-ink">Draft</span>
            <span className="type-body text-ink2">Still in progress: it can’t be merged until it’s marked ready for review.</span>
          </span>
        </label>
        {state?.error && <Alert>{state.error}</Alert>}
      </PlateBody>
      <PlateFooter>
        <Button variant="primary" icon={<PullRequestIcon />} disabled={pending}>
          {pending ? "Opening…" : "Open Pull Request"}
        </Button>
      </PlateFooter>
    </form>
  );
}