"use client";
import { useActionState, useState } from "react";
import { Checkbox, Select } from "@unlocalhosted/metalui";
import type { FormState } from "@/app/actions/types";
import { MergeIcon } from "@/components/icons";
import { Alert, Button } from "@/components/ui";
const METHODS = [
{ value: "merge", label: "Create a merge commit" },
{ value: "squash", label: "Squash and merge" },
] as const;
/** The merge button with its method, and whether to delete the head branch afterwards. */
export function MergeForm({
action,
headSha,
mergeable,
canDeleteBranch,
}: {
action: (prev: FormState, formData: FormData) => Promise<FormState>;
headSha: string;
mergeable: boolean;
canDeleteBranch: boolean;
}) {
const [state, formAction, pending] = useActionState(action, undefined);
const [method, setMethod] = useState<"merge" | "squash">("merge");
return (
<form action={formAction} className="flex flex-col gap-3">
<input type="hidden" name="headSha" value={headSha} />
<input type="hidden" name="method" value={method} />
<div className="flex flex-wrap items-center gap-3">
<Select aria-label="Merge method" options={[...METHODS]} value={method} onValueChange={(v) => setMethod(v as "merge" | "squash")} className="w-56" />
<Button variant="primary" icon={<MergeIcon />} disabled={!mergeable || pending}>
{pending ? "Merging…" : method === "squash" ? "Squash and Merge" : "Merge Pull Request"}
</Button>
{canDeleteBranch && (
<label className="flex cursor-pointer items-center gap-2 type-ui text-ink2">
<Checkbox name="deleteBranch" size="row" /> Delete the branch afterwards
</label>
)}
</div>
{state?.error && <Alert>{state.error.split("\n").map((line, i) => <div key={i}>{line}</div>)}</Alert>}
</form>
);
}