From 6392fac6ea63d65815cd01d7dde2faa838e89040 Mon Sep 17 00:00:00 2001 From: JohannaPeanut <76495099+JohannaPeanut@users.noreply.github.com> Date: Mon, 17 Jun 2024 15:19:50 +0200 Subject: [PATCH] Survey: sent survey response via email when survey feedback is submitted --- mailers/surveyFeedbackMailer.ts | 154 ++++++++++++++++++ .../components/SurveyMainPage.tsx | 14 +- .../mutations/surveyFeedbackEmail.ts | 50 ++++++ 3 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 mailers/surveyFeedbackMailer.ts create mode 100644 src/survey-responses/mutations/surveyFeedbackEmail.ts diff --git a/mailers/surveyFeedbackMailer.ts b/mailers/surveyFeedbackMailer.ts new file mode 100644 index 000000000..a38bd9bff --- /dev/null +++ b/mailers/surveyFeedbackMailer.ts @@ -0,0 +1,154 @@ +import Mailjet from "node-mailjet" +import previewEmail from "preview-email" +import { getPrdOrStgDomain } from "src/core/components/links/getDomain" + +type SurveyFeedbackMailer = { + userMail: string + userFirstname: string + userLastname: string + feedbackLocation: { lng: number; lat: number } + feedbackCategory: string + feedbackText: string + lineID: string +} + +export function surveyFeedbackMailer({ + userMail, + userFirstname, + userLastname, + feedbackLocation, + feedbackCategory, + feedbackText, + lineID, +}: SurveyFeedbackMailer) { + const origin = getPrdOrStgDomain() + // mailjet format + const msg = { + From: { Email: "", Name: "Trassenscout" }, + To: [{ Email: userMail }], + Subject: "Beteiligung zum Radnetz Brandenburg: Ihr eingereichter Hinweis", + TextPart: ` + Guten Tag, ${userFirstname} ${userLastname}, + + vielen Dank für Ihre Teilnahme! Hiermit bestätigen wir Ihnen den Eingang Ihres Beitrags mit folgenden Angaben: + + Eingangsdatum: ${new Date().toLocaleDateString("de-DE")} + Kategorie: ${feedbackCategory} + ID der gewählten Verbindung im Netzentwurf: ${lineID} + Ihr Hinweis: + ${feedbackText} + Ortsbezug des Beitrags (in OpenStreetMap): https://www.openstreetmap.org/?mlat=${ + feedbackLocation.lat + }&mlon=${feedbackLocation.lng}=16 + + Hinweis: Beachten Sie, dass Sie für jeden eingereichten Hinweis eine separate E-Mail erhalten. Dies ist eine automatisiert versandte E-Mail, auf die Sie nicht antworten können. + + Nach Abschluss der Beteiligung werden Ihre Hinweise fachlich geprüft und in die Abwägung zur Überarbeitung des Zielnetzentwurfs mit einbezogen. + + Mit freundlichen Grüßen + i.A. das Team von FixMyCity + + FixMyCity GmbH + Oberlandstraße 26-35 + 12099 Berlin + + mail: info@fixmycity.de + www.fixmycity.de + `, + HTMLPart: ` +

+ Guten Tag, ${userFirstname} ${userLastname}, +

+

+ vielen Dank für Ihre Teilnahme! Hiermit bestätigen wir Ihnen den Eingang Ihres Beitrags mit + folgenden Angaben: +

+

+ Eingangsdatum: ${new Date().toLocaleDateString("de-DE")}
+ Kategorie: ${feedbackCategory}
+ ID der gewählten Verbindung im Netzentwurf: ${lineID} +
+ Ihr Hinweis:
+ ${feedbackText} +
+ + Ortsbezug des Beitrags (in OpenStreetMap) + +

+

+ Hinweis: + Beachten Sie, dass Sie für jeden eingereichten Hinweis eine separate E-Mail erhalten. Dies + ist eine automatisiert versandte E-Mail, auf die Sie nicht antworten können. +

+

+ Nach Abschluss der Beteiligung werden Ihre Hinweise fachlich geprüft und in die Abwägung zur + Überarbeitung des Zielnetzentwurfs mit einbezogen. +

+

+ Mit freundlichen Grüßen
+ i.A. das Team von FixMyCity +

+

+ FixMyCity GmbH +
+ Oberlandstraße 26-35 +
+ 12099 Berlin +
+ + mail: info@fixmycity.de + +
+ + www.fixmycity.de + +
+ + + LinkedIn + + +

+ FixMyCity Logo + `, + } + + return { + async send() { + if (process.env.NODE_ENV !== "development") { + const mailjet = Mailjet.apiConnect( + // @ts-ignore + process.env.MAILJET_APIKEY_PUBLIC, + process.env.MAILJET_APIKEY_PRIVATE, + ) + const request = mailjet.post("send", { version: "v3.1" }).request({ Messages: [msg] }) + request + .then((result) => { + console.log(result.body) + }) + .catch((err) => { + console.error(err.statusCode) + }) + } else { + // Preview email in the browser + var { From, To, Subject, TextPart, HTMLPart } = msg + await previewEmail({ + from: `${From.Name} <${From.Email}>`, + // @ts-ignore + to: `${To[0]?.Name || ""} <${To[0].Email}>`, + subject: Subject, + text: TextPart, + html: HTMLPart, + }) + } + }, + } +} diff --git a/src/survey-public/components/SurveyMainPage.tsx b/src/survey-public/components/SurveyMainPage.tsx index 86b19057d..557e1de6a 100644 --- a/src/survey-public/components/SurveyMainPage.tsx +++ b/src/survey-public/components/SurveyMainPage.tsx @@ -11,7 +11,9 @@ import { SurveySpinnerLayover } from "src/survey-public/components/core/layout/S import { Feedback } from "src/survey-public/components/feedback/Feedback" import { ProgressContext } from "src/survey-public/context/contexts" import { scrollToTopWithDelay } from "src/survey-public/utils/scrollToTopWithDelay" +import surveyFeedbackEmail from "src/survey-responses/mutations/surveyFeedbackEmail" +import { useParams } from "next/navigation" import createSurveyResponse from "src/survey-responses/mutations/createSurveyResponse" import createSurveySession from "src/survey-sessions/mutations/createSurveySession" import { @@ -23,6 +25,7 @@ import { TResponseConfig, TSurvey, } from "./types" +import { useParam } from "@blitzjs/next" type Props = { startContent: React.ReactNode @@ -33,7 +36,7 @@ type Props = { surveyDefinition: TSurvey responseConfig: TResponseConfig surveyId: number - // clean up after BB ? - initial view state of surveymapline depending on institution + // todo survey clean up or refactor after survey BB ? - initial view state of surveymapline depending on institution // prop institutionsBboxes might be cleaned up after BB in this and the other components it is passed through institutionsBboxes?: TInstitutionsBboxes } @@ -57,6 +60,9 @@ export const SurveyMainPage: React.FC = ({ const [feedbackKey, setFeedbackKey] = useState(1) const [createSurveySessionMutation] = useMutation(createSurveySession) const [createSurveyResponseMutation] = useMutation(createSurveyResponse) + const [surveyFeedbackEmailMutation] = useMutation(surveyFeedbackEmail) + const surveySlug = useParam("surveySlug", "string") + useEffect(() => { const root = document.documentElement root.style.setProperty("--survey-primary-color", surveyDefinition.primaryColor) @@ -117,6 +123,12 @@ export const SurveyMainPage: React.FC = ({ data: JSON.stringify(feedbackResponses), source: "FORM", }) + // todo survey clean up or refactor after survey BB + if (surveySlug === "radnetz-brandenburg") + await surveyFeedbackEmailMutation({ + surveySessionId: surveySessionId_, + data: feedbackResponses, + }) })() setTimeout(() => { diff --git a/src/survey-responses/mutations/surveyFeedbackEmail.ts b/src/survey-responses/mutations/surveyFeedbackEmail.ts new file mode 100644 index 000000000..cc26b358b --- /dev/null +++ b/src/survey-responses/mutations/surveyFeedbackEmail.ts @@ -0,0 +1,50 @@ +import { resolver } from "@blitzjs/rpc" +import db from "db" +import { surveyFeedbackMailer } from "mailers/surveyFeedbackMailer" +import { z } from "zod" +import { feedbackDefinition } from "src/survey-public/radnetz-brandenburg/data/feedback" + +export const SurveyFeedbackMail = z.object({ + surveySessionId: z.number(), + data: z.record(z.any()), +}) + +export default resolver.pipe( + resolver.zod(SurveyFeedbackMail), + async ({ surveySessionId, data }) => { + // Get first survey part for personal data and email adress + const surveyPart1 = await db.surveyResponse.findFirst({ + where: { surveySessionId: surveySessionId, surveyPart: 1 }, + }) + + const categories = Object.fromEntries( + // @ts-expect-error + feedbackDefinition.pages[0]?.questions + // todo survey clean up or refactor after survey BB + // the category ref is hard coded + .find((q) => q.id == 22) + // @ts-expect-error + .props.responses.map((response) => [response.id, response.text.de]), + ) + + if (surveyPart1) { + const parsedSurveyPart1 = JSON.parse(surveyPart1?.data) + // Send the email + // todo survey clean up or refactor after survey BB + // the refs are hard coded to reduce the complexity of the code as we do not know if we keep this feature + await surveyFeedbackMailer({ + // @ts-expect-error + userMail: parsedSurveyPart1["3"], + // @ts-expect-error + userFirstname: parsedSurveyPart1["1"], + // @ts-expect-error + userLastname: parsedSurveyPart1["2"], + feedbackLocation: data["24"], + feedbackCategory: categories[data["22"]], + feedbackText: data["25"], + lineID: data["20"], + }).send() + } + return + }, +)