diff --git a/package.json b/package.json index 44d1d91..9e4523e 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,8 @@ "react-dom": "18.2.0", "react-gtm-module": "^2.0.11", "react-loader-spinner": "^5.3.4", - "swiper": "^8.3.2" + "swiper": "^8.3.2", + "zod": "^3.19.1" }, "devDependencies": { "@types/google-spreadsheet": "^3.3.0", diff --git a/src/pages/api/mail/contact.ts b/src/pages/api/mail/contact.ts index 8f93073..c010ce2 100644 --- a/src/pages/api/mail/contact.ts +++ b/src/pages/api/mail/contact.ts @@ -1,112 +1,108 @@ import type { NextApiRequest, NextApiResponse } from 'next' import { mailingClient } from '@/api/mailingClient' import { appendSpreadsheet } from '@/api/gSheets' - -interface ContactFormNextApiRequest extends NextApiRequest { - body: { - firstName: string - email: string - projectName: string - projectDescription: string - services: string[] - budget: string - deadline: string - discord: string | undefined - telegram: string | undefined - github: string | undefined - projectLink: string | undefined - aditionalInformation: string | undefined - } -} +import { Submit, SubmitSchema } from '@/types/submit' export default async function serverSideCall( - req: ContactFormNextApiRequest, + req: NextApiRequest, res: NextApiResponse ) { if (req.method !== 'POST') { res.status(405) } else { - const { - firstName, - email, - projectName, - projectDescription, - services, - budget, - deadline, - discord, - telegram, - github, - projectLink, - aditionalInformation, - } = req.body - const aditionalInformationHeader = - discord || telegram || github || projectLink || aditionalInformation - ? 'Aditional information' - : '' - const discordHandle = discord ? `Discord handle: ${discord}` : '' - const telegramHandle = telegram ? `Telegram handle: ${telegram}` : '' - const githubHandle = github ? `Github Profile: ${github}` : '' - const projectLinkText = projectLink ? `Project Link: ${projectLink}` : '' - const aditionalInformationText = aditionalInformation - ? `Additional Information given by the client: ${aditionalInformation}` - : '' - const mailData = { - from: process.env.GMAIL_ACCOUNT as string, - to: process.env.EMAIL_RECIPIENT as string, - subject: `Project Request from: ${firstName} | ${projectName}`, - text: `Who requested: - First Name: ${firstName} - E-mail: ${email} - Project Name: ${projectName} - Project Description: ${projectDescription} - Type of services: ${services} - Budget Range: ${budget} - Deadline(yyyy-mm-dd): ${deadline} + const submitData: Submit = req.body + const { success } = SubmitSchema.safeParse(submitData) + if (success) { + const { + firstName, + email, + projectName, + projectDescription, + services, + budget, + deadline, + discord, + telegram, + github, + projectLink, + aditionalInformation, + } = submitData - ${aditionalInformationHeader} - ${discordHandle} - ${telegramHandle} - ${githubHandle} - ${projectLinkText} - ${aditionalInformationText} - `, - } - const date = new Date() - const sheetsData = { - timeStamp: date.toUTCString(), - whoRequested: firstName, - emailContact: email, - projectName: projectName, - projectDescription: projectDescription, - typeOfServices: services.toString(), - budgetRange: budget, - deadline: deadline, - discordHandle: discord ? discord : '', - githubHandle: github ? github : '', - telegramHandle: telegram ? telegram : '', - projectLink: projectLink ? projectLink : '', - aditionalInformationText: aditionalInformation ? aditionalInformation : '' - } - try { - mailingClient.sendMail(mailData, (err) => { - if (err) { - console.log(err) - res.status(500).json({ - success: false, - body: err, - }) - } else { - res.status(200).json({ - success: true, - }) - } - }) - appendSpreadsheet(sheetsData) - } catch (err) { - console.log(err) - res.status(400).json({ + const aditionalInformationHeader = + discord || telegram || github || projectLink || aditionalInformation + ? 'Aditional information' + : '' + const discordHandle = discord ? `Discord handle: ${discord}` : '' + const telegramHandle = telegram ? `Telegram handle: ${telegram}` : '' + const githubHandle = github ? `Github Profile: ${github}` : '' + const projectLinkText = projectLink ? `Project Link: ${projectLink}` : '' + const aditionalInformationText = aditionalInformation + ? `Additional Information given by the client: ${aditionalInformation}` + : '' + const mailData = { + from: process.env.GMAIL_ACCOUNT as string, + to: process.env.EMAIL_RECIPIENT as string, + subject: `Project Request from: ${firstName} | ${projectName}`, + text: `Who requested: + First Name: ${firstName} + E-mail: ${email} + Project Name: ${projectName} + Project Description: ${projectDescription} + Type of services: ${services} + Budget Range: ${budget} + Deadline(yyyy-mm-dd): ${deadline} + + ${aditionalInformationHeader} + ${discordHandle} + ${telegramHandle} + ${githubHandle} + ${projectLinkText} + ${aditionalInformationText} + `, + } + const date = new Date() + const sheetsData = { + timeStamp: date.toUTCString(), + whoRequested: firstName, + emailContact: email, + projectName: projectName, + projectDescription: projectDescription, + typeOfServices: services.toString(), + budgetRange: budget, + deadline: deadline, + discordHandle: discord ? discord : '', + githubHandle: github ? github : '', + telegramHandle: telegram ? telegram : '', + projectLink: projectLink ? projectLink : '', + aditionalInformationText: aditionalInformation + ? aditionalInformation + : '', + } + try { + mailingClient.sendMail(mailData, (err) => { + if (err) { + console.log(err) + res.status(500).json({ + success: false, + body: err, + }) + } else { + res.status(200).json({ + success: true, + }) + } + }) + appendSpreadsheet(sheetsData) + } catch (err) { + console.log(err) + res.status(400).json({ + success: false, + }) + } + } else { + res.status(422).json({ success: false, + message: 'Invalid body format', }) } } diff --git a/src/types/submit.ts b/src/types/submit.ts new file mode 100644 index 0000000..44f4f79 --- /dev/null +++ b/src/types/submit.ts @@ -0,0 +1,21 @@ +import { z } from 'zod' + +const nonEmptyStringContraint = z.string().min(1) +const EmptyStringContraint = z.string() + +export const SubmitSchema = z.object({ + firstName: nonEmptyStringContraint, + email: nonEmptyStringContraint, + projectName: nonEmptyStringContraint, + projectDescription: nonEmptyStringContraint, + services: z.array(nonEmptyStringContraint), + budget: nonEmptyStringContraint, + deadline: nonEmptyStringContraint, + discord: EmptyStringContraint, + telegram: EmptyStringContraint, + github: EmptyStringContraint, + projectLink: EmptyStringContraint, + aditionalInformation: EmptyStringContraint, +}) + +export type Submit = z.infer diff --git a/yarn.lock b/yarn.lock index 1ef5da2..14e1e83 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3246,3 +3246,8 @@ yoga-wasm-web@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/yoga-wasm-web/-/yoga-wasm-web-0.1.2.tgz#05d3fc9cbdfd57ac9682debb5001aca075489a39" integrity sha512-8SkgawHcA0RUbMrnhxbaQkZDBi8rMed8pQHixkFF9w32zGhAwZ9/cOHWlpYfr6RCx42Yp3siV45/jPEkJxsk6w== + +zod@^3.19.1: + version "3.19.1" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.19.1.tgz#112f074a97b50bfc4772d4ad1576814bd8ac4473" + integrity sha512-LYjZsEDhCdYET9ikFu6dVPGp2YH9DegXjdJToSzD9rO6fy4qiRYFoyEYwps88OseJlPyl2NOe2iJuhEhL7IpEA==