From 84c42ccf3e3a92b169cbc1ddcf8315b275cf325c Mon Sep 17 00:00:00 2001 From: Tiago Ribeiro Date: Thu, 11 Jan 2024 21:35:26 +0000 Subject: [PATCH] Adapted the BatchCodeGenerator to use an Excel file --- src/pages/(admin)/BatchCodeGenerator.tsx | 47 +++++++++++++++--------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/src/pages/(admin)/BatchCodeGenerator.tsx b/src/pages/(admin)/BatchCodeGenerator.tsx index fb3f2743..211fdc4f 100644 --- a/src/pages/(admin)/BatchCodeGenerator.tsx +++ b/src/pages/(admin)/BatchCodeGenerator.tsx @@ -6,7 +6,7 @@ import {Type, User} from "@/interfaces/user"; import {USER_TYPE_LABELS} from "@/resources/user"; import axios from "axios"; import clsx from "clsx"; -import {capitalize} from "lodash"; +import {capitalize, uniqBy} from "lodash"; import moment from "moment"; import {useEffect, useState} from "react"; import ReactDatePicker from "react-datepicker"; @@ -15,8 +15,10 @@ import ShortUniqueId from "short-unique-id"; import {useFilePicker} from "use-file-picker"; import readXlsxFile from "read-excel-file"; +const EMAIL_REGEX = new RegExp(/^[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*@[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*$/); + export default function BatchCodeGenerator({user}: {user: User}) { - const [emails, setEmails] = useState([]); + const [infos, setInfos] = useState<{email: string; name: string; passport_id: string}[]>([]); const [isLoading, setIsLoading] = useState(false); const [expiryDate, setExpiryDate] = useState(null); const [isExpiryDateEnabled, setIsExpiryDateEnabled] = useState(true); @@ -44,31 +46,40 @@ export default function BatchCodeGenerator({user}: {user: User}) { if (filesContent.length > 0) { const file = filesContent[0]; readXlsxFile(file.content).then((rows) => { - console.log(rows); + const information = uniqBy( + rows + .map((row) => { + const [firstName, lastName, country, passport_id, email, phone] = row.map((x) => (x as string).trim()); + return EMAIL_REGEX.test(email) && !users.map((u) => u.email).includes(email) + ? { + email, + name: `${firstName} ${lastName}`, + passport_id, + } + : undefined; + }) + .filter((x) => !!x) as typeof infos, + (x) => x.email, + ); + + if (information.length === 0) + return toast.error( + "Please upload an Excel file containing user information, one per line! All already registered e-mails have also been ignored!", + ); + + setInfos(information); }); - // const emails = file.content - // .split("\n") - // .map((x) => x.trim()) - // .filter((x) => new RegExp(/^[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*@[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*$/).test(x)) - // .filter((x) => !users.map((u) => u.email).includes(x)); - - // if (emails.length === 0) { - // toast.error("Please upload a .txt file containing e-mails, one per line! All already registered e-mails have also been ignored!"); - // return; - // } - - // setEmails([...new Set(emails)]); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [filesContent]); const generateCode = (type: Type) => { const uid = new ShortUniqueId(); - const codes = emails.map(() => uid.randomUUID(6)); + const codes = infos.map(() => uid.randomUUID(6)); setIsLoading(true); axios - .post("/api/code", {type, codes, infos: emails.map((x) => ({email: x})), expiryDate}) + .post("/api/code", {type, codes, infos: infos, expiryDate}) .then(({data, status}) => { if (data.ok) { toast.success(`Successfully generated ${capitalize(type)} codes and they have been notified by e-mail!`, {toastId: "success"}); @@ -132,7 +143,7 @@ export default function BatchCodeGenerator({user}: {user: User}) { ))} )} -