Files
documenso/apps/remix/app/components/general/envelope-editor/envelope-file-selector.tsx
David Nguyen 7f09ba72f4 feat: add envelopes (#2025)
This PR is handles the changes required to support envelopes. The new
envelope editor/signing page will be hidden during release.

The core changes here is to migrate the documents and templates model to
a centralized envelopes model.

Even though Documents and Templates are removed, from the user
perspective they will still exist as we remap envelopes to documents and
templates.
2025-10-14 21:56:36 +11:00

88 lines
2.5 KiB
TypeScript

import { Plural } from '@lingui/react/macro';
import { useCurrentEnvelopeRender } from '@documenso/lib/client-only/providers/envelope-render-provider';
import { cn } from '@documenso/ui/lib/utils';
type EnvelopeItemSelectorProps = {
number: number;
primaryText: React.ReactNode;
secondaryText: React.ReactNode;
isSelected: boolean;
buttonProps: React.ButtonHTMLAttributes<HTMLButtonElement>;
};
export const EnvelopeItemSelector = ({
number,
primaryText,
secondaryText,
isSelected,
buttonProps,
}: EnvelopeItemSelectorProps) => {
return (
<button
className={`flex min-w-0 cursor-pointer items-center space-x-3 rounded-lg border px-4 py-3 transition-colors ${
isSelected
? 'border-blue-200 bg-blue-50 text-blue-900'
: 'border-gray-200 bg-gray-50 hover:bg-gray-100'
}`}
{...buttonProps}
>
<div
className={`flex h-6 w-6 items-center justify-center rounded-full text-xs font-medium ${
isSelected ? 'bg-blue-100 text-blue-600' : 'bg-gray-200 text-gray-600'
}`}
>
{number}
</div>
<div className="min-w-0 text-left">
<div className="truncate text-sm font-medium">{primaryText}</div>
<div className="text-xs text-gray-500">{secondaryText}</div>
</div>
<div
className={cn('h-2 w-2 rounded-full', {
'bg-blue-500': isSelected,
})}
></div>
</button>
);
};
type EnvelopeRendererFileSelectorProps = {
fields: { envelopeItemId: string }[];
className?: string;
secondaryOverride?: React.ReactNode;
};
export const EnvelopeRendererFileSelector = ({
fields,
className,
secondaryOverride,
}: EnvelopeRendererFileSelectorProps) => {
const { envelopeItems, currentEnvelopeItem, setCurrentEnvelopeItem } = useCurrentEnvelopeRender();
return (
<div className={cn('flex h-fit space-x-2 overflow-x-auto p-4', className)}>
{envelopeItems.map((doc, i) => (
<EnvelopeItemSelector
key={doc.id}
number={i + 1}
primaryText={doc.title}
secondaryText={
secondaryOverride ?? (
<Plural
one="1 Field"
other="# Fields"
value={fields.filter((field) => field.envelopeItemId === doc.id).length}
/>
)
}
isSelected={currentEnvelopeItem?.id === doc.id}
buttonProps={{
onClick: () => setCurrentEnvelopeItem(doc.id),
}}
/>
))}
</div>
);
};