feat(web): improve UX error interaction and update dependencies (#313)

* fix: remove react-cookie since we can't delete the user_session cookie using JS (due to httponly being set)

* chore: update dependencies and set a global react dependency override (react-ridge-state creates a problem, this fixes it)

* chore: tidy up APIClient, login and logout pages

* fix: catch canOnboard() error in login.tsx
enhancement: add toast notify on intentional logout and nicely reset the context state; make sure screen-blinking is down to a minimum by having min-h-screen present.

* fix: let onboarding redirect to / instead of /login (/login isn't used anymore)

* fix: use normal <input /> caret cursor for SearchColumnFilter, instead of pointer

* chore(web): remove react-cookie package
This commit is contained in:
stacksmash76 2022-06-16 17:32:07 +02:00 committed by GitHub
parent 0256ea52fd
commit a84a7364e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 220 additions and 144 deletions

View file

@ -1,12 +1,11 @@
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { useNavigate } from "react-router-dom";
import { useMutation } from "react-query";
import { APIClient } from "../../api/APIClient";
import logo from "../../logo.png";
import { APIClient } from "../../api/APIClient";
import { AuthContext } from "../../utils/Context";
import { useEffect } from "react";
import { SubmitHandler, useForm } from "react-hook-form";
import { PasswordInput, TextInput } from "../../components/inputs/text";
export type LoginFormFields = {
@ -15,7 +14,7 @@ export type LoginFormFields = {
};
export const Login = () => {
const { handleSubmit, register, formState: { errors } } = useForm<LoginFormFields>({
const { handleSubmit, register, formState } = useForm<LoginFormFields>({
defaultValues: { username: "", password: "" },
mode: "onBlur"
});
@ -26,8 +25,9 @@ export const Login = () => {
// Check if onboarding is available for this instance
// and redirect if needed
APIClient.auth.canOnboard()
.then(() => navigate("/onboard"));
}, [history]);
.then(() => navigate("/onboard"))
.catch(() => { /*don't log to console PAHLLEEEASSSE*/ });
}, []);
const loginMutation = useMutation(
(data: LoginFormFields) => APIClient.auth.login(data.username, data.password),
@ -42,7 +42,7 @@ export const Login = () => {
}
);
const onSubmit: SubmitHandler<LoginFormFields> = (data: LoginFormFields) => loginMutation.mutate(data);
const onSubmit = (data: LoginFormFields) => loginMutation.mutate(data);
return (
<div className="min-h-screen flex flex-col justify-center py-12 sm:px-6 lg:px-8">
@ -55,7 +55,6 @@ export const Login = () => {
</div>
<div className="sm:mx-auto sm:w-full sm:max-w-md shadow-lg">
<div className="bg-white dark:bg-gray-800 py-8 px-4 sm:rounded-lg sm:px-10">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="space-y-6">
<TextInput<LoginFormFields>
@ -65,7 +64,7 @@ export const Login = () => {
type="text"
register={register}
rules={{ required: "Username is required" }}
errors={errors}
errors={formState.errors}
autoComplete="username"
/>
<PasswordInput<LoginFormFields>
@ -74,7 +73,7 @@ export const Login = () => {
label="password"
register={register}
rules={{ required: "Password is required" }}
errors={errors}
errors={formState.errors}
autoComplete="current-password"
/>
</div>
@ -88,7 +87,6 @@ export const Login = () => {
</button>
</div>
</form>
</div>
</div>
</div>

View file

@ -1,32 +1,27 @@
import { useEffect } from "react";
import { useCookies } from "react-cookie";
import { useNavigate } from "react-router-dom";
import toast from "react-hot-toast";
import { APIClient } from "../../api/APIClient";
import Toast from "../../components/notifications/Toast";
import { AuthContext } from "../../utils/Context";
export const Logout = () => {
const navigate = useNavigate();
const [, setAuthContext] = AuthContext.use();
const [,, removeCookie] = useCookies(["user_session"]);
useEffect(
() => {
APIClient.auth.logout()
.then(() => {
removeCookie("user_session");
setAuthContext({ username: "", isLoggedIn: false });
navigate("/login");
toast.custom((t) => (
<Toast type="success" body="You have been logged out. Goodbye!" t={t} />
));
AuthContext.reset();
});
},
[history, removeCookie, setAuthContext]
[]
);
return (
<div className="min-h-screen bg-gray-50 dark:bg-gray-800 flex flex-col justify-center py-12 sm:px-6 lg:px-8">
<p>Logged out</p>
<div className="min-h-screen flex justify-center items-center">
{/*<h1 className="font-bold text-7xl">Goodbye!</h1>*/}
</div>
);
};

View file

@ -34,7 +34,7 @@ export const Onboarding = () => {
const mutation = useMutation(
(data: InputValues) => APIClient.auth.onboard(data.username, data.password1),
{ onSuccess: () => navigate("/login") }
{ onSuccess: () => navigate("/") }
);
return (

View file

@ -157,7 +157,7 @@ export const SearchColumnFilter = ({
id="filter"
type="text"
autoComplete="off"
className="relative w-full py-2 pl-3 pr-10 text-left bg-white dark:bg-gray-800 rounded-lg shadow-md cursor-default dark:text-gray-400 sm:text-sm border-none"
className="relative w-full py-2 pl-3 pr-10 text-left bg-white dark:bg-gray-800 rounded-lg shadow-md dark:text-gray-400 sm:text-sm border-none"
placeholder="Search releases..."
/>
</div>