fix(dashboard-v2): address review comments

This commit is contained in:
Michał Leszczyk 2022-03-24 15:47:35 +01:00
parent dda507fd5f
commit 731b1b6d52
No known key found for this signature in database
GPG Key ID: FA123CA8BAA2FBF4
4 changed files with 71 additions and 63 deletions

View File

@ -11,7 +11,7 @@ This is a Gatsby application. To run it locally, all you need is:
## Accessing remote APIs ## Accessing remote APIs
To be able to log in on a local environment with your production credentials, you'll need to make the browser believe you're actually on the same domain, otherwise browser will block the session cookie. To be able to log in on a local environment with your production credentials, you'll need to make the browser believe you're actually on the same domain, otherwise the browser will block the session cookie.
To do the trick, edit your `/etc/hosts` file and add a record like this: To do the trick, edit your `/etc/hosts` file and add a record like this:
@ -19,7 +19,7 @@ To do the trick, edit your `/etc/hosts` file and add a record like this:
127.0.0.1 local.skynetpro.net 127.0.0.1 local.skynetpro.net
``` ```
then run `yarn secure` -- it will run `gatsby develop` with `--https --host=local.skynetpro.net -p=443` options. then run `yarn develop:secure` -- it will run `gatsby develop` with `--https --host=local.skynetpro.net -p=443` options.
If you're on macOS, you may need to `sudo` the command to successfully bind to port `443`. If you're on macOS, you may need to `sudo` the command to successfully bind to port `443`.
> **NOTE:** This should become easier once we have a docker image for the new dashboard. > **NOTE:** This should become easier once we have a docker image for the new dashboard.

View File

@ -9,8 +9,8 @@
], ],
"scripts": { "scripts": {
"develop": "gatsby develop", "develop": "gatsby develop",
"develop:secure": "gatsby develop --https --host=local.skynetpro.net -p=443",
"start": "gatsby develop", "start": "gatsby develop",
"secure": "gatsby develop --https --host=local.skynetpro.net -p=443",
"build": "gatsby build", "build": "gatsby build",
"serve": "gatsby serve", "serve": "gatsby serve",
"clean": "gatsby clean", "clean": "gatsby clean",

View File

@ -81,6 +81,7 @@ export const NavBar = () => (
onClick={async () => { onClick={async () => {
await accountsService.post("logout"); await accountsService.post("logout");
navigate("/auth/login"); navigate("/auth/login");
// TODO: handle errors
}} }}
activeClassName="text-primary" activeClassName="text-primary"
className="cursor-pointer" className="cursor-pointer"

View File

@ -1,3 +1,4 @@
import { useState } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { Formik, Form } from "formik"; import { Formik, Form } from "formik";
import { Link } from "gatsby"; import { Link } from "gatsby";
@ -16,72 +17,78 @@ const loginSchema = Yup.object().shape({
const INVALID_CREDENTIALS_ERRORS = ["password mismatch", "user not found"]; const INVALID_CREDENTIALS_ERRORS = ["password mismatch", "user not found"];
export const LoginForm = ({ onSuccess }) => ( export const LoginForm = ({ onSuccess }) => {
<Formik const [error, setError] = useState(null);
initialValues={{
email: "",
password: "",
}}
validationSchema={loginSchema}
onSubmit={async (values, { setErrors }) => {
try {
await accountsService.post("login", {
json: values,
});
onSuccess(); return (
} catch (err) { <Formik
if (err.response) { initialValues={{
const data = await err.response.json(); email: "",
password: "",
}}
validationSchema={loginSchema}
onSubmit={async (values) => {
try {
await accountsService.post("login", {
json: values,
});
if (INVALID_CREDENTIALS_ERRORS.includes(data.message)) { onSuccess();
setErrors({ } catch (err) {
email: "Invalid e-mail address or password", if (err.response) {
password: "Invalid e-mail address or password", const data = await err.response.json();
});
if (INVALID_CREDENTIALS_ERRORS.includes(data.message)) {
setError("Invalid email address or password.");
} else {
setError(data.message);
}
} else {
setError("An error occured when logging you in. Please try again.");
} }
} }
} }}
}} >
> {({ errors, touched }) => (
{({ errors, touched }) => ( <Form className="flex flex-col gap-4">
<Form className="flex flex-col gap-4"> <h3 className="mt-4 mb-4">Log in to your account</h3>
<h3 className="mt-4 mb-8">Log in to your account</h3> {error && <p className="px-4 py-3 rounded border border-error bg-red-50 text-error mb-4">{error}</p>}
<TextField <TextField
type="text" type="text"
id="email" id="email"
name="email" name="email"
label="Email address" label="Email address"
error={errors.email} error={errors.email}
touched={touched.email} touched={touched.email}
/> />
<TextField <TextField
type="password" type="password"
id="password" id="password"
name="password" name="password"
label="Password" label="Password"
error={errors.password} error={errors.password}
touched={touched.password} touched={touched.password}
/> />
<div> <div>
<Link to="/auth/recover" className="text-sm inline transition-colors hover:text-primary"> <Link to="/auth/recover" className="text-sm inline transition-colors hover:text-primary">
Forgot your password? Forgot your password?
</Link> </Link>
</div> </div>
<div className="flex w-full justify-center mt-4"> <div className="flex w-full justify-center mt-4">
<Button type="submit" className="px-12" $primary> <Button type="submit" className="px-12" $primary>
Log in Log in
</Button> </Button>
</div> </div>
<p className="text-sm text-center mt-8"> <p className="text-sm text-center mt-8">
Don't have an account? <HighlightedLink to="/auth/signup">Sign up</HighlightedLink> Don't have an account? <HighlightedLink to="/auth/signup">Sign up</HighlightedLink>
</p> </p>
</Form> </Form>
)} )}
</Formik> </Formik>
); );
};
LoginForm.propTypes = { LoginForm.propTypes = {
onSuccess: PropTypes.func.isRequired, onSuccess: PropTypes.func.isRequired,