import { useCurrentEnvelopeEditor } from '@documenso/lib/client-only/providers/envelope-editor-provider'; import { nanoid } from '@documenso/lib/universal/id'; import { isHttpUrl, toSafeHref } from '@documenso/lib/utils/is-http-url'; 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'; 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 { useState } from 'react'; import { useForm } from 'react-hook-form'; import { z } from 'zod'; export type EmbeddedEditorAttachmentPopoverProps = { 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').refine(isHttpUrl, 'URL must use the http or https protocol'), }); type TAttachmentFormSchema = z.infer; // NOTE: REMEMBER TO UPDATE THE NON-EMBEDDED VERSION OF THIS COMPONENT TOO. export const EmbeddedEditorAttachmentPopover = ({ buttonClassName, buttonSize, }: EmbeddedEditorAttachmentPopoverProps) => { const { toast } = useToast(); const { _ } = useLingui(); const [isOpen, setIsOpen] = useState(false); const [isAdding, setIsAdding] = useState(false); const { envelope, setLocalEnvelope } = useCurrentEnvelopeEditor(); const attachments = envelope.attachments ?? []; const form = useForm({ resolver: zodResolver(ZAttachmentFormSchema), defaultValues: { label: '', url: '', }, }); const onSubmit = (data: TAttachmentFormSchema) => { setLocalEnvelope({ attachments: [ ...attachments, { id: nanoid(), type: 'link', label: data.label, data: data.url, }, ], }); form.reset(); setIsAdding(false); toast({ title: _(msg`Success`), description: _(msg`Attachment added successfully.`), }); }; const onDeleteAttachment = (id: string) => { setLocalEnvelope({ attachments: attachments.filter((a) => a.id !== id), }); toast({ title: _(msg`Success`), description: _(msg`Attachment removed successfully.`), }); }; return (

Attachments

Add links to relevant documents or resources.

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

{attachment.label}

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