feat: save subject and message on blur

This commit is contained in:
Catalin Pit
2024-08-20 14:19:16 +03:00
parent 2c9136498c
commit d74aca2aa6
3 changed files with 139 additions and 2 deletions

View File

@ -38,6 +38,7 @@ import {
ZResendDocumentMutationSchema,
ZSearchDocumentsMutationSchema,
ZSendDocumentMutationSchema,
ZSetDocumentEmailSettingsMutationSchema,
ZSetPasswordForDocumentMutationSchema,
ZSetSettingsForDocumentMutationSchema,
ZSetTitleForDocumentMutationSchema,
@ -275,6 +276,32 @@ export const documentRouter = router({
}
}),
setDocumentEmailSettings: authenticatedProcedure
.input(ZSetDocumentEmailSettingsMutationSchema)
.mutation(async ({ input, ctx }) => {
try {
const { documentId, subject, message } = input;
const userId = ctx.user.id;
return await upsertDocumentMeta({
documentId,
userId,
subject,
message,
requestMetadata: extractNextApiRequestMetadata(ctx.req),
});
} catch (err) {
console.error(err);
throw new TRPCError({
code: 'BAD_REQUEST',
message:
'We were unable to update the email settings for this document. Please try again later.',
});
}
}),
setPasswordForDocument: authenticatedProcedure
.input(ZSetPasswordForDocumentMutationSchema)
.mutation(async ({ input, ctx }) => {

View File

@ -139,6 +139,12 @@ export const ZSendDocumentMutationSchema = z.object({
}),
});
export const ZSetDocumentEmailSettingsMutationSchema = z.object({
documentId: z.number(),
subject: z.string().optional(),
message: z.string().optional(),
});
export const ZSetPasswordForDocumentMutationSchema = z.object({
documentId: z.number(),
password: z.string(),

View File

@ -1,13 +1,21 @@
'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form';
import { DO_NOT_INVALIDATE_QUERY_ON_MUTATION } from '@documenso/lib/constants/trpc';
import type { Field, Recipient } from '@documenso/prisma/client';
import { DocumentStatus } from '@documenso/prisma/client';
import type { DocumentWithData } from '@documenso/prisma/types/document-with-data';
import { trpc } from '@documenso/trpc/react';
import { DocumentSendEmailMessageHelper } from '@documenso/ui/components/document/document-send-email-message-helper';
import { useToast } from '@documenso/ui/primitives/use-toast';
import { Button } from '../button';
import { FormErrorMessage } from '../form/form-error-message';
import { Input } from '../input';
import { Label } from '../label';
@ -44,6 +52,7 @@ export const AddSubjectFormPartial = ({
const {
register,
handleSubmit,
setValue,
formState: { errors, isSubmitting },
} = useForm<TAddSubjectFormSchema>({
defaultValues: {
@ -55,6 +64,87 @@ export const AddSubjectFormPartial = ({
resolver: zodResolver(ZAddSubjectFormSchema),
});
const [oldEmailData, setOldEmailData] = useState<{ subject: string; message: string } | null>(
() =>
document.documentMeta
? {
subject: document.documentMeta.subject ?? '',
message: document.documentMeta.message ?? '',
}
: null,
);
const { toast } = useToast();
const router = useRouter();
const utils = trpc.useUtils();
const { mutateAsync: setEmailSettingsForDocument } =
trpc.document.setDocumentEmailSettings.useMutation({
...DO_NOT_INVALIDATE_QUERY_ON_MUTATION,
onSuccess: () => {
const data = utils.document.getDocumentWithDetailsById.getData({
id: document.id,
});
setOldEmailData({
subject: data?.documentMeta?.subject ?? '',
message: data?.documentMeta?.message ?? '',
});
},
});
const handleOnBlur = async (field: 'subject' | 'message', value: string) => {
try {
await setEmailSettingsForDocument({
documentId: document.id,
[field]: value,
});
router.refresh();
toast({
title: 'Email settings updated',
description: `The email settings for the document have been updated.`,
});
} catch (e) {
console.error(e);
toast({
title: 'Error',
description: 'An error occurred while updating the email settings.',
});
}
};
const handleUndoButton = async () => {
try {
if (oldEmailData) {
await setEmailSettingsForDocument({
documentId: document.id,
subject: oldEmailData.subject,
message: oldEmailData.message,
});
setValue('meta.subject', oldEmailData.subject);
setValue('meta.message', oldEmailData.message);
setOldEmailData(null);
router.refresh();
toast({
title: 'Changes reverted',
description: 'The latest change has been reverted to the original value.',
});
}
} catch (e) {
console.error(e);
toast({
title: 'Error',
description: 'An error occurred while undoing the latest change.',
});
}
};
const onFormSubmit = handleSubmit(onSubmit);
const { currentStep, totalSteps, previousStep } = useStep();
@ -64,6 +154,7 @@ export const AddSubjectFormPartial = ({
title={documentFlow.title}
description={documentFlow.description}
/>
<DocumentFlowFormContainerContent>
<div className="flex flex-col">
{isDocumentPdfLoaded &&
@ -81,7 +172,11 @@ export const AddSubjectFormPartial = ({
id="subject"
className="bg-background mt-2"
disabled={isSubmitting}
{...register('meta.subject')}
{...register('meta.subject', {
onBlur: (event) => {
void handleOnBlur('subject', event.target.value);
},
})}
/>
<FormErrorMessage className="mt-2" error={errors.meta?.subject} />
@ -96,7 +191,11 @@ export const AddSubjectFormPartial = ({
id="message"
className="bg-background mt-2 h-32 resize-none"
disabled={isSubmitting}
{...register('meta.message')}
{...register('meta.message', {
onBlur: (event) => {
void handleOnBlur('message', event.target.value);
},
})}
/>
<FormErrorMessage
@ -105,6 +204,11 @@ export const AddSubjectFormPartial = ({
/>
</div>
{/* Hide the button after 5 seconds */}
{oldEmailData && (
<Button onClick={() => void handleUndoButton()}>Undo latest change</Button>
)}
<DocumentSendEmailMessageHelper />
</div>
</div>