"use client" import { useMemo, useState, useTransition } from "react" import { useRouter } from "next/navigation" import { toast } from "sonner" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import type { RoleOption } from "@/lib/authz" type InviteStatus = "pending" | "accepted" | "revoked" | "expired" type InviteSummary = { id: string email: string name: string | null role: RoleOption tenantId: string status: InviteStatus token: string expiresAt: string } function formatDate(dateIso: string) { return new Intl.DateTimeFormat("pt-BR", { dateStyle: "long", timeStyle: "short", }).format(new Date(dateIso)) } function statusLabel(status: InviteStatus) { switch (status) { case "pending": return "Pendente" case "accepted": return "Aceito" case "revoked": return "Revogado" case "expired": return "Expirado" default: return status } } function statusVariant(status: InviteStatus) { if (status === "pending") return "secondary" if (status === "accepted") return "default" if (status === "revoked") return "destructive" return "outline" } export function InviteAcceptForm({ invite }: { invite: InviteSummary }) { const router = useRouter() const [name, setName] = useState(invite.name ?? "") const [password, setPassword] = useState("") const [confirmPassword, setConfirmPassword] = useState("") const [isPending, startTransition] = useTransition() const formattedExpiry = useMemo(() => formatDate(invite.expiresAt), [invite.expiresAt]) const isDisabled = invite.status !== "pending" function validate() { if (!password || password.length < 8) { toast.error("A senha deve ter pelo menos 8 caracteres") return false } if (password !== confirmPassword) { toast.error("As senhas não coincidem") return false } return true } function handleSubmit(event: React.FormEvent) { event.preventDefault() if (isDisabled) return if (!validate()) return startTransition(async () => { try { const response = await fetch(`/api/invites/${invite.token}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name, password }), }) if (!response.ok) { const data = await response.json().catch(() => ({})) throw new Error(data.error ?? "Não foi possível aceitar o convite") } toast.success("Convite aceito! Faça login para começar.") router.push(`/login?email=${encodeURIComponent(invite.email)}`) } catch (error) { const message = error instanceof Error ? error.message : "Falha ao aceitar convite" toast.error(message) } }) } return (
{statusLabel(invite.status)}

Convite direcionado para {invite.email}

Papel previsto: {invite.role} • Tenant: {invite.tenantId}

Válido até {formattedExpiry}

{isDisabled ? (

Este convite encontra-se {statusLabel(invite.status).toLowerCase()}. Solicite um novo convite à equipe administradora caso precise de acesso.

) : null}
setName(event.target.value)} autoComplete="name" disabled={isDisabled} />
setPassword(event.target.value)} placeholder="Mínimo de 8 caracteres" autoComplete="new-password" disabled={isDisabled} required />
setConfirmPassword(event.target.value)} autoComplete="new-password" disabled={isDisabled} required />
) }