diff --git a/package.json b/package.json
index 00bb49e..2da81e0 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,7 @@
"dependencies": {
"@emotion/react": "^11.10.6",
"@emotion/styled": "^11.10.6",
+ "@mui/icons-material": "^5.11.16",
"@mui/material": "^5.11.16",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
diff --git a/src/api/index.js b/src/api/index.js
index 1abbc2d..afe7b2c 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -1,38 +1,35 @@
-const signInUser = async (email, password) => {
- try {
- const response = await fetch('https://lmel2.wiremockapi.cloud/json/1', {
- method: 'POST',
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({ email, password })
- });
- const responseJson = await response.json()
- return responseJson
- } catch(e) {
- console.log('error occurred', e)
- return false
- }
-}
+const createUserAccount = async ({ email, password }) => {
+ try {
+ const response = await fetch("https://lmel2.wiremockapi.cloud/json/1", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ email, password }),
+ });
+ const responseJson = await response.json();
+ return responseJson;
+ } catch (e) {
+ console.log("error occurred", e);
+ return false;
+ }
+};
const signUpUser = async ({ email, password }) => {
- try {
- const response = await fetch('https://lmel2.wiremockapi.cloud/json/1', {
- method: 'POST',
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({ email, password })
- });
- const responseJson = await response.json()
- return responseJson
- } catch(e) {
- console.log('error occurred', e)
- return false
- }
-}
+ try {
+ const response = await fetch("https://lmel2.wiremockapi.cloud/json/1", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ email, password }),
+ });
+ const responseJson = await response.json();
+ return responseJson;
+ } catch (e) {
+ console.log("error occurred", e);
+ return false;
+ }
+};
-export {
- signInUser,
- signUpUser
-}
\ No newline at end of file
+export { createUserAccount, signUpUser };
diff --git a/src/components/CustomCheckbox.js b/src/components/CustomCheckbox.js
new file mode 100644
index 0000000..7ef7e7b
--- /dev/null
+++ b/src/components/CustomCheckbox.js
@@ -0,0 +1,22 @@
+import React from 'react';
+import Checkbox from '@mui/material/Checkbox';
+
+const label = { inputProps: { 'aria-label': 'Checkbox label' } };
+
+export default function CustomCheckbox(props) {
+ const onChange = (e) => {
+ props.onChange(props.name, e.target.checked)
+ }
+
+ return (
+
+
+ {props.text}
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/CustomSelect.js b/src/components/CustomSelect.js
new file mode 100644
index 0000000..972cf4f
--- /dev/null
+++ b/src/components/CustomSelect.js
@@ -0,0 +1,31 @@
+import React from 'react'
+import MenuItem from '@mui/material/MenuItem';
+import Select from '@mui/material/Select';
+import h from '../helper/index'
+import { InputLabel } from '@mui/material';
+
+export default function CustomSelect(props) {
+ const onChange = (e) => {
+ props.onChange(props.name, e.target.value)
+ }
+
+ return <>
+ {h.capitalizeFirst(props.name)}
+
+ >
+}
\ No newline at end of file
diff --git a/src/components/CustomTextField.js b/src/components/CustomTextField.js
index 244ea69..1b41b46 100644
--- a/src/components/CustomTextField.js
+++ b/src/components/CustomTextField.js
@@ -15,12 +15,13 @@ export default function CustomTextField(props) {
id={props.name}
name={props.name}
onChange={onChange}
- defaultValue={props.defaultValue || ''}
value={props.value}
label={h.capitalizeFirst(props.name)}
variant="outlined"
error={props.error}
helperText={props.helperText}
+ type={props.type}
+ InputProps={props.inputProps}
/>
);
}
\ No newline at end of file
diff --git a/src/components/Signup.css b/src/components/Signup.css
index c006280..16234fc 100644
--- a/src/components/Signup.css
+++ b/src/components/Signup.css
@@ -1,22 +1,26 @@
.signup-input {
- margin: 10px 0px !important;
+ margin: 10px 0px !important;
}
.dialog {
- display: flex;
- flex-direction: column;
- background-color: white;
- padding: 20px 35px;
- border-radius: 10px;
- width: 240px;
- height: fit-content;
- box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
+ display: flex;
+ flex-direction: column;
+ background-color: white;
+ padding: 20px 35px;
+ border-radius: 10px;
+ width: 240px;
+ height: fit-content;
+ box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
.dialog-header {
- color: #2d842d;
- font-size: 20px;
- font-weight: bold;
- margin-bottom: 15px;
- text-align: center;
-}
\ No newline at end of file
+ color: #2d842d;
+ font-size: 20px;
+ font-weight: bold;
+ margin-bottom: 15px;
+ text-align: center;
+}
+
+.anonymous-input {
+ margin-left: -10px !important;
+}
diff --git a/src/components/Signup.js b/src/components/Signup.js
index 6a577d9..82ce706 100644
--- a/src/components/Signup.js
+++ b/src/components/Signup.js
@@ -1,8 +1,17 @@
import * as React from "react";
-import { signUpUser } from "../api/index";
+import { createUserAccount } from "../api/index";
import "./Signup.css";
import CustomTextField from "./CustomTextField";
-import h from '../helper/index';
+import h from "../helper/index";
+
+import IconButton from "@mui/material/IconButton";
+import InputAdornment from "@mui/material/InputAdornment";
+import Visibility from "@mui/icons-material/Visibility";
+import VisibilityOff from "@mui/icons-material/VisibilityOff";
+import CustomSelect from "./CustomSelect";
+import CustomCheckbox from "./CustomCheckbox";
+import Button from "@mui/material/Button";
+import CircularProgress from "@mui/material/CircularProgress";
const defaultUser = {
username: "",
@@ -20,20 +29,27 @@ const defaultUser = {
const SignUp = (props) => {
const [user, setUser] = React.useState(defaultUser);
const [errors, setErrors] = React.useState(defaultUser);
+ const [showPassword, setShowPassword] = React.useState(false);
+ const [saving, setSaving] = React.useState(null);
+
+ const handleClickShowPassword = () => setShowPassword((show) => !show);
+
+ const handleMouseDownPassword = (e) => e.preventDefault();
- const onChangeOfValue = (key, value) => {
- setUser({ ...user, [key]: value });
+ const onChangeOfValue = (key, value) => setUser({ ...user, [key]: value });
+
+ const createUser = async () => {
+ setSaving(true);
+ const response = await createUserAccount(user);
+ console.log("----", response);
+ setSaving(false);
};
- const onBlur = () => {
- setErrors(h.validator(user))
- }
+ const onBlur = () => setErrors(h.validator(user));
return (
-
- Sign up here!
-
+
Sign up here!
{
error={errors.password.helperText}
helperText={errors.password.helperText}
name="password"
+ type={showPassword ? "text" : "password"}
value={user.password}
onChange={onChangeOfValue}
+ inputProps={{
+ endAdornment: (
+
+
+ {showPassword ? : }
+
+
+ ),
+ }}
/>
-
-
-
+
{
value={user.state}
onChange={onChangeOfValue}
/>
+
+
);
};
diff --git a/src/helper/index.js b/src/helper/index.js
index 7765194..c4db9b1 100644
--- a/src/helper/index.js
+++ b/src/helper/index.js
@@ -2,34 +2,114 @@ const validUsername = (username) => {
return /^(?=.{6,15}$)(?![_.])(?!.*[_.]{2})[a-zA-Z0-9._]+(? {
+ return /^[a-zA-Z ]+$/.test(firstname)
+}
+
+const validLastname = (lastname) => {
+ return validFirstname(lastname)
+}
+
+const validEmail = (email) => {
+ return /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(email)
+}
+
+const validPassword = (password) => {
+ return /^(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]{6,16}$/.test(password)
+}
+
+const validAge = (age) => {
+ const n = Number(age)
+ if(Number.isNaN(n)) {
+ return false
+ } else if(n <=0 || n > 120) {
+ return false
+ }
+ return true;
+}
+
+const validCity = (city) => {
+ return /^[a-zA-Z ]+$/.test(city)
+}
+
const isUsernameValid = (username) => {
if(!username) return true;
return validUsername(username)
}
+const isFirstnameValid = (firstname) => {
+ if(!firstname) return true;
+ return validFirstname(firstname)
+}
+
+const isLastnameValid = (lastname) => {
+ if(!lastname) return true;
+ return validLastname(lastname)
+}
+
+const isValidEmail = (email) => {
+ if(!email) return true;
+ return validEmail(email)
+}
+
+const isValidPassword = (password) => {
+ if(!password) return true;
+ return validPassword(password)
+}
+
+const isValidAge = (age) => {
+ if(!age) return true;
+ return validAge(age)
+}
+
+const isValidCity = (city) => {
+ if(!city) return true;
+ if(city.length > 50) return false;
+ return validCity(city)
+}
+
const capitalizeFirst = (str) => {
if(!str) return '';
return str[0].toUpperCase() + str.slice(1, str.length)
}
const validator = (user) => {
- const errorObj = {
- username: {
- helperText: undefined
- }
- }
+ const errorObj = {}
Object.keys(user).forEach((key) => {
errorObj[key] = {}
errorObj[key].helperText = undefined
})
-
if (!isUsernameValid(user.username)) {
- errorObj.username.helperText = `username is invalid`
+ errorObj.username.helperText = `Username is invalid`
+ }
+
+ if (!isFirstnameValid(user.firstname)) {
+ errorObj.firstname.helperText = `Firstname is invalid`
+ }
+
+ if (!isLastnameValid(user.lastname)) {
+ errorObj.lastname.helperText = `Lastname is invalid`
+ }
+
+ if (!isValidEmail(user.email)) {
+ errorObj.email.helperText = `Email is invalid`
+ }
+
+ if (!isValidPassword(user.password)) {
+ errorObj.password.helperText = 'Password is invalid'
+ }
+
+ if(!isValidAge(user.age)) {
+ errorObj.age.helperText = 'Age is invalid'
+ }
+
+ if(!isValidCity(user.city)) {
+ errorObj.city.helperText = 'City is invalid'
}
- if (!isUsernameValid(user.firstname)) {
- errorObj.firstname.helperText = `firstname is invalid`
+ if(!isValidCity(user.state)) {
+ errorObj.state.helperText = 'State is invalid'
}
return errorObj