"use client"; import { createPagadorAction, updatePagadorAction, } from "@/app/(dashboard)/pagadores/actions"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Textarea } from "@/components/ui/textarea"; import { useControlledState } from "@/hooks/use-controlled-state"; import { useFormState } from "@/hooks/use-form-state"; import { DEFAULT_PAGADOR_AVATAR, PAGADOR_STATUS_OPTIONS, type PagadorStatus, } from "@/lib/pagadores/constants"; import { RiCheckLine, RiCloseCircleLine } from "@remixicon/react"; import Image from "next/image"; import { useCallback, useEffect, useMemo, useState, useTransition, } from "react"; import { toast } from "sonner"; import { StatusSelectContent } from "./pagador-select-items"; import { getAvatarSrc } from "@/lib/pagadores/utils"; import type { Pagador, PagadorFormValues } from "./types"; interface PagadorDialogProps { mode: "create" | "update"; trigger?: React.ReactNode; pagador?: Pagador; avatarOptions: string[]; open?: boolean; onOpenChange?: (open: boolean) => void; } const buildInitialValues = ({ pagador, avatarOptions, }: { pagador?: Pagador; avatarOptions: string[]; }): PagadorFormValues => { const defaultAvatar = avatarOptions[0] ?? DEFAULT_PAGADOR_AVATAR; return { name: pagador?.name ?? "", email: pagador?.email ?? "", status: (pagador?.status as PagadorStatus) ?? PAGADOR_STATUS_OPTIONS[0], avatarUrl: pagador?.avatarUrl ?? defaultAvatar, note: pagador?.note ?? "", isAutoSend: pagador?.isAutoSend ?? false, }; }; export function PagadorDialog({ mode, trigger, pagador, avatarOptions, open, onOpenChange, }: PagadorDialogProps) { const [errorMessage, setErrorMessage] = useState(null); const [isPending, startTransition] = useTransition(); // Use controlled state hook for dialog open state const [dialogOpen, setDialogOpen] = useControlledState( open, false, onOpenChange ); const initialState = useMemo( () => buildInitialValues({ pagador, avatarOptions }), [pagador, avatarOptions] ); // Use form state hook for form management const { formState, updateField, setFormState } = useFormState(initialState); const availableAvatars = useMemo(() => { const set = new Set(); avatarOptions.forEach((avatar) => set.add(avatar)); set.add(initialState.avatarUrl); set.add(DEFAULT_PAGADOR_AVATAR); return Array.from(set).sort((a, b) => a.localeCompare(b, "pt-BR", { sensitivity: "base" }) ); }, [avatarOptions, initialState.avatarUrl]); // Reset form when dialog opens useEffect(() => { if (dialogOpen) { setFormState(initialState); setErrorMessage(null); } }, [dialogOpen, initialState, setFormState]); const handleSubmit = useCallback( (event: React.FormEvent) => { event.preventDefault(); setErrorMessage(null); if (mode === "update" && !pagador?.id) { const message = "Pagador inválido."; setErrorMessage(message); toast.error(message); return; } const payload: { name: string; email?: string; status: PagadorStatus; avatarUrl: string; note: string; isAutoSend: boolean; } = { name: formState.name.trim(), status: formState.status, avatarUrl: formState.avatarUrl, note: formState.note.trim(), isAutoSend: formState.isAutoSend, }; const emailValue = formState.email.trim(); if (emailValue.length > 0) { payload.email = emailValue; } startTransition(async () => { const result = mode === "create" ? await createPagadorAction(payload) : await updatePagadorAction({ id: pagador?.id ?? "", ...payload, }); if (result.success) { toast.success(result.message); setDialogOpen(false); setFormState(initialState); return; } setErrorMessage(result.error); toast.error(result.error); }); }, [formState, initialState, mode, pagador?.id, setDialogOpen, setFormState] ); const title = mode === "create" ? "Novo pagador" : "Editar pagador"; const description = mode === "create" ? "Selecione um avatar e informe os detalhes para criar um novo pagador." : "Atualize os detalhes do pagador selecionado."; const submitLabel = mode === "create" ? "Salvar pagador" : "Atualizar pagador"; return ( {trigger ? {trigger} : null} {title} {description}
updateField("name", event.target.value) } placeholder="Ex.: Felipe Coutinho" required />
updateField("email", event.target.value) } placeholder="Ex.: felipe@email.com" />
updateField("isAutoSend", Boolean(checked)) } aria-label="Ativar envio automático" />

Dispare cobranças e lembretes sem intervenção manual.

{availableAvatars.length === 0 ? (
Nenhum avatar disponível. Adicione imagens em public/avatares .
) : null} {availableAvatars.map((avatar) => { const isSelected = avatar === formState.avatarUrl; return ( ); })}