Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: be/new auth structure #1775

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Client/src/Components/Inputs/TextInput/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const getSx = (theme, type, maxWidth) => {
const sx = {
maxWidth: maxWidth,
"& .MuiOutlinedInput-root ": {
backgroundColor: theme.palette.background.paper,
"&:hover .MuiOutlinedInput-notchedOutline": {
borderColor: theme.palette.primary.contrastText, // Adjust hover border color
},
Expand Down Expand Up @@ -152,7 +153,7 @@ TextInput.displayName = "TextInput";

TextInput.propTypes = {
type: PropTypes.string,
id: PropTypes.string.isRequired,
id: PropTypes.string,
name: PropTypes.string,
value: PropTypes.string,
placeholder: PropTypes.string,
Expand Down
2 changes: 1 addition & 1 deletion Client/src/Pages/Auth/Register/StepThree/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function StepThree({ onSubmit, onBack }) {
}
}, []);

const { handleChange, feedbacks, form, errors } = useValidatePassword();
const [handleChange, feedbacks, form, errors] = useValidatePassword();
return (
<>
<Stack
Expand Down
220 changes: 220 additions & 0 deletions Client/src/Pages/Auth/Register/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
// Components
import { Stack, Typography, Box, Button } from "@mui/material";
import Background from "../../../assets/Images/background-grid.svg?react";
import TextInput from "../../../Components/Inputs/TextInput";
import Check from "../../../Components/Check/Check";

// Utils
import { createToast } from "../../../Utils/toastUtils";
import { useTheme } from "@emotion/react";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useValidatePassword } from "../hooks/useValidatePassword";
import { credentials } from "../../../Validation/validation";
import { useDispatch } from "react-redux";
import { register } from "../../../Features/Auth/authSlice";
import { useNavigate } from "react-router-dom";
const Register = () => {
const theme = useTheme();
const navigate = useNavigate();
const { t } = useTranslation();
const dispatch = useDispatch();
const [handlePasswordChange, feedbacks, passwordForm, passwordErrors] =
useValidatePassword();

// Local state
const [form, setForm] = useState({
firstName: "",
lastName: "",
email: "",
password: "",
confirm: "",
});

const [errors, setErrors] = useState({});
console.log(passwordErrors);
const handleFormChange = (e) => {
const { name, value } = e.target;
// Handle password
if (name === "password" || name === "confirm") {
handlePasswordChange(e);
}
setForm((prev) => ({ ...prev, [name]: value }));
const { error } = credentials.validate({ [name]: value }, { abortEarly: false });
setErrors((prev) => ({
...prev,
...(error ? { [name]: error.details[0].message } : { [name]: undefined }),
}));
};

const handleSubmit = async () => {
const { error } = credentials.validate(form, {
abortEarly: false,
context: { password: form.password }, // Why do we have to do this?
});
if (error) {
const newErrors = {};
error.details.forEach((err) => {
newErrors[err.path[0]] = err.message;
});
setErrors(newErrors);
return;
}

const registrationForm = {
firstName: form.firstName,
lastName: form.lastName,
email: form.email,
password: form.password,
plan: "free",
role: ["owner", "admin", "user"],
};
const action = await dispatch(register(registrationForm));
if (action.payload.success) {
navigate("/uptime");
createToast({
body: "Welcome! Your account was created successfully.",
});
} else {
if (action.payload) {
createToast({
body: action.payload.msg,
});
} else {
createToast({
body: "Unknown error.",
});
}
}
};

return (
<Stack
margin="auto"
maxWidth={400}
minHeight="100vh"
spacing={theme.spacing(10)}
justifyContent="center"
>
<Typography
variant="h1"
sx={{ alignSelf: "center" }}
>
Checkmate
</Typography>
<Typography>Create your account to get started</Typography>
<TextInput
label="Name"
name="firstName"
isRequired={true}
placeholder="Jordan"
autoComplete="given-name"
value={form.firstName}
onChange={handleFormChange}
error={errors.firstName ? true : false}
helperText={errors.firstName}
/>
<TextInput
label="Surname"
name="lastName"
isRequired={true}
placeholder="Ellis"
autoComplete="family-name"
value={form.lastName}
onChange={handleFormChange}
error={errors.lastName ? true : false}
helperText={errors.lastName}
/>
<TextInput
type="email"
name="email"
label={t("commonEmail")}
isRequired={true}
placeholder="[email protected]"
autoComplete="email"
value={form.email}
onChange={handleFormChange}
error={errors.email ? true : false}
helperText={errors.email}
/>
<TextInput
type="password"
name="password"
label={t("commonPassword")}
isRequired={true}
placeholder={t("createAPassword")}
autoComplete="current-password"
value={form.password}
onChange={handleFormChange}
error={errors.password ? true : false}
/>
<TextInput
type="password"
id="register-confirm-input"
name="confirm"
label={t("authSetNewPasswordConfirmPassword")}
isRequired={true}
placeholder={t("confirmPassword")}
onChange={handleFormChange}
error={errors.confirm ? true : false}
/>
<Stack
gap={theme.spacing(4)}
mb={{ xs: theme.spacing(6), sm: theme.spacing(8) }}
>
<Check
noHighlightText={t("authPasswordMustBeAtLeast")}
text={t("authPasswordCharactersLong")}
variant={feedbacks.length}
/>
<Check
noHighlightText={t("authPasswordMustContainAtLeast")}
text={t("authPasswordSpecialCharacter")}
variant={feedbacks.special}
/>
<Check
noHighlightText={t("authPasswordMustContainAtLeast")}
text={t("authPasswordOneNumber")}
variant={feedbacks.number}
/>
<Check
noHighlightText={t("authPasswordMustContainAtLeast")}
text={t("authPasswordUpperCharacter")}
variant={feedbacks.uppercase}
/>
<Check
noHighlightText={t("authPasswordMustContainAtLeast")}
text={t("authPasswordLowerCharacter")}
variant={feedbacks.lowercase}
/>
<Check
noHighlightText={t("authPasswordConfirmAndPassword")}
text={t("authPasswordMustMatch")}
variant={feedbacks.confirm}
/>
</Stack>
<Button
variant="contained"
color="accent"
sx={{ width: "100%" }}
onClick={handleSubmit}
>
Get Started
</Button>
<Box
position="absolute"
zIndex={-1}
className="background-pattern-svg"
sx={{
"& svg g g:last-of-type path": {
stroke: theme.palette.primary.lowContrast,
},
}}
>
<Background style={{ width: "100%" }} />
</Box>
</Stack>
);
};

export default Register;
2 changes: 1 addition & 1 deletion Client/src/Pages/Auth/hooks/useValidatePassword.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,6 @@ function useValidatePassword() {
[form, errors]
);

return { handleChange, feedbacks, form, errors };
return [handleChange, feedbacks, form, errors];
}
export { useValidatePassword };
7 changes: 6 additions & 1 deletion Client/src/Routes/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import NotFound from "../Pages/NotFound";

// Auth
import AuthLogin from "../Pages/Auth/Login/Login";
import AuthRegister from "../Pages/Auth/Register/Register";
import OldAuthRegister from "../Pages/Auth/Register/Register";
import AuthRegister from "../Pages/Auth/Register";
import AuthForgotPassword from "../Pages/Auth/ForgotPassword";
import AuthCheckEmail from "../Pages/Auth/CheckEmail";
import AuthSetNewPassword from "../Pages/Auth/SetNewPassword";
Expand Down Expand Up @@ -243,6 +244,10 @@ const Routes = () => {
path="/register"
element={<AdminCheckedRegister />}
/>
<Route
path="/old-register"
element={<OldAuthRegister />}
/>

<Route
exact
Expand Down
117 changes: 59 additions & 58 deletions Client/src/locales/gb.json
Original file line number Diff line number Diff line change
@@ -1,59 +1,60 @@
{
"dontHaveAccount": "Don't have account",
"email": "E-mail",
"forgotPassword": "Forgot Password",
"password": "password",
"signUp": "Sign up",
"submit": "Submit",
"title": "Title",
"continue": "Continue",
"enterEmail": "Enter your email",
"authLoginTitle": "Log In",
"authLoginEnterPassword": "Enter your password",
"commonPassword": "Password",
"createPassword": "Create your password",
"createAPassword": "Create a password",
"commonBack": "Back",
"authForgotPasswordTitle": "Forgot password?",
"authForgotPasswordResetPassword": "Reset password",
"authRegisterAlreadyHaveAccount": "Already have an account?",
"commonAppName": "Checkmate",
"authLoginEnterEmail": "Enter your email",
"authRegisterTitle": "Create an account",
"authRegisterStepOneTitle": "Create your account",
"authRegisterStepOneDescription": "Enter your details to get started",
"authRegisterStepTwoTitle": "Set up your profile",
"authRegisterStepTwoDescription": "Tell us more about yourself",
"authRegisterStepThreeTitle": "Almost done!",
"authRegisterStepThreeDescription": "Review your information",
"authForgotPasswordDescription": "No worries, we'll send you reset instructions.",
"authForgotPasswordSendInstructions": "Send instructions",
"authForgotPasswordBackTo": "Back to",
"authCheckEmailTitle": "Check your email",
"authCheckEmailDescription": "We sent a password reset link to {{email}}",
"authCheckEmailResendEmail": "Resend email",
"authCheckEmailBackTo": "Back to",
"goBackTo": "Go back to",
"authCheckEmailDidntReceiveEmail": "Didn't receive the email?",
"authCheckEmailClickToResend": "Click to resend",
"authSetNewPasswordTitle": "Set new password",
"authSetNewPasswordDescription": "Your new password must be different from previously used passwords.",
"authSetNewPasswordNewPassword": "New password",
"authSetNewPasswordConfirmPassword": "Confirm password",
"confirmPassword": "Confirm your password",
"authSetNewPasswordResetPassword": "Reset password",
"authSetNewPasswordBackTo": "Back to",
"authPasswordMustBeAtLeast": "Must be at least",
"authPasswordCharactersLong": "8 characters long",
"authPasswordMustContainAtLeast": "Must contain at least",
"authPasswordSpecialCharacter": "one special character",
"authPasswordOneNumber": "one number",
"authPasswordUpperCharacter": "one upper character",
"authPasswordLowerCharacter": "one lower character",
"authPasswordConfirmAndPassword": "Confirm password and password",
"authPasswordMustMatch": "must match",
"authRegisterCreateAccount": "Create your account to get started",
"authRegisterCreateSuperAdminAccount": "Create your Super admin account to get started",
"authRegisterSignUpWithEmail": "Sign up with Email",
"authRegisterBySigningUp": "By signing up, you agree to our"
}
"dontHaveAccount": "Don't have account",
"email": "E-mail",
"forgotPassword": "Forgot Password",
"password": "password",
"signUp": "Sign up",
"submit": "Submit",
"title": "Title",
"continue": "Continue",
"enterEmail": "Enter your email",
"authLoginTitle": "Log In",
"authLoginEnterPassword": "Enter your password",
"commonPassword": "Password",
"createPassword": "Create your password",
"createAPassword": "Create a password",
"commonBack": "Back",
"commonEmail": "Email",
"authForgotPasswordTitle": "Forgot password?",
"authForgotPasswordResetPassword": "Reset password",
"authRegisterAlreadyHaveAccount": "Already have an account?",
"commonAppName": "Checkmate",
"authLoginEnterEmail": "Enter your email",
"authRegisterTitle": "Create an account",
"authRegisterStepOneTitle": "Create your account",
"authRegisterStepOneDescription": "Enter your details to get started",
"authRegisterStepTwoTitle": "Set up your profile",
"authRegisterStepTwoDescription": "Tell us more about yourself",
"authRegisterStepThreeTitle": "Almost done!",
"authRegisterStepThreeDescription": "Review your information",
"authForgotPasswordDescription": "No worries, we'll send you reset instructions.",
"authForgotPasswordSendInstructions": "Send instructions",
"authForgotPasswordBackTo": "Back to",
"authCheckEmailTitle": "Check your email",
"authCheckEmailDescription": "We sent a password reset link to {{email}}",
"authCheckEmailResendEmail": "Resend email",
"authCheckEmailBackTo": "Back to",
"goBackTo": "Go back to",
"authCheckEmailDidntReceiveEmail": "Didn't receive the email?",
"authCheckEmailClickToResend": "Click to resend",
"authSetNewPasswordTitle": "Set new password",
"authSetNewPasswordDescription": "Your new password must be different from previously used passwords.",
"authSetNewPasswordNewPassword": "New password",
"authSetNewPasswordConfirmPassword": "Confirm password",
"confirmPassword": "Confirm your password",
"authSetNewPasswordResetPassword": "Reset password",
"authSetNewPasswordBackTo": "Back to",
"authPasswordMustBeAtLeast": "Must be at least",
"authPasswordCharactersLong": "8 characters long",
"authPasswordMustContainAtLeast": "Must contain at least",
"authPasswordSpecialCharacter": "one special character",
"authPasswordOneNumber": "one number",
"authPasswordUpperCharacter": "one upper character",
"authPasswordLowerCharacter": "one lower character",
"authPasswordConfirmAndPassword": "Confirm password and password",
"authPasswordMustMatch": "must match",
"authRegisterCreateAccount": "Create your account to get started",
"authRegisterCreateSuperAdminAccount": "Create your Super admin account to get started",
"authRegisterSignUpWithEmail": "Sign up with Email",
"authRegisterBySigningUp": "By signing up, you agree to our"
}
Loading