'use client'; import { useMemo, useState } from 'react'; import Link from 'next/link'; import { useRouter } from 'next/navigation'; import { Loader } from 'lucide-react'; import { useSession } from 'next-auth/react'; import { useLimits } from '@documenso/ee/server-only/limits/provider/client'; import { useAnalytics } from '@documenso/lib/client-only/hooks/use-analytics'; import { APP_DOCUMENT_UPLOAD_SIZE_LIMIT } from '@documenso/lib/constants/app'; import { createDocumentData } from '@documenso/lib/server-only/document-data/create-document-data'; import { putFile } from '@documenso/lib/universal/upload/put-file'; import { formatDocumentsPath } from '@documenso/lib/utils/teams'; import { TRPCClientError } from '@documenso/trpc/client'; import { trpc } from '@documenso/trpc/react'; import { cn } from '@documenso/ui/lib/utils'; import { DocumentDropzone } from '@documenso/ui/primitives/document-dropzone'; import { useToast } from '@documenso/ui/primitives/use-toast'; export type UploadDocumentProps = { className?: string; team?: { id: number; url: string; }; }; export const UploadDocument = ({ className, team }: UploadDocumentProps) => { const router = useRouter(); const analytics = useAnalytics(); const { data: session } = useSession(); const { toast } = useToast(); const { quota, remaining } = useLimits(); const [isLoading, setIsLoading] = useState(false); const { mutateAsync: createDocument } = trpc.document.createDocument.useMutation(); const disabledMessage = useMemo(() => { if (remaining.documents === 0) { return team ? 'Document upload disabled due to unpaid invoices' : 'You have reached your document limit.'; } if (!session?.user.emailVerified) { return 'Verify your email to upload documents.'; } }, [remaining.documents, session?.user.emailVerified, team]); const onFileDrop = async (file: File) => { try { setIsLoading(true); const { type, data } = await putFile(file); const { id: documentDataId } = await createDocumentData({ type, data, }); const { id } = await createDocument({ title: file.name, documentDataId, teamId: team?.id, }); toast({ title: 'Document uploaded', description: 'Your document has been uploaded successfully.', duration: 5000, }); analytics.capture('App: Document Uploaded', { userId: session?.user.id, documentId: id, timestamp: new Date().toISOString(), }); router.push(`${formatDocumentsPath(team?.url)}/${id}/edit`); } catch (error) { console.error(error); if (error instanceof TRPCClientError) { toast({ title: 'Error', description: error.message, variant: 'destructive', }); } else { toast({ title: 'Error', description: 'An error occurred while uploading your document.', variant: 'destructive', }); } } finally { setIsLoading(false); } }; const onFileDropRejected = () => { toast({ title: 'Your document failed to upload.', description: `File cannot be larger than ${APP_DOCUMENT_UPLOAD_SIZE_LIMIT}MB`, duration: 5000, variant: 'destructive', }); }; return (
{team?.id === undefined && remaining.documents > 0 && Number.isFinite(remaining.documents) && (

{remaining.documents} of {quota.documents} documents remaining this month.

)}
{isLoading && (
)} {team?.id === undefined && remaining.documents === 0 && (

You have reached your document limit.

You can upload up to {quota.documents} documents per month on your current plan.

Upgrade your account to upload more documents.
)}
); };