mirror of
https://github.com/documenso/documenso.git
synced 2025-11-11 04:52:41 +10:00
fix: tidy code and base on main
This commit is contained in:
@ -4,19 +4,20 @@ import { useState } from 'react';
|
|||||||
|
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
import { DocumentData, Field, Recipient, Template, User } from '@documenso/prisma/client';
|
import type { DocumentData, Field, Recipient, Template, User } from '@documenso/prisma/client';
|
||||||
import { cn } from '@documenso/ui/lib/utils';
|
import { cn } from '@documenso/ui/lib/utils';
|
||||||
import { Card, CardContent } from '@documenso/ui/primitives/card';
|
import { Card, CardContent } from '@documenso/ui/primitives/card';
|
||||||
import {
|
import {
|
||||||
DocumentFlowFormContainer,
|
DocumentFlowFormContainer,
|
||||||
DocumentFlowFormContainerHeader,
|
DocumentFlowFormContainerHeader,
|
||||||
} from '@documenso/ui/primitives/document-flow/document-flow-root';
|
} from '@documenso/ui/primitives/document-flow/document-flow-root';
|
||||||
import { DocumentFlowStep } from '@documenso/ui/primitives/document-flow/types';
|
import type { DocumentFlowStep } from '@documenso/ui/primitives/document-flow/types';
|
||||||
import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer';
|
import { LazyPDFViewer } from '@documenso/ui/primitives/lazy-pdf-viewer';
|
||||||
|
import { Stepper } from '@documenso/ui/primitives/stepper';
|
||||||
import { AddTemplateFieldsFormPartial } from '@documenso/ui/primitives/template-flow/add-template-fields';
|
import { AddTemplateFieldsFormPartial } from '@documenso/ui/primitives/template-flow/add-template-fields';
|
||||||
import { TAddTemplateFieldsFormSchema } from '@documenso/ui/primitives/template-flow/add-template-fields.types';
|
import type { TAddTemplateFieldsFormSchema } from '@documenso/ui/primitives/template-flow/add-template-fields.types';
|
||||||
import { AddTemplatePlaceholderRecipientsFormPartial } from '@documenso/ui/primitives/template-flow/add-template-placeholder-recipients';
|
import { AddTemplatePlaceholderRecipientsFormPartial } from '@documenso/ui/primitives/template-flow/add-template-placeholder-recipients';
|
||||||
import { TAddTemplatePlacholderRecipientsFormSchema } from '@documenso/ui/primitives/template-flow/add-template-placeholder-recipients.types';
|
import type { TAddTemplatePlacholderRecipientsFormSchema } from '@documenso/ui/primitives/template-flow/add-template-placeholder-recipients.types';
|
||||||
import { useToast } from '@documenso/ui/primitives/use-toast';
|
import { useToast } from '@documenso/ui/primitives/use-toast';
|
||||||
|
|
||||||
import { addTemplateFields } from '~/components/forms/edit-template/add-template-fields.action';
|
import { addTemplateFields } from '~/components/forms/edit-template/add-template-fields.action';
|
||||||
@ -32,6 +33,7 @@ export type EditTemplateFormProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
type EditTemplateStep = 'signers' | 'fields';
|
type EditTemplateStep = 'signers' | 'fields';
|
||||||
|
const EditTemplateSteps: EditTemplateStep[] = ['signers', 'fields'];
|
||||||
|
|
||||||
export const EditTemplateForm = ({
|
export const EditTemplateForm = ({
|
||||||
className,
|
className,
|
||||||
@ -56,7 +58,6 @@ export const EditTemplateForm = ({
|
|||||||
title: 'Add Fields',
|
title: 'Add Fields',
|
||||||
description: 'Add all relevant fields for each recipient.',
|
description: 'Add all relevant fields for each recipient.',
|
||||||
stepIndex: 2,
|
stepIndex: 2,
|
||||||
onBackStep: () => setStep('signers'),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -118,33 +119,35 @@ export const EditTemplateForm = ({
|
|||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<div className="col-span-12 lg:col-span-6 xl:col-span-5">
|
<div className="col-span-12 lg:col-span-6 xl:col-span-5">
|
||||||
<DocumentFlowFormContainer onSubmit={(e) => e.preventDefault()}>
|
<DocumentFlowFormContainer
|
||||||
|
className="lg:h-[calc(100vh-6rem)]"
|
||||||
|
onSubmit={(e) => e.preventDefault()}
|
||||||
|
>
|
||||||
<DocumentFlowFormContainerHeader
|
<DocumentFlowFormContainerHeader
|
||||||
title={currentDocumentFlow.title}
|
title={currentDocumentFlow.title}
|
||||||
description={currentDocumentFlow.description}
|
description={currentDocumentFlow.description}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{step === 'signers' && (
|
<Stepper
|
||||||
|
currentStep={currentDocumentFlow.stepIndex}
|
||||||
|
setCurrentStep={(step) => setStep(EditTemplateSteps[step - 1])}
|
||||||
|
>
|
||||||
<AddTemplatePlaceholderRecipientsFormPartial
|
<AddTemplatePlaceholderRecipientsFormPartial
|
||||||
key={recipients.length}
|
key={recipients.length}
|
||||||
documentFlow={documentFlow.signers}
|
documentFlow={documentFlow.signers}
|
||||||
recipients={recipients}
|
recipients={recipients}
|
||||||
fields={fields}
|
fields={fields}
|
||||||
numberOfSteps={Object.keys(documentFlow).length}
|
|
||||||
onSubmit={onAddTemplatePlaceholderFormSubmit}
|
onSubmit={onAddTemplatePlaceholderFormSubmit}
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
|
|
||||||
{step === 'fields' && (
|
|
||||||
<AddTemplateFieldsFormPartial
|
<AddTemplateFieldsFormPartial
|
||||||
key={fields.length}
|
key={fields.length}
|
||||||
documentFlow={documentFlow.fields}
|
documentFlow={documentFlow.fields}
|
||||||
recipients={recipients}
|
recipients={recipients}
|
||||||
fields={fields}
|
fields={fields}
|
||||||
numberOfSteps={Object.keys(documentFlow).length}
|
|
||||||
onSubmit={onAddFieldsFormSubmit}
|
onSubmit={onAddFieldsFormSubmit}
|
||||||
/>
|
/>
|
||||||
)}
|
</Stepper>
|
||||||
</DocumentFlowFormContainer>
|
</DocumentFlowFormContainer>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { redirect } from 'next/navigation';
|
|||||||
|
|
||||||
import { ChevronLeft } from 'lucide-react';
|
import { ChevronLeft } from 'lucide-react';
|
||||||
|
|
||||||
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-session';
|
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
|
||||||
import { getFieldsForTemplate } from '@documenso/lib/server-only/field/get-fields-for-template';
|
import { getFieldsForTemplate } from '@documenso/lib/server-only/field/get-fields-for-template';
|
||||||
import { getRecipientsForTemplate } from '@documenso/lib/server-only/recipient/get-recipients-for-template';
|
import { getRecipientsForTemplate } from '@documenso/lib/server-only/recipient/get-recipients-for-template';
|
||||||
import { getTemplateById } from '@documenso/lib/server-only/template/get-template-by-id';
|
import { getTemplateById } from '@documenso/lib/server-only/template/get-template-by-id';
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import Link from 'next/link';
|
|||||||
import { Copy, Edit, MoreHorizontal, Trash2 } from 'lucide-react';
|
import { Copy, Edit, MoreHorizontal, Trash2 } from 'lucide-react';
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
|
|
||||||
import { Template } from '@documenso/prisma/client';
|
import type { Template } from '@documenso/prisma/client';
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { useRouter } from 'next/navigation';
|
|||||||
import { Loader, Plus } from 'lucide-react';
|
import { Loader, Plus } from 'lucide-react';
|
||||||
|
|
||||||
import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params';
|
import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params';
|
||||||
import { Template } from '@documenso/prisma/client';
|
import type { Template } from '@documenso/prisma/client';
|
||||||
import { trpc } from '@documenso/trpc/react';
|
import { trpc } from '@documenso/trpc/react';
|
||||||
import { Button } from '@documenso/ui/primitives/button';
|
import { Button } from '@documenso/ui/primitives/button';
|
||||||
import { DataTable } from '@documenso/ui/primitives/data-table';
|
import { DataTable } from '@documenso/ui/primitives/data-table';
|
||||||
@ -109,7 +109,7 @@ export const TemplatesDataTable = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{!isRowLoading && <Plus className="-ml-1 mr-2 h-4 w-4" />}
|
{!isRowLoading && <Plus className="-ml-1 mr-2 h-4 w-4" />}
|
||||||
Use
|
Use Template
|
||||||
</Button>
|
</Button>
|
||||||
<DataTableActionDropdown row={row.original} />
|
<DataTableActionDropdown row={row.original} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React, { useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { FilePlus, X } from 'lucide-react';
|
import { FilePlus, X } from 'lucide-react';
|
||||||
|
import { useSession } from 'next-auth/react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import * as z from 'zod';
|
import * as z from 'zod';
|
||||||
|
|
||||||
@ -18,7 +19,6 @@ import { Card, CardContent } from '@documenso/ui/primitives/card';
|
|||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogDescription,
|
|
||||||
DialogHeader,
|
DialogHeader,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
@ -45,7 +45,9 @@ type TCreateTemplateFormSchema = z.infer<typeof ZCreateTemplateFormSchema>;
|
|||||||
|
|
||||||
export const NewTemplateDialog = () => {
|
export const NewTemplateDialog = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const { data: session } = useSession();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
|
|
||||||
const form = useForm<TCreateTemplateFormSchema>({
|
const form = useForm<TCreateTemplateFormSchema>({
|
||||||
resolver: zodResolver(ZCreateTemplateFormSchema),
|
resolver: zodResolver(ZCreateTemplateFormSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
@ -128,23 +130,29 @@ export const NewTemplateDialog = () => {
|
|||||||
setUploadedFile(null);
|
setUploadedFile(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!showNewTemplateDialog) {
|
||||||
|
form.reset();
|
||||||
|
}
|
||||||
|
}, [form, showNewTemplateDialog]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={showNewTemplateDialog} onOpenChange={setShowNewTemplateDialog}>
|
<Dialog open={showNewTemplateDialog} onOpenChange={setShowNewTemplateDialog}>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button className="cursor-pointer">
|
<Button className="cursor-pointer" disabled={!session?.user.emailVerified}>
|
||||||
<>
|
<FilePlus className="-ml-1 mr-2 h-4 w-4" />
|
||||||
<FilePlus className="-ml-1 mr-2 h-4 w-4" />
|
New Template
|
||||||
New Template
|
|
||||||
</>
|
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
|
|
||||||
<DialogContent className="w-full max-w-xl">
|
<DialogContent className="w-full max-w-xl">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="mb-4">New Template</DialogTitle>
|
<DialogTitle className="mb-4">New Template</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<DialogDescription asChild>
|
|
||||||
|
<div>
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
|
<form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col gap-y-4">
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="name"
|
name="name"
|
||||||
@ -167,23 +175,26 @@ export const NewTemplateDialog = () => {
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Label htmlFor="template">Upload a Document</Label>
|
<Label htmlFor="template">Upload a Document</Label>
|
||||||
|
|
||||||
<div className="my-3">
|
<div className="my-3">
|
||||||
{uploadedFile ? (
|
{uploadedFile ? (
|
||||||
<Card gradient className="h-[40vh]">
|
<Card gradient className="h-[40vh]">
|
||||||
<CardContent className="flex h-full flex-col items-center justify-center p-2">
|
<CardContent className="flex h-full flex-col items-center justify-center p-2">
|
||||||
<div
|
<button
|
||||||
onClick={() => resetForm()}
|
onClick={() => resetForm()}
|
||||||
className="absolute right-2 top-2 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none"
|
title="Remove Template"
|
||||||
|
className="text-muted-foreground absolute right-2.5 top-2.5 rounded-sm opacity-60 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none"
|
||||||
>
|
>
|
||||||
<X className="h-5 w-5" />
|
<X className="h-6 w-6" />
|
||||||
<span className="sr-only">Remove Template</span>
|
<span className="sr-only">Remove Template</span>
|
||||||
</div>
|
</button>
|
||||||
|
|
||||||
<div className="border-muted-foreground/20 group-hover:border-documenso/80 dark:bg-muted/80 z-10 flex aspect-[3/4] w-24 flex-col gap-y-1 rounded-lg border bg-white/80 px-2 py-4 backdrop-blur-sm">
|
<div className="border-muted-foreground/20 group-hover:border-documenso/80 dark:bg-muted/80 z-10 flex aspect-[3/4] w-24 flex-col gap-y-1 rounded-lg border bg-white/80 px-2 py-4 backdrop-blur-sm">
|
||||||
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-full rounded-[2px]" />
|
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-full rounded-[2px]" />
|
||||||
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-5/6 rounded-[2px]" />
|
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-5/6 rounded-[2px]" />
|
||||||
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-full rounded-[2px]" />
|
<div className="bg-muted-foreground/20 group-hover:bg-documenso h-2 w-full rounded-[2px]" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="group-hover:text-foreground text-muted-foreground mt-4 font-medium">
|
<p className="group-hover:text-foreground text-muted-foreground mt-4 font-medium">
|
||||||
Uploaded Document
|
Uploaded Document
|
||||||
</p>
|
</p>
|
||||||
@ -210,7 +221,7 @@ export const NewTemplateDialog = () => {
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
</DialogDescription>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-session';
|
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
|
||||||
import { getTemplates } from '@documenso/lib/server-only/template/get-templates';
|
import { getTemplates } from '@documenso/lib/server-only/template/get-templates';
|
||||||
|
|
||||||
import { TemplatesDataTable } from './data-table-templates';
|
import { TemplatesDataTable } from './data-table-templates';
|
||||||
@ -27,9 +27,12 @@ export default async function TemplatesPage({ searchParams = {} }: TemplatesPage
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto max-w-screen-xl px-4 md:px-8">
|
<div className="mx-auto max-w-screen-xl px-4 md:px-8">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-baseline justify-between">
|
||||||
<h1 className="mb-5 mt-2 truncate text-2xl font-semibold md:text-3xl">Templates</h1>
|
<h1 className="mb-5 mt-2 truncate text-2xl font-semibold md:text-3xl">Templates</h1>
|
||||||
<NewTemplateDialog />
|
|
||||||
|
<div>
|
||||||
|
<NewTemplateDialog />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
|
|||||||
@ -41,9 +41,29 @@ export const DesktopNav = ({ className, ...props }: DesktopNavProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn('ml-8 hidden flex-1 gap-x-6 md:flex md:justify-center', className)}
|
className={cn(
|
||||||
|
'ml-8 hidden flex-1 items-center gap-x-12 md:flex md:justify-between',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
|
<div className="flex items-baseline gap-x-6">
|
||||||
|
{navigationLinks.map(({ href, label }) => (
|
||||||
|
<Link
|
||||||
|
key={href}
|
||||||
|
href={href}
|
||||||
|
className={cn(
|
||||||
|
'text-muted-foreground dark:text-muted focus-visible:ring-ring ring-offset-background rounded-md font-medium leading-5 hover:opacity-80 focus-visible:outline-none focus-visible:ring-2',
|
||||||
|
{
|
||||||
|
'text-foreground dark:text-muted-foreground': pathname?.startsWith(href),
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
<CommandMenu open={open} onOpenChange={setOpen} />
|
<CommandMenu open={open} onOpenChange={setOpen} />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@ -62,21 +82,6 @@ export const DesktopNav = ({ className, ...props }: DesktopNavProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{navigationLinks.map(({ href, label }) => (
|
|
||||||
<Link
|
|
||||||
key={href}
|
|
||||||
href={href}
|
|
||||||
className={cn(
|
|
||||||
'text-muted-foreground dark:text-muted focus-visible:ring-ring ring-offset-background rounded-md font-medium leading-5 hover:opacity-80 focus-visible:outline-none focus-visible:ring-2',
|
|
||||||
{
|
|
||||||
'text-foreground dark:text-muted-foreground': pathname?.startsWith(href),
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{label}
|
|
||||||
</Link>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -49,7 +49,7 @@ export const Header = ({ className, user, ...props }: HeaderProps) => {
|
|||||||
|
|
||||||
<DesktopNav />
|
<DesktopNav />
|
||||||
|
|
||||||
<div className="flex gap-x-4">
|
<div className="flex gap-x-4 md:ml-8">
|
||||||
<ProfileDropdown user={user} />
|
<ProfileDropdown user={user} />
|
||||||
|
|
||||||
{/* <Button variant="outline" size="sm" className="h-10 w-10 p-0.5 md:hidden">
|
{/* <Button variant="outline" size="sm" className="h-10 w-10 p-0.5 md:hidden">
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
'use server';
|
'use server';
|
||||||
|
|
||||||
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-session';
|
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
|
||||||
import { setFieldsForTemplate } from '@documenso/lib/server-only/field/set-fields-for-template';
|
import { setFieldsForTemplate } from '@documenso/lib/server-only/field/set-fields-for-template';
|
||||||
import { TAddTemplateFieldsFormSchema } from '@documenso/ui/primitives/template-flow/add-template-fields.types';
|
import type { TAddTemplateFieldsFormSchema } from '@documenso/ui/primitives/template-flow/add-template-fields.types';
|
||||||
|
|
||||||
export type AddTemplateFieldsActionInput = TAddTemplateFieldsFormSchema & {
|
export type AddTemplateFieldsActionInput = TAddTemplateFieldsFormSchema & {
|
||||||
templateId: number;
|
templateId: number;
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
'use server';
|
'use server';
|
||||||
|
|
||||||
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-session';
|
import { getRequiredServerComponentSession } from '@documenso/lib/next-auth/get-server-component-session';
|
||||||
import { setRecipientsForTemplate } from '@documenso/lib/server-only/recipient/set-recipients-for-template';
|
import { setRecipientsForTemplate } from '@documenso/lib/server-only/recipient/set-recipients-for-template';
|
||||||
import { TAddTemplatePlacholderRecipientsFormSchema } from '@documenso/ui/primitives/template-flow/add-template-placeholder-recipients.types';
|
import type { TAddTemplatePlacholderRecipientsFormSchema } from '@documenso/ui/primitives/template-flow/add-template-placeholder-recipients.types';
|
||||||
|
|
||||||
export type AddTemplatePlaceholdersActionInput = TAddTemplatePlacholderRecipientsFormSchema & {
|
export type AddTemplatePlaceholdersActionInput = TAddTemplatePlacholderRecipientsFormSchema & {
|
||||||
templateId: number;
|
templateId: number;
|
||||||
|
|||||||
@ -20,7 +20,7 @@ const DialogPortal = ({
|
|||||||
}: DialogPrimitive.DialogPortalProps & { position?: 'start' | 'end' | 'center' }) => (
|
}: DialogPrimitive.DialogPortalProps & { position?: 'start' | 'end' | 'center' }) => (
|
||||||
<DialogPrimitive.Portal {...props}>
|
<DialogPrimitive.Portal {...props}>
|
||||||
<div
|
<div
|
||||||
className={cn('fixed inset-0 z-50 flex justify-center sm:items-center', {
|
className={cn('fixed inset-0 z-[9999] flex justify-center sm:items-center', {
|
||||||
'items-start': position === 'start',
|
'items-start': position === 'start',
|
||||||
'items-end': position === 'end',
|
'items-end': position === 'end',
|
||||||
'items-center': position === 'center',
|
'items-center': position === 'center',
|
||||||
|
|||||||
@ -11,7 +11,8 @@ import { getBoundingClientRect } from '@documenso/lib/client-only/get-bounding-c
|
|||||||
import { useDocumentElement } from '@documenso/lib/client-only/hooks/use-document-element';
|
import { useDocumentElement } from '@documenso/lib/client-only/hooks/use-document-element';
|
||||||
import { PDF_VIEWER_PAGE_SELECTOR } from '@documenso/lib/constants/pdf-viewer';
|
import { PDF_VIEWER_PAGE_SELECTOR } from '@documenso/lib/constants/pdf-viewer';
|
||||||
import { nanoid } from '@documenso/lib/universal/id';
|
import { nanoid } from '@documenso/lib/universal/id';
|
||||||
import { Field, FieldType, Recipient } from '@documenso/prisma/client';
|
import type { Field, Recipient } from '@documenso/prisma/client';
|
||||||
|
import { FieldType } from '@documenso/prisma/client';
|
||||||
import { cn } from '@documenso/ui/lib/utils';
|
import { cn } from '@documenso/ui/lib/utils';
|
||||||
import { Button } from '@documenso/ui/primitives/button';
|
import { Button } from '@documenso/ui/primitives/button';
|
||||||
import { Card, CardContent } from '@documenso/ui/primitives/card';
|
import { Card, CardContent } from '@documenso/ui/primitives/card';
|
||||||
@ -29,14 +30,13 @@ import {
|
|||||||
DocumentFlowFormContainerStep,
|
DocumentFlowFormContainerStep,
|
||||||
} from '@documenso/ui/primitives/document-flow/document-flow-root';
|
} from '@documenso/ui/primitives/document-flow/document-flow-root';
|
||||||
import { FieldItem } from '@documenso/ui/primitives/document-flow/field-item';
|
import { FieldItem } from '@documenso/ui/primitives/document-flow/field-item';
|
||||||
import {
|
import type { DocumentFlowStep } from '@documenso/ui/primitives/document-flow/types';
|
||||||
DocumentFlowStep,
|
import { FRIENDLY_FIELD_TYPE } from '@documenso/ui/primitives/document-flow/types';
|
||||||
FRIENDLY_FIELD_TYPE,
|
|
||||||
} from '@documenso/ui/primitives/document-flow/types';
|
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from '@documenso/ui/primitives/popover';
|
import { Popover, PopoverContent, PopoverTrigger } from '@documenso/ui/primitives/popover';
|
||||||
|
|
||||||
|
import { useStep } from '../stepper';
|
||||||
// import { Tooltip, TooltipContent, TooltipTrigger } from '@documenso/ui/primitives/tooltip';
|
// import { Tooltip, TooltipContent, TooltipTrigger } from '@documenso/ui/primitives/tooltip';
|
||||||
import { TAddTemplateFieldsFormSchema } from './add-template-fields.types';
|
import type { TAddTemplateFieldsFormSchema } from './add-template-fields.types';
|
||||||
|
|
||||||
const fontCaveat = Caveat({
|
const fontCaveat = Caveat({
|
||||||
weight: ['500'],
|
weight: ['500'],
|
||||||
@ -56,7 +56,6 @@ export type AddTemplateFieldsFormProps = {
|
|||||||
hideRecipients?: boolean;
|
hideRecipients?: boolean;
|
||||||
recipients: Recipient[];
|
recipients: Recipient[];
|
||||||
fields: Field[];
|
fields: Field[];
|
||||||
numberOfSteps: number;
|
|
||||||
onSubmit: (_data: TAddTemplateFieldsFormSchema) => void;
|
onSubmit: (_data: TAddTemplateFieldsFormSchema) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -65,11 +64,12 @@ export const AddTemplateFieldsFormPartial = ({
|
|||||||
hideRecipients = false,
|
hideRecipients = false,
|
||||||
recipients,
|
recipients,
|
||||||
fields,
|
fields,
|
||||||
numberOfSteps,
|
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: AddTemplateFieldsFormProps) => {
|
}: AddTemplateFieldsFormProps) => {
|
||||||
const { isWithinPageBounds, getFieldPosition, getPage } = useDocumentElement();
|
const { isWithinPageBounds, getFieldPosition, getPage } = useDocumentElement();
|
||||||
|
|
||||||
|
const { currentStep, totalSteps, previousStep } = useStep();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@ -519,8 +519,8 @@ export const AddTemplateFieldsFormPartial = ({
|
|||||||
<DocumentFlowFormContainerFooter>
|
<DocumentFlowFormContainerFooter>
|
||||||
<DocumentFlowFormContainerStep
|
<DocumentFlowFormContainerStep
|
||||||
title={documentFlow.title}
|
title={documentFlow.title}
|
||||||
step={documentFlow.stepIndex}
|
step={currentStep}
|
||||||
maxStep={numberOfSteps}
|
maxStep={totalSteps}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<DocumentFlowFormContainerActions
|
<DocumentFlowFormContainerActions
|
||||||
@ -528,7 +528,7 @@ export const AddTemplateFieldsFormPartial = ({
|
|||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
goNextLabel="Save Template"
|
goNextLabel="Save Template"
|
||||||
onGoBackClick={() => {
|
onGoBackClick={() => {
|
||||||
documentFlow.onBackStep?.();
|
previousStep();
|
||||||
remove();
|
remove();
|
||||||
}}
|
}}
|
||||||
onGoNextClick={() => void onFormSubmit()}
|
onGoNextClick={() => void onFormSubmit()}
|
||||||
|
|||||||
@ -5,10 +5,10 @@ import React, { useId, useState } from 'react';
|
|||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { AnimatePresence, motion } from 'framer-motion';
|
import { AnimatePresence, motion } from 'framer-motion';
|
||||||
import { Plus, Trash } from 'lucide-react';
|
import { Plus, Trash } from 'lucide-react';
|
||||||
import { Controller, useFieldArray, useForm } from 'react-hook-form';
|
import { useFieldArray, useForm } from 'react-hook-form';
|
||||||
|
|
||||||
import { nanoid } from '@documenso/lib/universal/id';
|
import { nanoid } from '@documenso/lib/universal/id';
|
||||||
import { Field, Recipient } from '@documenso/prisma/client';
|
import type { Field, Recipient } from '@documenso/prisma/client';
|
||||||
import { Button } from '@documenso/ui/primitives/button';
|
import { Button } from '@documenso/ui/primitives/button';
|
||||||
import { FormErrorMessage } from '@documenso/ui/primitives/form/form-error-message';
|
import { FormErrorMessage } from '@documenso/ui/primitives/form/form-error-message';
|
||||||
import { Input } from '@documenso/ui/primitives/input';
|
import { Input } from '@documenso/ui/primitives/input';
|
||||||
@ -20,29 +20,30 @@ import {
|
|||||||
DocumentFlowFormContainerFooter,
|
DocumentFlowFormContainerFooter,
|
||||||
DocumentFlowFormContainerStep,
|
DocumentFlowFormContainerStep,
|
||||||
} from '../document-flow/document-flow-root';
|
} from '../document-flow/document-flow-root';
|
||||||
import { DocumentFlowStep } from '../document-flow/types';
|
import type { DocumentFlowStep } from '../document-flow/types';
|
||||||
import {
|
import { useStep } from '../stepper';
|
||||||
TAddTemplatePlacholderRecipientsFormSchema,
|
import type { TAddTemplatePlacholderRecipientsFormSchema } from './add-template-placeholder-recipients.types';
|
||||||
ZAddTemplatePlacholderRecipientsFormSchema,
|
import { ZAddTemplatePlacholderRecipientsFormSchema } from './add-template-placeholder-recipients.types';
|
||||||
} from './add-template-placeholder-recipients.types';
|
|
||||||
|
|
||||||
export type AddTemplatePlaceholderRecipientsFormProps = {
|
export type AddTemplatePlaceholderRecipientsFormProps = {
|
||||||
documentFlow: DocumentFlowStep;
|
documentFlow: DocumentFlowStep;
|
||||||
recipients: Recipient[];
|
recipients: Recipient[];
|
||||||
fields: Field[];
|
fields: Field[];
|
||||||
numberOfSteps: number;
|
|
||||||
onSubmit: (_data: TAddTemplatePlacholderRecipientsFormSchema) => void;
|
onSubmit: (_data: TAddTemplatePlacholderRecipientsFormSchema) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AddTemplatePlaceholderRecipientsFormPartial = ({
|
export const AddTemplatePlaceholderRecipientsFormPartial = ({
|
||||||
documentFlow,
|
documentFlow,
|
||||||
numberOfSteps,
|
|
||||||
recipients,
|
recipients,
|
||||||
fields: _fields,
|
fields: _fields,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: AddTemplatePlaceholderRecipientsFormProps) => {
|
}: AddTemplatePlaceholderRecipientsFormProps) => {
|
||||||
const initialId = useId();
|
const initialId = useId();
|
||||||
const [placeholderRecipientCount, setPlaceholderRecipientCount] = useState(1);
|
const [placeholderRecipientCount, setPlaceholderRecipientCount] = useState(() =>
|
||||||
|
recipients.length > 1 ? recipients.length + 1 : 2,
|
||||||
|
);
|
||||||
|
|
||||||
|
const { currentStep, totalSteps, previousStep } = useStep();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
@ -62,8 +63,8 @@ export const AddTemplatePlaceholderRecipientsFormPartial = ({
|
|||||||
: [
|
: [
|
||||||
{
|
{
|
||||||
formId: initialId,
|
formId: initialId,
|
||||||
name: `John Doe`,
|
name: `Recipient 1`,
|
||||||
email: `johndoe@documenso.com`,
|
email: `recipient.1@documenso.com`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -81,13 +82,13 @@ export const AddTemplatePlaceholderRecipientsFormPartial = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const onAddPlaceholderRecipient = () => {
|
const onAddPlaceholderRecipient = () => {
|
||||||
setPlaceholderRecipientCount(placeholderRecipientCount + 1);
|
|
||||||
|
|
||||||
appendSigner({
|
appendSigner({
|
||||||
formId: nanoid(12),
|
formId: nanoid(12),
|
||||||
name: `John Doe ${placeholderRecipientCount}`,
|
name: `Recipient ${placeholderRecipientCount}`,
|
||||||
email: `johndoe${placeholderRecipientCount}@documenso.com`,
|
email: `recipient.${placeholderRecipientCount}@documenso.com`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setPlaceholderRecipientCount((count) => count + 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onRemoveSigner = (index: number) => {
|
const onRemoveSigner = (index: number) => {
|
||||||
@ -117,38 +118,24 @@ export const AddTemplatePlaceholderRecipientsFormPartial = ({
|
|||||||
<span className="text-destructive ml-1 inline-block font-medium">*</span>
|
<span className="text-destructive ml-1 inline-block font-medium">*</span>
|
||||||
</Label>
|
</Label>
|
||||||
|
|
||||||
<Controller
|
<Input
|
||||||
control={control}
|
id={`signer-${signer.id}-email`}
|
||||||
name={`signers.${index}.email`}
|
type="email"
|
||||||
render={({ field }) => (
|
value={signer.email}
|
||||||
<Input
|
disabled
|
||||||
id={`signer-${signer.id}-email`}
|
className="bg-background mt-2"
|
||||||
type="email"
|
|
||||||
className="bg-background mt-2"
|
|
||||||
disabled={isSubmitting}
|
|
||||||
onKeyDown={onKeyDown}
|
|
||||||
{...field}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<Label htmlFor={`signer-${signer.id}-name`}>Name</Label>
|
<Label htmlFor={`signer-${signer.id}-name`}>Name</Label>
|
||||||
|
|
||||||
<Controller
|
<Input
|
||||||
control={control}
|
id={`signer-${signer.id}-name`}
|
||||||
name={`signers.${index}.name`}
|
type="text"
|
||||||
render={({ field }) => (
|
value={signer.name}
|
||||||
<Input
|
disabled
|
||||||
id={`signer-${signer.id}-name`}
|
className="bg-background mt-2"
|
||||||
type="text"
|
|
||||||
className="bg-background mt-2"
|
|
||||||
disabled={isSubmitting}
|
|
||||||
onKeyDown={onKeyDown}
|
|
||||||
{...field}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -189,14 +176,15 @@ export const AddTemplatePlaceholderRecipientsFormPartial = ({
|
|||||||
<DocumentFlowFormContainerFooter>
|
<DocumentFlowFormContainerFooter>
|
||||||
<DocumentFlowFormContainerStep
|
<DocumentFlowFormContainerStep
|
||||||
title={documentFlow.title}
|
title={documentFlow.title}
|
||||||
step={documentFlow.stepIndex}
|
step={currentStep}
|
||||||
maxStep={numberOfSteps}
|
maxStep={totalSteps}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<DocumentFlowFormContainerActions
|
<DocumentFlowFormContainerActions
|
||||||
loading={isSubmitting}
|
loading={isSubmitting}
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
onGoBackClick={documentFlow.onBackStep}
|
canGoBack={currentStep > 1}
|
||||||
|
onGoBackClick={() => previousStep()}
|
||||||
onGoNextClick={() => void onFormSubmit()}
|
onGoNextClick={() => void onFormSubmit()}
|
||||||
/>
|
/>
|
||||||
</DocumentFlowFormContainerFooter>
|
</DocumentFlowFormContainerFooter>
|
||||||
|
|||||||
Reference in New Issue
Block a user