Skip to content

Commit

Permalink
Refactor form validation
Browse files Browse the repository at this point in the history
Use answers from request in uniq
  • Loading branch information
HendrikSchmidt committed Sep 27, 2024
1 parent 43749ea commit eb378c2
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 41 deletions.
4 changes: 1 addition & 3 deletions packages/dito/app/routes/uniq.($encrypted).($iv).tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
import { gunzipSync, gzipSync } from "node:zlib";
import { ROUTE_RESULT_PDF } from "resources/staticRoutes";
import { ENCRYPTION_ALGORITHM, ENCRYPTION_KEY } from "utils/constants.server";
import { getAnswersFromCookie } from "utils/cookies.server";
import unleash from "utils/featureFlags.server";

enum QuestionAbbreviations {
Expand Down Expand Up @@ -168,9 +167,8 @@ export async function action({ request }: ActionFunctionArgs) {
"http://",
process.env.NODE_ENV === "production" ? "https://" : "http://",
);
const { answers } = await getAnswersFromCookie(request);
const formData = await request.formData();
const { title, negativeReasoning } = Object.fromEntries(formData);
const { title, negativeReasoning, ...answers } = Object.fromEntries(formData);

const combinedResponse = {
title,
Expand Down
71 changes: 33 additions & 38 deletions packages/dito/app/routes/vorpruefung.ergebnis/ResultForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import RichText from "@digitalcheck/shared/components/RichText";
import Textarea from "@digitalcheck/shared/components/Textarea";
import { useForm } from "@rvf/remix";
import { withZod } from "@rvf/zod";
import React, { useEffect, useState } from "react";
import React, { useState } from "react";
import { preCheck } from "resources/content";
import { PRE_CHECK_PDF, ROUTE_RESULT_PDF } from "resources/staticRoutes";
import { PreCheckAnswers } from "routes/vorpruefung.$questionId/route";
Expand Down Expand Up @@ -42,30 +42,38 @@ export default function ResultForm({
isPositive ? positiveValidation : negativeValidation,
);

const form = useForm({
validator,
validationBehaviorConfig: {
initial: "onChange",
whenTouched: "onChange",
whenSubmitted: "onChange",
},
});
const form = useForm({ validator });

const [downloadDisabled, setDownloadDisabled] = useState(false);
const downloadDocument = async () => {
setDownloadDisabled(true);
const validateFormAndGetData = async () => {
await form.validate();
if (!form.transient.formState.isValid) {
return null;
}
const formData = new FormData();
formData.append("title", form.value("title"));
formData.append("negativeReasoning", form.value("negativeReasoning"));
// we need to use transient.value here because the form state is not yet updated
formData.append("title", form.transient.value("title") as string);
formData.append(
"negativeReasoning",
form.transient.value("negativeReasoning") as string,
);
Object.entries(answers).forEach(([key, value]) => {
formData.append(key, value);
});
return formData;
};

const [downloadDisabled, setDownloadDisabled] = useState(false);
const downloadDocument = async () => {
const formData = await validateFormAndGetData();
if (!formData) {
return;
}

setDownloadDisabled(true);
const response = await fetch(ROUTE_RESULT_PDF.url, {
method: "POST",
body: formData,
});

if (!response.ok) {
alert(`Error processing PDF: ${response.statusText}`);
setDownloadDisabled(false);
Expand All @@ -74,10 +82,9 @@ export default function ResultForm({

const blob = await response.blob();
const downloadUrl = window.URL.createObjectURL(blob);

const a = document.createElement("a");
a.href = downloadUrl;
a.download = PRE_CHECK_PDF;
a.download = PRE_CHECK_PDF; // set filename
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(downloadUrl);
Expand All @@ -86,18 +93,20 @@ export default function ResultForm({
};

const openMailTo = async () => {
const formData = new FormData();
formData.append("title", form.value("title"));
formData.append("negativeReasoning", form.value("negativeReasoning"));
const formData = await validateFormAndGetData();
if (!formData) {
return;
}
const uniqueResponse = await fetch("/uniq", {
method: "POST",
body: formData,
});
const emailTemplate = preCheck.result.form.emailTemplate;
const uniqueUrl = (await uniqueResponse.json()).url;

Check warning on line 105 in packages/dito/app/routes/vorpruefung.ergebnis/ResultForm.tsx

View workflow job for this annotation

GitHub Actions / check-test-build-deploy (dito) / check-and-test-shared / check-and-test

Unsafe assignment of an `any` value

Check warning on line 105 in packages/dito/app/routes/vorpruefung.ergebnis/ResultForm.tsx

View workflow job for this annotation

GitHub Actions / check-test-build-deploy (dito) / check-and-test-shared / check-and-test

Unsafe member access .url on an `any` value

Check warning on line 105 in packages/dito/app/routes/vorpruefung.ergebnis/ResultForm.tsx

View workflow job for this annotation

GitHub Actions / check-test-build-deploy (dito) / check-and-test-shared / check-and-test

Unsafe assignment of an `any` value

Check warning on line 105 in packages/dito/app/routes/vorpruefung.ergebnis/ResultForm.tsx

View workflow job for this annotation

GitHub Actions / check-test-build-deploy (dito) / check-and-test-shared / check-and-test

Unsafe member access .url on an `any` value
const subject = `${preCheck.result.form.emailTemplate.subject}: „${form.value("title")}“`;
const body = `${preCheck.result.form.emailTemplate.bodyBefore}\n\n${uniqueUrl}\n\n${preCheck.result.form.emailTemplate.bodyAfter}`;
const subject = `${emailTemplate.subject}: „${form.value("title")}“`;
const body = `${emailTemplate.bodyBefore}\n\n${uniqueUrl}\n\n${emailTemplate.bodyAfter}`;
const mailToLink = encodeURI(
`mailto:${preCheck.result.form.emailTemplate.to}?subject=${subject}&body=${body}`,
`mailto:${emailTemplate.to}?subject=${subject}&body=${body}`,
);
window.location.href = mailToLink;
};
Expand All @@ -114,15 +123,6 @@ export default function ResultForm({
}
};

const [buttonsDisabled, setButtonsDisabled] = useState(false);
useEffect(() => {
// Workaround to call async validation in useEffect
void (async function () {
const result = await validator.validate(form.value());
setButtonsDisabled(!!result.error);
})();
}, [form, validator]);

return (
<Container
backgroundColor="white"
Expand Down Expand Up @@ -172,9 +172,7 @@ export default function ResultForm({
id: "result-email-button",
text: preCheck.result.form.sendEmailButton.text,
look: "primary",
disabled: buttonsDisabled,
className: "plausible-event-name=Quicksend+Click",
type: "button",
onClick: () => void openMailTo(),
},
{
Expand All @@ -183,8 +181,7 @@ export default function ResultForm({
? preCheck.result.form.downloadStarted
: preCheck.result.form.downloadPdfButton.text,
look: "ghost",
disabled: buttonsDisabled || downloadDisabled,
type: "button",
disabled: downloadDisabled,
onClick: () => void downloadDocument(),
},
]
Expand All @@ -195,8 +192,6 @@ export default function ResultForm({
? preCheck.result.form.downloadStarted
: preCheck.result.form.downloadPdfButton.text,
look: "primary",
disabled: buttonsDisabled || downloadDisabled,
type: "button",
onClick: () => void downloadDocument(),
},
]
Expand Down

0 comments on commit eb378c2

Please sign in to comment.