mirror of
https://github.com/documenso/documenso.git
synced 2026-08-25 15:52:29 +10:00
feat: add custom branding for signing pages (#2785)
Platform-plan organisations and teams can now customise non-embed signing pages with six brand colour tokens, a border-radius, and a free-text custom CSS block (up to 256 KB). - Stored on OrganisationGlobalSettings / TeamGlobalSettings; teams inherit from the org via brandingEnabled === null. - CSS is sanitised on save (PostCSS) so we can inline it at SSR with no per-render parsing. - Rendered via a nonce'd <style> scoped under .documenso-branded, using native CSS nesting so user selectors don't need scoping. - Gated on the existing embedSigningWhiteLabel claim (or self-hosted) — reuses the embed white-label decision.
This commit is contained in:
@@ -2,6 +2,7 @@ import { getOptionalSession } from '@documenso/auth/server/lib/utils/get-session
|
||||
import { EnvelopeRenderProvider } from '@documenso/lib/client-only/providers/envelope-render-provider';
|
||||
import { useOptionalSession } from '@documenso/lib/client-only/providers/session';
|
||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import { loadRecipientBrandingByTeamId } from '@documenso/lib/server-only/branding/load-recipient-branding';
|
||||
import { getEnvelopeForDirectTemplateSigning } from '@documenso/lib/server-only/envelope/get-envelope-for-direct-template-signing';
|
||||
import { getTemplateByDirectLinkToken } from '@documenso/lib/server-only/template/get-template-by-direct-link-token';
|
||||
import { DocumentAccessAuth } from '@documenso/lib/types/document-auth';
|
||||
@@ -20,6 +21,8 @@ import { DocumentSigningAuthProvider } from '~/components/general/document-signi
|
||||
import { DocumentSigningPageViewV2 } from '~/components/general/document-signing/document-signing-page-view-v2';
|
||||
import { DocumentSigningProvider } from '~/components/general/document-signing/document-signing-provider';
|
||||
import { EnvelopeSigningProvider } from '~/components/general/document-signing/envelope-signing-provider';
|
||||
import { RecipientBranding } from '~/components/general/recipient-branding';
|
||||
import { useCspNonce } from '~/utils/nonce';
|
||||
import { superLoaderJson, useSuperLoaderData } from '~/utils/super-json-loader';
|
||||
|
||||
import type { Route } from './+types/_index';
|
||||
@@ -125,6 +128,7 @@ export async function loader(loaderArgs: Route.LoaderArgs) {
|
||||
},
|
||||
select: {
|
||||
internalVersion: true,
|
||||
teamId: true,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -132,12 +136,17 @@ export async function loader(loaderArgs: Route.LoaderArgs) {
|
||||
throw new Response('Not Found', { status: 404 });
|
||||
}
|
||||
|
||||
const branding = await loadRecipientBrandingByTeamId({
|
||||
teamId: directEnvelope.teamId,
|
||||
});
|
||||
|
||||
if (directEnvelope.internalVersion === 2) {
|
||||
const payloadV2 = await handleV2Loader(loaderArgs);
|
||||
|
||||
return superLoaderJson({
|
||||
version: 2,
|
||||
payload: payloadV2,
|
||||
branding,
|
||||
} as const);
|
||||
}
|
||||
|
||||
@@ -146,17 +155,20 @@ export async function loader(loaderArgs: Route.LoaderArgs) {
|
||||
return superLoaderJson({
|
||||
version: 1,
|
||||
payload: payloadV1,
|
||||
branding,
|
||||
} as const);
|
||||
}
|
||||
|
||||
export default function DirectTemplatePage() {
|
||||
const data = useSuperLoaderData<typeof loader>();
|
||||
const cspNonce = useCspNonce();
|
||||
|
||||
if (data.version === 2) {
|
||||
return <DirectSigningPageV2 data={data.payload} />;
|
||||
}
|
||||
|
||||
return <DirectSigningPageV1 data={data.payload} />;
|
||||
return (
|
||||
<>
|
||||
<RecipientBranding branding={data.branding} cspNonce={cspNonce} />
|
||||
{data.version === 2 ? <DirectSigningPageV2 data={data.payload} /> : <DirectSigningPageV1 data={data.payload} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const DirectSigningPageV1 = ({ data }: { data: Awaited<ReturnType<typeof handleV1Loader>> }) => {
|
||||
|
||||
Reference in New Issue
Block a user