Vectrum
Sign In
42 lines · 1.8 KB · TypeScript
"use client";

import { useActionState, useRef } from "react";
import { Select } from "@unlocalhosted/metalui";
import type { FormState } from "@/app/actions/types";
import { BranchIcon, PlusIcon } from "@/components/icons";
import { TextField } from "@/components/settings-fields";
import { Alert, Box, Button } from "@/components/ui";

/** A new branch: its name, and the branch it starts from. */
export function NewBranchForm({ action, branches, from }: { action: (prev: FormState, formData: FormData) => Promise<FormState>; branches: string[]; from: string }) {
  const form = useRef<HTMLFormElement>(null);
  const [state, formAction, pending] = useActionState(async (prev: FormState, formData: FormData) => {
    const result = await action(prev, formData);
    if (result?.success) form.current?.reset();
    return result;
  }, undefined);
  return (
    <Box className="mb-5 px-4 py-3">
      <form ref={form} action={formAction} className="flex flex-wrap items-end gap-3">
        <TextField label="New branch" name="name" required placeholder="feature/my-change" className="min-w-56 flex-1" icon={<BranchIcon />} />
        <div className="flex flex-col gap-1.5">
          <span className="type-ui text-ink">From</span>
          <Select name="from" aria-label="Start from" defaultValue={from} options={branches.map((b) => ({ value: b, label: b, lead: <BranchIcon /> }))} className="w-56" />
        </div>
        <Button variant="primary" icon={<PlusIcon />} disabled={pending}>
          {pending ? "Creating…" : "Create Branch"}
        </Button>
      </form>
      {state?.error && (
        <div className="mt-3">
          <Alert>{state.error}</Alert>
        </div>
      )}
      {state?.success && (
        <div className="mt-3">
          <Alert kind="success">{state.success}</Alert>
        </div>
      )}
    </Box>
  );
}