47 lines
1.5 KiB
TypeScript
47 lines
1.5 KiB
TypeScript
"use client";
|
|
|
|
import { useActionState, useEffect, useRef } from "react";
|
|
import { inviteUser, type InviteStatus } from "@/app/dashboard/settings/team/actions";
|
|
|
|
export function InviteMemberForm() {
|
|
const formRef = useRef<HTMLFormElement>(null);
|
|
const [state, formAction, isPending] = useActionState<InviteStatus | null, FormData>(
|
|
inviteUser,
|
|
null
|
|
);
|
|
|
|
useEffect(() => {
|
|
if (state?.success) {
|
|
formRef.current?.reset();
|
|
}
|
|
}, [state]);
|
|
|
|
return (
|
|
<div className="space-y-4">
|
|
<form ref={formRef} action={formAction} className="flex gap-4">
|
|
<input
|
|
type="email"
|
|
name="email"
|
|
placeholder="Email address"
|
|
required
|
|
disabled={isPending}
|
|
className="flex-1 px-3 py-2 bg-background border border-border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-ring disabled:opacity-50"
|
|
/>
|
|
<button
|
|
type="submit"
|
|
disabled={isPending}
|
|
className="bg-primary text-primary-foreground px-4 py-2 rounded-md text-sm font-medium hover:bg-primary/90 transition-colors flex-shrink-0 disabled:opacity-50"
|
|
>
|
|
{isPending ? "Sending..." : "Send Invite"}
|
|
</button>
|
|
</form>
|
|
|
|
{state?.error && (
|
|
<p className="text-sm text-destructive mt-1 animate-in fade-in slide-in-from-top-1">{state.error}</p>
|
|
)}
|
|
{state?.success && (
|
|
<p className="text-sm text-green-500 mt-1 animate-in fade-in slide-in-from-top-1">{state.message}</p>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|