diff --git a/README.md b/README.md index a9db435..b2504b2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +//TODO: update this README + # MERN-template A website template using the MERN stack. diff --git a/client/components/app.jsx b/client/components/app.jsx index 7f53509..1b4dfd0 100644 --- a/client/components/app.jsx +++ b/client/components/app.jsx @@ -21,6 +21,8 @@ const App = props => { import('./pages/homepage')} /> + import('./pages/signup')} /> + () => } /> () => } /> diff --git a/client/components/pages/signup.jsx b/client/components/pages/signup.jsx new file mode 100644 index 0000000..b4a369f --- /dev/null +++ b/client/components/pages/signup.jsx @@ -0,0 +1,120 @@ +import React from 'react'; + +//utilities +const validateEmail = require('../../../common/utilities/validate-email.js'); +const validateUsername = require('../../../common/utilities/validate-username.js'); + +const SignUp = props => { + //TODO: redirect if logged in + + //refs + let emailElement, usernameElement, passwordElement, retypeElement, contactElement; + + return ( +
+

Signup

+
{ + //on submit + evt.preventDefault(); + const [redirect, result] = await handleSubmit(emailElement.value, usernameElement.value, passwordElement.value, retypeElement.value, contactElement.checked); + if (result) { + alert(result); + } + + //cleanup & redirect + emailElement.value = usernameElement.value = passwordElement.value = retypeElement.value = ''; //clear input + contactElement.checked = false; + + if (redirect) { + props.history.push('/'); + } + } + }> +
+ + emailElement = e} /> +
+ +
+ + usernameElement = e} /> +
+ +
+ + passwordElement = e} /> +
+ +
+ + retypeElement = e} /> +
+ +
+ + contactElement = e} /> +
+ + +
+
+ ); +}; + +const handleSubmit = async (email, username, password, retype, contact) => { + email = email.trim(); + username = username.trim(); + + const err = handleValidation(email, username, password, retype); + + if (err) { + return err; + } + + //send to the auth server + const result = await fetch(`${process.env.AUTH_URI}/signup`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*' + }, + body: JSON.stringify({ + email, + username, + password, + contact + }) + }); + + if (!result.ok) { + const err = `${result.status}: ${await result.text()}`; + console.error(err); + return [false, err]; + } + + return [true, await result.text()]; +}; + +//returns an error message, or null on success +const handleValidation = (email, username, password, retype) => { + if (!validateEmail(email)) { + return 'invalid email'; + } + + if (!validateUsername(username)) { + return 'invalid username'; + } + + if (password.length < 8) { + return 'invalid password (Must be at least 8 characters long)'; + } + + if (password !== retype) { + return 'passwords do not match'; + } + + return null; +}; + +export default SignUp; \ No newline at end of file