mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-02-06 00:58:45 -06:00
feat: getting rid of unnecessary ids and changing validation format
This commit is contained in:
12
.chores.md
Normal file
12
.chores.md
Normal file
@@ -0,0 +1,12 @@
|
||||
- [ ] Take validation out from the component.
|
||||
- [ ] SetNewPassword
|
||||
- [ ] Register
|
||||
- [ ] Create Check with highlight component. Check receives: status and message
|
||||
- [ ] Split some of these user feedbacks? Like:
|
||||
- [ ] Must contain at least one special character,
|
||||
- [ ] Must contain at least one number,
|
||||
- [ ] Must contain at least one upper character,
|
||||
- [ ] Must contain at least one lower character
|
||||
- [ ] Pass mismatching password user feedback as the other messages, for consistency
|
||||
- [ ] Get rid of toast message
|
||||
- [ ] Do it on blur
|
||||
@@ -1,7 +1,10 @@
|
||||
import { useEffect } from "react";
|
||||
import { Routes, Route } from "react-router-dom";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useDispatch } from "react-redux";
|
||||
// import "./App.css";
|
||||
import "react-toastify/dist/ReactToastify.css";
|
||||
import { ToastContainer } from "react-toastify";
|
||||
// import "./App.css";
|
||||
import NotFound from "./Pages/NotFound";
|
||||
import Login from "./Pages/Auth/Login";
|
||||
import Register from "./Pages/Auth/Register/Register";
|
||||
@@ -21,21 +24,18 @@ import ProtectedRoute from "./Components/ProtectedRoute";
|
||||
import Details from "./Pages/Monitors/Details";
|
||||
import AdvancedSettings from "./Pages/AdvancedSettings";
|
||||
import Maintenance from "./Pages/Maintenance";
|
||||
import withAdminCheck from "./HOC/withAdminCheck";
|
||||
import withAdminProp from "./HOC/withAdminProp";
|
||||
import Configure from "./Pages/Monitors/Configure";
|
||||
import PageSpeed from "./Pages/PageSpeed";
|
||||
import CreatePageSpeed from "./Pages/PageSpeed/CreatePageSpeed";
|
||||
import CreateNewMaintenanceWindow from "./Pages/Maintenance/CreateMaintenance";
|
||||
import PageSpeedDetails from "./Pages/PageSpeed/Details";
|
||||
import PageSpeedConfigure from "./Pages/PageSpeed/Configure";
|
||||
import withAdminCheck from "./HOC/withAdminCheck";
|
||||
import withAdminProp from "./HOC/withAdminProp";
|
||||
import { ThemeProvider } from "@emotion/react";
|
||||
import lightTheme from "./Utils/Theme/lightTheme";
|
||||
import darkTheme from "./Utils/Theme/darkTheme";
|
||||
import { useSelector } from "react-redux";
|
||||
import { CssBaseline } from "@mui/material";
|
||||
import { useEffect } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { getAppSettings } from "./Features/Settings/settingsSlice";
|
||||
import { logger } from "./Utils/Logger"; // Import the logger
|
||||
import { networkService } from "./main";
|
||||
@@ -181,16 +181,18 @@ function App() {
|
||||
path="/register"
|
||||
element={<AdminCheckedRegister />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
exact
|
||||
path="/register/:token"
|
||||
element={<Register />}
|
||||
/>
|
||||
{/* <Route path="/toast" element={<ToastComponent />} /> */}
|
||||
|
||||
<Route
|
||||
path="*"
|
||||
element={<NotFound />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/forgot-password"
|
||||
element={<ForgotPassword />}
|
||||
|
||||
@@ -20,7 +20,7 @@ import { useTheme } from "@emotion/react";
|
||||
*
|
||||
* @returns {React.Element} The `Check` component with a check icon and a label, defined by the `text` prop.
|
||||
*/
|
||||
const Check = ({ text, variant = "info", outlined = false }) => {
|
||||
const Check = ({ text, noHighlightText, variant = "info", outlined = false }) => {
|
||||
const theme = useTheme();
|
||||
const colors = {
|
||||
success: theme.palette.success.main,
|
||||
@@ -54,7 +54,7 @@ const Check = ({ text, variant = "info", outlined = false }) => {
|
||||
opacity: 0.8,
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
<Typography component="span">{noHighlightText}</Typography> {text}
|
||||
</Typography>
|
||||
</Stack>
|
||||
);
|
||||
@@ -62,6 +62,7 @@ const Check = ({ text, variant = "info", outlined = false }) => {
|
||||
|
||||
Check.propTypes = {
|
||||
text: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired,
|
||||
noHighlightText: PropTypes.string,
|
||||
variant: PropTypes.oneOf(["info", "error", "success"]),
|
||||
outlined: PropTypes.bool,
|
||||
};
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import { useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { Box, Stack, Typography } from "@mui/material";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
import { setNewPassword } from "../../Features/Auth/authSlice";
|
||||
import { createToast } from "../../Utils/toastUtils";
|
||||
import { Box, Stack, Typography } from "@mui/material";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useState } from "react";
|
||||
import { credentials } from "../../Validation/validation";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Check from "../../Components/Check/Check";
|
||||
import Field from "../../Components/Inputs/Field";
|
||||
import LockIcon from "../../assets/icons/lock.svg?react";
|
||||
import Background from "../../assets/Images/background-grid.svg?react";
|
||||
import Logo from "../../assets/icons/bwu-icon.svg?react";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
import "./index.css";
|
||||
import { IconBox } from "./styled";
|
||||
import LockIcon from "../../assets/icons/lock.svg?react";
|
||||
import Logo from "../../assets/icons/bwu-icon.svg?react";
|
||||
import Background from "../../assets/Images/background-grid.svg?react";
|
||||
import "./index.css";
|
||||
|
||||
const SetNewPassword = () => {
|
||||
const navigate = useNavigate();
|
||||
@@ -27,11 +27,6 @@ const SetNewPassword = () => {
|
||||
confirm: "",
|
||||
});
|
||||
|
||||
const idMap = {
|
||||
"register-password-input": "password",
|
||||
"confirm-password-input": "confirm",
|
||||
};
|
||||
|
||||
const { isLoading } = useSelector((state) => state.auth);
|
||||
const { token } = useParams();
|
||||
|
||||
@@ -41,7 +36,7 @@ const SetNewPassword = () => {
|
||||
const passwordForm = { ...form };
|
||||
const { error } = credentials.validate(passwordForm, {
|
||||
abortEarly: false,
|
||||
context: { password: form.password },
|
||||
/* context: { password: form.password }, */
|
||||
});
|
||||
|
||||
if (error) {
|
||||
@@ -82,8 +77,8 @@ const SetNewPassword = () => {
|
||||
};
|
||||
|
||||
const handleChange = (event) => {
|
||||
const { value, id } = event.target;
|
||||
const name = idMap[id];
|
||||
//TODO Change from id to name
|
||||
const { value, name } = event.target;
|
||||
setForm((prev) => ({
|
||||
...prev,
|
||||
[name]: value,
|
||||
@@ -91,15 +86,35 @@ const SetNewPassword = () => {
|
||||
|
||||
const { error } = credentials.validate(
|
||||
{ [name]: value },
|
||||
{ abortEarly: false, context: { password: form.password } }
|
||||
{
|
||||
abortEarly: false,
|
||||
context: { password: form.password },
|
||||
}
|
||||
);
|
||||
|
||||
setErrors((prev) => {
|
||||
const prevErrors = { ...prev };
|
||||
if (error) prevErrors[name] = error.details[0].message;
|
||||
else delete prevErrors[name];
|
||||
return prevErrors;
|
||||
});
|
||||
const errors = error.details.map((error) => error.message);
|
||||
|
||||
setErrors((prev) => ({ ...prev, [name]: errors }));
|
||||
};
|
||||
|
||||
console.log(errors);
|
||||
|
||||
/* function getCheckStatus() */
|
||||
|
||||
const feedbacks = {
|
||||
length: "info" /* !errors.password
|
||||
? "info"
|
||||
: errors.password === "length" || errors.password === "empty"
|
||||
? "error"
|
||||
: "success", */,
|
||||
special: "info" /* !errors
|
||||
? "info"
|
||||
: errors.password === "length" || errors.password === "empty"
|
||||
? "error"
|
||||
: "success", */,
|
||||
number: "info",
|
||||
upper: "success",
|
||||
lower: "error",
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -189,7 +204,7 @@ const SetNewPassword = () => {
|
||||
>
|
||||
<Field
|
||||
type="password"
|
||||
id="register-password-input"
|
||||
name="password"
|
||||
label="Password"
|
||||
isRequired={true}
|
||||
placeholder="••••••••"
|
||||
@@ -206,7 +221,7 @@ const SetNewPassword = () => {
|
||||
>
|
||||
<Field
|
||||
type="password"
|
||||
id="confirm-password-input"
|
||||
name="confirm"
|
||||
label="Confirm password"
|
||||
isRequired={true}
|
||||
placeholder="••••••••"
|
||||
@@ -226,49 +241,43 @@ const SetNewPassword = () => {
|
||||
characters long
|
||||
</>
|
||||
}
|
||||
variant={
|
||||
errors?.password === "Password is required"
|
||||
? "error"
|
||||
: form.password === ""
|
||||
? "info"
|
||||
: form.password.length < 8
|
||||
? "error"
|
||||
: "success"
|
||||
}
|
||||
/>
|
||||
<Check
|
||||
text={
|
||||
<>
|
||||
<Typography component="span">Must contain</Typography> one special
|
||||
character and a number
|
||||
</>
|
||||
}
|
||||
variant={
|
||||
errors?.password === "Password is required"
|
||||
? "error"
|
||||
: form.password === ""
|
||||
? "info"
|
||||
: !/^(?=.*[!@#$%^&*(),.?":{}|])(?=.*\d).+$/.test(form.password)
|
||||
? "error"
|
||||
: "success"
|
||||
}
|
||||
variant={feedbacks.length}
|
||||
/>
|
||||
<Check
|
||||
text={
|
||||
<>
|
||||
<Typography component="span">Must contain at least</Typography> one
|
||||
upper and lower character
|
||||
special character
|
||||
</>
|
||||
}
|
||||
variant={
|
||||
errors?.password === "Password is required"
|
||||
? "error"
|
||||
: form.password === ""
|
||||
? "info"
|
||||
: !/^(?=.*[A-Z])(?=.*[a-z]).+$/.test(form.password)
|
||||
? "error"
|
||||
: "success"
|
||||
variant={feedbacks.special}
|
||||
/>
|
||||
<Check
|
||||
text={
|
||||
<>
|
||||
<Typography component="span">Must contain at least</Typography> one
|
||||
one number
|
||||
</>
|
||||
}
|
||||
variant={feedbacks.number}
|
||||
/>
|
||||
<Check
|
||||
text={
|
||||
<>
|
||||
<Typography component="span">Must contain at least</Typography> one
|
||||
upper character
|
||||
</>
|
||||
}
|
||||
variant={feedbacks.upper}
|
||||
/>
|
||||
<Check
|
||||
text={
|
||||
<>
|
||||
<Typography component="span">Must contain at least</Typography> one
|
||||
lower character
|
||||
</>
|
||||
}
|
||||
variant={feedbacks.lower}
|
||||
/>
|
||||
</Stack>
|
||||
</Box>
|
||||
|
||||
@@ -17,26 +17,33 @@ const passwordSchema = joi
|
||||
.trim()
|
||||
.min(8)
|
||||
.messages({
|
||||
"string.empty": "Password is required",
|
||||
"string.min": "Password must be at least 8 characters long",
|
||||
"string.empty": "empty",
|
||||
"string.min": "length",
|
||||
})
|
||||
.custom((value, helpers) => {
|
||||
if (!/[A-Z]/.test(value)) {
|
||||
return helpers.message("Password must contain at least one uppercase letter");
|
||||
return helpers.message("uppercase");
|
||||
}
|
||||
return value;
|
||||
})
|
||||
.custom((value, helpers) => {
|
||||
if (!/[a-z]/.test(value)) {
|
||||
return helpers.message("Password must contain at least one lowercase letter");
|
||||
return helpers.message("lowercase");
|
||||
}
|
||||
return value;
|
||||
})
|
||||
.custom((value, helpers) => {
|
||||
if (!/\d/.test(value)) {
|
||||
return helpers.message("Password must contain at least one number");
|
||||
return helpers.message("number");
|
||||
}
|
||||
return value;
|
||||
})
|
||||
.custom((value, helpers) => {
|
||||
if (!/[!@#$%^&*]/.test(value)) {
|
||||
return helpers.message("Password must contain at least one special character");
|
||||
return helpers.message("special");
|
||||
}
|
||||
|
||||
return value;
|
||||
});
|
||||
|
||||
const credentials = joi.object({
|
||||
firstName: nameSchema,
|
||||
lastName: nameSchema,
|
||||
@@ -61,12 +68,12 @@ const credentials = joi.object({
|
||||
.string()
|
||||
.trim()
|
||||
.messages({
|
||||
"string.empty": "Password confirmation is required",
|
||||
"string.empty": "empty",
|
||||
})
|
||||
.custom((value, helpers) => {
|
||||
const { password } = helpers.prefs.context;
|
||||
if (value !== password) {
|
||||
return helpers.message("Passwords do not match");
|
||||
return helpers.message("different");
|
||||
}
|
||||
return value;
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user