83 lines
2.5 KiB
TypeScript
83 lines
2.5 KiB
TypeScript
"use client";
|
|
|
|
import { useActionState, useState } from "react";
|
|
import { suggestSlug } from "@/lib/slug";
|
|
import { addBusinessAction, type AddBusinessState } from "./actions";
|
|
|
|
const initialState: AddBusinessState = { error: null };
|
|
|
|
export function AddBusinessForm() {
|
|
const [state, formAction, isPending] = useActionState(addBusinessAction, initialState);
|
|
const [slug, setSlug] = useState("");
|
|
const [slugTouched, setSlugTouched] = useState(false);
|
|
|
|
return (
|
|
<form action={formAction} className="space-y-4">
|
|
<div>
|
|
<label htmlFor="name" className="block text-sm font-medium text-muted">
|
|
Business name
|
|
</label>
|
|
<input
|
|
id="name"
|
|
name="name"
|
|
type="text"
|
|
required
|
|
onChange={(e) => {
|
|
if (!slugTouched) setSlug(suggestSlug(e.target.value));
|
|
}}
|
|
className="mt-1 w-full rounded-md border border-line px-3 py-2 text-sm"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label htmlFor="slug" className="block text-sm font-medium text-muted">
|
|
Slug
|
|
</label>
|
|
<input
|
|
id="slug"
|
|
name="slug"
|
|
type="text"
|
|
required
|
|
value={slug}
|
|
onChange={(e) => {
|
|
setSlugTouched(true);
|
|
setSlug(e.target.value);
|
|
}}
|
|
className="mt-1 w-full rounded-md border border-line px-3 py-2 font-mono text-sm"
|
|
/>
|
|
<p className="mt-1 text-xs text-muted">
|
|
Used for the container name, database name, and stack directory — lowercase letters, numbers, and hyphens
|
|
only.
|
|
</p>
|
|
</div>
|
|
<div>
|
|
<label htmlFor="domain" className="block text-sm font-medium text-muted">
|
|
Domain
|
|
</label>
|
|
<input
|
|
id="domain"
|
|
name="domain"
|
|
type="text"
|
|
required
|
|
placeholder="business.example.com"
|
|
className="mt-1 w-full rounded-md border border-line px-3 py-2 text-sm"
|
|
/>
|
|
<p className="mt-1 text-xs text-muted">
|
|
Must already point at this server’s IP before Caddy can issue a certificate for it.
|
|
</p>
|
|
</div>
|
|
{state.error && (
|
|
<p role="alert" className="text-sm font-medium text-danger">
|
|
{state.error}
|
|
</p>
|
|
)}
|
|
<button
|
|
type="submit"
|
|
disabled={isPending}
|
|
className="w-full rounded-md bg-ink py-2 text-sm font-semibold text-white disabled:opacity-60"
|
|
>
|
|
{isPending ? "Provisioning…" : "Create Business"}
|
|
</button>
|
|
</form>
|
|
);
|
|
}
|