import Button from "@/components/Low/Button"; import Checkbox from "@/components/Low/Checkbox"; import {PERMISSIONS} from "@/constants/userPermissions"; import useUsers from "@/hooks/useUsers"; import {Type, User} from "@/interfaces/user"; import {USER_TYPE_LABELS} from "@/resources/user"; import axios from "axios"; import clsx from "clsx"; import {capitalize, uniqBy} from "lodash"; import moment from "moment"; import {useEffect, useState} from "react"; import ReactDatePicker from "react-datepicker"; import {toast} from "react-toastify"; 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 [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); const [type, setType] = useState("student"); const {users} = useUsers(); const {openFilePicker, filesContent} = useFilePicker({ accept: ".xlsx", multiple: false, readAs: "ArrayBuffer", }); useEffect(() => { if (user && (user.type === "corporate" || user.type === "teacher")) { setExpiryDate(user.subscriptionExpirationDate || null); } }, [user]); useEffect(() => { if (!isExpiryDateEnabled) setExpiryDate(null); }, [isExpiryDateEnabled]); useEffect(() => { if (filesContent.length > 0) { const file = filesContent[0]; readXlsxFile(file.content).then((rows) => { const information = uniqBy( rows .map((row) => { const [firstName, lastName, country, passport_id, email, phone] = row as string[]; 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); }); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [filesContent]); const generateCode = (type: Type) => { const uid = new ShortUniqueId(); const codes = infos.map(() => uid.randomUUID(6)); setIsLoading(true); axios .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"}); return; } if (status === 403) { toast.error(data.reason, {toastId: "forbidden"}); } }) .catch(({response: {status, data}}) => { if (status === 403) { toast.error(data.reason, {toastId: "forbidden"}); return; } toast.error(`Something went wrong, please try again later!`, {toastId: "error"}); }) .finally(() => setIsLoading(false)); }; return (
{user && (user.type === "developer" || user.type === "admin") && ( <>
Enabled
{isExpiryDateEnabled && ( moment(date).isAfter(new Date())} dateFormat="dd/MM/yyyy" selected={expiryDate} onChange={(date) => setExpiryDate(date)} /> )} )} {user && ( )}
); }