Browse Source

Improved CustomErrors.

KrisVos130 7 years ago
parent
commit
0895ba26a5

+ 38 - 3
frontend/app/js/views/Auth/CustomErrors.jsx

@@ -3,15 +3,50 @@ import PropTypes from "prop-types";
 
 export default class CustomErrors extends Component {
 	static propTypes = {
-		errors: PropTypes.array,
+		onRef: PropTypes.func,
 	};
 
 	static defaultProps = {
-		errors: [],
+		onRef: () => {},
+	};
+
+	constructor() {
+		super();
+
+		this.state = {
+			errors: [],
+		};
+	}
+
+	componentDidMount() {
+		this.props.onRef(this);
+	}
+
+	componentWillUnmount() {
+		this.props.onRef(null);
+	}
+
+	clearErrors = () => {
+		this.setState({
+			errors: [],
+		});
+	};
+
+	addError = (error) => {
+		// TODO add error parsing, e.g. for arrays/objects
+		this.setState({
+			errors: this.state.errors.concat([error]),
+		});
+	};
+
+	clearAddError = (error) => {
+		this.setState({
+			errors: [error],
+		});
 	};
 
 	listErrors = () => {
-		let errors = this.props.errors;
+		let errors = this.state.errors;
 		let key = 0;
 		if (errors.length > 0) {
 			errors = errors.map((error) => {

+ 11 - 18
frontend/app/js/views/Auth/ForgotPassword.jsx

@@ -39,7 +39,6 @@ export default class Settings extends Component {
 				newPassword: true,
 				newPasswordAgain: true,
 			},
-			errors: [],
 		};
 	}
 
@@ -74,9 +73,9 @@ export default class Settings extends Component {
 
 	requestResetCode = () => {
 		if (CustomInput.hasInvalidInput(this.state.inputInvalid, ["email"])) {
-			alert("Input invalid. Fix before continuing.");
+			this.errors.clearAddError("Some fields are incorrect. Please fix them before continuing.");
 		} else {
-			this.setState({ errors: [] });
+			this.errors.clearErrors();
 			io.getSocket(socket => {
 				socket.emit("users.requestPasswordReset", this.state.email, res => {
 					if (res.status === "success") {
@@ -85,9 +84,7 @@ export default class Settings extends Component {
 							step: 2,
 						});
 					} else {
-						this.setState({
-							errors: this.state.errors.concat([res.message]),
-						});
+						this.errors.addError(res.message);
 					}
 				});
 			});
@@ -96,9 +93,9 @@ export default class Settings extends Component {
 
 	verifyResetCode = () => {
 		if (CustomInput.hasInvalidInput(this.state.inputInvalid, ["resetCode"])) {
-			alert("Input invalid. Fix before continuing.");
+			this.errors.clearAddError("Some fields are incorrect. Please fix them before continuing.");
 		} else {
-			this.setState({ errors: [] });
+			this.errors.clearErrors();
 			io.getSocket(socket => {
 				socket.emit("users.verifyPasswordResetCode", this.state.resetCode, res => {
 					if (res.status === "success") {
@@ -107,9 +104,7 @@ export default class Settings extends Component {
 							step: 3,
 						});
 					} else {
-						this.setState({
-							errors: this.state.errors.concat([res.message]),
-						});
+						this.errors.addError(res.message);
 					}
 				});
 			});
@@ -118,20 +113,18 @@ export default class Settings extends Component {
 
 	changePassword = () => {
 		if (CustomInput.hasInvalidInput(this.state.inputInvalid, ["newPassword", "newPasswordAgain"])) {
-			alert("Input invalid. Fix before continuing.");
+			this.errors.clearAddError("Some fields are incorrect. Please fix them before continuing.");
 		} else if (this.state.newPassword !== this.state.newPasswordAgain) {
-			alert("Passwords need to be the same.");
+			this.errors.clearAddError("New password and new password again need to be the same.");
 		} else {
-			this.setState({ errors: [] });
+			this.errors.clearErrors();
 			io.getSocket(socket => {
 				socket.emit("users.changePasswordWithResetCode", this.state.resetCode, this.state.newPassword, res => {
 					if (res.status === "success") {
 						alert("Success!");
 						location.href = "/login";
 					} else {
-						this.setState({
-							errors: this.state.errors.concat([res.message]),
-						});
+						this.errors.addError(res.message);
 					}
 				});
 			});
@@ -161,7 +154,7 @@ export default class Settings extends Component {
 					<span className="step-line-2" />
 					<span className={ `step-circle-3 ${ this.state.step === 3 ? "step-circle-active" : "" }` }>3</span>
 				</div>
-				<CustomErrors errors={ this.state.errors } />
+				<CustomErrors onRef={ ref => (this.errors = ref) } />
 				{ this.getActions() }
 			</div>
 		);

+ 4 - 5
frontend/app/js/views/Auth/Login.jsx

@@ -13,7 +13,6 @@ export default class Login extends Component {
 		this.state = {
 			password: "",
 			email: "",
-			errors: [],
 			inputInvalid: {
 				email: true,
 				password: true,
@@ -31,9 +30,9 @@ export default class Login extends Component {
 
 	login() {
 		if (CustomInput.hasInvalidInput(this.state.inputInvalid)) {
-			alert("Input invalid. Fix before continuing.");
+			this.errors.clearAddError("Some fields are incorrect. Please fix them before continuing.");
 		} else {
-			this.setState({ errors: [] });
+			this.errors.clearErrors();
 			io.getSocket(socket => {
 				socket.emit("users.login", this.state.email, this.state.password, res => {
 					if (res.status === "success") {
@@ -45,7 +44,7 @@ export default class Login extends Component {
 						document.cookie = `SID=${ res.SID }; expires=${ date.toGMTString() }; ${ domain }${ secure }path=/`;
 						location.reload(); // if we could avoid this, then that would be better
 					} else {
-						this.setState({ errors: [res.message] });
+						this.errors.addError(res.message);
 					}
 				});
 			});
@@ -61,7 +60,7 @@ export default class Login extends Component {
 	render() {
 		return (
 			<div>
-				<CustomErrors errors={ this.state.errors } />
+				<CustomErrors onRef={ ref => (this.errors = ref) } />
 				<CustomInput label="Email" placeholder="Email" inputType="email" type="email" name="email" value={ this.state.email } customInputEvents={ { onChange: event => this.updateField("email", event) } } validationCallback={ this.validationCallback } />
 				<CustomInput label="Password" placeholder="Password" inputType="password" type="password" name="password" value={ this.state.password } customInputEvents={ { onChange: event => this.updateField("password", event) } } validationCallback={ this.validationCallback } />
 				<p>By logging in/registering you agree to our <a href="/terms">Terms of Service</a> and <a href="/privacy">Privacy Policy</a>.</p>

+ 4 - 5
frontend/app/js/views/Auth/Register.jsx

@@ -20,7 +20,6 @@ export default class Register extends Component {
 				username: true,
 				password: true,
 			},
-			errors: [],
 		};
 
 		this.register = this.register.bind(this);
@@ -40,9 +39,9 @@ export default class Register extends Component {
 
 	register() {
 		if (CustomInput.hasInvalidInput(this.state.inputInvalid)) {
-			alert("Input invalid. Fix before continuing.");
+			this.errors.clearAddError("Some fields are incorrect. Please fix them before continuing.");
 		} else {
-			this.setState({ errors: [] });
+			this.errors.clearErrors();
 			io.getSocket(socket => {
 				socket.emit("users.register", this.state.username, this.state.email, this.state.password, grecaptcha.getResponse(this.state.recaptcha), res => {
 					if (res.status === "success") {
@@ -56,7 +55,7 @@ export default class Register extends Component {
 							// redirect to login
 						}
 					} else {
-						this.setState({ errors: [res.message] });
+						this.errors.addError(res.message);
 					}
 				});
 			});
@@ -72,7 +71,7 @@ export default class Register extends Component {
 	render() {
 		return (
 			<div>
-				<CustomErrors errors={ this.state.errors } />
+				<CustomErrors onRef={ ref => (this.errors = ref) } />
 				<CustomInput label="Email" placeholder="Email" inputType="email" type="email" name="email" value={ this.state.email } customInputEvents={ { onChange: event => this.updateField("email", event) } } validationCallback={ this.validationCallback } />
 				<CustomInput label="Username" placeholder="Username" inputType="text" type="username" name="username" value={ this.state.username } customInputEvents={ { onChange: event => this.updateField("username", event) } } validationCallback={ this.validationCallback } />
 				<CustomInput label="Password" placeholder="Password" inputType="password" type="password" name="password" value={ this.state.password } customInputEvents={ { onChange: event => this.updateField("password", event) } } validationCallback={ this.validationCallback } />

+ 17 - 30
frontend/app/js/views/Auth/Settings.jsx

@@ -40,7 +40,6 @@ export default class Settings extends Component {
 				username: true,
 				newPassword: true,
 			},
-			errors: [],
 			savedValue: {
 				email: "",
 				username: "",
@@ -66,7 +65,7 @@ export default class Settings extends Component {
 						this.customInputs.username.triggerChangeEvent(true);
 					});
 				} else {
-					this.state.errors = ["You are currently not logged in."];
+					this.errors.addError("You are currently not logged in.");
 				}
 			});
 
@@ -124,11 +123,11 @@ export default class Settings extends Component {
 
 	saveChanges = () => {
 		if (CustomInput.hasInvalidInput(this.state.inputInvalid, ["username", "email"])) {
-			alert("Input invalid. Fix before continuing.");
+			this.errors.clearAddError("Some fields are incorrect. Please fix them before continuing.");
 		} else if (this.isTheSame("username") && this.isTheSame("email")) {
-			alert("Nothing has changed.");
+			this.errors.clearAddError("Username or email hasn't changed.");
 		} else {
-			this.setState({ errors: [] });
+			this.errors.clearErrors();
 			const email = this.state.email;
 			const username = this.state.username;
 			io.getSocket(socket => {
@@ -137,9 +136,7 @@ export default class Settings extends Component {
 						if (res.status === "success") {
 							alert("Success!");
 						} else {
-							this.setState({
-								errors: this.state.errors.concat([res.message]),
-							});
+							this.errors.addError(res.message);
 						}
 					});
 				}
@@ -149,9 +146,7 @@ export default class Settings extends Component {
 						if (res.status === "success") {
 							alert("Success!");
 						} else {
-							this.setState({
-								errors: this.state.errors.concat([res.message]),
-							});
+							this.errors.addError(res.message);
 						}
 					});
 				}
@@ -161,20 +156,18 @@ export default class Settings extends Component {
 
 	changePassword = () => {
 		if (CustomInput.hasInvalidInput(this.state.inputInvalid, ["newPassword"])) {
-			alert("Input invalid. Fix before continuing.");
+			this.errors.clearAddError("Some fields are incorrect. Please fix them before continuing.");
 		} else if (!this.state.passwordLinked) {
-			alert("You don't have a password yet");
+			this.errors.clearAddError("You don't have a password set.");
 		} else {
-			this.setState({ errors: [] });
+			this.errors.clearErrors();
 			const newPassword = this.state.newPassword;
 			io.getSocket(socket => {
 				socket.emit("users.updatePassword", newPassword, res => {
 					if (res.status === "success") {
 						alert("Success!");
 					} else {
-						this.setState({
-							errors: this.state.errors.concat([res.message]),
-						});
+						this.errors.addError(res.message);
 					}
 				});
 			});
@@ -182,45 +175,39 @@ export default class Settings extends Component {
 	};
 
 	logOutEverywhere = () => {
-		this.setState({ errors: [] });
+		this.errors.clearErrors();
 		io.getSocket(socket => {
 			socket.emit("users.removeSessions", this.props.user.userId, res => {
 				if (res.status === "success") {
 					alert("Success!");
 				} else {
-					this.setState({
-						errors: this.state.errors.concat([res.message]),
-					});
+					this.errors.addError(res.message);
 				}
 			});
 		});
 	};
 
 	unlinkGitHub = () => {
-		this.setState({ errors: [] });
+		this.errors.clearErrors();
 		io.getSocket(socket => {
 			socket.emit("users.unlinkGitHub", res => {
 				if (res.status === "success") {
 					alert("Success!");
 				} else {
-					this.setState({
-						errors: this.state.errors.concat([res.message]),
-					});
+					this.errors.addError(res.message);
 				}
 			});
 		});
 	};
 
 	unlinkPassword = () => {
-		this.setState({ errors: [] });
+		this.errors.clearErrors();
 		io.getSocket(socket => {
 			socket.emit("users.unlinkPassword", res => {
 				if (res.status === "success") {
 					alert("Success!");
 				} else {
-					this.setState({
-						errors: this.state.errors.concat([res.message]),
-					});
+					this.errors.addError(res.message);
 				}
 			});
 		});
@@ -247,7 +234,7 @@ export default class Settings extends Component {
 	render() {
 		return (
 			<div>
-				<CustomErrors errors={ this.state.errors } />
+				<CustomErrors onRef={ ref => (this.errors = ref) } />
 				<div>
 					<h2>General</h2>
 					<CustomInput label="Email" placeholder="Email" inputType="email" type="email" name="email" value={ this.state.email } customInputEvents={ { onChange: event => this.updateField("email", event) } } validationCallback={ this.validationCallback } onRef={ ref => (this.customInputs.email = ref) } />