Vectrum
Sign In
89 lines · 3.8 KB · TypeScript
"use client";

import { useActionState } from "react";
import { Checkbox, Rule, Select } from "@unlocalhosted/metalui";
import { createRepoAction } from "@/app/actions/repo";
import { BookIcon, GlobeIcon, LockIcon, PlusIcon } from "@/components/icons";
import { ChoiceCards, TextField } from "@/components/settings-fields";
import { PlateBody, PlateFooter } from "@/components/settings-plate";
import { Alert, Avatar, Box, Button } from "@/components/ui";

export function NewRepoForm({ owners, owner }: { owners: string[]; owner: string }) {
  const [state, action, pending] = useActionState(createRepoAction, undefined);
  return (
    <form action={action}>
      <Box>
        <PlateBody>
          <div className="flex flex-wrap items-start gap-2">
            <div className="flex flex-col gap-1.5">
              <span className="type-ui text-ink">Owner</span>
              {owners.length > 1 ? (
                // You, or an organization you may create repositories in.
                <Select name="owner" aria-label="Owner" defaultValue={owner} options={owners.map((o) => ({ value: o, label: o }))} className="min-w-36" />
              ) : (
                // Not a choice here: the owner sits in a sunk, read-only well.
                <span className="flex h-8 items-center gap-2 rounded-[11px] recipe-well-field pr-3.5 pl-2 type-ui text-ink2">
                  <Avatar name={owner} size={20} /> {owner}
                  <input type="hidden" name="owner" value={owner} />
                </span>
              )}
            </div>
            <span aria-hidden className="mt-[22px] flex h-8 items-center type-content text-ink3">
              /
            </span>
            <TextField
              className="min-w-60 flex-1"
              label="Repository name"
              description="Great repository names are short and memorable."
              name="name"
              required
              autoFocus
              pattern="[A-Za-z0-9][A-Za-z0-9._\-]*"
              placeholder="my-project"
            />
          </div>

          <TextField label="Description" optional name="description" maxLength={350} placeholder="What’s this project about?" />
        </PlateBody>

        <Rule className="mx-6" />
        <PlateBody>
          <div className="flex flex-col gap-1.5">
            <span id="new-repo-visibility" className="type-ui text-ink">
              Visibility
            </span>
            <ChoiceCards
              name="visibility"
              aria-labelledby="new-repo-visibility"
              defaultValue="public"
              choices={[
                { value: "public", icon: <GlobeIcon />, title: "Public", description: "Anyone can see this repository. You choose who can push." },
                { value: "private", icon: <LockIcon />, title: "Private", description: "Only you and collaborators can see and push." },
              ]}
            />
          </div>
        </PlateBody>

        <Rule className="mx-6" />
        <PlateBody>
          <label className="flex cursor-pointer items-start gap-3">
            <Checkbox name="readme" defaultChecked className="mt-px" />
            <span className="flex flex-col gap-0.5">
              <span className="flex items-center gap-2 type-title text-ink">
                <BookIcon width={14} height={14} className="text-ink2" /> Add a README file
              </span>
              <span className="type-body text-ink2">Start with a first commit so you can edit files in the browser right away.</span>
            </span>
          </label>
          {state?.error && <Alert>{state.error}</Alert>}
        </PlateBody>

        <PlateFooter>
          <Button variant="primary" icon={<PlusIcon />} disabled={pending}>
            {pending ? "Creating…" : "Create Repository"}
          </Button>
        </PlateFooter>
      </Box>
    </form>
  );
}