feat: migrate nextjs to rr7

This commit is contained in:
David Nguyen
2025-01-02 15:33:37 +11:00
committed by Mythie
parent 9183f668d3
commit 75d7336763
1021 changed files with 60930 additions and 40839 deletions

View File

@ -1,5 +1,3 @@
'use client';
import { motion } from 'framer-motion';
type AnimateGenericFadeInOutProps = {

View File

@ -1,35 +0,0 @@
import Link from 'next/link';
import { Button } from '../primitives/button';
import { Card, CardContent } from '../primitives/card';
type CallToActionProps = {
className?: string;
utmSource?: string;
};
export const CallToAction = ({ className, utmSource = 'generic-cta' }: CallToActionProps) => {
return (
<Card spotlight className={className}>
<CardContent className="flex flex-col items-center justify-center p-12">
<h2 className="text-center text-2xl font-bold">Looking for the managed solution?</h2>
<p className="text-muted-foreground mt-4 max-w-[55ch] text-center leading-normal">
You can get started with Documenso in minutes. We handle the infrastructure, so you can
focus on signing documents.
</p>
<Button
className="focus-visible:ring-ring ring-offset-background bg-primary text-primary-foreground hover:bg-primary/90text-sm mt-8 inline-flex items-center justify-center rounded-full border font-medium no-underline transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"
variant="default"
size="lg"
asChild
>
<Link href={`https://app.documenso.com/signup?utm_source=${utmSource}`} target="_blank">
Get started
</Link>
</Button>
</CardContent>
</Card>
);
};

View File

@ -0,0 +1,11 @@
import { useEffect, useState } from 'react';
export const ClientOnly = async ({ children }: { children: React.ReactNode }) => {
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
return mounted ? children : null;
};

View File

@ -1,5 +1,3 @@
'use client';
import { useState } from 'react';
import { motion } from 'framer-motion';

View File

@ -1,9 +1,8 @@
import { msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { CheckIcon } from 'lucide-react';
import { SUPPORTED_LANGUAGES } from '@documenso/lib/constants/i18n';
import { switchI18NLanguage } from '@documenso/lib/server-only/i18n/switch-i18n-language';
import { dynamicActivate } from '@documenso/lib/utils/i18n';
import { cn } from '@documenso/ui/lib/utils';
import {
@ -25,8 +24,16 @@ export const LanguageSwitcherDialog = ({ open, setOpen }: LanguageSwitcherDialog
const setLanguage = async (lang: string) => {
setOpen(false);
await dynamicActivate(i18n, lang);
await switchI18NLanguage(lang);
await dynamicActivate(lang);
const formData = new FormData();
formData.append('lang', lang);
await fetch('/api/locale', {
method: 'post',
body: formData,
});
};
return (

View File

@ -1,24 +1,22 @@
'use client';
import { useState } from 'react';
import type { DocumentData } from '@prisma/client';
import * as DialogPrimitive from '@radix-ui/react-dialog';
import { X } from 'lucide-react';
import type { DocumentData } from '@documenso/prisma/client';
import { cn } from '../../lib/utils';
import { Dialog, DialogOverlay, DialogPortal } from '../../primitives/dialog';
import { LazyPDFViewerNoLoader } from '../../primitives/lazy-pdf-viewer';
import { Dialog, DialogOverlay, DialogPortal, DialogTrigger } from '../../primitives/dialog';
import PDFViewer from '../../primitives/pdf-viewer';
export type DocumentDialogProps = {
trigger?: React.ReactNode;
documentData: DocumentData;
} & Omit<DialogPrimitive.DialogProps, 'children'>;
/**
* A dialog which renders the provided document.
*/
export default function DocumentDialog({ documentData, ...props }: DocumentDialogProps) {
export default function DocumentDialog({ trigger, documentData, ...props }: DocumentDialogProps) {
const [documentLoaded, setDocumentLoaded] = useState(false);
const onDocumentLoad = () => {
@ -30,6 +28,12 @@ export default function DocumentDialog({ documentData, ...props }: DocumentDialo
<DialogPortal>
<DialogOverlay className="bg-black/80" />
{trigger && (
<DialogTrigger onClick={(e) => e.stopPropagation()} asChild={true}>
{trigger}
</DialogTrigger>
)}
<DialogPrimitive.Content
className={cn(
'animate-in data-[state=open]:fade-in-90 sm:zoom-in-90 pointer-events-none fixed z-50 h-screen w-screen overflow-y-auto px-2 py-14 opacity-0 transition-opacity lg:py-32',
@ -39,7 +43,7 @@ export default function DocumentDialog({ documentData, ...props }: DocumentDialo
)}
onClick={() => props.onOpenChange?.(false)}
>
<LazyPDFViewerNoLoader
<PDFViewer
className="mx-auto w-full max-w-3xl xl:max-w-5xl"
documentData={documentData}
onClick={(e) => e.stopPropagation()}

View File

@ -1,14 +1,12 @@
'use client';
import type { HTMLAttributes } from 'react';
import { useState } from 'react';
import { Trans } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import type { DocumentData } from '@prisma/client';
import { Download } from 'lucide-react';
import { downloadPDF } from '@documenso/lib/client-only/download-pdf';
import type { DocumentData } from '@documenso/prisma/client';
import { useToast } from '@documenso/ui/primitives/use-toast';
import { Button } from '../../primitives/button';

View File

@ -1,4 +1,4 @@
import { Trans } from '@lingui/macro';
import { Trans } from '@lingui/react/macro';
import { InfoIcon } from 'lucide-react';
import type { TDocumentEmailSettings } from '@documenso/lib/types/document-email';

View File

@ -1,9 +1,8 @@
'use client';
import React, { forwardRef } from 'react';
import { Trans, msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import type { SelectProps } from '@radix-ui/react-select';
import { InfoIcon } from 'lucide-react';

View File

@ -1,9 +1,8 @@
'use client';
import React, { forwardRef } from 'react';
import { Trans, msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import type { SelectProps } from '@radix-ui/react-select';
import { InfoIcon } from 'lucide-react';

View File

@ -1,8 +1,6 @@
'use client';
import React from 'react';
import { Trans } from '@lingui/macro';
import { Trans } from '@lingui/react/macro';
export const DocumentSendEmailMessageHelper = () => {
return (

View File

@ -1,10 +1,9 @@
'use client';
import type { HTMLAttributes } from 'react';
import React, { useState } from 'react';
import { Trans, msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import { Copy, Sparkles } from 'lucide-react';
import { FaXTwitter } from 'react-icons/fa6';

View File

@ -1,3 +1,4 @@
import type { Field } from '@prisma/client';
import { TooltipArrow } from '@radix-ui/react-tooltip';
import type { VariantProps } from 'class-variance-authority';
import { cva } from 'class-variance-authority';
@ -12,7 +13,6 @@ import {
TooltipProvider,
TooltipTrigger,
} from '../..//primitives/tooltip';
import type { Field } from '.prisma/client';
const tooltipVariants = cva('font-semibold', {
variants: {

View File

@ -1,13 +1,11 @@
'use client';
import React, { useEffect, useMemo, useState } from 'react';
import type { Field } from '@prisma/client';
import { createPortal } from 'react-dom';
import { useFieldPageCoords } from '@documenso/lib/client-only/hooks/use-field-page-coords';
import type { TFieldMetaSchema } from '@documenso/lib/types/field-meta';
import { ZFieldMetaSchema } from '@documenso/lib/types/field-meta';
import type { Field } from '@documenso/prisma/client';
import { cn } from '../../lib/utils';
import { Card, CardContent } from '../../primitives/card';
@ -31,7 +29,8 @@ const getCardClassNames = (
checkBoxOrRadio: boolean,
cardClassName?: string,
) => {
const baseClasses = 'field-card-container relative z-20 h-full w-full transition-all';
const baseClasses =
'field--FieldRootContainer field-card-container relative z-20 h-full w-full transition-all';
const insertedClasses =
'bg-primary/20 border-primary ring-primary/20 ring-offset-primary/20 ring-2 ring-offset-2 dark:shadow-none';
@ -141,6 +140,7 @@ export function FieldRootContainer({ field, children, cardClassName }: FieldCont
<Card
id={`field-${field.id}`}
ref={ref}
data-field-type={field.type}
data-inserted={field.inserted ? 'true' : 'false'}
className={cardClassNames}
>

View File

@ -1,9 +1,8 @@
'use client';
import React from 'react';
import { Trans, msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
import type { SelectProps } from '@radix-ui/react-select';
import { InfoIcon } from 'lucide-react';

View File

@ -1,22 +1,23 @@
'use client';
import React, { forwardRef } from 'react';
import { Trans } from '@lingui/macro';
import { Trans } from '@lingui/react/macro';
import { RecipientRole } from '@prisma/client';
import type { SelectProps } from '@radix-ui/react-select';
import { InfoIcon } from 'lucide-react';
import { RecipientRole } from '@documenso/prisma/client';
import { ROLE_ICONS } from '@documenso/ui/primitives/recipient-role-icons';
import { Select, SelectContent, SelectItem, SelectTrigger } from '@documenso/ui/primitives/select';
import { Tooltip, TooltipContent, TooltipTrigger } from '@documenso/ui/primitives/tooltip';
import { cn } from '../../lib/utils';
export type RecipientRoleSelectProps = SelectProps & {
hideCCRecipients?: boolean;
isAssistantEnabled?: boolean;
};
export const RecipientRoleSelect = forwardRef<HTMLButtonElement, RecipientRoleSelectProps>(
({ hideCCRecipients, ...props }, ref) => (
({ hideCCRecipients, isAssistantEnabled = true, ...props }, ref) => (
<Select {...props}>
<SelectTrigger ref={ref} className="bg-background w-[50px] p-2">
{/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */}
@ -110,6 +111,42 @@ export const RecipientRoleSelect = forwardRef<HTMLButtonElement, RecipientRoleSe
</div>
</SelectItem>
)}
<SelectItem
value={RecipientRole.ASSISTANT}
disabled={!isAssistantEnabled}
className={cn(
!isAssistantEnabled &&
'cursor-not-allowed opacity-50 data-[disabled]:pointer-events-auto',
)}
>
<div className="flex items-center">
<div className="flex w-[150px] items-center">
<span className="mr-2">{ROLE_ICONS[RecipientRole.ASSISTANT]}</span>
<Trans>Can prepare</Trans>
</div>
<Tooltip>
<TooltipTrigger>
<InfoIcon className="h-4 w-4" />
</TooltipTrigger>
<TooltipContent className="text-foreground z-9999 max-w-md p-4">
<p>
{isAssistantEnabled ? (
<Trans>
The recipient can prepare the document for later signers by pre-filling
suggest values.
</Trans>
) : (
<Trans>
Assistant role is only available when the document is in sequential signing
mode.
</Trans>
)}
</p>
</TooltipContent>
</Tooltip>
</div>
</SelectItem>
</SelectContent>
</Select>
),

View File

@ -1,15 +1,9 @@
'use client';
import { useCallback, useEffect, useRef, useState } from 'react';
import type { StaticImageData } from 'next/image';
import Image from 'next/image';
import type { Signature } from '@prisma/client';
import { animate, motion, useMotionTemplate, useMotionValue, useTransform } from 'framer-motion';
import { P, match } from 'ts-pattern';
import type { Signature } from '@documenso/prisma/client';
import { cn } from '../lib/utils';
import { Card, CardContent } from '../primitives/card';
@ -17,7 +11,7 @@ export type SigningCardProps = {
className?: string;
name: string;
signature?: Signature;
signingCelebrationImage?: StaticImageData;
signingCelebrationImage?: string;
};
/**
@ -213,7 +207,7 @@ const SigningCardContent = ({ className, name, signature }: SigningCardContentPr
};
type SigningCardImageProps = {
signingCelebrationImage: StaticImageData;
signingCelebrationImage: string;
};
const SigningCardImage = ({ signingCelebrationImage }: SigningCardImageProps) => {
@ -233,7 +227,7 @@ const SigningCardImage = ({ signingCelebrationImage }: SigningCardImageProps) =>
duration: 0.5,
}}
>
<Image
<img
src={signingCelebrationImage}
alt="background pattern"
className="w-full dark:brightness-150 dark:contrast-[70%] dark:invert dark:sepia"
@ -241,7 +235,6 @@ const SigningCardImage = ({ signingCelebrationImage }: SigningCardImageProps) =>
mask: 'radial-gradient(rgba(255, 255, 255, 1) 0%, transparent 67%)',
WebkitMask: 'radial-gradient(rgba(255, 255, 255, 1) 0%, transparent 67%)',
}}
priority
/>
</motion.div>
);