"use client";
import { useActionState } from "react";
import { Rule, Select } from "@unlocalhosted/metalui";
import type { FormState } from "@/app/actions/types";
import { DeleteZone } from "./delete-zone";
import { BookmarkIcon, GlobeIcon, LockIcon, PlusIcon } from "./icons";
import { ChoiceCards, TextareaField, TextField } from "./settings-fields";
import { PlateBody, PlateFooter } from "./settings-plate";
import { Alert, Avatar, Box, Button } from "./ui";
type Action = (prev: FormState, formData: FormData) => Promise<FormState>;
export type ListFields = { name: string; description: string; visibility: "public" | "private" };
/** A list's name, description and visibility; new lists also choose their owner (you, or an organization). */
export function ListForm({ action, owners, owner, list }: { action: Action; owners: string[]; owner: string; list?: ListFields }) {
const [state, formAction, pending] = useActionState(action, undefined);
return (
<form action={formAction}>
<Box>
<PlateBody>
{!list && (
<div className="flex flex-col gap-1.5">
<span className="type-ui text-ink">Owner</span>
{owners.length > 1 ? (
<Select name="owner" aria-label="Owner" defaultValue={owner} options={owners.map((o) => ({ value: o, label: o }))} className="self-start min-w-36" />
) : (
<span className="flex h-8 items-center gap-2 self-start 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>
)}
<TextField
label="Name"
description={list ? "Renaming the list changes its address." : "Its address is made from the name, e.g. /lists/alice/tools-i-use."}
name="name"
required
autoFocus={!list}
maxLength={60}
defaultValue={list?.name}
placeholder="Tools I use"
/>
<TextareaField label="Description" optional name="description" minRows={2} maxLength={300} defaultValue={list?.description} placeholder="What do these repositories have in common?" />
</PlateBody>
<Rule className="mx-6" />
<PlateBody>
<div className="flex flex-col gap-1.5">
<span id="list-visibility" className="type-ui text-ink">
Visibility
</span>
<ChoiceCards
name="visibility"
aria-labelledby="list-visibility"
defaultValue={list?.visibility ?? "public"}
choices={[
{ value: "public", icon: <GlobeIcon />, title: "Public", description: "Anyone can see the list. Private repositories in it stay hidden from those who can’t see them." },
{ value: "private", icon: <LockIcon />, title: "Private", description: "Only you can see it, or for an organization’s list, its members." },
]}
/>
</div>
{state?.error && <Alert>{state.error}</Alert>}
</PlateBody>
<PlateFooter>
<Button variant="primary" icon={list ? <BookmarkIcon /> : <PlusIcon />} disabled={pending}>
{list ? (pending ? "Saving…" : "Save List") : pending ? "Creating…" : "Create List"}
</Button>
</PlateFooter>
</Box>
</form>
);
}
export function DeleteListZone({ action, name }: { action: Action; name: string }) {
return (
<DeleteZone
action={action}
confirmText={name}
title="Delete this list"
description="The repositories in it stay as they are; only the list goes."
consequence={
<>
This will permanently delete the list <strong>{name}</strong>.
</>
}
openLabel="Delete List"
confirmLabel="I Understand, Delete This List"
/>
);
}