Started trying out reading Excel files
This commit is contained in:
@@ -19,7 +19,7 @@ interface Props {
|
||||
export default function DemographicInformationInput({user, mutateUser}: Props) {
|
||||
const [country, setCountry] = useState<string>();
|
||||
const [phone, setPhone] = useState<string>();
|
||||
const [passport_id, setPassportID] = useState<string>();
|
||||
const [passport_id, setPassportID] = useState<string | undefined>(user.type === "student" ? user.demographicInformation?.passport_id : undefined);
|
||||
const [gender, setGender] = useState<Gender>();
|
||||
const [employment, setEmployment] = useState<EmploymentStatus>();
|
||||
const [position, setPosition] = useState<string>();
|
||||
@@ -87,6 +87,7 @@ export default function DemographicInformationInput({user, mutateUser}: Props) {
|
||||
name="passport_id"
|
||||
label="Passport/National ID"
|
||||
onChange={(e) => setPassportID(e)}
|
||||
value={passport_id}
|
||||
placeholder="Enter National ID or Passport number"
|
||||
required
|
||||
/>
|
||||
|
||||
@@ -13,6 +13,7 @@ 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";
|
||||
|
||||
export default function BatchCodeGenerator({user}: {user: User}) {
|
||||
const [emails, setEmails] = useState<string[]>([]);
|
||||
@@ -24,8 +25,9 @@ export default function BatchCodeGenerator({user}: {user: User}) {
|
||||
const {users} = useUsers();
|
||||
|
||||
const {openFilePicker, filesContent} = useFilePicker({
|
||||
accept: ".txt",
|
||||
accept: ".xlsx",
|
||||
multiple: false,
|
||||
readAs: "ArrayBuffer",
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -41,18 +43,21 @@ export default function BatchCodeGenerator({user}: {user: User}) {
|
||||
useEffect(() => {
|
||||
if (filesContent.length > 0) {
|
||||
const file = filesContent[0];
|
||||
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));
|
||||
readXlsxFile(file.content).then((rows) => {
|
||||
console.log(rows);
|
||||
});
|
||||
// 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;
|
||||
}
|
||||
// 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)]);
|
||||
// setEmails([...new Set(emails)]);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [filesContent]);
|
||||
@@ -63,7 +68,7 @@ export default function BatchCodeGenerator({user}: {user: User}) {
|
||||
|
||||
setIsLoading(true);
|
||||
axios
|
||||
.post("/api/code", {type, codes, emails, expiryDate})
|
||||
.post("/api/code", {type, codes, infos: emails.map((x) => ({email: x})), expiryDate})
|
||||
.then(({data, status}) => {
|
||||
if (data.ok) {
|
||||
toast.success(`Successfully generated ${capitalize(type)} codes and they have been notified by e-mail!`, {toastId: "success"});
|
||||
|
||||
@@ -10,16 +10,20 @@ import {KeyedMutator} from "swr";
|
||||
|
||||
interface Props {
|
||||
queryCode?: string;
|
||||
defaultEmail?: string;
|
||||
defaultInformation?: {
|
||||
email: string;
|
||||
name: string;
|
||||
passport_id?: string;
|
||||
};
|
||||
isLoading: boolean;
|
||||
setIsLoading: (isLoading: boolean) => void;
|
||||
mutateUser: KeyedMutator<User>;
|
||||
sendEmailVerification: typeof sendEmailVerification;
|
||||
}
|
||||
|
||||
export default function RegisterIndividual({queryCode, defaultEmail, isLoading, setIsLoading, mutateUser, sendEmailVerification}: Props) {
|
||||
const [name, setName] = useState("");
|
||||
const [email, setEmail] = useState(defaultEmail || "");
|
||||
export default function RegisterIndividual({queryCode, defaultInformation, isLoading, setIsLoading, mutateUser, sendEmailVerification}: Props) {
|
||||
const [name, setName] = useState(defaultInformation?.name || "");
|
||||
const [email, setEmail] = useState(defaultInformation?.email || "");
|
||||
const [password, setPassword] = useState("");
|
||||
const [confirmPassword, setConfirmPassword] = useState("");
|
||||
const [code, setCode] = useState(queryCode || "");
|
||||
@@ -48,6 +52,7 @@ export default function RegisterIndividual({queryCode, defaultEmail, isLoading,
|
||||
password,
|
||||
type: "individual",
|
||||
code,
|
||||
passport_id: defaultInformation?.passport_id,
|
||||
profilePicture: "/defaultAvatar.png",
|
||||
})
|
||||
.then((response) => {
|
||||
@@ -73,14 +78,14 @@ export default function RegisterIndividual({queryCode, defaultEmail, isLoading,
|
||||
|
||||
return (
|
||||
<form className="flex flex-col items-center gap-6 w-full" onSubmit={register}>
|
||||
<Input type="text" name="name" onChange={(e) => setName(e)} placeholder="Enter your name" defaultValue={name} required />
|
||||
<Input type="text" name="name" onChange={(e) => setName(e)} placeholder="Enter your name" value={name} required />
|
||||
<Input
|
||||
type="email"
|
||||
name="email"
|
||||
onChange={(e) => setEmail(e)}
|
||||
placeholder="Enter email address"
|
||||
value={email}
|
||||
disabled={!!defaultEmail}
|
||||
disabled={!!defaultInformation?.email}
|
||||
required
|
||||
/>
|
||||
<Input
|
||||
|
||||
@@ -19,7 +19,12 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {type, codes, emails, expiryDate} = req.body as {type: Type; codes: string[]; emails?: string[]; expiryDate: null | Date};
|
||||
const {type, codes, infos, expiryDate} = req.body as {
|
||||
type: Type;
|
||||
codes: string[];
|
||||
infos?: {email: string; name: string; passport_id: string}[];
|
||||
expiryDate: null | Date;
|
||||
};
|
||||
const permission = PERMISSIONS.generateCode[type];
|
||||
|
||||
if (!permission.includes(req.session.user.type)) {
|
||||
@@ -47,8 +52,9 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
const codeRef = doc(db, "codes", code);
|
||||
await setDoc(codeRef, {type, code, creator: req.session.user!.id, expiryDate});
|
||||
|
||||
if (emails && emails.length > index) {
|
||||
await setDoc(codeRef, {email: emails[index]}, {merge: true});
|
||||
if (infos && infos.length > index) {
|
||||
const {email, name, passport_id} = infos[index];
|
||||
await setDoc(codeRef, {email, name, passport_id}, {merge: true});
|
||||
|
||||
const transport = prepareMailer();
|
||||
const mailOptions = prepareMailOptions(
|
||||
@@ -56,7 +62,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
type,
|
||||
code,
|
||||
},
|
||||
[emails[index]],
|
||||
[email],
|
||||
"EnCoach Registration",
|
||||
"main",
|
||||
);
|
||||
|
||||
@@ -37,8 +37,9 @@ async function register(req: NextApiRequest, res: NextApiResponse) {
|
||||
}
|
||||
|
||||
async function registerIndividual(req: NextApiRequest, res: NextApiResponse) {
|
||||
const {email, password, code} = req.body as {
|
||||
const {email, passport_id, password, code} = req.body as {
|
||||
email: string;
|
||||
passport_id?: string;
|
||||
password: string;
|
||||
code?: string;
|
||||
};
|
||||
@@ -67,6 +68,7 @@ async function registerIndividual(req: NextApiRequest, res: NextApiResponse) {
|
||||
focus: "academic",
|
||||
type: email.endsWith("@ecrop.dev") ? "developer" : codeData ? codeData.type : "student",
|
||||
subscriptionExpirationDate: codeData ? codeData.expiryDate : moment().subtract(1, "days").toISOString(),
|
||||
...(passport_id ? {demographicInformation: {passport_id}} : {}),
|
||||
registrationDate: new Date(),
|
||||
status: code ? "active" : "paymentDue",
|
||||
};
|
||||
|
||||
@@ -23,12 +23,18 @@ export const getServerSideProps = (context: any) => {
|
||||
|
||||
export default function Register({code: queryCode}: {code: string}) {
|
||||
const [defaultEmail, setDefaultEmail] = useState<string>();
|
||||
const [defaultName, setDefaultName] = useState<string>();
|
||||
const [passport_id, setPassportID] = useState<string>();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (queryCode) {
|
||||
(async () => {
|
||||
axios.get<{email?: string}>(`/api/code/${queryCode}`).then((result) => setDefaultEmail(result.data.email));
|
||||
axios.get<{email?: string; name?: string; passport_id?: string}>(`/api/code/${queryCode}`).then((result) => {
|
||||
setDefaultEmail(result.data.email);
|
||||
setDefaultName(result.data.name);
|
||||
setPassportID(result.data.passport_id);
|
||||
});
|
||||
})();
|
||||
}
|
||||
}, [queryCode]);
|
||||
@@ -95,7 +101,9 @@ export default function Register({code: queryCode}: {code: string}) {
|
||||
mutateUser={mutateUser}
|
||||
sendEmailVerification={sendEmailVerification}
|
||||
queryCode={queryCode}
|
||||
defaultEmail={defaultEmail}
|
||||
defaultInformation={
|
||||
defaultEmail && defaultName ? {email: defaultEmail, name: defaultName, passport_id} : undefined
|
||||
}
|
||||
/>
|
||||
</Tab.Panel>
|
||||
<Tab.Panel>
|
||||
|
||||
Reference in New Issue
Block a user