import { useState } from 'react'; import { zodResolver } from '@hookform/resolvers/zod'; import { msg } from '@lingui/core/macro'; import { useLingui } from '@lingui/react'; import { Trans } from '@lingui/react/macro'; import { Paperclip, Plus, X } from 'lucide-react'; import { useForm } from 'react-hook-form'; import { z } from 'zod'; import { AppError } from '@documenso/lib/errors/app-error'; import { trpc } from '@documenso/trpc/react'; import { cn } from '@documenso/ui/lib/utils'; import { Button } from '@documenso/ui/primitives/button'; import { Form, FormControl, FormField, FormItem, FormMessage, } from '@documenso/ui/primitives/form/form'; import { Input } from '@documenso/ui/primitives/input'; import { Popover, PopoverContent, PopoverTrigger } from '@documenso/ui/primitives/popover'; import { useToast } from '@documenso/ui/primitives/use-toast'; export type DocumentAttachmentsPopoverProps = { envelopeId: string; buttonClassName?: string; buttonSize?: 'sm' | 'default'; }; const ZAttachmentFormSchema = z.object({ label: z.string().min(1, 'Label is required'), url: z.string().url('Must be a valid URL'), }); type TAttachmentFormSchema = z.infer; export const DocumentAttachmentsPopover = ({ envelopeId, buttonClassName, buttonSize, }: DocumentAttachmentsPopoverProps) => { const { toast } = useToast(); const { _ } = useLingui(); const [isOpen, setIsOpen] = useState(false); const [isAdding, setIsAdding] = useState(false); const utils = trpc.useUtils(); const { data: attachments } = trpc.envelope.attachment.find.useQuery({ envelopeId, }); const { mutateAsync: createAttachment, isPending: isCreating } = trpc.envelope.attachment.create.useMutation({ onSuccess: () => { void utils.envelope.attachment.find.invalidate({ envelopeId }); }, }); const { mutateAsync: deleteAttachment } = trpc.envelope.attachment.delete.useMutation({ onSuccess: () => { void utils.envelope.attachment.find.invalidate({ envelopeId }); }, }); const form = useForm({ resolver: zodResolver(ZAttachmentFormSchema), defaultValues: { label: '', url: '', }, }); const onSubmit = async (data: TAttachmentFormSchema) => { try { await createAttachment({ envelopeId, data: { label: data.label, data: data.url, }, }); form.reset(); setIsAdding(false); toast({ title: _(msg`Success`), description: _(msg`Attachment added successfully.`), }); } catch (err) { const error = AppError.parseError(err); toast({ title: _(msg`Error`), description: error.message, variant: 'destructive', }); } }; const onDeleteAttachment = async (id: string) => { try { await deleteAttachment({ id }); toast({ title: _(msg`Success`), description: _(msg`Attachment removed successfully.`), }); } catch (err) { const error = AppError.parseError(err); toast({ title: _(msg`Error`), description: error.message, variant: 'destructive', }); } }; return (

Attachments

Add links to relevant documents or resources.

{attachments && attachments.data.length > 0 && (
{attachments?.data.map((attachment) => (

{attachment.label}

{attachment.data}
))}
)} {!isAdding && ( )} {isAdding && (
( )} /> ( )} />
)}
); };