Source: pages/signup.js

import React from "react";
import Link from "next/link";

// @material-ui/core components
import { makeStyles } from "@material-ui/core/styles";
import InputAdornment from "@material-ui/core/InputAdornment";
import Icon from "@material-ui/core/Icon";
// @material-ui/icons
import Email from "@material-ui/icons/Email";
import People from "@material-ui/icons/People";
// core components
import Header from "/components/Header/Header.js";
import HeaderLinks from "/components/Header/HeaderLinks.js";
import Footer from "/components/Footer/Footer.js";
import GridContainer from "/components/Grid/GridContainer.js";
import GridItem from "/components/Grid/GridItem.js";
import Button from "/components/CustomButtons/Button.js";
import Card from "/components/Card/Card.js";
import CardBody from "/components/Card/CardBody.js";
import CardHeader from "/components/Card/CardHeader.js";
import CardFooter from "/components/Card/CardFooter.js";
import CustomInput from "/components/CustomInput/CustomInput.js";
import { useState } from "react";
import { useRouter } from "next/dist/client/router";
import { useAuth } from "../context/AuthContext";

import styles from "/styles/jss/nextjs-material-kit/pages/loginPage.js";

import generateCode from "/pages-sections/SignUp-Sections/generateCode.js";
import validateCredentials from "/pages-sections/SignUp-Sections/validateCredentials.js";
import emailjs from "emailjs-com";
import {
  REACT_APP_EMAILJS_SERVICE_ID,
  REACT_APP_EMAILJS_TEMPLATE_ID,
  REACT_APP_EMAILJS_USER_ID,
} from "../env";

const useStyles = makeStyles(styles);

/**
 * The function `handleUsernameChange` updates the username based on the value entered in an input
 * field.
 * @param event - The `event` parameter in the `handleUsernameChange` function is an object that
 * contains information about the event of changing the username input field.
 */
export const handleUsernameChange = (event) => {
  const enteredUsername = event.target.value;
  setUsername(enteredUsername);
};

/**
 * The function `handlePasswordChange` updates the password state with the value entered in an input
 * field.
 * @param event - The `event` parameter in the `handlePasswordChange` function is an object that
 * represents the event of changing the password input field.
 */
export const handlePasswordChange = (event) => {
  const enteredPassword = event.target.value;
  setPassword(enteredPassword);
};

/**
 * The function `handleReconfirmPasswordChange` updates the reconfirm password state based on user
 * input.
 * @param event - The `event` parameter in the `handleReconfirmPasswordChange` function is an object
 * that represents the event of changing the reconfirm password input field.
 */
export const handleReconfirmPasswordChange = (event) => {
  const enteredReconfirmPassword = event.target.value;
  setReconfirmPassword(enteredReconfirmPassword);
};

/**
 * The function `handleEmailChange` updates the email state with the value entered in an input field.
 * @param event - The `event` parameter in the `handleEmailChange` function is an object that
 * represents the event of changing the email input field.
 */
export const handleEmailChange = (event) => {
  const enteredEmail = event.target.value;
  setEmail(enteredEmail);
};

/**
 * The handleSubmit function handles form submission, validates user input, generates a code, sends
 * an email using EmailJS, and redirects the user to a verification page.
 * @param event - The `event` parameter in the `handleSubmit` function is an event object that
 * represents the event of clicking the submit button.
 * @returns The `handleSubmit` function is returning either an alert message for validation errors or
 * it is sending an email using EmailJS with the provided template parameters. After that, it is
 * redirecting the user to the "/createaccver" page with the username, password, email, and generated
 * code as query parameters.
 */
export const handleSubmit = async (event) => {
  event.preventDefault();

  const validationError = validateCredentials(
    username,
    password,
    reconfirmPassword,
    email
  );

  if (validationError) {
    alert(validationError);
    setReconfirmPassword("");
    setPassword("");
    setUsername("");
    setEmail("");
    return;
  }

  let genCode = generateCode(15);

  const templateParams = {
    to_username: username,
    to_code: genCode,
    to_email: email,
  };

  emailjs
    .send(
      // process.env.REACT_APP_EMAILJS_SERVICE_ID, // Replace with your EmailJS template ID
      // process.env.REACT_APP_EMAILJS_TEMPLATE_ID, // Replace with your EmailJS user ID
      // templateParams,
      // process.env.REACT_APP_EMAILJS_USER_ID, // Replace with your EmailJS service ID
      REACT_APP_EMAILJS_SERVICE_ID,
      REACT_APP_EMAILJS_TEMPLATE_ID,
      templateParams,
      REACT_APP_EMAILJS_USER_ID
    )
    .then(
      (response) => {
        console.log("Email sent successfully:", response);
      },
      (error) => {
        console.error("Email failed to send:", error);
      }
    );

  router.push({
    pathname: "/createaccver",
    query: {
      username,
      password,
      email,
      code: genCode,
    },
  });
};

/**
 * The `CreateAccountPage` function in JavaScript handles form submission, validates user input, sends
 * an email using EmailJS, and redirects the user to a verification page with query parameters.
 * @param props - The `CreateAccountPage` function takes in `props` as a parameter. Within the component,
 * it uses these props to render different elements on the page.
 * @returns The `CreateAccountPage` component is being returned. It consists of a form for creating a
 * new account with fields for username, password, reconfirm password, and email. The form includes
 * event handlers for input changes and form submission. Upon submission, the form data is validated, a
 * code is generated, an email is sent using EmailJS, and the user is redirected to a verification page
 * with the
 */
export function CreateAccountPage(props) {
  // Form data confirmation
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [reconfirmPassword, setReconfirmPassword] = useState("");
  const [email, setEmail] = useState("");
  const { isEmailUsed } = useAuth();

  // Event handler for username input change

  // const handleFormSubmit = (event) => {
  //   if (event.key === "Enter") {
  //     event.preventDefault();
  //     handleSubmit(event);
  //   }
  // };

  let router = useRouter();

  const [cardAnimaton, setCardAnimation] = React.useState("cardHidden");
  setTimeout(function () {
    setCardAnimation("");
  }, 700);
  const classes = useStyles();
  const { ...rest } = props;
  return (
    <div>
      <Header
        absolute
        color="transparent"
        brand="ThisIsNotFair"
        rightLinks={
          <HeaderLinks enableapps={false} login={false} loginButton={false} />
        }
        {...rest}
      />
      <div
        className={classes.pageHeader}
        style={{
          backgroundImage: "url('/img/bg7.jpg')",
          backgroundSize: "cover",
          backgroundPosition: "top center",
        }}
      >
        <div className={classes.container}>
          <GridContainer justify="center">
            <GridItem xs={12} sm={6} md={4}>
              <Card className={classes[cardAnimaton]}>
                <form className={classes.form}>
                  <CardHeader color="primary" className={classes.cardHeader}>
                    <h3>Join The Family</h3>
                  </CardHeader>
                  <CardBody>
                    <CustomInput
                      labelText="Username"
                      id="username"
                      name="username"
                      formControlProps={{
                        fullWidth: true,
                      }}
                      inputProps={{
                        type: "text",
                        onChange: handleUsernameChange,
                        value: username,
                        endAdornment: (
                          <InputAdornment position="end">
                            <People className={classes.inputIconsColor} />
                          </InputAdornment>
                        ),
                      }}
                    />
                    <CustomInput
                      labelText="Password"
                      id="password"
                      formControlProps={{
                        fullWidth: true,
                      }}
                      inputProps={{
                        type: "password",
                        value: password,
                        onChange: handlePasswordChange,
                        endAdornment: (
                          <InputAdornment position="end">
                            <Icon className={classes.inputIconsColor}>
                              lock_outline
                            </Icon>
                          </InputAdornment>
                        ),
                        autoComplete: "off",
                      }}
                    />
                    <CustomInput
                      labelText="Reconfirm Password"
                      id="reconfirmPassword"
                      formControlProps={{
                        fullWidth: true,
                      }}
                      inputProps={{
                        type: "password",
                        value: reconfirmPassword,
                        onChange: handleReconfirmPasswordChange,
                        endAdornment: (
                          <InputAdornment position="end">
                            <Icon className={classes.inputIconsColor}>
                              lock_outline
                            </Icon>
                          </InputAdornment>
                        ),
                        autoComplete: "off",
                      }}
                    />
                    <CustomInput
                      labelText="Email"
                      id="email"
                      formControlProps={{
                        fullWidth: true,
                      }}
                      inputProps={{
                        type: "email",
                        value: email,
                        onChange: handleEmailChange,
                        endAdornment: (
                          <InputAdornment position="end">
                            <Email className={classes.inputIconsColor} />
                          </InputAdornment>
                        ),
                      }}
                    />
                  </CardBody>
                  <CardFooter className={classes.cardFooter}>
                    {/* Remove the href next time */}
                    <Button
                      simple
                      color="primary"
                      size="lg"
                      onClick={handleSubmit}
                      onKeyDown={(e) => e.key === "Enter" && handleSubmit(e)}
                    >
                      Sign Up
                    </Button>
                  </CardFooter>
                </form>
              </Card>
            </GridItem>
          </GridContainer>
        </div>
        <Footer whiteFont />
      </div>
    </div>
  );
}