import { useOptionalCurrentOrganisation } from '@documenso/lib/client-only/providers/organisation'; import { SUPPORT_EMAIL } from '@documenso/lib/constants/app'; import { DO_NOT_INVALIDATE_QUERY_ON_MUTATION, SKIP_QUERY_BATCH_META } from '@documenso/lib/constants/trpc'; import { INTERNAL_CLAIM_ID } from '@documenso/lib/types/subscription'; import { trpc } from '@documenso/trpc/react'; import { cn } from '@documenso/ui/lib/utils'; import { Alert, AlertDescription } from '@documenso/ui/primitives/alert'; import { Button } from '@documenso/ui/primitives/button'; import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@documenso/ui/primitives/dialog'; import { Trans } from '@lingui/react/macro'; import { AlertTriangle } from 'lucide-react'; import { useState } from 'react'; export const OrganisationQuotaBanner = () => { const [isOpen, setIsOpen] = useState(false); const organisation = useOptionalCurrentOrganisation(); const { data: quotaFlags } = trpc.organisation.getQuotaFlags.useQuery( { organisationId: organisation?.id ?? '' }, { enabled: Boolean(organisation), ...DO_NOT_INVALIDATE_QUERY_ON_MUTATION, ...SKIP_QUERY_BATCH_META, refetchInterval: 1000 * 60, refetchIntervalInBackground: false, }, ); const isAnyQuotaExceeded = Boolean( quotaFlags?.isDocumentQuotaExceeded || quotaFlags?.isEmailQuotaExceeded || quotaFlags?.isApiQuotaExceeded, ); const isAnyQuotaNearing = Boolean( quotaFlags?.isDocumentQuotaNearing || quotaFlags?.isEmailQuotaNearing || quotaFlags?.isApiQuotaNearing, ); // Every member of the organisation sees the banner when a quota is exhausted or // nearing its limit. When both states apply, "exceeded" wins for the banner copy // and the dialog lists both exceeded and nearing items. // Note: Skipping free plan banner for now because their quota can incorrectly show as exceeded. if ( !organisation || !quotaFlags || (!isAnyQuotaExceeded && !isAnyQuotaNearing) || organisation.organisationClaim.originalSubscriptionClaimId === INTERNAL_CLAIM_ID.FREE ) { return null; } return ( <>