From 844e3cb8756495bd6987994cf18a63eeefc005c7 Mon Sep 17 00:00:00 2001 From: DrMint Date: Wed, 23 Mar 2022 16:19:23 +0100 Subject: [PATCH] Added contact system --- README.md | 3 + package-lock.json | 45 +++++- package.json | 2 + src/graphql/operation.graphql | 7 + src/graphql/operations-types.ts | 7 + src/pages/about-us/contact.tsx | 225 ++++++++++++++++++++++++++ src/pages/about-us/sharing-policy.tsx | 2 +- src/pages/api/mail.ts | 51 ++++++ src/pages/editor.tsx | 2 +- src/queries/helpers.ts | 4 + src/tailwind.css | 18 ++- 11 files changed, 354 insertions(+), 12 deletions(-) create mode 100644 src/pages/about-us/contact.tsx create mode 100644 src/pages/api/mail.ts diff --git a/README.md b/README.md index 7912e64..a37b4b6 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,9 @@ Enter the followind information: ```txt URL_GRAPHQL=https://url-to.strapi-accords-library.com/graphql ACCESS_TOKEN=genatedcode-by-strapi-api +SMTP_HOST=email.provider.com +SMTP_USER=email@example.com +SMTP_PASSWORD=mypassword123 NEXT_PUBLIC_URL_CMS=https://url-to.strapi-accords-library.com/ NEXT_PUBLIC_URL_IMG=https://url-to.img-accords-library.com/ NEXT_PUBLIC_URL_SELF=https://url-to-front-accords-library.com diff --git a/package-lock.json b/package-lock.json index a6f4ebf..d38fcc9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@tippyjs/react": "^4.2.6", "markdown-to-jsx": "^7.1.7", "next": "^12.1.0", + "nodemailer": "^6.7.3", "react": "17.0.2", "react-dom": "17.0.2", "react-image-lightbox": "^5.1.4", @@ -22,6 +23,7 @@ }, "devDependencies": { "@types/node": "17.0.21", + "@types/nodemailer": "^6.4.4", "@types/react": "17.0.40", "@types/react-dom": "^17.0.13", "eslint": "8.10.0", @@ -489,6 +491,15 @@ "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==", "dev": true }, + "node_modules/@types/nodemailer": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.4.tgz", + "integrity": "sha512-Ksw4t7iliXeYGvIQcSIgWQ5BLuC/mljIEbjf615svhZL10PE9t+ei8O9gDaD3FPCasUJn9KTLwz2JFJyiiyuqw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -2493,9 +2504,9 @@ } }, "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, "node_modules/ms": { @@ -2594,6 +2605,14 @@ "dev": true, "peer": true }, + "node_modules/nodemailer": { + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.7.3.tgz", + "integrity": "sha512-KUdDsspqx89sD4UUyUKzdlUOper3hRkDVkrKh/89G+d9WKsU5ox51NWS4tB1XR5dPUdR4SP0E3molyEfOvSa3g==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -4004,6 +4023,15 @@ "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==", "dev": true }, + "@types/nodemailer": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.4.tgz", + "integrity": "sha512-Ksw4t7iliXeYGvIQcSIgWQ5BLuC/mljIEbjf615svhZL10PE9t+ei8O9gDaD3FPCasUJn9KTLwz2JFJyiiyuqw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -5485,9 +5513,9 @@ } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, "ms": { @@ -5549,6 +5577,11 @@ "dev": true, "peer": true }, + "nodemailer": { + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.7.3.tgz", + "integrity": "sha512-KUdDsspqx89sD4UUyUKzdlUOper3hRkDVkrKh/89G+d9WKsU5ox51NWS4tB1XR5dPUdR4SP0E3molyEfOvSa3g==" + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", diff --git a/package.json b/package.json index 69a7da8..9b9738f 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@tippyjs/react": "^4.2.6", "markdown-to-jsx": "^7.1.7", "next": "^12.1.0", + "nodemailer": "^6.7.3", "react": "17.0.2", "react-dom": "17.0.2", "react-image-lightbox": "^5.1.4", @@ -24,6 +25,7 @@ }, "devDependencies": { "@types/node": "17.0.21", + "@types/nodemailer": "^6.4.4", "@types/react": "17.0.40", "@types/react-dom": "^17.0.13", "eslint": "8.10.0", diff --git a/src/graphql/operation.graphql b/src/graphql/operation.graphql index e4fa3f8..f4353e7 100644 --- a/src/graphql/operation.graphql +++ b/src/graphql/operation.graphql @@ -125,6 +125,13 @@ query getWebsiteInterface($language_code: String) { members sharing_policy contact_us + email + email_gdpr_notice + message + send + response_invalid_code + response_invalid_email + response_email_success } } } diff --git a/src/graphql/operations-types.ts b/src/graphql/operations-types.ts index 13ff3ef..9a5259a 100644 --- a/src/graphql/operations-types.ts +++ b/src/graphql/operations-types.ts @@ -214,6 +214,13 @@ export type GetWebsiteInterfaceQuery = { members: string; sharing_policy: string; contact_us: string; + email: string; + email_gdpr_notice: string; + message: string; + send: string; + response_invalid_code: string; + response_invalid_email: string; + response_email_success: string; }; }>; }; diff --git a/src/pages/about-us/contact.tsx b/src/pages/about-us/contact.tsx new file mode 100644 index 0000000..1121dba --- /dev/null +++ b/src/pages/about-us/contact.tsx @@ -0,0 +1,225 @@ +import SubPanel from "components/Panels/SubPanel"; +import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; +import ReturnButton, { + ReturnButtonType, +} from "components/PanelComponents/ReturnButton"; +import AppLayout from "components/AppLayout"; +import ContentPanel from "components/Panels/ContentPanel"; +import { GetStaticProps } from "next"; +import { getPost, getPostLanguages } from "graphql/operations"; +import { GetPostQuery } from "graphql/operations-types"; +import { useRouter } from "next/router"; +import LanguageSwitcher from "components/LanguageSwitcher"; +import Markdawn from "components/Markdown/Markdawn"; +import { RequestMailProps, ResponseMailProps } from "pages/api/mail"; +import { useState } from "react"; +import InsetBox from "components/InsetBox"; +import { randomInt } from "queries/helpers"; +import TOC from "components/Markdown/TOC"; + +interface ContactProps extends AppStaticProps { + post: GetPostQuery["posts"]["data"][number]["attributes"]; + locales: string[]; +} + +export default function AboutUs(props: ContactProps): JSX.Element { + const { langui, post, locales } = props; + const router = useRouter(); + const [formResponse, setFormResponse] = useState(""); + const [formCompleted, setFormCompleted] = useState(false); + + const random1 = randomInt(0, 10); + const random2 = randomInt(0, 10); + + const subPanel = ( + + + {post.translations.length > 0 && post.translations[0].body && ( + + )} + + ); + + const contentPanel = ( + + + {locales.includes(router.locale || "en") ? ( + + ) : ( + + )} + +
+
{ + e.preventDefault(); + + if (e.target.verif.value == random1 + random2 && !formCompleted) { + const content: RequestMailProps = { + name: e.target.name.value, + email: e.target.email.value, + message: e.target.message.value, + formName: "Contact Form", + }; + fetch("/api/mail", { + method: "POST", + body: JSON.stringify(content), + headers: { + "Content-type": "application/json; charset=UTF-8", + }, + }) + .then((response) => response.json()) + .then((data: ResponseMailProps) => { + switch (data.code) { + case "OKAY": + setFormResponse(langui.response_email_success); + setFormCompleted(true); + break; + + case "EENVELOPE": + langui.response_invalid_email; + break; + + default: + setFormResponse(data.message || ""); + break; + } + }); + } else { + setFormResponse(langui.response_invalid_code); + } + + router.replace("#send-response"); + e.target.verif.value = ""; + }} + > +
+ + +
+ +
+ + +

+ {langui.email_gdpr_notice} +

+
+ +
+ +