import { FormControl, FormField, FormItem, FormLabel, FormMessage } from '@documenso/ui/primitives/form/form'; import { Input } from '@documenso/ui/primitives/input'; import { Trans, useLingui } from '@lingui/react/macro'; import type { ReactNode } from 'react'; import type { Control, FieldValues, Path } from 'react-hook-form'; import { RateLimitArrayInput } from './rate-limit-array-input'; /** * The rate-limit editor renders its own per-row inline errors, but a submit * attempt can still surface array-level Zod issues (e.g. a committed duplicate * window). Rendering the field's message here guarantees the form never fails * silently when those errors are not tied to a row the editor is showing. */ type ClaimLimitFieldsProps = { control: Control; /** e.g. '' for the claim form, 'claims.' for the org admin form. */ prefix?: string; disabled?: boolean; }; type LimitGroup = { title: ReactNode; quotaKey: string; rateLimitKey: string; }; export const ClaimLimitFields = ({ control, prefix = '', disabled, }: ClaimLimitFieldsProps) => { const { t } = useLingui(); // eslint-disable-next-line @typescript-eslint/consistent-type-assertions const name = (key: string) => `${prefix}${key}` as Path; const limitGroups: LimitGroup[] = [ { title: Documents, quotaKey: 'documentQuota', rateLimitKey: 'documentRateLimits', }, { title: Emails, quotaKey: 'emailQuota', rateLimitKey: 'emailRateLimits', }, { title: API, quotaKey: 'apiQuota', rateLimitKey: 'apiRateLimits', }, ]; const renderQuotaField = (group: LimitGroup) => ( ( Monthly quota field.onChange(e.target.value === '' ? null : parseInt(e.target.value, 10))} /> )} /> ); const renderRateLimitField = (group: LimitGroup) => ( ( )} /> ); return (

Limits

Empty quota means unlimited, 0 blocks the resource. Rate limit windows accept values like 5m, 1h or 24h.

{limitGroups.map((group) => (

{group.title}

{renderQuotaField(group)} {renderRateLimitField(group)}
))}
); };