From ebc2946dc9898ed496cb74d124377b7cb8b99f52 Mon Sep 17 00:00:00 2001 From: John Darragh Date: Thu, 17 Aug 2023 20:36:06 -0700 Subject: [PATCH 1/2] Fix conditional logic that activates clarity for produciton env only --- client/public/index.html | 27 +- client/src/components/Account/ConfirmEmail.js | 5 +- .../src/components/Account/ForgotPassword.js | 262 +++++----- client/src/components/Account/Login.js | 318 ++++++----- client/src/components/Account/Register.js | 238 +++++---- .../src/components/Account/ResetPassword.js | 248 +++++---- .../Account/ResetPasswordEmailSent.js | 60 ++- client/src/components/StaticPages/About.js | 492 +++++++++--------- 8 files changed, 822 insertions(+), 828 deletions(-) diff --git a/client/public/index.html b/client/public/index.html index f90f31df2..0240f7e7a 100644 --- a/client/public/index.html +++ b/client/public/index.html @@ -83,19 +83,22 @@ }); diff --git a/client/src/components/Account/ConfirmEmail.js b/client/src/components/Account/ConfirmEmail.js index c21763b0f..295d4e384 100644 --- a/client/src/components/Account/ConfirmEmail.js +++ b/client/src/components/Account/ConfirmEmail.js @@ -1,6 +1,6 @@ import EmailOutlinedIcon from "@mui/icons-material/EmailOutlined"; import LoadingButton from "@mui/lab/LoadingButton"; -import { Avatar, Container, TextField, Typography, Box } from "@mui/material"; +import { Avatar, TextField, Typography, Box } from "@mui/material"; import { Formik } from "formik"; import { useEffect, useState } from "react"; import { Navigate, useParams } from "react-router-dom"; @@ -18,7 +18,6 @@ const validationSchema = Yup.object().shape({ }); const ConfirmEmail = (props) => { - const { classes } = props; const [confirmResult, setConfirmResult] = useState(false); const { token } = useParams(); const { setToast } = useToasterContext(); @@ -148,7 +147,7 @@ const ConfirmEmail = (props) => { {(props) => renderView(props)} - + ); }; diff --git a/client/src/components/Account/ForgotPassword.js b/client/src/components/Account/ForgotPassword.js index bdd5625e3..cf2bb9921 100644 --- a/client/src/components/Account/ForgotPassword.js +++ b/client/src/components/Account/ForgotPassword.js @@ -3,15 +3,7 @@ import { Formik } from "formik"; import * as Yup from "yup"; import * as accountService from "../../services/account-service"; import { Button } from "@mui/material"; -import { - Avatar, - Container, - Link, - Grid, - TextField, - Typography, - Box -} from "@mui/material"; +import { Avatar, Link, Grid, TextField, Typography, Box } from "@mui/material"; import LockOutlinedIcon from "@mui/icons-material/LockOutlined"; import { useToasterContext } from "../../contexts/toasterContext"; import debounce from "lodash.debounce"; @@ -20,8 +12,6 @@ import { useNavigate, useParams } from "react-router-dom"; import { palette } from "theme/palette"; import { PageWrapper } from "./PageWrapper"; - - const validationSchema = Yup.object().shape({ email: Yup.string() .email("Invalid email address format") @@ -29,7 +19,6 @@ const validationSchema = Yup.object().shape({ }); const ForgotPassword = (props) => { - const { classes } = props; const { setToast } = useToasterContext(); const { email } = useParams(); const navigate = useNavigate(); @@ -49,147 +38,150 @@ const ForgotPassword = (props) => { return ( - - + - - - - Forgot Password - - { - try { - const response = await accountService.forgotPassword( - values.email - ); - if (response.isSuccess) { - navigate(`/resetpasswordemailsent/${values.email || ""}`); - } else if ( - response.code === "FORGOT_PASSWORD_ACCOUNT_NOT_FOUND" - ) { - const msg = - "Account not found. If you want to create a new account with this email, please register."; - console.error(msg); - setToast({ - message: msg, - }); - formikBag.setSubmitting(false); - } else if (response.code === "FORGOT_PASSWORD_EMAIL_FAILED") { - const msg = - "A problem occurred with sending an email to this address."; - console.error(msg); - setToast({ - message: msg, - }); - formikBag.setSubmitting(false); - } else { - console.error(response.message); - setToast({ - message: response.message, - }); - formikBag.setSubmitting(false); - } - } catch (err) { + }} + > + + + + Forgot Password + + { + try { + const response = await accountService.forgotPassword( + values.email + ); + if (response.isSuccess) { + navigate(`/resetpasswordemailsent/${values.email || ""}`); + } else if ( + response.code === "FORGOT_PASSWORD_ACCOUNT_NOT_FOUND" + ) { + const msg = + "Account not found. If you want to create a new account with this email, please register."; + console.error(msg); + setToast({ + message: msg, + }); + formikBag.setSubmitting(false); + } else if (response.code === "FORGOT_PASSWORD_EMAIL_FAILED") { + const msg = + "A problem occurred with sending an email to this address."; + console.error(msg); + setToast({ + message: msg, + }); + formikBag.setSubmitting(false); + } else { + console.error(response.message); setToast({ - message: `Server error. ${err.message}`, + message: response.message, }); - console.error(err); formikBag.setSubmitting(false); } - }} - > - {({ - values, - errors, - touched, - handleChange, - handleBlur, - handleSubmit, - isSubmitting, - setFieldError, - isValid, - }) => { - const handleEmailChange = (e) => { - handleChange(e); - debouncedEmailValidation(e.target.value, setFieldError); - }; - return ( -
{ - evt.preventDefault(); - handleSubmit(evt); - }} - > - + {({ + values, + errors, + touched, + handleChange, + handleBlur, + handleSubmit, + isSubmitting, + setFieldError, + isValid, + }) => { + const handleEmailChange = (e) => { + handleChange(e); + debouncedEmailValidation(e.target.value, setFieldError); + }; + return ( + { + evt.preventDefault(); + handleSubmit(evt); + }} + > + - - + container + spacing={2} + > + + - - + + + + - Send Password Reset Link - - - - - - Return to Login - - - + Return to Login + + - - ); - }} -
-
-
+ + + ); + }} + + + ); }; diff --git a/client/src/components/Account/Login.js b/client/src/components/Account/Login.js index 435566172..f467fc910 100644 --- a/client/src/components/Account/Login.js +++ b/client/src/components/Account/Login.js @@ -3,12 +3,11 @@ import { useLocation, useNavigate, useParams } from "react-router-dom"; import { Avatar, Box, - Container, Link, Grid, TextField, Typography, - Button + Button, } from "@mui/material"; import { Formik } from "formik"; import * as Yup from "yup"; @@ -23,8 +22,6 @@ import Label from "components/Admin/ui/Label"; import { palette } from "theme/palette"; import { PageWrapper } from "./PageWrapper"; - - const validationSchema = Yup.object().shape({ email: Yup.string() .email("Invalid email address format") @@ -54,192 +51,191 @@ const LoginForm = (props) => { return ( - - {state?.isPasswordReset && ( - - Password has been successfully updated - - )} - + {state?.isPasswordReset && ( + + Password has been successfully updated + + )} + - - - - Login - - { - setTimeout(async () => { - try { - const response = await accountService.login( - values.email, - values.password - ); - if (response.isSuccess) { - analytics.identify(response.user.id); - onLogin(response.user); + > + + + + Login + + { + setTimeout(async () => { + try { + const response = await accountService.login( + values.email, + values.password + ); + if (response.isSuccess) { + analytics.identify(response.user.id); + onLogin(response.user); + setToast({ + message: "Login successful.", + }); + if (state?.from) { + navigate(state.from); + } else if ( + response.user.isAdmin || + response.user.isCoordinator + ) { + navigate("/verificationAdmin"); + } else if (response.user.isSecurityAdmin) { + navigate("/securityadmindashboard"); + } else if (response.user.isDataEntry) { + navigate("/verificationdashboard"); + } else { + navigate("/"); + } + } else if (response.code === "AUTH_NOT_CONFIRMED") { + try { + await accountService.resendConfirmationEmail(values.email); setToast({ - message: "Login successful.", - }); - if (state?.from) { - navigate(state.from); - } else if ( - response.user.isAdmin || - response.user.isCoordinator - ) { - navigate("/verificationAdmin"); - } else if (response.user.isSecurityAdmin) { - navigate("/securityadmindashboard"); - } else if (response.user.isDataEntry) { - navigate("/verificationdashboard"); - } else { - navigate("/"); - } - } else if (response.code === "AUTH_NOT_CONFIRMED") { - try { - await accountService.resendConfirmationEmail( - values.email - ); - setToast({ - message: `Your email has not been confirmed. + message: `Your email has not been confirmed. Please look through your email for a Registration Confirmation link and use it to confirm that you own this email address.`, - }); - formikBag.setSubmitting(false); - } catch (err) { - setToast({ - message: `An internal error occurred in sending - an email to ${values.email}`, - }); - formikBag.setSubmitting(false); - } - } else if (response.code === "AUTH_NO_ACCOUNT") { - console.error("Account not found!!"); - setToast({ - message: `The email ${values.email} does not correspond to an - existing account. Please verify the email or register as a - new account.`, }); formikBag.setSubmitting(false); - } else { - // Presumably response.code === "AUTH_INVALID_PASSWORD" + } catch (err) { setToast({ - message: `The password is incorrect, please check it - and try again or use the Forgot Password feature.`, + message: `An internal error occurred in sending + an email to ${values.email}`, }); formikBag.setSubmitting(false); } - return true; - } catch (err) { + } else if (response.code === "AUTH_NO_ACCOUNT") { + console.error("Account not found!!"); + setToast({ + message: `The email ${values.email} does not correspond to an + existing account. Please verify the email or register as a + new account.`, + }); + formikBag.setSubmitting(false); + } else { + // Presumably response.code === "AUTH_INVALID_PASSWORD" setToast({ - message: "Server error. Please contact support.", + message: `The password is incorrect, please check it + and try again or use the Forgot Password feature.`, }); - console.error(err); formikBag.setSubmitting(false); } - }, 400); - }} - > - {({ - values, - errors, - touched, - handleChange, - handleBlur, - handleSubmit, - isSubmitting, - dirty, - isValid, - }) => ( -
- + {({ + values, + errors, + touched, + handleChange, + handleBlur, + handleSubmit, + isSubmitting, + dirty, + isValid, + }) => ( + + - - - - - - - - - - - + + + + + + + + + + + + Forgot password? + - - )} -
-
-
+ + + Register + + + + + )} + + + ); }; diff --git a/client/src/components/Account/Register.js b/client/src/components/Account/Register.js index 08ae7e315..c4a6c28a7 100644 --- a/client/src/components/Account/Register.js +++ b/client/src/components/Account/Register.js @@ -12,7 +12,6 @@ import { Grid, TextField, Typography, - Container, } from "@mui/material"; import LockOutlinedIcon from "@mui/icons-material/LockOutlined"; import { useToasterContext } from "contexts/toasterContext"; @@ -25,12 +24,9 @@ import Label from "components/Admin/ui/Label"; import { palette } from "theme/palette"; import { PageWrapper } from "./PageWrapper"; - - // Core component is the Material UI form itself const form = (props) => { const { - classes, dirty, values, touched, @@ -44,138 +40,140 @@ const form = (props) => { return ( - - + - + - - - - Register - -
- + + + + Register + + + - - - - - - - - - - + container + spacing={2} + > + + - - - - - - - Already have an account? Login - - + id="lastName" + placeholder="Last Name" + name="lastName" + autoComplete="lname" + value={values.lastName} + onChange={handleChange} + onBlur={handleBlur} + helperText={touched.lastName ? errors.lastName : ""} + error={touched.lastName && Boolean(errors.lastName)} + /> + + + + + + + + + + + + + + + Already have an account? Login + - -
-
+ + + + ); }; diff --git a/client/src/components/Account/ResetPassword.js b/client/src/components/Account/ResetPassword.js index 63b623691..78e55bb93 100644 --- a/client/src/components/Account/ResetPassword.js +++ b/client/src/components/Account/ResetPassword.js @@ -4,7 +4,7 @@ import { Formik } from "formik"; import * as Yup from "yup"; import * as accountService from "../../services/account-service"; import { Button } from "@mui/material"; -import { Avatar, Box, Container, CssBaseline, Typography } from "@mui/material"; +import { Avatar, Box, CssBaseline, Typography } from "@mui/material"; import LockOutlinedIcon from "@mui/icons-material/LockOutlined"; import { useToasterContext } from "../../contexts/toasterContext"; import PasswordInput from "../UI/PasswordInput"; @@ -16,7 +16,6 @@ import Label from "components/Admin/ui/Label"; import { palette } from "theme/palette"; import { PageWrapper } from "./PageWrapper"; - const validationSchema = Yup.object().shape({ token: Yup.string().required("Token is required"), password: Yup.string() @@ -28,154 +27,153 @@ const validationSchema = Yup.object().shape({ }); const ResetPassword = (props) => { - const { classes} = props; const { setToast } = useToasterContext(); const navigate = useNavigate(); const { token } = useParams(); return ( - - + - + - - - - Password Reset - - { - try { - const response = await accountService.resetPassword( - values.token, - values.password + > + + + + Password Reset + + { + try { + const response = await accountService.resetPassword( + values.token, + values.password + ); + if (response.isSuccess) { + setToast({ + message: "Password has been reset. Please use it to login.", + }); + navigate({ + pathname: `/login/${response.email}`, + state: { + isPasswordReset: true, + }, + }); + } else if ( + response.code === "RESET_PASSWORD_TOKEN_INVALID" || + response.code === "RESET_PASSWORD_TOKEN_EXPIRED" + ) { + console.error( + "The reset token is invalid or has expired. Use the forgot password link to try again." ); - if (response.isSuccess) { - setToast({ - message: "Password has been reset. Please use it to login.", - }); - navigate({ - pathname: `/login/${response.email}`, - state: { - isPasswordReset: true, - }, - }); - } else if ( - response.code === "RESET_PASSWORD_TOKEN_INVALID" || - response.code === "RESET_PASSWORD_TOKEN_EXPIRED" - ) { - console.error( - "The reset token is invalid or has expired. Use the forgot password link to try again." - ); - formikBag.setSubmitting(false); - } else { - // RESET_PASSWORD_FAILED with unexpected error - setToast({ - message: `${response.message}`, - }); - formikBag.setSubmitting(false); - } - } catch (err) { + formikBag.setSubmitting(false); + } else { + // RESET_PASSWORD_FAILED with unexpected error setToast({ - message: `Password reset failed. ${err.message}`, + message: `${response.message}`, }); - console.error(err); formikBag.setSubmitting(false); } - }} - > - {({ - values, - errors, - touched, - handleChange, - handleBlur, - handleSubmit, - isSubmitting, - isValid, - dirty, - /* and other goodies */ - }) => ( -
{ - evt.preventDefault(); - handleSubmit(evt); - }} - > - + {({ + values, + errors, + touched, + handleChange, + handleBlur, + handleSubmit, + isSubmitting, + isValid, + dirty, + /* and other goodies */ + }) => ( + { + evt.preventDefault(); + handleSubmit(evt); + }} + > + + + + + + - - - )} -
-
-
+ Reset Password + + + + )} + + + ); }; diff --git a/client/src/components/Account/ResetPasswordEmailSent.js b/client/src/components/Account/ResetPasswordEmailSent.js index 82c7cb21d..2c0032273 100644 --- a/client/src/components/Account/ResetPasswordEmailSent.js +++ b/client/src/components/Account/ResetPasswordEmailSent.js @@ -1,7 +1,7 @@ import React from "react"; import { useNavigate, useParams } from "react-router-dom"; import { Button } from "@mui/material"; -import { Avatar, Box, Container, CssBaseline, Typography } from "@mui/material"; +import { Avatar, Box, CssBaseline, Typography } from "@mui/material"; import { palette } from "theme/palette"; import { PageWrapper } from "./PageWrapper"; @@ -28,53 +28,51 @@ const MailIcon = () => { ); }; - const ResetPasswordEmailSent = (props) => { - const { classes} = props; const navigate = useNavigate(); const { email } = useParams(); return ( - - + - + - - - - Password Reset Link was Sent - - - A password reset link was sent to {email}.
If you - don’t see it in your inbox, please check your junk/spam folder. -
- - - + > + +
+ + Password Reset Link was Sent + + + A password reset link was sent to {email}.
If you don’t see it + in your inbox, please check your junk/spam folder. +
+ + -
+ + ); }; diff --git a/client/src/components/StaticPages/About.js b/client/src/components/StaticPages/About.js index 8122a6cb8..74e137a68 100644 --- a/client/src/components/StaticPages/About.js +++ b/client/src/components/StaticPages/About.js @@ -1,6 +1,5 @@ import React, { useEffect } from "react"; import aboutbg from "./assets/about-bg.webp"; -import iconSpacerGray from "./assets/icon-spacer-gray.svg"; import foodCycle from "./assets/food-cycle.png"; import foodForward from "./assets/food-forward.png"; import farm2people from "./assets/farm2people.png"; @@ -13,87 +12,93 @@ import Footer from "../Layout/Footer"; import IconSpacerSVG from "./assets/IconSpacerSVG"; import { PageWrapper } from "./PageWrapper"; - const About = () => { - useEffect(() => { analytics.postEvent("visitAboutPage"); }, []); return ( - - - + + - About Food Oasis / LA - - + About Food Oasis / LA + + - There are numerous free food resources in Los Angeles County. With - an updated directory of over 1000 listings, our website helps - connect you to these resources. - {" "} - + > + There are numerous free food resources in Los Angeles County. With an + updated directory of over 1000 listings, our website helps connect you + to these resources. + {" "} + - - + - + - Our Mission - - + Our Mission + + + - Food Oasis is a web-based directory that connects people to free - food resources in Los Angeles. Our team is dedicated to - maintaining an updated directory of hundreds of free food - resources in the area such as food pantries and meal programs. Our - volunteers frequently verify each listing for the most - comprehensive and up-to-date information.  - - - - + Food Oasis is a web-based directory that connects people to free + food resources in Los Angeles. Our team is dedicated to maintaining + an updated directory of hundreds of free food resources in the area + such as food pantries and meal programs. Our volunteers frequently + verify each listing for the most comprehensive and up-to-date + information.  + + + + { background: "#B6D8FB", display: "flex", flexDirection: "column", - }}> - - - - + + + Our Team - - + Our Team + + + - We are a 100% volunteer-run project. We are part of{" "} - - Hack for LA - - . Our team includes product managers, researchers, designers, - developers, writers and data validators who maintain this - web-based directory. We verify each listing in our directory - regularly to ensure the contact information, hours of operation, - and services provided are accurate. - - - - + We are a 100% volunteer-run project. We are part of{" "} + + Hack for LA + + . Our team includes product managers, researchers, designers, + developers, writers and data validators who maintain this web-based + directory. We verify each listing in our directory regularly to + ensure the contact information, hours of operation, and services + provided are accurate. + + + + { background: "#f0f0f0", display: "flex", flexDirection: "column", - textAlign: "center" + textAlign: "center", }} - > - - - - + + + Questions - + Questions + + - For more information, please visit our{" "} - - FAQ page - - . - - - + For more information, please visit our{" "} + + FAQ page + + . + + + - - - - + + + Contact Us - - + Contact Us + + + - Questions about our project? -
- Updates to the listings? -
- General inquiries? -
-
- - Please contact our Support Team -
- - foodoasisinfo@hackforla.org - -
-
-
- + Questions about our project? +
+ Updates to the listings? +
+ General inquiries? +
+ + + Please contact our Support Team +
+ + foodoasisinfo@hackforla.org + +
+ +
+ { alignItems: "center", display: "flex", flexWrap: "wrap", - flexDirection: {xs: "column", md: "row"} + flexDirection: { xs: "column", md: "row" }, }} - > - + { fontWeight: "500", fontSize: "32px", marginTop: "10px", - marginBottom: "60px" + marginBottom: "60px", }} - variant="h2">Our Partners - - - - - - - - - - - - - -