Source: routes/Profile.js

  1. import React from "react";
  2. import { Button, Form, FormGroup, Label, Input } from 'reactstrap';
  3. import {firebase} from '../firebase'
  4. import { getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword } from "firebase/auth";
  5. import ModalPopup from "../components/ModalPopup";
  6. import '../styles/Profile.css'
  7. /**
  8. * Renders the user signup/login page if they are not authenticated, otherwise renders the user's profile
  9. * @module Profile
  10. */
  11. export default function Profile(){
  12. const [email, setEmail] = React.useState("")
  13. const [password, setPassword] = React.useState("")
  14. const [loginState, toggleLoginState] = React.useState(true)
  15. const [confirmPassword, setConfirmedPassword] = React.useState("")
  16. const [showForgotPasswordModal, toggleModal] = React.useState(false);
  17. const [showGeneralModal, toggleGeneralModal] = React.useState(false);
  18. const [generalModalText, setModalText] = React.useState("")
  19. const [generalModalHeader, setModalHeader] = React.useState("")
  20. const [auth] = React.useState(getAuth(firebase));
  21. /**
  22. * Checks whether a password is secure: in this case, whether it is at least 8 characters long and contains at least one uppercase letter, lowercase letter and number
  23. * @function checkForStrongPassword
  24. * @param {string} password Password to check
  25. * @returns boolean value of whether or not password is secure
  26. */
  27. function checkForStrongPassword(password){
  28. return password.length >= 8 && /[A-Z]/.test(password) && /[a-z]/.test(password) && /[0-9]/.test(password)
  29. }
  30. /**
  31. * Checks whether a string is in a valid email format: s1@s2.s3, where s1, s2 and s3 are strings.
  32. * @function checkForValidEmail
  33. * @param {string} email Email string to check
  34. * @returns boolean value of whether string is a valid email address
  35. */
  36. function checkForValidEmail(email){
  37. return email.split("@").length==2 && email.split("a")[1].split(".").length==2
  38. }
  39. /**
  40. * Handles user authentication: attempts to login with Firebase if client is in login state, otherwise tries to sign them up if password is secure.
  41. * @function handleAuthentication
  42. */
  43. function handleAuthentication(){
  44. if(loginState) {
  45. signInWithEmailAndPassword(auth, email, password)
  46. .then((userCredential) => {
  47. // Signed in
  48. const user = userCredential.user;
  49. // ...
  50. })
  51. .catch((error) => {
  52. const errorCode = error.code;
  53. const errorMessage = error.message;
  54. generateModal("Sign In Failed", errorMessage+"\n Error Code: "+errorCode)
  55. })
  56. }
  57. else {
  58. if(password !== confirmPassword)
  59. generateModal("Passwords Don't Match!", "Please ensure \"Password\" and \"Confirm password\" fields are the same.")
  60. else {
  61. if(checkForStrongPassword(password)) {
  62. createUserWithEmailAndPassword(auth, email, password)
  63. .then((userCredential) => {
  64. // Signed in
  65. const user = userCredential.user;
  66. // ...
  67. })
  68. .catch((error) => {
  69. const errorCode = error.code;
  70. const errorMessage = error.message;
  71. // ..
  72. generateModal("Sign In Failed", errorMessage+"\n Error Code: "+errorCode)
  73. })
  74. }
  75. else
  76. generateModal("Password Not Secure!", "Please ensure your password is at least eight characters long and contains at least one uppercase letter, one lowercase letter, and one number.")
  77. }
  78. }
  79. }
  80. /**
  81. * Shows a pop up modal with a given header and body text
  82. * @function generateModal
  83. * @param {string} header Header text
  84. * @param {string} body Body text
  85. */
  86. function generateModal(header, body){
  87. toggleGeneralModal(true)
  88. setModalHeader(header)
  89. setModalText(body)
  90. }
  91. return (
  92. <div className="Profile-header">
  93. <div className='Login-box'>
  94. <ModalPopup showModal={showForgotPasswordModal} toggleModal={()=>{toggleModal(!showForgotPasswordModal)}}
  95. header={"Forgot Password?"}
  96. body={<div>
  97. <p>Enter the email address you made your account with and press submit to receive a password reset email.</p>
  98. <Form>
  99. <FormGroup>
  100. <Input type="email" placeholder="example@email.com" value={email} onChange={(e) => {
  101. setEmail(e.target.value)
  102. }}/>
  103. </FormGroup>
  104. </Form>
  105. </div>
  106. }
  107. footer={<div>
  108. <Button color="primary" onClick={()=>{
  109. if(checkForValidEmail(email)){
  110. generateModal("Check Your Inbox", "If we have your email on file, we'll send a password reset email shortly.")
  111. } else{
  112. generateModal("Invalid Email", "Please make sure the inputted email is valid.")
  113. }
  114. }}>Submit</Button>{' '}
  115. <Button color="secondary" onClick={()=>{toggleModal(!showForgotPasswordModal)}}>Cancel</Button>
  116. </div>
  117. }/>
  118. <ModalPopup showModal={showGeneralModal} toggleModal={()=>{toggleGeneralModal(!showGeneralModal)}}
  119. header={generalModalHeader}
  120. body={<div>
  121. <p>{generalModalText}</p>
  122. </div>
  123. }
  124. footer={<div>
  125. <Button color="primary" onClick={()=>{toggleGeneralModal(!showGeneralModal)}}>OK</Button>
  126. </div>
  127. }/>
  128. <h1>Log In to New Beginnings</h1>
  129. <p style={{textAlign:'center'}}>Don't have an account? <button className="link" onClick={() =>{
  130. toggleLoginState(!loginState) }}>Click here</button> to sign up</p>
  131. <Form>
  132. <FormGroup>
  133. <Label for="email" size="lg">Email</Label>
  134. <Input type="email" name="email" id="email" placeholder="email@example.com" bsSize="lg" onChange={(e) => {
  135. setEmail(e.target.value)
  136. }}/>
  137. </FormGroup>
  138. <FormGroup>
  139. <Label for="password" size="lg">Password</Label>
  140. <Input type="password" name="password" id="password" placeholder="enter password" bsSize="lg" onChange={(e) => {
  141. setPassword(e.target.value)
  142. }} />
  143. {
  144. !loginState?
  145. <div>
  146. <Label for="Confirm Password" size="lg">Confirm Password</Label>
  147. <Input type="password" name="Confirm Password" id="confirm" placeholder="re-enter password" bsSize="lg" onChange={(e) => {
  148. setConfirmedPassword(e.target.value)
  149. }} />
  150. </div>:<></>
  151. }
  152. <p style={{fontSize: 15}}>
  153. Forgot password? <button className="link" type="button" onClick={()=>{
  154. toggleModal(true)
  155. }}>Click here.</button>
  156. </p>
  157. </FormGroup>
  158. <Button size="lg" className="center" onClick={()=>{
  159. handleAuthentication(auth,loginState,email,password,confirmPassword)
  160. }}>Submit</Button>
  161. </Form>
  162. </div>
  163. </div>
  164. )
  165. }