diff --git a/apps/remix/app/components/embed/embed-document-signing-page.tsx b/apps/remix/app/components/embed/embed-document-signing-page.tsx index 79d87e6aa..31cbe3b0d 100644 --- a/apps/remix/app/components/embed/embed-document-signing-page.tsx +++ b/apps/remix/app/components/embed/embed-document-signing-page.tsx @@ -15,6 +15,7 @@ import { LucideChevronDown, LucideChevronUp } from 'lucide-react'; import { useThrottleFn } from '@documenso/lib/client-only/hooks/use-throttle-fn'; import { PDF_VIEWER_PAGE_SELECTOR } from '@documenso/lib/constants/pdf-viewer'; +import type { DocumentField } from '@documenso/lib/server-only/field/get-fields-for-document'; import { isFieldUnsignedAndRequired } from '@documenso/lib/utils/advanced-fields-helpers'; import { validateFieldsInserted } from '@documenso/lib/utils/fields'; import type { RecipientWithFields } from '@documenso/prisma/types/recipient-with-fields'; @@ -36,6 +37,7 @@ import { ZSignDocumentEmbedDataSchema } from '../../types/embed-document-sign-sc import { useRequiredDocumentSigningContext } from '../general/document-signing/document-signing-provider'; import { DocumentSigningRecipientProvider } from '../general/document-signing/document-signing-recipient-provider'; import { DocumentSigningRejectDialog } from '../general/document-signing/document-signing-reject-dialog'; +import { DocumentReadOnlyFields } from '../general/document/document-read-only-fields'; import { EmbedClientLoading } from './embed-client-loading'; import { EmbedDocumentCompleted } from './embed-document-completed'; import { EmbedDocumentFields } from './embed-document-fields'; @@ -47,6 +49,7 @@ export type EmbedSignDocumentClientPageProps = { documentData: DocumentData; recipient: RecipientWithFields; fields: Field[]; + completedFields: DocumentField[]; metadata?: DocumentMeta | TemplateMeta | null; isCompleted?: boolean; hidePoweredBy?: boolean; @@ -60,6 +63,7 @@ export const EmbedSignDocumentClientPage = ({ documentData, recipient, fields, + completedFields, metadata, isCompleted, hidePoweredBy = false, @@ -85,6 +89,8 @@ export const EmbedSignDocumentClientPage = ({ const [isExpanded, setIsExpanded] = useState(false); const [isNameLocked, setIsNameLocked] = useState(false); const [showPendingFieldTooltip, setShowPendingFieldTooltip] = useState(false); + const [showOtherRecipientsCompletedFields, setShowOtherRecipientsCompletedFields] = + useState(false); const [allowDocumentRejection, setAllowDocumentRejection] = useState(false); @@ -202,6 +208,7 @@ export const EmbedSignDocumentClientPage = ({ // a to be provided by the parent application, unlike direct templates. setIsNameLocked(!!data.lockName); setAllowDocumentRejection(!!data.allowDocumentRejection); + setShowOtherRecipientsCompletedFields(!!data.showOtherRecipientsCompletedFields); if (data.darkModeDisabled) { document.documentElement.classList.add('dark-mode-disabled'); @@ -468,6 +475,9 @@ export const EmbedSignDocumentClientPage = ({ {/* Fields */} + + {/* Completed fields */} + {!hidePoweredBy && ( diff --git a/apps/remix/app/components/general/document-signing/document-signing-page-view.tsx b/apps/remix/app/components/general/document-signing/document-signing-page-view.tsx index 628e66dca..c194d8e61 100644 --- a/apps/remix/app/components/general/document-signing/document-signing-page-view.tsx +++ b/apps/remix/app/components/general/document-signing/document-signing-page-view.tsx @@ -157,7 +157,7 @@ export const DocumentSigningPageView = ({ - + {recipient.role !== RecipientRole.ASSISTANT && ( diff --git a/apps/remix/app/components/general/document/document-read-only-fields.tsx b/apps/remix/app/components/general/document/document-read-only-fields.tsx index 6970a88be..26b0b20da 100644 --- a/apps/remix/app/components/general/document/document-read-only-fields.tsx +++ b/apps/remix/app/components/general/document/document-read-only-fields.tsx @@ -2,7 +2,7 @@ import { useState } from 'react'; import { useLingui } from '@lingui/react'; import { Trans } from '@lingui/react/macro'; -import type { DocumentMeta } from '@prisma/client'; +import type { DocumentMeta, TemplateMeta } from '@prisma/client'; import { FieldType, SigningStatus } from '@prisma/client'; import { Clock, EyeOffIcon } from 'lucide-react'; import { P, match } from 'ts-pattern'; @@ -27,7 +27,7 @@ import { PopoverHover } from '@documenso/ui/primitives/popover'; export type DocumentReadOnlyFieldsProps = { fields: DocumentField[]; - documentMeta?: DocumentMeta; + documentMeta?: DocumentMeta | TemplateMeta; showFieldStatus?: boolean; }; diff --git a/apps/remix/app/routes/embed+/sign.$url.tsx b/apps/remix/app/routes/embed+/sign.$url.tsx index 75ad163f2..7c16e3beb 100644 --- a/apps/remix/app/routes/embed+/sign.$url.tsx +++ b/apps/remix/app/routes/embed+/sign.$url.tsx @@ -8,6 +8,7 @@ import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-ent import { isDocumentPlatform } from '@documenso/ee/server-only/util/is-document-platform'; import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app'; import { getDocumentAndSenderByToken } from '@documenso/lib/server-only/document/get-document-by-token'; +import { getCompletedFieldsForToken } from '@documenso/lib/server-only/field/get-completed-fields-for-token'; import { getFieldsForToken } from '@documenso/lib/server-only/field/get-fields-for-token'; import { getIsRecipientsTurnToSign } from '@documenso/lib/server-only/recipient/get-is-recipient-turn'; import { getRecipientByToken } from '@documenso/lib/server-only/recipient/get-recipient-by-token'; @@ -33,7 +34,7 @@ export async function loader({ params, request }: Route.LoaderArgs) { const { user } = await getOptionalSession(request); - const [document, fields, recipient] = await Promise.all([ + const [document, fields, recipient, completedFields] = await Promise.all([ getDocumentAndSenderByToken({ token, userId: user?.id, @@ -41,6 +42,7 @@ export async function loader({ params, request }: Route.LoaderArgs) { }).catch(() => null), getFieldsForToken({ token }), getRecipientByToken({ token }).catch(() => null), + getCompletedFieldsForToken({ token }).catch(() => []), ]); // `document.directLink` is always available but we're doing this to @@ -130,6 +132,7 @@ export async function loader({ params, request }: Route.LoaderArgs) { allRecipients, recipient, fields, + completedFields, hidePoweredBy, isPlatformDocument, isEnterpriseDocument, @@ -145,6 +148,7 @@ export default function EmbedSignDocumentPage() { allRecipients, recipient, fields, + completedFields, hidePoweredBy, isPlatformDocument, isEnterpriseDocument, @@ -171,6 +175,7 @@ export default function EmbedSignDocumentPage() { documentData={document.documentData} recipient={recipient} fields={fields} + completedFields={completedFields} metadata={document.documentMeta} isCompleted={isDocumentCompleted(document.status)} hidePoweredBy={ diff --git a/apps/remix/app/types/embed-document-sign-schema.ts b/apps/remix/app/types/embed-document-sign-schema.ts index 72d4c1992..4de1c7ed8 100644 --- a/apps/remix/app/types/embed-document-sign-schema.ts +++ b/apps/remix/app/types/embed-document-sign-schema.ts @@ -14,4 +14,5 @@ export const ZSignDocumentEmbedDataSchema = ZBaseEmbedDataSchema.extend({ .transform((value) => value || undefined), lockName: z.boolean().optional().default(false), allowDocumentRejection: z.boolean().optional(), + showOtherRecipientsCompletedFields: z.boolean().optional(), });