diff --git a/sports-matcher/client/package-lock.json b/sports-matcher/client/package-lock.json
index 3104365..65b29a5 100644
--- a/sports-matcher/client/package-lock.json
+++ b/sports-matcher/client/package-lock.json
@@ -18,6 +18,7 @@
"react-dom": "^17.0.2",
"react-router-dom": "^6.2.2",
"react-scripts": "5.0.0",
+ "validator": "^13.7.0",
"web-vitals": "^2.1.4"
},
"devDependencies": {
@@ -15382,6 +15383,14 @@
"node": ">= 8"
}
},
+ "node_modules/validator": {
+ "version": "13.7.0",
+ "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz",
+ "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -27295,6 +27304,11 @@
}
}
},
+ "validator": {
+ "version": "13.7.0",
+ "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz",
+ "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw=="
+ },
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
diff --git a/sports-matcher/client/package.json b/sports-matcher/client/package.json
index 1e67687..290931b 100644
--- a/sports-matcher/client/package.json
+++ b/sports-matcher/client/package.json
@@ -13,6 +13,7 @@
"react-dom": "^17.0.2",
"react-router-dom": "^6.2.2",
"react-scripts": "5.0.0",
+ "validator": "^13.7.0",
"web-vitals": "^2.1.4"
},
"scripts": {
@@ -43,4 +44,4 @@
"eslint": "^8.12.0",
"eslint-plugin-react": "^7.29.4"
}
-}
\ No newline at end of file
+}
diff --git a/sports-matcher/client/src/pages/SIgnup.js b/sports-matcher/client/src/pages/SIgnup.js
deleted file mode 100644
index c603579..0000000
--- a/sports-matcher/client/src/pages/SIgnup.js
+++ /dev/null
@@ -1,88 +0,0 @@
-import React from "react";
-import { Button, Card, Form } from "react-bootstrap";
-import { apiClient } from "../utils/httpClients";
-import { guard } from "../utils/routing";
-
-export default class Signup extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- user: null,
- alertShow: false,
- alertKey: null,
- alertMsg: null
- }
- this.state.user = {
- email: null,
- firstName: null,
- lastName: null,
- phone: null,
- password: null
- }
- }
-
- async registerUser() {
- const res = await apiClient.post("/user", this.state);
- if (res.status === 200) {
- this.warnUser("You are successfully signed up!", "success")
- } else if (res === 409) {
- this.warnUser("This user already exists. Try logging in instead.", "danger")
- } else if (res === 400) {
- this.warnUser("Missing required fields.", "danger")
- } else {
- this.warnUser("Internal server error. Please try again later.", "danger")
- }
- }
-
- setUserState(event) {
- newUser = this.state.user;
- newUser[event.target.controlId] = event.target.value
- this.setState({user: newUser})
- }
-
- warnUser(msg, key) {
- this.setState({alertMsg: msg})
- this.setState({show: true})
- }
-
- render() {
- return (
-
-
- {this.state.alertMsg}
-
-
-
- Login
- Welcome to Sports Matcher!
-
- First name
-
-
-
- Last name
-
-
-
- E-mail
-
-
-
- Phone number
-
-
-
- Password
-
-
-
-
-
-
-
- );
- }
-}
diff --git a/sports-matcher/client/src/pages/Signup.js b/sports-matcher/client/src/pages/Signup.js
new file mode 100644
index 0000000..6ea309f
--- /dev/null
+++ b/sports-matcher/client/src/pages/Signup.js
@@ -0,0 +1,140 @@
+import React from "react";
+import { Alert, Button, Card, Container, Form } from "react-bootstrap";
+import { Link } from "react-router-dom";
+import validator from "validator";
+import { apiClient } from "../utils/httpClients";
+
+export default class Signup extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ user: {
+ email: null,
+ firstName: null,
+ lastName: null,
+ phone: null,
+ password: null
+ },
+ alert: {
+ show: false,
+ variant: null,
+ headerMsg: null,
+ content: null
+ }
+ };
+
+ this.registerUser = this.registerUser.bind(this);
+ this.setUserState = this.setUserState.bind(this);
+ }
+
+
+ async registerUser(event) {
+ event.preventDefault(); // We need this so that the page doesn't refresh.
+ let formIssues = this.validateCurrentForm();
+ if (formIssues.length > 0) {
+ this.notifyUser("Oops there were issue(s)", (
+
+ {formIssues.map((issue) => {
+ return (
+ - {issue}
+ );
+ })}
+
+ ), "danger");
+ return;
+ }
+
+ const res = await apiClient.post("/user", this.state.user);
+ console.log(res.data);
+ if (res.status === 201) {
+ this.notifyUser("Success!", You are successfully signed up! You can now go log in.
, "success");
+ } else if (res.status === 409) {
+ this.notifyUser("User exists!", This user already exists. Try logging in instead.
, "danger");
+ } else if (res.status === 400) {
+ this.notifyUser("There were errors in the submitted info.", Double check to see if everything is inputted is valid.
, "danger");
+ } else {
+ this.notifyUser("Error", Internal server error. Please try again later.
, "danger");
+ }
+ }
+
+ validateCurrentForm() {
+ console.log(this.state);
+ let formIssues = [];
+ if (!validator.isEmail(this.state.user.email)) {
+ formIssues.push("The email submitted is invalid.");
+ }
+
+ if (this.state.user.password.length < 8) {
+ formIssues.push("The password submitted must have a minimum length of 8 characters.");
+ }
+
+ return formIssues;
+ }
+
+ setUserState(event) {
+ this.setState((state) => {
+ state.user[event.target.id] = event.target.value;
+ return state;
+ });
+ }
+
+ notifyUser(headerMsg, content, key) {
+ this.setState((state) => {
+ state.alert.show = true;
+ state.alert.headerMsg = headerMsg;
+ state.alert.content = content;
+ state.alert.key = key;
+ return state;
+ });
+ }
+
+ componentDidMount() {
+ if (this.context.user) {
+ this.context.navigate("/dashboard");
+ }
+ }
+
+ render() {
+ return (
+
+
+ this.setState((state) => { state.alert.show = false; return state; })} dismissible>
+ {this.state.alert.headerMsg}
+ {this.state.alert.content}
+
+
+
+ Login
+ Welcome to Sports Matcher!
+
+ First name
+
+
+
+ Last name
+
+
+
+ E-mail
+
+
+
+ Phone number
+
+
+
+ Password
+
+
+
+
+
+
+
+
+ );
+ }
+}