chore: dependency updates

This commit is contained in:
Lucas Smith
2025-11-22 00:06:12 +11:00
parent 17c6098638
commit 7ff27b3b30
95 changed files with 16657 additions and 72401 deletions

View File

@ -1,7 +1,8 @@
import type { NextConfig } from 'next';
import nextra from 'nextra';
/** @type {import('next').NextConfig} */
const nextConfig = {
const nextConfig: NextConfig = {
transpilePackages: [
'@documenso/assets',
'@documenso/lib',

View File

@ -4,7 +4,7 @@
"private": true,
"scripts": {
"dev": "next dev -p 3002",
"build": "next build && next-sitemap",
"build": "next build",
"start": "next start -p 3002",
"lint:fix": "next lint --fix",
"clean": "rimraf .next && rimraf node_modules"
@ -15,18 +15,18 @@
"@documenso/tailwind-config": "*",
"@documenso/trpc": "*",
"@documenso/ui": "*",
"next": "14.2.28",
"next-plausible": "^3.12.0",
"nextra": "^2.13.4",
"nextra-theme-docs": "^2.13.4",
"next": "^15",
"next-plausible": "^3.12.5",
"nextra": "^3",
"nextra-theme-docs": "^3",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18",
"@types/react": "18.3.27",
"@types/react-dom": "^18",
"next-sitemap": "^4.2.3",
"pagefind": "^1.2.0",
"typescript": "5.6.2"
}
}
}

View File

@ -1,10 +0,0 @@
import { PlausibleProvider } from '../providers/plausible.tsx';
import '../styles.css';
export default function App({ Component, pageProps }) {
return (
<PlausibleProvider>
<Component {...pageProps} />
</PlausibleProvider>
);
}

View File

@ -0,0 +1,18 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import React from 'react';
import { PlausibleProvider } from '../providers/plausible';
import '../styles.css';
export type AppProps = {
Component: React.ComponentType<any>;
pageProps: any;
};
export default function App({ Component, pageProps }: AppProps) {
return (
<PlausibleProvider>
<Component {...pageProps} />
</PlausibleProvider>
);
}

View File

@ -0,0 +1,34 @@
export default {
index: {
type: 'page',
title: 'Home',
display: 'hidden',
theme: {
timestamp: false,
},
},
users: {
type: 'page',
title: 'Users',
},
developers: {
type: 'page',
title: 'Developers',
},
updates: {
title: "What's New",
type: 'menu',
items: {
changelog: {
title: 'Changelog',
href: 'https://documenso.com/changelog',
newWindow: true,
},
blog: {
title: 'Blog',
href: 'https://documenso.com/blog',
newWindow: true,
},
},
},
};

View File

@ -1,34 +0,0 @@
{
"index": {
"type": "page",
"title": "Home",
"display": "hidden",
"theme": {
"timestamp": false
}
},
"users": {
"type": "page",
"title": "Users"
},
"developers": {
"type": "page",
"title": "Developers"
},
"updates": {
"title": "What's New",
"type": "menu",
"items": {
"changelog": {
"title": "Changelog",
"href": "https://documenso.com/changelog",
"newWindow": true
},
"blog": {
"title": "Blog",
"href": "https://documenso.com/blog",
"newWindow": true
}
}
}
}

View File

@ -0,0 +1,18 @@
export default {
index: 'Introduction',
'-- Development & Deployment': {
type: 'separator',
title: 'Development & Deployment',
},
'local-development': 'Local Development',
'developer-mode': 'Developer Mode',
'self-hosting': 'Self Hosting',
contributing: 'Contributing',
'-- API & Integration Guides': {
type: 'separator',
title: 'API & Integration Guides',
},
'public-api': 'Public API',
embedding: 'Embedding',
webhooks: 'Webhooks',
};

View File

@ -1,18 +0,0 @@
{
"index": "Introduction",
"-- Development & Deployment": {
"type": "separator",
"title": "Development & Deployment"
},
"local-development": "Local Development",
"developer-mode": "Developer Mode",
"self-hosting": "Self Hosting",
"contributing": "Contributing",
"-- API & Integration Guides": {
"type": "separator",
"title": "API & Integration Guides"
},
"public-api": "Public API",
"embedding": "Embedding",
"webhooks": "Webhooks"
}

View File

@ -0,0 +1,4 @@
export default {
index: 'Getting Started',
'contributing-translations': 'Contributing Translations',
};

View File

@ -1,4 +0,0 @@
{
"index": "Getting Started",
"contributing-translations": "Contributing Translations"
}

View File

@ -0,0 +1,11 @@
export default {
index: 'Get Started',
react: 'React Integration',
vue: 'Vue Integration',
svelte: 'Svelte Integration',
solid: 'Solid Integration',
preact: 'Preact Integration',
angular: 'Angular Integration',
'css-variables': 'CSS Variables',
authoring: 'Authoring',
};

View File

@ -1,11 +0,0 @@
{
"index": "Get Started",
"react": "React Integration",
"vue": "Vue Integration",
"svelte": "Svelte Integration",
"solid": "Solid Integration",
"preact": "Preact Integration",
"angular": "Angular Integration",
"css-variables": "CSS Variables",
"authoring": "Authoring"
}

View File

@ -3,16 +3,16 @@ title: Developer Documentation
description: Learn how to run Documenso locally, use our API, integrate webhooks, contribute to the project, and self-host Documenso.
---
import { Card, Cards } from 'nextra/components';
import { Cards } from 'nextra/components';
# Developer Documentation
The developer documentation is a comprehensive guide to help you:
<Cards>
<Card title="Set up dev environment" href="/developers/local-development" />
<Card title="Use the API" href="/developers/public-api" />
<Card title="Integrate webhooks" href="/developers/webhooks" />
<Card title="Contribute to the project" href="/developers/contributing" />
<Card title="Self-host Documenso" href="/developers/self-hosting" />
<Cards.Card title="Set up dev environment" href="/developers/local-development" />
<Cards.Card title="Use the API" href="/developers/public-api" />
<Cards.Card title="Integrate webhooks" href="/developers/webhooks" />
<Cards.Card title="Contribute to the project" href="/developers/contributing" />
<Cards.Card title="Self-host Documenso" href="/developers/self-hosting" />
</Cards>

View File

@ -0,0 +1,8 @@
export default {
index: 'Get Started',
quickstart: 'Developer Quickstart',
manual: 'Manual Setup',
gitpod: 'Gitpod',
'signing-certificate': 'Signing Certificate',
translations: 'Translations',
};

View File

@ -1,8 +0,0 @@
{
"index": "Get Started",
"quickstart": "Developer Quickstart",
"manual": "Manual Setup",
"gitpod": "Gitpod",
"signing-certificate": "Signing Certificate",
"translations": "Translations"
}

View File

@ -0,0 +1,6 @@
export default {
index: 'Get Started',
authentication: 'Authentication',
'rate-limits': 'Rate Limits',
versioning: 'Versioning',
};

View File

@ -1,6 +0,0 @@
{
"index": "Get Started",
"authentication": "Authentication",
"rate-limits": "Rate Limits",
"versioning": "Versioning"
}

View File

@ -0,0 +1,6 @@
export default {
index: 'Getting Started',
'signing-certificate': 'Signing Certificate',
'how-to': 'How To',
'setting-up-oauth-providers': 'Setting up OAuth Providers',
};

View File

@ -1,6 +0,0 @@
{
"index": "Getting Started",
"signing-certificate": "Signing Certificate",
"how-to": "How To",
"setting-up-oauth-providers": "Setting up OAuth Providers"
}

View File

@ -0,0 +1,23 @@
export default {
index: 'Introduction',
support: 'Support',
'-- How To Use': {
type: 'separator',
title: 'How To Use',
},
'get-started': 'Get Started',
profile: 'Public Profile',
organisations: 'Organisations',
documents: 'Documents',
templates: 'Templates',
branding: 'Branding',
'email-domains': 'Email Domains',
'direct-links': 'Direct Signing Links',
'-- Legal Overview': {
type: 'separator',
title: 'Legal Overview',
},
'fair-use': 'Fair Use Policy',
licenses: 'Licenses',
compliance: 'Compliance',
};

View File

@ -1,23 +0,0 @@
{
"index": "Introduction",
"support": "Support",
"-- How To Use": {
"type": "separator",
"title": "How To Use"
},
"get-started": "Get Started",
"profile": "Public Profile",
"organisations": "Organisations",
"documents": "Documents",
"templates": "Templates",
"branding": "Branding",
"email-domains": "Email Domains",
"direct-links": "Direct Signing Links",
"-- Legal Overview": {
"type": "separator",
"title": "Legal Overview"
},
"fair-use": "Fair Use Policy",
"licenses": "Licenses",
"compliance": "Compliance"
}

View File

@ -0,0 +1,4 @@
export default {
'signature-levels': 'Signature Levels',
'standards-and-regulations': 'Standards and Regulations',
};

View File

@ -1,4 +0,0 @@
{
"signature-levels": "Signature Levels",
"standards-and-regulations": "Standards and Regulations"
}

View File

@ -0,0 +1,7 @@
export default {
'sending-documents': 'Sending Documents',
'document-preferences': 'Document Preferences',
'document-visibility': 'Document Visibility',
fields: 'Document Fields',
'email-preferences': 'Email Preferences',
};

View File

@ -1,7 +0,0 @@
{
"sending-documents": "Sending Documents",
"document-preferences": "Document Preferences",
"document-visibility": "Document Visibility",
"fields": "Document Fields",
"email-preferences": "Email Preferences"
}

View File

@ -178,7 +178,7 @@ The dropdown/select field collects a single choice from a list of options.
Place the dropdown/select field on the document where you want the signer to select a choice. The dropdown/select field comes with additional settings that can be configured.
![The dropdown/select field in the Documenso document editor](/document-signing/dropdown-field-document-editor-view.webp)
{/* ![The dropdown/select field in the Documenso document editor](/document-signing/dropdown-field-document-editor-view.webp) */}
The dropdown/select field settings include:

View File

@ -0,0 +1,5 @@
export default {
index: 'Overview',
'community-edition': 'Community Edition',
'enterprise-edition': 'Enterprise Edition',
};

View File

@ -1,5 +0,0 @@
{
"index": "Overview",
"community-edition": "Community Edition",
"enterprise-edition": "Enterprise Edition"
}

View File

@ -0,0 +1,8 @@
export default {
index: 'Introduction',
members: 'Members',
groups: 'Groups',
teams: 'Teams',
sso: 'SSO',
billing: 'Billing',
};

View File

@ -1,8 +0,0 @@
{
"index": "Introduction",
"members": "Members",
"groups": "Groups",
"teams": "Teams",
"sso": "SSO",
"billing": "Billing"
}

View File

@ -0,0 +1,4 @@
export default {
index: 'Configuration',
'microsoft-entra-id': 'Microsoft Entra ID',
};

View File

@ -1,4 +0,0 @@
{
"index": "Configuration",
"microsoft-entra-id": "Microsoft Entra ID"
}

View File

@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,7 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
html {
scroll-behavior: smooth;
}

View File

@ -8,7 +8,9 @@ module.exports = {
...baseConfig.content,
`${path.join(require.resolve('@documenso/ui'), '..')}/**/*.{ts,tsx}`,
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./content/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
'./app/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
fontFamily: {

View File

@ -4,7 +4,7 @@ import { useConfig } from 'nextra-theme-docs';
const themeConfig: DocsThemeConfig = {
logo: <span>Documenso</span>,
head: function useHead() {
const config = useConfig<{ title?: string; description?: string }>();
const config = useConfig();
const title = `${config.frontMatter.title} | Documenso Docs` || 'Documenso Docs';
const description = config.frontMatter.description || 'The official Documenso documentation';
@ -12,6 +12,7 @@ const themeConfig: DocsThemeConfig = {
return (
<>
<meta httpEquiv="Content-Language" content="en" />
<title>{title}</title>
<meta name="title" content={title} />
<meta name="og:title" content={title} />
<meta name="description" content={description} />
@ -46,7 +47,7 @@ const themeConfig: DocsThemeConfig = {
},
docsRepositoryBase: 'https://github.com/documenso/documenso/tree/main/apps/documentation',
footer: {
text: (
content: (
<span>
{new Date().getFullYear()} ©{' '}
<a href="https://documen.so" target="_blank">
@ -56,12 +57,9 @@ const themeConfig: DocsThemeConfig = {
</span>
),
},
primaryHue: 100,
primarySaturation: 48.47,
useNextSeoProps() {
return {
titleTemplate: '%s | Documenso Docs',
};
color: {
hue: 100,
saturation: 48.47,
},
};

View File

@ -1,13 +1,17 @@
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
@ -18,10 +22,21 @@
}
],
"paths": {
"@/*": ["./*"]
"@/*": [
"./*"
]
},
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"target": "ES2017"
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "tailwind.config.js"],
"exclude": ["node_modules"]
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
"tailwind.config.js"
],
"exclude": [
"node_modules"
]
}

View File

@ -1,4 +0,0 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};
module.exports = nextConfig;

View File

@ -0,0 +1,5 @@
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {};
export default nextConfig;

View File

@ -11,12 +11,12 @@
},
"dependencies": {
"@documenso/prisma": "*",
"luxon": "^3.5.0",
"next": "14.2.28"
"luxon": "^3.7.2",
"next": "^15"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "18.3.5",
"@types/react": "18.3.27",
"typescript": "5.6.2"
}
}

View File

@ -13,7 +13,7 @@ import {
DialogHeader,
DialogTitle,
} from '@documenso/ui/primitives/dialog';
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
import { PDFViewerSuspense } from '@documenso/ui/primitives/pdf-viewer.suspense';
import { useToast } from '@documenso/ui/primitives/use-toast';
import { useCurrentTeam } from '~/providers/team';
@ -96,7 +96,7 @@ export const DocumentDuplicateDialog = ({
</div>
) : (
<div className="p-2 [&>div]:h-[50vh] [&>div]:overflow-y-scroll">
<PDFViewer
<PDFViewerSuspense
key={envelopeItems[0].id}
envelopeItem={envelopeItems[0]}
token={undefined}

View File

@ -23,7 +23,7 @@ import { FRIENDLY_FIELD_TYPE } from '@documenso/ui/primitives/document-flow/type
import { ElementVisible } from '@documenso/ui/primitives/element-visible';
import { FieldSelector } from '@documenso/ui/primitives/field-selector';
import { Form } from '@documenso/ui/primitives/form/form';
import PDFViewer from '@documenso/ui/primitives/pdf-viewer';
import { PDFViewerSuspense } from '@documenso/ui/primitives/pdf-viewer.suspense';
import { RecipientSelector } from '@documenso/ui/primitives/recipient-selector';
import { Sheet, SheetContent, SheetTrigger } from '@documenso/ui/primitives/sheet';
import { useToast } from '@documenso/ui/primitives/use-toast';
@ -463,12 +463,12 @@ export const ConfigureFieldsView = ({
{/* Desktop sidebar */}
{!isMobile && (
<div className="order-2 col-span-12 md:order-1 md:col-span-4">
<div className="bg-widget border-border sticky top-4 max-h-[calc(100vh-2rem)] rounded-lg border p-4 pb-6">
<div className="sticky top-4 max-h-[calc(100vh-2rem)] rounded-lg border border-border bg-widget p-4 pb-6">
<h2 className="mb-1 text-lg font-medium">
<Trans>Configure Fields</Trans>
</h2>
<p className="text-muted-foreground mb-6 text-sm">
<p className="mb-6 text-sm text-muted-foreground">
<Trans>Configure the fields you want to place on the document.</Trans>
</p>
@ -522,7 +522,7 @@ export const ConfigureFieldsView = ({
{selectedField && (
<div
className={cn(
'text-muted-foreground dark:text-muted-background pointer-events-none fixed z-50 flex cursor-pointer flex-col items-center justify-center bg-white transition duration-200 [container-type:size]',
'dark:text-muted-background pointer-events-none fixed z-50 flex cursor-pointer flex-col items-center justify-center bg-white text-muted-foreground transition duration-200 [container-type:size]',
selectedRecipientStyles.base,
{
'-rotate-6 scale-90 opacity-50 dark:bg-black/20': !isFieldWithinBounds,
@ -545,7 +545,7 @@ export const ConfigureFieldsView = ({
<Form {...form}>
<div>
<PDFViewer
<PDFViewerSuspense
presignToken={presignToken}
overrideData={normalizedDocumentData}
envelopeItem={normalizedEnvelopeItem}
@ -597,14 +597,14 @@ export const ConfigureFieldsView = ({
{isMobile && (
<Sheet open={isDrawerOpen} onOpenChange={setIsDrawerOpen}>
<SheetTrigger asChild>
<div className="bg-widget border-border fixed bottom-6 left-6 right-6 z-50 flex items-center justify-between gap-2 rounded-lg border p-4">
<div className="fixed bottom-6 left-6 right-6 z-50 flex items-center justify-between gap-2 rounded-lg border border-border bg-widget p-4">
<span className="text-lg font-medium">
<Trans>Configure Fields</Trans>
</span>
<button
type="button"
className="border-border text-muted-foreground inline-flex h-10 w-10 items-center justify-center rounded-lg border"
className="inline-flex h-10 w-10 items-center justify-center rounded-lg border border-border text-muted-foreground"
>
<ChevronsUpDown className="h-6 w-6" />
</button>
@ -614,13 +614,13 @@ export const ConfigureFieldsView = ({
<SheetContent
position="bottom"
size="xl"
className="bg-widget h-fit max-h-[80vh] overflow-y-auto rounded-t-xl p-4"
className="h-fit max-h-[80vh] overflow-y-auto rounded-t-xl bg-widget p-4"
>
<h2 className="mb-1 text-lg font-medium">
<Trans>Configure Fields</Trans>
</h2>
<p className="text-muted-foreground mb-6 text-sm">
<p className="mb-6 text-sm text-muted-foreground">
<Trans>Configure the fields you want to place on the document.</Trans>
</p>

View File

@ -28,7 +28,7 @@ import { Button } from '@documenso/ui/primitives/button';
import { ElementVisible } from '@documenso/ui/primitives/element-visible';
import { Input } from '@documenso/ui/primitives/input';
import { Label } from '@documenso/ui/primitives/label';
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
import { PDFViewerSuspense } from '@documenso/ui/primitives/pdf-viewer.suspense';
import { SignaturePadDialog } from '@documenso/ui/primitives/signature-pad/signature-pad-dialog';
import { useToast } from '@documenso/ui/primitives/use-toast';
@ -334,7 +334,7 @@ export const EmbedDirectTemplateClientPage = ({
<div className="relative flex w-full flex-col gap-x-6 gap-y-12 md:flex-row">
{/* Viewer */}
<div className="flex-1">
<PDFViewer
<PDFViewerSuspense
envelopeItem={envelopeItems[0]}
token={recipient.token}
version="signed"
@ -348,11 +348,11 @@ export const EmbedDirectTemplateClientPage = ({
className="group/document-widget fixed bottom-8 left-0 z-50 h-fit max-h-[calc(100dvh-2rem)] w-full flex-shrink-0 px-6 md:sticky md:bottom-[unset] md:top-4 md:z-auto md:w-[350px] md:px-0"
data-expanded={isExpanded || undefined}
>
<div className="border-border bg-widget flex h-fit w-full flex-col rounded-xl border px-4 py-4 md:min-h-[min(calc(100dvh-2rem),48rem)] md:py-6">
<div className="flex h-fit w-full flex-col rounded-xl border border-border bg-widget px-4 py-4 md:min-h-[min(calc(100dvh-2rem),48rem)] md:py-6">
{/* Header */}
<div>
<div className="flex items-center justify-between gap-x-2">
<h3 className="text-foreground text-xl font-semibold md:text-2xl">
<h3 className="text-xl font-semibold text-foreground md:text-2xl">
<Trans>Sign document</Trans>
</h3>
@ -362,7 +362,7 @@ export const EmbedDirectTemplateClientPage = ({
className="h-8 w-8 p-0 md:hidden"
onClick={() => setIsExpanded(false)}
>
<LucideChevronDown className="text-muted-foreground h-5 w-5" />
<LucideChevronDown className="h-5 w-5 text-muted-foreground" />
</Button>
) : pendingFields.length > 0 ? (
<Button
@ -370,7 +370,7 @@ export const EmbedDirectTemplateClientPage = ({
className="h-8 w-8 p-0 md:hidden"
onClick={() => setIsExpanded(true)}
>
<LucideChevronUp className="text-muted-foreground h-5 w-5" />
<LucideChevronUp className="h-5 w-5 text-muted-foreground" />
</Button>
) : (
<Button
@ -388,11 +388,11 @@ export const EmbedDirectTemplateClientPage = ({
</div>
<div className="hidden group-data-[expanded]/document-widget:block md:block">
<p className="text-muted-foreground mt-2 text-sm">
<p className="mt-2 text-sm text-muted-foreground">
<Trans>Sign the document to complete the process.</Trans>
</p>
<hr className="border-border mb-8 mt-4" />
<hr className="mb-8 mt-4 border-border" />
</div>
{/* Form */}
@ -406,7 +406,7 @@ export const EmbedDirectTemplateClientPage = ({
<Input
type="text"
id="full-name"
className="bg-background mt-2"
className="mt-2 bg-background"
disabled={isNameLocked}
value={fullName}
onChange={(e) => !isNameLocked && setFullName(e.target.value)}
@ -421,7 +421,7 @@ export const EmbedDirectTemplateClientPage = ({
<Input
type="email"
id="email"
className="bg-background mt-2"
className="mt-2 bg-background"
disabled={isEmailLocked}
value={email}
onChange={(e) => !isEmailLocked && setEmail(e.target.value.trim())}
@ -490,7 +490,7 @@ export const EmbedDirectTemplateClientPage = ({
</div>
{!hidePoweredBy && (
<div className="bg-primary text-primary-foreground fixed bottom-0 left-0 z-40 rounded-tr px-2 py-1 text-xs font-medium opacity-60 hover:opacity-100">
<div className="fixed bottom-0 left-0 z-40 rounded-tr bg-primary px-2 py-1 text-xs font-medium text-primary-foreground opacity-60 hover:opacity-100">
<span>Powered by</span>
<BrandingLogo className="ml-2 inline-block h-[14px]" />
</div>

View File

@ -22,7 +22,7 @@ import { Button } from '@documenso/ui/primitives/button';
import { ElementVisible } from '@documenso/ui/primitives/element-visible';
import { Input } from '@documenso/ui/primitives/input';
import { Label } from '@documenso/ui/primitives/label';
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
import { PDFViewerSuspense } from '@documenso/ui/primitives/pdf-viewer.suspense';
import { RadioGroup, RadioGroupItem } from '@documenso/ui/primitives/radio-group';
import { SignaturePadDialog } from '@documenso/ui/primitives/signature-pad/signature-pad-dialog';
import { useToast } from '@documenso/ui/primitives/use-toast';
@ -286,7 +286,7 @@ export const EmbedSignDocumentV1ClientPage = ({
<div className="embed--DocumentContainer relative flex w-full flex-col gap-x-6 gap-y-12 md:flex-row">
{/* Viewer */}
<div className="embed--DocumentViewer flex-1">
<PDFViewer
<PDFViewerSuspense
envelopeItem={envelopeItems[0]}
token={token}
version="signed"
@ -300,11 +300,11 @@ export const EmbedSignDocumentV1ClientPage = ({
className="embed--DocumentWidgetContainer group/document-widget fixed bottom-8 left-0 z-50 h-fit max-h-[calc(100dvh-2rem)] w-full flex-shrink-0 px-6 md:sticky md:bottom-[unset] md:top-4 md:z-auto md:w-[350px] md:px-0"
data-expanded={isExpanded || undefined}
>
<div className="embed--DocumentWidget border-border bg-widget flex w-full flex-col rounded-xl border px-4 py-4 md:py-6">
<div className="embed--DocumentWidget flex w-full flex-col rounded-xl border border-border bg-widget px-4 py-4 md:py-6">
{/* Header */}
<div className="embed--DocumentWidgetHeader">
<div className="flex items-center justify-between gap-x-2">
<h3 className="text-foreground text-xl font-semibold md:text-2xl">
<h3 className="text-xl font-semibold text-foreground md:text-2xl">
{isAssistantMode ? (
<Trans>Assist with signing</Trans>
) : (
@ -315,18 +315,18 @@ export const EmbedSignDocumentV1ClientPage = ({
{isExpanded ? (
<Button
variant="outline"
className="bg-background dark:bg-foreground h-8 w-8 p-0 md:hidden"
className="h-8 w-8 bg-background p-0 md:hidden dark:bg-foreground"
onClick={() => setIsExpanded(false)}
>
<LucideChevronDown className="text-muted-foreground dark:text-background h-5 w-5" />
<LucideChevronDown className="h-5 w-5 text-muted-foreground dark:text-background" />
</Button>
) : pendingFields.length > 0 ? (
<Button
variant="outline"
className="bg-background dark:bg-foreground h-8 w-8 p-0 md:hidden"
className="h-8 w-8 bg-background p-0 md:hidden dark:bg-foreground"
onClick={() => setIsExpanded(true)}
>
<LucideChevronUp className="text-muted-foreground dark:text-background h-5 w-5" />
<LucideChevronUp className="h-5 w-5 text-muted-foreground dark:text-background" />
</Button>
) : (
<Button
@ -346,7 +346,7 @@ export const EmbedSignDocumentV1ClientPage = ({
</div>
<div className="embed--DocumentWidgetContent hidden group-data-[expanded]/document-widget:block md:block">
<p className="text-muted-foreground mt-2 text-sm">
<p className="mt-2 text-sm text-muted-foreground">
{isAssistantMode ? (
<Trans>Help complete the document for other signers.</Trans>
) : (
@ -354,7 +354,7 @@ export const EmbedSignDocumentV1ClientPage = ({
)}
</p>
<hr className="border-border mb-8 mt-4" />
<hr className="mb-8 mt-4 border-border" />
</div>
{/* Form */}
@ -366,7 +366,7 @@ export const EmbedSignDocumentV1ClientPage = ({
<Trans>Signing for</Trans>
</Label>
<fieldset className="dark:bg-background border-border mt-2 rounded-2xl border bg-white p-3">
<fieldset className="mt-2 rounded-2xl border border-border bg-white p-3 dark:bg-background">
<RadioGroup
className="gap-0 space-y-3 shadow-none"
value={selectedSignerId?.toString()}
@ -377,7 +377,7 @@ export const EmbedSignDocumentV1ClientPage = ({
.map((r) => (
<div
key={`${assistantSignersId}-${r.id}`}
className="bg-widget border-border relative flex flex-col gap-4 rounded-lg border p-4"
className="relative flex flex-col gap-4 rounded-lg border border-border bg-widget p-4"
>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
@ -395,15 +395,15 @@ export const EmbedSignDocumentV1ClientPage = ({
{r.name}
{r.id === recipient.id && (
<span className="text-muted-foreground ml-2">
<span className="ml-2 text-muted-foreground">
{_(msg`(You)`)}
</span>
)}
</Label>
<p className="text-muted-foreground text-xs">{r.email}</p>
<p className="text-xs text-muted-foreground">{r.email}</p>
</div>
</div>
<div className="text-muted-foreground text-xs leading-[inherit]">
<div className="text-xs leading-[inherit] text-muted-foreground">
{r.fields.length} {r.fields.length === 1 ? 'field' : 'fields'}
</div>
</div>
@ -424,7 +424,7 @@ export const EmbedSignDocumentV1ClientPage = ({
<Input
type="text"
id="full-name"
className="bg-background mt-2"
className="mt-2 bg-background"
disabled={isNameLocked}
value={fullName}
onChange={(e) => !isNameLocked && setFullName(e.target.value)}
@ -439,7 +439,7 @@ export const EmbedSignDocumentV1ClientPage = ({
<Input
type="email"
id="email"
className="bg-background mt-2"
className="mt-2 bg-background"
value={email}
disabled
/>
@ -507,7 +507,7 @@ export const EmbedSignDocumentV1ClientPage = ({
</div>
{!hidePoweredBy && (
<div className="bg-primary text-primary-foreground fixed bottom-0 left-0 z-40 rounded-tr px-2 py-1 text-xs font-medium opacity-60 hover:opacity-100">
<div className="fixed bottom-0 left-0 z-40 rounded-tr bg-primary px-2 py-1 text-xs font-medium text-primary-foreground opacity-60 hover:opacity-100">
<span>Powered by</span>
<BrandingLogo className="ml-2 inline-block h-[14px]" />
</div>

View File

@ -21,7 +21,7 @@ import { Button } from '@documenso/ui/primitives/button';
import { ElementVisible } from '@documenso/ui/primitives/element-visible';
import { Input } from '@documenso/ui/primitives/input';
import { Label } from '@documenso/ui/primitives/label';
import PDFViewer from '@documenso/ui/primitives/pdf-viewer';
import { PDFViewerSuspense } from '@documenso/ui/primitives/pdf-viewer.suspense';
import { SignaturePadDialog } from '@documenso/ui/primitives/signature-pad/signature-pad-dialog';
import { useToast } from '@documenso/ui/primitives/use-toast';
@ -177,14 +177,14 @@ export const MultiSignDocumentSigningView = ({
};
return (
<div className="bg-background min-h-screen overflow-hidden">
<div className="min-h-screen overflow-hidden bg-background">
<div id="document-field-portal-root" className="relative h-full w-full overflow-y-auto p-8">
{match({ isLoading, document })
.with({ isLoading: true }, () => (
<div className="flex min-h-[400px] w-full items-center justify-center">
<div className="flex flex-col items-center gap-4">
<Loader className="text-primary h-8 w-8 animate-spin" />
<p className="text-muted-foreground text-sm">
<Loader className="h-8 w-8 animate-spin text-primary" />
<p className="text-sm text-muted-foreground">
<Trans>Loading document...</Trans>
</p>
</div>
@ -192,7 +192,7 @@ export const MultiSignDocumentSigningView = ({
))
.with({ isLoading: false, document: undefined }, () => (
<div className="flex min-h-[400px] w-full items-center justify-center">
<p className="text-muted-foreground text-sm">
<p className="text-sm text-muted-foreground">
<Trans>Failed to load document</Trans>
</p>
</div>
@ -225,7 +225,7 @@ export const MultiSignDocumentSigningView = ({
'md:mx-auto md:max-w-2xl': document.status === DocumentStatus.COMPLETED,
})}
>
<PDFViewer
<PDFViewerSuspense
envelopeItem={document.envelopeItems[0]}
token={token}
version="signed"
@ -243,23 +243,23 @@ export const MultiSignDocumentSigningView = ({
className="embed--DocumentWidgetContainer group/document-widget fixed bottom-8 left-0 z-50 h-fit max-h-[calc(100dvh-2rem)] w-full flex-shrink-0 px-6 md:sticky md:bottom-[unset] md:top-0 md:z-auto md:w-[350px] md:px-0"
data-expanded={isExpanded || undefined}
>
<div className="embed--DocumentWidget border-border bg-widget flex w-full flex-col rounded-xl border px-4 py-4 md:py-6">
<div className="embed--DocumentWidget flex w-full flex-col rounded-xl border border-border bg-widget px-4 py-4 md:py-6">
{/* Header */}
<div className="embed--DocumentWidgetHeader">
<div className="flex items-center justify-between gap-x-2">
<h3 className="text-foreground text-xl font-semibold md:text-2xl">
<h3 className="text-xl font-semibold text-foreground md:text-2xl">
<Trans>Sign document</Trans>
</h3>
<Button variant="outline" className="h-8 w-8 p-0 md:hidden">
{isExpanded ? (
<LucideChevronDown
className="text-muted-foreground h-5 w-5"
className="h-5 w-5 text-muted-foreground"
onClick={() => setIsExpanded(false)}
/>
) : (
<LucideChevronUp
className="text-muted-foreground h-5 w-5"
className="h-5 w-5 text-muted-foreground"
onClick={() => setIsExpanded(true)}
/>
)}
@ -268,11 +268,11 @@ export const MultiSignDocumentSigningView = ({
</div>
<div className="embed--DocumentWidgetContent hidden group-data-[expanded]/document-widget:block md:block">
<p className="text-muted-foreground mt-2 text-sm">
<p className="mt-2 text-sm text-muted-foreground">
<Trans>Sign the document to complete the process.</Trans>
</p>
<hr className="border-border mb-8 mt-4" />
<hr className="mb-8 mt-4 border-border" />
</div>
{/* Form */}
@ -288,7 +288,7 @@ export const MultiSignDocumentSigningView = ({
<Input
type="text"
id="full-name"
className="bg-background mt-2"
className="mt-2 bg-background"
disabled={isNameLocked}
value={fullName}
onChange={(e) => !isNameLocked && setFullName(e.target.value)}
@ -303,7 +303,7 @@ export const MultiSignDocumentSigningView = ({
<Input
type="email"
id="email"
className="bg-background mt-2"
className="mt-2 bg-background"
value={email}
disabled
/>

View File

@ -42,7 +42,7 @@ import { useToast } from '@documenso/ui/primitives/use-toast';
import { ZCreateOrganisationFormSchema } from '../dialogs/organisation-create-dialog';
const MotionCard = motion(Card);
const MotionCard = motion.create(Card);
export type BillingPlansProps = {
plans: InternalClaimPlans;
@ -101,7 +101,7 @@ export const BillingPlans = ({ plans }: BillingPlansProps) => {
<CardContent className="flex h-full flex-col p-6">
<CardTitle>{price.product.name}</CardTitle>
<div className="text-muted-foreground mt-2 text-lg font-medium">
<div className="mt-2 text-lg font-medium text-muted-foreground">
{price.friendlyPrice + ' '}
<span className="text-xs">
{interval === 'monthlyPrice' ? (
@ -112,12 +112,12 @@ export const BillingPlans = ({ plans }: BillingPlansProps) => {
</span>
</div>
<div className="text-muted-foreground mt-1.5 text-sm">
<div className="mt-1.5 text-sm text-muted-foreground">
{price.product.description}
</div>
{price.product.features && price.product.features.length > 0 && (
<div className="text-muted-foreground mt-4">
<div className="mt-4 text-muted-foreground">
<div className="text-sm font-medium">Includes:</div>
<ul className="mt-1 divide-y text-sm">
@ -261,7 +261,7 @@ const BillingDialog = ({
<Building2Icon className="h-4 w-4" />
<Trans>Update current organisation</Trans>
</Label>
<p className="text-muted-foreground text-sm">
<p className="text-sm text-muted-foreground">
<Trans>
Upgrade <strong>{organisation.name}</strong> to {planName}
</Trans>
@ -276,7 +276,7 @@ const BillingDialog = ({
<PlusIcon className="h-4 w-4" />
<Trans>Create separate organisation</Trans>
</Label>
<p className="text-muted-foreground text-sm">
<p className="text-sm text-muted-foreground">
<Trans>
Create a new organisation with {planName} plan. Keep your current organisation
on it's current plan

View File

@ -13,7 +13,7 @@ import { trpc } from '@documenso/trpc/react';
import { Card, CardContent } from '@documenso/ui/primitives/card';
import { DocumentFlowFormContainer } from '@documenso/ui/primitives/document-flow/document-flow-root';
import type { DocumentFlowStep } from '@documenso/ui/primitives/document-flow/types';
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
import { PDFViewerSuspense } from '@documenso/ui/primitives/pdf-viewer.suspense';
import { Stepper } from '@documenso/ui/primitives/stepper';
import { useToast } from '@documenso/ui/primitives/use-toast';
@ -151,7 +151,7 @@ export const DirectTemplatePageView = ({
gradient
>
<CardContent className="p-2">
<PDFViewer
<PDFViewerSuspense
key={template.id}
envelopeItem={template.envelopeItems[0]}
token={directTemplateRecipient.token}

View File

@ -30,7 +30,7 @@ import { DocumentReadOnlyFields } from '@documenso/ui/components/document/docume
import { Button } from '@documenso/ui/primitives/button';
import { Card, CardContent } from '@documenso/ui/primitives/card';
import { ElementVisible } from '@documenso/ui/primitives/element-visible';
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
import { PDFViewerSuspense } from '@documenso/ui/primitives/pdf-viewer.suspense';
import { DocumentSigningAttachmentsPopover } from '~/components/general/document-signing/document-signing-attachments-popover';
import { DocumentSigningAutoSign } from '~/components/general/document-signing/document-signing-auto-sign';
@ -187,7 +187,7 @@ export const DocumentSigningPageViewV1 = ({
<div className="mt-1.5 flex flex-wrap items-center justify-between gap-y-2 sm:mt-2.5 sm:gap-y-0">
<div className="max-w-[50ch]">
<span className="text-muted-foreground truncate" title={senderName}>
<span className="truncate text-muted-foreground" title={senderName}>
{senderName} {senderEmail}
</span>{' '}
<span className="text-muted-foreground">
@ -245,7 +245,7 @@ export const DocumentSigningPageViewV1 = ({
<div className="flex-1">
<Card className="rounded-xl before:rounded-xl" gradient>
<CardContent className="p-2">
<PDFViewer
<PDFViewerSuspense
key={document.envelopeItems[0].id}
envelopeItem={document.envelopeItems[0]}
token={recipient.token}
@ -260,9 +260,9 @@ export const DocumentSigningPageViewV1 = ({
className="group/document-widget fixed bottom-6 left-0 z-50 h-fit max-h-[calc(100dvh-2rem)] w-full flex-shrink-0 px-4 md:sticky md:bottom-[unset] md:top-4 md:z-auto md:w-[350px] md:px-0"
data-expanded={isExpanded || undefined}
>
<div className="border-border bg-widget flex w-full flex-col rounded-xl border px-4 py-4 md:py-6">
<div className="flex w-full flex-col rounded-xl border border-border bg-widget px-4 py-4 md:py-6">
<div className="flex items-center justify-between gap-x-2">
<h3 className="text-foreground text-xl font-semibold md:text-2xl">
<h3 className="text-xl font-semibold text-foreground md:text-2xl">
{match(recipient.role)
.with(RecipientRole.VIEWER, () => <Trans>View Document</Trans>)
.with(RecipientRole.SIGNER, () => <Trans>Sign Document</Trans>)
@ -305,25 +305,25 @@ export const DocumentSigningPageViewV1 = ({
.with({ isExpanded: true }, () => (
<Button
variant="outline"
className="bg-background dark:bg-foreground h-8 w-8 p-0 md:hidden"
className="h-8 w-8 bg-background p-0 md:hidden dark:bg-foreground"
onClick={() => setIsExpanded(false)}
>
<LucideChevronDown className="text-muted-foreground dark:text-background h-5 w-5" />
<LucideChevronDown className="h-5 w-5 text-muted-foreground dark:text-background" />
</Button>
))
.otherwise(() => (
<Button
variant="outline"
className="bg-background dark:bg-foreground h-8 w-8 p-0 md:hidden"
className="h-8 w-8 bg-background p-0 md:hidden dark:bg-foreground"
onClick={() => setIsExpanded(true)}
>
<LucideChevronUp className="text-muted-foreground dark:text-background h-5 w-5" />
<LucideChevronUp className="h-5 w-5 text-muted-foreground dark:text-background" />
</Button>
))}
</div>
<div className="hidden group-data-[expanded]/document-widget:block md:block">
<p className="text-muted-foreground mt-2 text-sm">
<p className="mt-2 text-sm text-muted-foreground">
{match(recipient.role)
.with(RecipientRole.VIEWER, () => (
<Trans>Please mark as viewed to complete.</Trans>
@ -340,7 +340,7 @@ export const DocumentSigningPageViewV1 = ({
.otherwise(() => null)}
</p>
<hr className="border-border mb-8 mt-4" />
<hr className="mb-8 mt-4 border-border" />
</div>
<div className="-mx-2 hidden px-2 group-data-[expanded]/document-widget:block md:block">

View File

@ -34,7 +34,7 @@ import { DocumentSigningRejectDialog } from './document-signing-reject-dialog';
import { useRequiredEnvelopeSigningContext } from './envelope-signing-provider';
const EnvelopeSignerPageRenderer = lazy(
async () => import('../envelope-signing/envelope-signer-page-renderer'),
async () => import('~/components/general/envelope-signing/envelope-signer-page-renderer'),
);
export const DocumentSigningPageViewV2 = () => {
@ -71,7 +71,7 @@ export const DocumentSigningPageViewV2 = () => {
}, [recipientFieldsRemaining, selectedAssistantRecipientFields, currentEnvelopeItem]);
return (
<div className="dark:bg-background min-h-screen w-screen bg-gray-50">
<div className="min-h-screen w-screen bg-gray-50 dark:bg-background">
<SignFieldEmailDialog.Root />
<SignFieldTextDialog.Root />
<SignFieldNumberDialog.Root />
@ -86,9 +86,9 @@ export const DocumentSigningPageViewV2 = () => {
{/* Main Content Area */}
<div className="flex h-[calc(100vh-4rem)] w-screen">
{/* Left Section - Step Navigation */}
<div className="embed--DocumentWidgetContainer bg-background border-border hidden w-80 flex-shrink-0 flex-col overflow-y-auto border-r py-4 lg:flex">
<div className="embed--DocumentWidgetContainer hidden w-80 flex-shrink-0 flex-col overflow-y-auto border-r border-border bg-background py-4 lg:flex">
<div className="px-4">
<h3 className="text-foreground flex items-end justify-between text-sm font-semibold">
<h3 className="flex items-end justify-between text-sm font-semibold text-foreground">
{match(recipient.role)
.with(RecipientRole.VIEWER, () => <Trans>View Document</Trans>)
.with(RecipientRole.SIGNER, () => <Trans>Sign Document</Trans>)
@ -96,7 +96,7 @@ export const DocumentSigningPageViewV2 = () => {
.with(RecipientRole.ASSISTANT, () => <Trans>Assist Document</Trans>)
.otherwise(() => null)}
<span className="text-muted-foreground bg-muted/50 ml-2 rounded border px-2 py-0.5 text-xs">
<span className="ml-2 rounded border bg-muted/50 px-2 py-0.5 text-xs text-muted-foreground">
<Plural
value={recipientFieldsRemaining.length}
one="1 Field Remaining"
@ -105,11 +105,11 @@ export const DocumentSigningPageViewV2 = () => {
</span>
</h3>
<div className="bg-muted relative my-4 h-[4px] rounded-md">
<div className="relative my-4 h-[4px] rounded-md bg-muted">
<motion.div
layout="size"
layoutId="document-flow-container-step"
className="bg-documenso absolute inset-y-0 left-0"
className="absolute inset-y-0 left-0 bg-documenso"
style={{
width: `${100 - (100 / requiredRecipientFields.length) * (recipientFieldsRemaining.length ?? 0)}%`,
}}
@ -126,7 +126,7 @@ export const DocumentSigningPageViewV2 = () => {
{/* Quick Actions. */}
{!isDirectTemplate && (
<div className="embed--Actions space-y-3 px-4">
<h4 className="text-foreground text-sm font-semibold">
<h4 className="text-sm font-semibold text-foreground">
<Trans>Actions</Trans>
</h4>
@ -173,7 +173,7 @@ export const DocumentSigningPageViewV2 = () => {
<Button
variant="ghost"
size="sm"
className="hover:text-destructive w-full justify-start"
className="w-full justify-start hover:text-destructive"
>
<BanIcon className="mr-2 h-4 w-4" />
<Trans>Reject Document</Trans>
@ -235,7 +235,7 @@ export const DocumentSigningPageViewV2 = () => {
/>
) : (
<div className="flex flex-col items-center justify-center py-32">
<p className="text-foreground text-sm">
<p className="text-sm text-foreground">
<Trans>No documents found</Trans>
</p>
</div>
@ -250,7 +250,7 @@ export const DocumentSigningPageViewV2 = () => {
<a
href="https://documenso.com"
target="_blank"
className="bg-primary text-primary-foreground fixed bottom-0 right-0 z-40 hidden cursor-pointer rounded-tl px-2 py-1 text-xs font-medium opacity-60 hover:opacity-100 lg:block"
className="fixed bottom-0 right-0 z-40 hidden cursor-pointer rounded-tl bg-primary px-2 py-1 text-xs font-medium text-primary-foreground opacity-60 hover:opacity-100 lg:block"
>
<span>Powered by</span>
<BrandingLogo className="ml-2 inline-block h-[14px]" />

View File

@ -1,4 +1,4 @@
import { useEffect, useState } from 'react';
import { lazy, useEffect, useState } from 'react';
import { Trans } from '@lingui/react/macro';
import { type DocumentData, DocumentStatus, type EnvelopeItem, EnvelopeType } from '@prisma/client';
@ -21,12 +21,15 @@ import {
DialogHeader,
DialogTitle,
} from '@documenso/ui/primitives/dialog';
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
import { PDFViewerSuspense } from '@documenso/ui/primitives/pdf-viewer.suspense';
import { EnvelopeDownloadDialog } from '~/components/dialogs/envelope-download-dialog';
import { EnvelopeRendererFileSelector } from '../envelope-editor/envelope-file-selector';
import EnvelopeGenericPageRenderer from '../envelope-editor/envelope-generic-page-renderer';
const EnvelopeGenericPageRenderer = lazy(
async () => import('~/components/general/envelope-editor/envelope-generic-page-renderer'),
);
export type DocumentCertificateQRViewProps = {
documentId: number;
@ -120,7 +123,7 @@ export const DocumentCertificateQRView = ({
<div className="flex w-full flex-col justify-between gap-4 md:flex-row md:items-end">
<div className="space-y-1">
<h1 className="text-xl font-medium">{title}</h1>
<div className="text-muted-foreground flex flex-col gap-0.5 text-sm">
<div className="flex flex-col gap-0.5 text-sm text-muted-foreground">
<p>
<Trans>{recipientCount} recipients</Trans>
</p>
@ -146,7 +149,7 @@ export const DocumentCertificateQRView = ({
</div>
<div className="mt-12 w-full">
<PDFViewer
<PDFViewerSuspense
key={envelopeItems[0].id}
envelopeItem={envelopeItems[0]}
token={token}
@ -179,7 +182,7 @@ const DocumentCertificateQrV2 = ({
<div className="flex w-full flex-col justify-between gap-4 md:flex-row md:items-end">
<div className="space-y-1">
<h1 className="text-xl font-medium">{title}</h1>
<div className="text-muted-foreground flex flex-col gap-0.5 text-sm">
<div className="flex flex-col gap-0.5 text-sm text-muted-foreground">
<p>
<Trans>{recipientCount} recipients</Trans>
</p>

View File

@ -27,7 +27,7 @@ import { AddSubjectFormPartial } from '@documenso/ui/primitives/document-flow/ad
import type { TAddSubjectFormSchema } from '@documenso/ui/primitives/document-flow/add-subject.types';
import { DocumentFlowFormContainer } from '@documenso/ui/primitives/document-flow/document-flow-root';
import type { DocumentFlowStep } from '@documenso/ui/primitives/document-flow/types';
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
import { PDFViewerSuspense } from '@documenso/ui/primitives/pdf-viewer.suspense';
import { Stepper } from '@documenso/ui/primitives/stepper';
import { useToast } from '@documenso/ui/primitives/use-toast';
@ -440,7 +440,7 @@ export const DocumentEditForm = ({
gradient
>
<CardContent className="p-2">
<PDFViewer
<PDFViewerSuspense
key={document.envelopeItems[0].id}
envelopeItem={document.envelopeItems[0]}
token={undefined}

View File

@ -47,7 +47,7 @@ import { EnvelopeRendererFileSelector } from './envelope-file-selector';
import { EnvelopeRecipientSelector } from './envelope-recipient-selector';
const EnvelopeEditorFieldsPageRenderer = lazy(
async () => import('./envelope-editor-fields-page-renderer'),
async () => import('~/components/general/envelope-editor/envelope-editor-fields-page-renderer'),
);
const FieldSettingsTypeTranslations: Record<FieldType, MessageDescriptor> = {
@ -119,7 +119,7 @@ export const EnvelopeEditorFieldsPage = () => {
{envelope.recipients.length === 0 && (
<Alert
variant="neutral"
className="border-border bg-background mb-4 flex max-w-[800px] flex-row items-center justify-between space-y-0 rounded-sm border"
className="mb-4 flex max-w-[800px] flex-row items-center justify-between space-y-0 rounded-sm border border-border bg-background"
>
<div className="flex flex-col gap-1">
<AlertTitle>
@ -145,11 +145,11 @@ export const EnvelopeEditorFieldsPage = () => {
/>
) : (
<div className="flex flex-col items-center justify-center py-32">
<FileTextIcon className="text-muted-foreground h-10 w-10" />
<p className="text-foreground mt-1 text-sm">
<FileTextIcon className="h-10 w-10 text-muted-foreground" />
<p className="mt-1 text-sm text-foreground">
<Trans>No documents found</Trans>
</p>
<p className="text-muted-foreground mt-1 text-sm">
<p className="mt-1 text-sm text-muted-foreground">
<Trans>Please upload a document to continue</Trans>
</p>
</div>
@ -159,10 +159,10 @@ export const EnvelopeEditorFieldsPage = () => {
{/* Right Section - Form Fields Panel */}
{currentEnvelopeItem && envelope.recipients.length > 0 && (
<div className="bg-background border-border sticky top-0 h-full w-80 flex-shrink-0 overflow-y-auto border-l py-4">
<div className="sticky top-0 h-full w-80 flex-shrink-0 overflow-y-auto border-l border-border bg-background py-4">
{/* Recipient selector section. */}
<section className="px-4">
<h3 className="text-foreground mb-2 text-sm font-semibold">
<h3 className="mb-2 text-sm font-semibold text-foreground">
<Trans>Selected Recipient</Trans>
</h3>
@ -194,7 +194,7 @@ export const EnvelopeEditorFieldsPage = () => {
{/* Add fields section. */}
<section className="px-4">
<h3 className="text-foreground mb-2 text-sm font-semibold">
<h3 className="mb-2 text-sm font-semibold text-foreground">
<Trans>Add Fields</Trans>
</h3>
@ -213,25 +213,25 @@ export const EnvelopeEditorFieldsPage = () => {
{searchParams.get('devmode') && (
<>
<div className="px-4">
<h3 className="text-foreground mb-3 text-sm font-semibold">
<h3 className="mb-3 text-sm font-semibold text-foreground">
<Trans>Developer Mode</Trans>
</h3>
<div className="bg-muted/50 border-border text-foreground space-y-2 rounded-md border p-3 text-sm">
<div className="space-y-2 rounded-md border border-border bg-muted/50 p-3 text-sm text-foreground">
<p>
<span className="text-muted-foreground min-w-12">Pos X:&nbsp;</span>
<span className="min-w-12 text-muted-foreground">Pos X:&nbsp;</span>
{selectedField.positionX.toFixed(2)}
</p>
<p>
<span className="text-muted-foreground min-w-12">Pos Y:&nbsp;</span>
<span className="min-w-12 text-muted-foreground">Pos Y:&nbsp;</span>
{selectedField.positionY.toFixed(2)}
</p>
<p>
<span className="text-muted-foreground min-w-12">Width:&nbsp;</span>
<span className="min-w-12 text-muted-foreground">Width:&nbsp;</span>
{selectedField.width.toFixed(2)}
</p>
<p>
<span className="text-muted-foreground min-w-12">Height:&nbsp;</span>
<span className="min-w-12 text-muted-foreground">Height:&nbsp;</span>
{selectedField.height.toFixed(2)}
</p>
</div>
@ -241,7 +241,7 @@ export const EnvelopeEditorFieldsPage = () => {
</>
)}
<div className="[&_label]:text-foreground/70 px-4 [&_label]:text-xs">
<div className="px-4 [&_label]:text-xs [&_label]:text-foreground/70">
<h3 className="text-sm font-semibold">
{t(FieldSettingsTypeTranslations[selectedField.type])}
</h3>

View File

@ -23,7 +23,9 @@ import { Separator } from '@documenso/ui/primitives/separator';
import { EnvelopeRendererFileSelector } from './envelope-file-selector';
const EnvelopeGenericPageRenderer = lazy(async () => import('./envelope-generic-page-renderer'));
const EnvelopeGenericPageRenderer = lazy(
async () => import('~/components/general/envelope-editor/envelope-generic-page-renderer'),
);
// Todo: Envelopes - Dynamically import faker
export const EnvelopeEditorPreviewPage = () => {
@ -232,11 +234,11 @@ export const EnvelopeEditorPreviewPage = () => {
/>
) : (
<div className="flex flex-col items-center justify-center py-32">
<FileTextIcon className="text-muted-foreground h-10 w-10" />
<p className="text-foreground mt-1 text-sm">
<FileTextIcon className="h-10 w-10 text-muted-foreground" />
<p className="mt-1 text-sm text-foreground">
<Trans>No documents found</Trans>
</p>
<p className="text-muted-foreground mt-1 text-sm">
<p className="mt-1 text-sm text-muted-foreground">
<Trans>Please upload a document to continue</Trans>
</p>
</div>

View File

@ -171,7 +171,7 @@ export default function EnvelopeSignerPageRenderer() {
const handleFieldGroupClick = (e: KonvaEventObject<Event>) => {
const currentTarget = e.currentTarget as Konva.Group;
const target = e.target;
const target = e.target as Konva.Shape;
const { width: fieldWidth, height: fieldHeight } = fieldGroup.getClientRect();

View File

@ -18,7 +18,7 @@ import { cn } from '@documenso/ui/lib/utils';
import { Card, CardContent } from '@documenso/ui/primitives/card';
import { DocumentFlowFormContainer } from '@documenso/ui/primitives/document-flow/document-flow-root';
import type { DocumentFlowStep } from '@documenso/ui/primitives/document-flow/types';
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
import { PDFViewerSuspense } from '@documenso/ui/primitives/pdf-viewer.suspense';
import { Stepper } from '@documenso/ui/primitives/stepper';
import { AddTemplateFieldsFormPartial } from '@documenso/ui/primitives/template-flow/add-template-fields';
import type { TAddTemplateFieldsFormSchema } from '@documenso/ui/primitives/template-flow/add-template-fields.types';
@ -312,7 +312,7 @@ export const TemplateEditForm = ({
gradient
>
<CardContent className="p-2">
<PDFViewer
<PDFViewerSuspense
key={template.envelopeItems[0].id}
envelopeItem={template.envelopeItems[0]}
token={undefined}

View File

@ -1,6 +1,3 @@
import { useEffect } from 'react';
import Plausible from 'plausible-tracker';
import {
Links,
Meta,
@ -17,7 +14,7 @@ import { PreventFlashOnWrongTheme, ThemeProvider, useTheme } from 'remix-themes'
import { getOptionalSession } from '@documenso/auth/server/lib/utils/get-session';
import { SessionProvider } from '@documenso/lib/client-only/providers/session';
import { APP_I18N_OPTIONS, type SupportedLanguageCodes } from '@documenso/lib/constants/i18n';
import { createPublicEnv, env } from '@documenso/lib/utils/env';
import { createPublicEnv } from '@documenso/lib/utils/env';
import { extractLocaleData } from '@documenso/lib/utils/i18n';
import { TrpcProvider } from '@documenso/trpc/react';
import { getOrganisationSession } from '@documenso/trpc/server/organisation-router/get-organisation-session';
@ -31,11 +28,6 @@ import { langCookie } from './storage/lang-cookie.server';
import { themeSessionResolver } from './storage/theme-session.server';
import { appMetaTags } from './utils/meta';
const { trackPageview } = Plausible({
domain: 'documenso.com',
trackLocalhost: false,
});
export const links: Route.LinksFunction = () => [{ rel: 'stylesheet', href: stylesheet }];
export function meta() {
@ -92,12 +84,6 @@ export function Layout({ children }: { children: React.ReactNode }) {
const location = useLocation();
useEffect(() => {
if (env('NODE_ENV') === 'production') {
trackPageview();
}
}, [location.pathname]);
return (
<ThemeProvider specifiedTheme={theme} themeAction="/api/theme">
<LayoutContent>{children}</LayoutContent>

View File

@ -1,3 +1,5 @@
import { lazy } from 'react';
import { msg } from '@lingui/core/macro';
import { Plural, Trans, useLingui } from '@lingui/react/macro';
import { DocumentStatus } from '@prisma/client';
@ -19,7 +21,7 @@ import { cn } from '@documenso/ui/lib/utils';
import { Badge } from '@documenso/ui/primitives/badge';
import { Button } from '@documenso/ui/primitives/button';
import { Card, CardContent } from '@documenso/ui/primitives/card';
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
import { PDFViewerSuspense } from '@documenso/ui/primitives/pdf-viewer.suspense';
import { Spinner } from '@documenso/ui/primitives/spinner';
import { DocumentPageViewButton } from '~/components/general/document/document-page-view-button';
@ -33,13 +35,16 @@ import {
FRIENDLY_STATUS_MAP,
} from '~/components/general/document/document-status';
import { EnvelopeRendererFileSelector } from '~/components/general/envelope-editor/envelope-file-selector';
import EnvelopeGenericPageRenderer from '~/components/general/envelope-editor/envelope-generic-page-renderer';
import { GenericErrorLayout } from '~/components/general/generic-error-layout';
import { StackAvatarsWithTooltip } from '~/components/general/stack-avatars-with-tooltip';
import { useCurrentTeam } from '~/providers/team';
import type { Route } from './+types/documents.$id._index';
const EnvelopeGenericPageRenderer = lazy(
async () => import('~/components/general/envelope-editor/envelope-generic-page-renderer'),
);
export default function DocumentPage({ params }: Route.ComponentProps) {
const { t } = useLingui();
const { user } = useSession();
@ -56,7 +61,7 @@ export default function DocumentPage({ params }: Route.ComponentProps) {
if (isLoadingEnvelope) {
return (
<div className="text-foreground flex w-screen flex-col items-center justify-center gap-2 py-64">
<div className="flex w-screen flex-col items-center justify-center gap-2 py-64 text-foreground">
<Spinner />
<Trans>Loading</Trans>
</div>
@ -117,7 +122,7 @@ export default function DocumentPage({ params }: Route.ComponentProps) {
/>
{envelope.recipients.length > 0 && (
<div className="text-muted-foreground flex items-center">
<div className="flex items-center text-muted-foreground">
<Users2 className="mr-2 h-5 w-5" />
<StackAvatarsWithTooltip
@ -188,7 +193,7 @@ export default function DocumentPage({ params }: Route.ComponentProps) {
/>
)}
<PDFViewer
<PDFViewerSuspense
envelopeItem={envelope.envelopeItems[0]}
token={undefined}
key={envelope.envelopeItems[0].id}
@ -202,16 +207,16 @@ export default function DocumentPage({ params }: Route.ComponentProps) {
className={cn('col-span-12 lg:col-span-6 xl:col-span-5', isMultiEnvelopeItem && 'mt-20')}
>
<div className="space-y-6">
<section className="border-border bg-widget flex flex-col rounded-xl border pb-4 pt-6">
<section className="flex flex-col rounded-xl border border-border bg-widget pb-4 pt-6">
<div className="flex flex-row items-center justify-between px-4">
<h3 className="text-foreground text-2xl font-semibold">
<h3 className="text-2xl font-semibold text-foreground">
{t(FRIENDLY_STATUS_MAP[envelope.status].labelExtended)}
</h3>
<DocumentPageViewDropdown envelope={envelope} />
</div>
<p className="text-muted-foreground mt-2 px-4 text-sm">
<p className="mt-2 px-4 text-sm text-muted-foreground">
{match(envelope.status)
.with(DocumentStatus.COMPLETED, () => (
<Trans>This document has been signed by all recipients</Trans>

View File

@ -1,3 +1,5 @@
import { lazy } from 'react';
import { msg } from '@lingui/core/macro';
import { Trans, useLingui } from '@lingui/react/macro';
import { DocumentSigningOrder, SigningStatus } from '@prisma/client';
@ -14,14 +16,13 @@ import PDFViewerKonvaLazy from '@documenso/ui/components/pdf-viewer/pdf-viewer-k
import { cn } from '@documenso/ui/lib/utils';
import { Button } from '@documenso/ui/primitives/button';
import { Card, CardContent } from '@documenso/ui/primitives/card';
import { PDFViewer } from '@documenso/ui/primitives/pdf-viewer';
import { PDFViewerSuspense } from '@documenso/ui/primitives/pdf-viewer.suspense';
import { Spinner } from '@documenso/ui/primitives/spinner';
import { TemplateBulkSendDialog } from '~/components/dialogs/template-bulk-send-dialog';
import { TemplateDirectLinkDialog } from '~/components/dialogs/template-direct-link-dialog';
import { TemplateUseDialog } from '~/components/dialogs/template-use-dialog';
import { EnvelopeRendererFileSelector } from '~/components/general/envelope-editor/envelope-file-selector';
import EnvelopeGenericPageRenderer from '~/components/general/envelope-editor/envelope-generic-page-renderer';
import { GenericErrorLayout } from '~/components/general/generic-error-layout';
import { TemplateDirectLinkBadge } from '~/components/general/template/template-direct-link-badge';
import { TemplatePageViewDocumentsTable } from '~/components/general/template/template-page-view-documents-table';
@ -34,6 +35,10 @@ import { useCurrentTeam } from '~/providers/team';
import type { Route } from './+types/templates.$id._index';
const EnvelopeGenericPageRenderer = lazy(
async () => import('~/components/general/envelope-editor/envelope-generic-page-renderer'),
);
export default function TemplatePage({ params }: Route.ComponentProps) {
const { t } = useLingui();
const { user } = useSession();
@ -51,7 +56,7 @@ export default function TemplatePage({ params }: Route.ComponentProps) {
if (isLoadingEnvelope) {
return (
<div className="text-foreground flex w-screen flex-col items-center justify-center gap-2 py-64">
<div className="flex w-screen flex-col items-center justify-center gap-2 py-64 text-foreground">
<Spinner />
<Trans>Loading</Trans>
</div>
@ -205,7 +210,7 @@ export default function TemplatePage({ params }: Route.ComponentProps) {
documentMeta={mockedDocumentMeta}
/>
<PDFViewer
<PDFViewerSuspense
envelopeItem={envelope.envelopeItems[0]}
token={undefined}
version="signed"
@ -219,9 +224,9 @@ export default function TemplatePage({ params }: Route.ComponentProps) {
className={cn('col-span-12 lg:col-span-6 xl:col-span-5', isMultiEnvelopeItem && 'mt-20')}
>
<div className="space-y-6">
<section className="border-border bg-widget flex flex-col rounded-xl border pb-4 pt-6">
<section className="flex flex-col rounded-xl border border-border bg-widget pb-4 pt-6">
<div className="flex flex-row items-center justify-between px-4">
<h3 className="text-foreground text-2xl font-semibold">
<h3 className="text-2xl font-semibold text-foreground">
<Trans>Template</Trans>
</h3>
@ -239,7 +244,7 @@ export default function TemplatePage({ params }: Route.ComponentProps) {
</div>
</div>
<p className="text-muted-foreground mt-2 px-4 text-sm">
<p className="mt-2 px-4 text-sm text-muted-foreground">
<Trans>Manage and view template</Trans>
</p>

View File

@ -3,7 +3,7 @@ import sharp from 'sharp';
import { getFileServerSide } from '@documenso/lib/universal/upload/get-file.server';
import { prisma } from '@documenso/prisma';
import type { Route } from './+types/branding.logo.team.$teamId';
import type { Route } from './+types/branding.logo.organisation.$orgId';
export async function loader({ params }: Route.LoaderArgs) {
const organisationId = params.orgId;
@ -69,7 +69,7 @@ export async function loader({ params }: Route.LoaderArgs) {
})
.toBuffer();
return new Response(img, {
return new Response(Buffer.from(img), {
headers: {
'Content-Type': 'image/png',
'Content-Length': img.length.toString(),

View File

@ -14,7 +14,7 @@
"with:env": "dotenv -e ../../.env -e ../../.env.local --"
},
"dependencies": {
"@cantoo/pdf-lib": "^2.5.2",
"@cantoo/pdf-lib": "^2.5.3",
"@documenso/api": "*",
"@documenso/assets": "*",
"@documenso/auth": "*",
@ -26,85 +26,86 @@
"@documenso/ui": "*",
"@epic-web/remember": "^1.1.0",
"@faker-js/faker": "^10.1.0",
"@hono/node-server": "^1.13.7",
"@hono/trpc-server": "^0.3.4",
"@hookform/resolvers": "^3.1.0",
"@lingui/core": "^5.2.0",
"@lingui/detect-locale": "^5.2.0",
"@lingui/macro": "^5.2.0",
"@lingui/react": "^5.2.0",
"@hono/node-server": "^1.19.6",
"@hono/trpc-server": "^0.4.0",
"@hono/standard-validator": "^0.2.0",
"@hookform/resolvers": "^3",
"@lingui/core": "^5.6.0",
"@lingui/detect-locale": "^5.6.0",
"@lingui/macro": "^5.6.0",
"@lingui/react": "^5.6.0",
"@oslojs/crypto": "^1.0.1",
"@oslojs/encoding": "^1.1.0",
"@react-router/node": "^7.6.0",
"@react-router/serve": "^7.6.0",
"@react-router/node": "^7.9.6",
"@react-router/serve": "^7.9.6",
"@simplewebauthn/browser": "^9.0.1",
"@simplewebauthn/server": "^9.0.3",
"autoprefixer": "^10.4.13",
"@tanstack/react-query": "5.90.10",
"autoprefixer": "^10.4.22",
"colord": "^2.9.3",
"content-disposition": "^0.5.4",
"framer-motion": "^10.12.8",
"hono": "4.7.0",
"content-disposition": "^1.0.1",
"framer-motion": "^12.23.24",
"hono": "4.10.6",
"hono-rate-limiter": "^0.4.2",
"hono-react-router-adapter": "^0.6.2",
"input-otp": "^1.2.4",
"isbot": "^5.1.17",
"jsonwebtoken": "^9.0.2",
"konva": "^10.0.2",
"lucide-react": "^0.279.0",
"luxon": "^3.4.0",
"papaparse": "^5.4.1",
"plausible-tracker": "^0.3.9",
"posthog-js": "^1.245.0",
"posthog-node": "^4.17.0",
"hono-react-router-adapter": "^0.6.5",
"input-otp": "^1.4.2",
"isbot": "^5.1.32",
"konva": "^10.0.9",
"lucide-react": "^0.554.0",
"luxon": "^3.7.2",
"nanoid": "^5.1.6",
"papaparse": "^5.5.3",
"posthog-js": "^1.297.2",
"posthog-node": "^4.18.0",
"react": "^18",
"react-call": "^1.7.0",
"react-call": "^1.8.1",
"react-dom": "^18",
"react-dropzone": "^14.2.3",
"react-hook-form": "^7.43.9",
"react-hotkeys-hook": "^4.4.1",
"react-icons": "^5.4.0",
"react-rnd": "^10.4.1",
"react-router": "^7.6.0",
"recharts": "^2.7.2",
"remeda": "^2.17.3",
"react-dropzone": "^14.3.8",
"react-hook-form": "^7.66.1",
"react-hotkeys-hook": "^4.6.2",
"react-icons": "^5.5.0",
"react-rnd": "^10.5.2",
"react-router": "^7.9.6",
"recharts": "^2.15.4",
"remeda": "^2.32.0",
"remix-themes": "^2.0.4",
"satori": "^0.12.1",
"sharp": "0.32.6",
"tailwindcss": "^3.4.15",
"ts-pattern": "^5.0.5",
"ua-parser-js": "^1.0.37",
"satori": "^0.18.3",
"sharp": "0.34.5",
"tailwindcss": "^3.4.18",
"ts-pattern": "^5.9.0",
"ua-parser-js": "^1.0.41",
"uqr": "^0.1.2"
},
"devDependencies": {
"@babel/core": "^7.26.7",
"@babel/preset-react": "^7.26.3",
"@babel/preset-typescript": "^7.26.0",
"@lingui/babel-plugin-lingui-macro": "^5.2.0",
"@lingui/vite-plugin": "^5.3.1",
"@react-router/dev": "^7.6.0",
"@react-router/remix-routes-option-adapter": "^7.6.0",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-commonjs": "^28.0.2",
"@rollup/plugin-node-resolve": "^16.0.0",
"@rollup/plugin-typescript": "^12.1.2",
"@babel/core": "^7.28.5",
"@babel/preset-react": "^7.28.5",
"@babel/preset-typescript": "^7.28.5",
"@lingui/babel-plugin-lingui-macro": "^5.6.0",
"@lingui/vite-plugin": "^5.6.0",
"@react-router/dev": "^7.9.6",
"@react-router/remix-routes-option-adapter": "^7.9.6",
"@rollup/plugin-babel": "^6.1.0",
"@rollup/plugin-commonjs": "^28.0.9",
"@rollup/plugin-node-resolve": "^16.0.3",
"@rollup/plugin-typescript": "^12.3.0",
"@simplewebauthn/types": "^9.0.1",
"@types/content-disposition": "^0.5.9",
"@types/formidable": "^2.0.6",
"@types/luxon": "^3.3.1",
"@types/formidable": "^3.4.6",
"@types/luxon": "^3.7.1",
"@types/node": "^20",
"@types/papaparse": "^5.3.15",
"@types/react": "^18",
"@types/papaparse": "^5.5.0",
"@types/react": "18.3.27",
"@types/react-dom": "^18",
"@types/ua-parser-js": "^0.7.39",
"cross-env": "^7.0.3",
"esbuild": "^0.25.4",
"remix-flat-routes": "^0.8.4",
"rollup": "^4.34.5",
"tsx": "^4.19.2",
"cross-env": "^10.1.0",
"esbuild": "^0.27.0",
"remix-flat-routes": "^0.8.5",
"rollup": "^4.53.3",
"tsx": "^4.20.6",
"typescript": "5.6.2",
"vite": "^6.3.5",
"vite": "^7.2.4",
"vite-plugin-babel-macros": "^1.0.6",
"vite-tsconfig-paths": "^5.1.4"
},
"version": "2.0.14"
}
}

View File

@ -49,7 +49,7 @@ export default defineConfig({
}),
],
ssr: {
noExternal: ['react-dropzone', 'plausible-tracker', 'pdfjs-dist'],
noExternal: ['react-dropzone', 'plausible-tracker'],
external: [
'@node-rs/bcrypt',
'@prisma/client',