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

@ -3,22 +3,24 @@
"version": "0.2.0",
"private": true,
"homepage": ".",
"overrides": {
"react": "$react"
},
"dependencies": {
"@fontsource/inter": "^4.5.10",
"@headlessui/react": "^1.6.3",
"@fontsource/inter": "^4.5.11",
"@headlessui/react": "^1.6.4",
"@heroicons/react": "^1.0.6",
"@hookform/error-message": "^2.0.0",
"date-fns": "^2.28.0",
"formik": "^2.2.9",
"react": "^18.1.0",
"react-cookie": "^4.1.1",
"react-debounce-input": "^3.2.5",
"react-dom": "^18.1.0",
"react": "^18.2.0",
"react-debounce-input": "^3.3.0",
"react-dom": "^18.2.0",
"react-error-boundary": "^3.1.4",
"react-hook-form": "^7.31.3",
"react-hook-form": "^7.32.1",
"react-hot-toast": "^2.2.0",
"react-multi-select-component": "^4.2.7",
"react-query": "^3.39.0",
"react-multi-select-component": "^4.2.9",
"react-query": "^3.39.1",
"react-ridge-state": "4.2.2",
"react-router-dom": "^6.3.0",
"react-scripts": "^5.0.1",
@ -47,22 +49,22 @@
},
"devDependencies": {
"@tailwindcss/forms": "^0.5.2",
"@types/node": "^17.0.35",
"@types/react": "^18.0.9",
"@types/node": "^18.0.0",
"@types/react": "^18.0.12",
"@types/react-dom": "^18.0.5",
"@types/react-router-dom": "^5.1.7",
"@types/react-table": "^7.7.12",
"@typescript-eslint/eslint-plugin": "^5.26.0",
"@typescript-eslint/parser": "^5.26.0",
"@typescript-eslint/eslint-plugin": "^5.28.0",
"@typescript-eslint/parser": "^5.28.0",
"autoprefixer": "^10.4.7",
"eslint": "^8.16.0",
"eslint": "^8.17.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-react": "^7.30.0",
"eslint-plugin-react-hooks": "^4.5.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-watch": "^8.0.0",
"http-proxy-middleware": "^2.0.6",
"postcss": "^8.4.14",
"tailwindcss": "^3.0.24",
"typescript": "^4.7.2"
"tailwindcss": "^3.1.3",
"typescript": "^4.7.3"
}
}

View file

@ -1,13 +1,12 @@
import { baseUrl, sseBaseUrl } from "../utils";
import { AuthContext } from "../utils/Context";
import { Cookies } from "react-cookie";
interface ConfigType {
body?: BodyInit | Record<string, unknown> | unknown | null;
body?: BodyInit | Record<string, unknown> | unknown;
headers?: Record<string, string>;
}
type PostBody = BodyInit | Record<string, unknown> | unknown | null;
type PostBody = BodyInit | Record<string, unknown> | unknown;
export async function HttpClient<T>(
endpoint: string,
@ -16,7 +15,7 @@ export async function HttpClient<T>(
): Promise<T> {
const config = {
method: method,
body: body ? JSON.stringify(body) : null,
body: body ? JSON.stringify(body) : undefined,
headers: {
"Content-Type": "application/json"
},
@ -24,44 +23,34 @@ export async function HttpClient<T>(
...customConfig
} as RequestInit;
return window.fetch(`${baseUrl()}${endpoint}`, config)
.then(async response => {
if (response.status === 401) {
if (!response.ok) {
// if 401 consider the session expired and force logout
const cookies = new Cookies();
cookies.remove("user_session");
if (response.status === 401) {
// Remove auth info from localStorage
AuthContext.reset();
return Promise.reject(new Error(response.statusText));
// Show an error toast to notify the user what occurred
return Promise.reject(new Error("Unauthorized."));
}
if ([403, 404].includes(response.status))
return Promise.reject(new Error(response.statusText));
return Promise.reject(new Error(await response.text()));
}
// 201 comes from a POST and can contain data
if ([201].includes(response.status))
return await response.json();
// 204 ok no data
if ([204].includes(response.status))
// Resolve immediately since 204 contains no data
if (response.status === 204)
return Promise.resolve(response);
if (response.ok) {
return await response.json();
} else {
const errorMessage = await response.text();
return Promise.reject(new Error(errorMessage));
}
});
}
const appClient = {
Get: <T>(endpoint: string) => HttpClient<T>(endpoint, "GET"),
Post: <T>(endpoint: string, data: PostBody) => HttpClient<void | T>(endpoint, "POST", { body: data }),
PostBody: <T>(endpoint: string, data: PostBody) => HttpClient<T>(endpoint, "POST", { body: data }),
Post: <T = void>(endpoint: string, data: PostBody = undefined) => HttpClient<T>(endpoint, "POST", { body: data }),
Put: (endpoint: string, data: PostBody) => HttpClient<void>(endpoint, "PUT", { body: data }),
Patch: (endpoint: string, data: PostBody) => HttpClient<void>(endpoint, "PATCH", { body: data }),
Patch: (endpoint: string, data: PostBody = undefined) => HttpClient<void>(endpoint, "PATCH", { body: data }),
Delete: (endpoint: string) => HttpClient<void>(endpoint, "DELETE")
};
@ -71,7 +60,7 @@ export const APIClient = {
username: username,
password: password
}),
logout: () => appClient.Post("api/auth/logout", null),
logout: () => appClient.Post("api/auth/logout"),
validate: () => appClient.Get<void>("api/auth/validate"),
onboard: (username: string, password: string) => appClient.Post("api/auth/onboard", {
username: username,
@ -83,7 +72,7 @@ export const APIClient = {
create: (action: Action) => appClient.Post("api/actions", action),
update: (action: Action) => appClient.Put(`api/actions/${action.id}`, action),
delete: (id: number) => appClient.Delete(`api/actions/${id}`),
toggleEnable: (id: number) => appClient.Patch(`api/actions/${id}/toggleEnabled`, null)
toggleEnable: (id: number) => appClient.Patch(`api/actions/${id}/toggleEnabled`)
},
config: {
get: () => appClient.Get<Config>("api/config")
@ -118,7 +107,7 @@ export const APIClient = {
getAll: () => appClient.Get<IndexerDefinition[]>("api/indexer"),
// returns all possible indexer definitions
getSchema: () => appClient.Get<IndexerDefinition[]>("api/indexer/schema"),
create: (indexer: Indexer) => appClient.PostBody<Indexer>("api/indexer", indexer),
create: (indexer: Indexer) => appClient.Post<Indexer>("api/indexer", indexer),
update: (indexer: Indexer) => appClient.Put("api/indexer", indexer),
delete: (id: number) => appClient.Delete(`api/indexer/${id}`)
},

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>

View file

@ -1266,12 +1266,12 @@
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
"@fontsource/inter@^4.5.10":
"@fontsource/inter@^4.5.11":
version "4.5.11"
resolved "https://registry.yarnpkg.com/@fontsource/inter/-/inter-4.5.11.tgz#3c45014821e8c82b247a291f1944dd2764a2d1ed"
integrity sha512-toizzQkfXL8YJcG/f8j3EYXYGQe4OxiDEItThSigvHU+cYNDw8HPp3wLYQX745hddsnHqOGCM4exitFSBOU8+w==
"@headlessui/react@^1.6.3":
"@headlessui/react@^1.6.4":
version "1.6.4"
resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.6.4.tgz#c73084e23386bef5fb86cd16da3352c3a844bb4c"
integrity sha512-0yqz1scwbFtwljmbbKjXsSGl5ABEYNICVHZnMCWo0UtOZodo2Tpu94uOVgCRjRZ77l2WcTi2S0uidINDvG7lsA==
@ -1869,11 +1869,6 @@
dependencies:
"@types/node" "*"
"@types/cookie@^0.3.3":
version "0.3.3"
resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.3.3.tgz#85bc74ba782fb7aa3a514d11767832b0e3bc6803"
integrity sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==
"@types/eslint-scope@^3.7.3":
version "3.7.3"
resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224"
@ -1939,14 +1934,6 @@
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64"
integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==
"@types/hoist-non-react-statics@^3.0.1":
version "3.3.1"
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
dependencies:
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
"@types/html-minifier-terser@^6.0.0":
version "6.1.0"
resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35"
@ -1993,11 +1980,16 @@
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a"
integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==
"@types/node@*", "@types/node@^17.0.35":
"@types/node@*":
version "17.0.41"
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.41.tgz#1607b2fd3da014ae5d4d1b31bc792a39348dfb9b"
integrity sha512-xA6drNNeqb5YyV5fO3OAEsnXLfO7uF0whiOfPTz5AeDo8KeZFmODKnvwPymMNO8qE/an8pVY/O50tig2SQCrGw==
"@types/node@^18.0.0":
version "18.0.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.0.tgz#67c7b724e1bcdd7a8821ce0d5ee184d3b4dd525a"
integrity sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==
"@types/parse-json@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
@ -2066,7 +2058,7 @@
dependencies:
"@types/react" "*"
"@types/react@*", "@types/react@^18.0.9":
"@types/react@*":
version "18.0.12"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.12.tgz#cdaa209d0a542b3fcf69cf31a03976ec4cdd8840"
integrity sha512-duF1OTASSBQtcigUvhuiTB1Ya3OvSy+xORCiEf20H0P0lzx+/KeVsA99U5UjLXSbyo1DRJDlLKqTeM1ngosqtg==
@ -2075,6 +2067,15 @@
"@types/scheduler" "*"
csstype "^3.0.2"
"@types/react@^18.0.12":
version "18.0.13"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.13.tgz#0f5bd24a5f26593e04e450fe85ff43f51c1524ff"
integrity sha512-psqptIYQxGUFuGYwP3KCFVtPTkMpIcrqFmtKblWEUQhLuYLpHBwJkXhjp6eHfDM5IbyskY4x7qQpLedEsPkHlA==
dependencies:
"@types/prop-types" "*"
"@types/scheduler" "*"
csstype "^3.0.2"
"@types/resolve@1.17.1":
version "1.17.1"
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6"
@ -2150,7 +2151,22 @@
dependencies:
"@types/yargs-parser" "*"
"@typescript-eslint/eslint-plugin@^5.26.0", "@typescript-eslint/eslint-plugin@^5.5.0":
"@typescript-eslint/eslint-plugin@^5.28.0":
version "5.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.28.0.tgz#6204ac33bdd05ab27c7f77960f1023951115d403"
integrity sha512-DXVU6Cg29H2M6EybqSg2A+x8DgO9TCUBRp4QEXQHJceLS7ogVDP0g3Lkg/SZCqcvkAP/RruuQqK0gdlkgmhSUA==
dependencies:
"@typescript-eslint/scope-manager" "5.28.0"
"@typescript-eslint/type-utils" "5.28.0"
"@typescript-eslint/utils" "5.28.0"
debug "^4.3.4"
functional-red-black-tree "^1.0.1"
ignore "^5.2.0"
regexpp "^3.2.0"
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/eslint-plugin@^5.5.0":
version "5.27.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.27.1.tgz#fdf59c905354139046b41b3ed95d1609913d0758"
integrity sha512-6dM5NKT57ZduNnJfpY81Phe9nc9wolnMCnknb1im6brWi1RYv84nbMS3olJa27B6+irUVV1X/Wb+Am0FjJdGFw==
@ -2172,7 +2188,17 @@
dependencies:
"@typescript-eslint/utils" "5.27.1"
"@typescript-eslint/parser@^5.26.0", "@typescript-eslint/parser@^5.5.0":
"@typescript-eslint/parser@^5.28.0":
version "5.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.28.0.tgz#639b101cad2bfb7ae16e69710ac95c42bd4eae33"
integrity sha512-ekqoNRNK1lAcKhZESN/PdpVsWbP9jtiNqzFWkp/yAUdZvJalw2heCYuqRmM5eUJSIYEkgq5sGOjq+ZqsLMjtRA==
dependencies:
"@typescript-eslint/scope-manager" "5.28.0"
"@typescript-eslint/types" "5.28.0"
"@typescript-eslint/typescript-estree" "5.28.0"
debug "^4.3.4"
"@typescript-eslint/parser@^5.5.0":
version "5.27.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.27.1.tgz#3a4dcaa67e45e0427b6ca7bb7165122c8b569639"
integrity sha512-7Va2ZOkHi5NP+AZwb5ReLgNF6nWLGTeUJfxdkVUAPPSaAdbWNnFZzLZ4EGGmmiCTg+AwlbE1KyUYTBglosSLHQ==
@ -2190,6 +2216,14 @@
"@typescript-eslint/types" "5.27.1"
"@typescript-eslint/visitor-keys" "5.27.1"
"@typescript-eslint/scope-manager@5.28.0":
version "5.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.28.0.tgz#ef9a5c68fecde72fd2ff8a84b9c120324826c1b9"
integrity sha512-LeBLTqF/he1Z+boRhSqnso6YrzcKMTQ8bO/YKEe+6+O/JGof9M0g3IJlIsqfrK/6K03MlFIlycbf1uQR1IjE+w==
dependencies:
"@typescript-eslint/types" "5.28.0"
"@typescript-eslint/visitor-keys" "5.28.0"
"@typescript-eslint/type-utils@5.27.1":
version "5.27.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.27.1.tgz#369f695199f74c1876e395ebea202582eb1d4166"
@ -2199,11 +2233,25 @@
debug "^4.3.4"
tsutils "^3.21.0"
"@typescript-eslint/type-utils@5.28.0":
version "5.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.28.0.tgz#53ccc78fdcf0205ef544d843b84104c0e9c7ca8e"
integrity sha512-SyKjKh4CXPglueyC6ceAFytjYWMoPHMswPQae236zqe1YbhvCVQyIawesYywGiu98L9DwrxsBN69vGIVxJ4mQQ==
dependencies:
"@typescript-eslint/utils" "5.28.0"
debug "^4.3.4"
tsutils "^3.21.0"
"@typescript-eslint/types@5.27.1":
version "5.27.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.27.1.tgz#34e3e629501349d38be6ae97841298c03a6ffbf1"
integrity sha512-LgogNVkBhCTZU/m8XgEYIWICD6m4dmEDbKXESCbqOXfKZxRKeqpiJXQIErv66sdopRKZPo5l32ymNqibYEH/xg==
"@typescript-eslint/types@5.28.0":
version "5.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.28.0.tgz#cffd9bcdce28db6daaa146e48a0be4387a6f4e9d"
integrity sha512-2OOm8ZTOQxqkPbf+DAo8oc16sDlVR5owgJfKheBkxBKg1vAfw2JsSofH9+16VPlN9PWtv8Wzhklkqw3k/zCVxA==
"@typescript-eslint/typescript-estree@5.27.1":
version "5.27.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.27.1.tgz#7621ee78607331821c16fffc21fc7a452d7bc808"
@ -2217,6 +2265,19 @@
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/typescript-estree@5.28.0":
version "5.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.28.0.tgz#3487d158d091ca2772b285e67412ff6d9797d863"
integrity sha512-9GX+GfpV+F4hdTtYc6OV9ZkyYilGXPmQpm6AThInpBmKJEyRSIjORJd1G9+bknb7OTFYL+Vd4FBJAO6T78OVqA==
dependencies:
"@typescript-eslint/types" "5.28.0"
"@typescript-eslint/visitor-keys" "5.28.0"
debug "^4.3.4"
globby "^11.1.0"
is-glob "^4.0.3"
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/utils@5.27.1", "@typescript-eslint/utils@^5.13.0":
version "5.27.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.27.1.tgz#b4678b68a94bc3b85bf08f243812a6868ac5128f"
@ -2229,6 +2290,18 @@
eslint-scope "^5.1.1"
eslint-utils "^3.0.0"
"@typescript-eslint/utils@5.28.0":
version "5.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.28.0.tgz#b27a136eac300a48160b36d2aad0da44a1341b99"
integrity sha512-E60N5L0fjv7iPJV3UGc4EC+A3Lcj4jle9zzR0gW7vXhflO7/J29kwiTGITA2RlrmPokKiZbBy2DgaclCaEUs6g==
dependencies:
"@types/json-schema" "^7.0.9"
"@typescript-eslint/scope-manager" "5.28.0"
"@typescript-eslint/types" "5.28.0"
"@typescript-eslint/typescript-estree" "5.28.0"
eslint-scope "^5.1.1"
eslint-utils "^3.0.0"
"@typescript-eslint/visitor-keys@5.27.1":
version "5.27.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.1.tgz#05a62666f2a89769dac2e6baa48f74e8472983af"
@ -2237,6 +2310,14 @@
"@typescript-eslint/types" "5.27.1"
eslint-visitor-keys "^3.3.0"
"@typescript-eslint/visitor-keys@5.28.0":
version "5.28.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.28.0.tgz#982bb226b763c48fc1859a60de33fbf939d40a0f"
integrity sha512-BtfP1vCor8cWacovzzPFOoeW4kBQxzmhxGoOpt0v1SFvG+nJ0cWaVdJk7cky1ArTcFHHKNIxyo2LLr3oNkSuXA==
dependencies:
"@typescript-eslint/types" "5.28.0"
eslint-visitor-keys "^3.3.0"
"@webassemblyjs/ast@1.11.1":
version "1.11.1"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7"
@ -2531,7 +2612,7 @@ anymatch@^3.0.3, anymatch@~3.1.2:
normalize-path "^3.0.0"
picomatch "^2.0.4"
arg@^5.0.1:
arg@^5.0.1, arg@^5.0.2:
version "5.0.2"
resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c"
integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==
@ -3264,11 +3345,6 @@ cookie@0.5.0:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
cookie@^0.4.0:
version "0.4.2"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432"
integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
core-js-compat@^3.21.0, core-js-compat@^3.22.1:
version "3.22.8"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.22.8.tgz#46fa34ce1ddf742acd7f95f575f66bbb21e05d62"
@ -4058,11 +4134,16 @@ eslint-plugin-jsx-a11y@^6.5.1:
language-tags "^1.0.5"
minimatch "^3.0.4"
eslint-plugin-react-hooks@^4.3.0, eslint-plugin-react-hooks@^4.5.0:
eslint-plugin-react-hooks@^4.3.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.5.0.tgz#5f762dfedf8b2cf431c689f533c9d3fa5dcf25ad"
integrity sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw==
eslint-plugin-react-hooks@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3"
integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==
eslint-plugin-react@^7.27.1, eslint-plugin-react@^7.30.0:
version "7.30.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.30.0.tgz#8e7b1b2934b8426ac067a0febade1b13bd7064e3"
@ -4150,7 +4231,7 @@ eslint-webpack-plugin@^3.1.1:
normalize-path "^3.0.0"
schema-utils "^3.1.1"
eslint@^8.16.0, eslint@^8.3.0:
eslint@^8.17.0, eslint@^8.3.0:
version "8.17.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.17.0.tgz#1cfc4b6b6912f77d24b874ca1506b0fe09328c21"
integrity sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==
@ -4793,7 +4874,7 @@ history@^5.2.0:
dependencies:
"@babel/runtime" "^7.7.6"
hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1:
hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1:
version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
@ -7379,16 +7460,7 @@ react-app-polyfill@^3.0.0:
regenerator-runtime "^0.13.9"
whatwg-fetch "^3.6.2"
react-cookie@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/react-cookie/-/react-cookie-4.1.1.tgz#832e134ad720e0de3e03deaceaab179c4061a19d"
integrity sha512-ffn7Y7G4bXiFbnE+dKhHhbP+b8I34mH9jqnm8Llhj89zF4nPxPutxHT1suUqMeCEhLDBI7InYwf1tpaSoK5w8A==
dependencies:
"@types/hoist-non-react-statics" "^3.0.1"
hoist-non-react-statics "^3.0.0"
universal-cookie "^4.0.0"
react-debounce-input@^3.2.5:
react-debounce-input@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/react-debounce-input/-/react-debounce-input-3.3.0.tgz#85e3ebcaa41f2016e50613134a1ec9fe3cdb422e"
integrity sha512-VEqkvs8JvY/IIZvh71Z0TC+mdbxERvYF33RcebnodlsUZ8RSgyKe2VWaHXv4+/8aoOgXLxWrdsYs2hDhcwbUgA==
@ -7426,13 +7498,13 @@ react-dev-utils@^12.0.1:
strip-ansi "^6.0.1"
text-table "^0.2.0"
react-dom@^18.1.0:
version "18.1.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.1.0.tgz#7f6dd84b706408adde05e1df575b3a024d7e8a2f"
integrity sha512-fU1Txz7Budmvamp7bshe4Zi32d0ll7ect+ccxNu9FlObT605GOEB8BfO4tmRJ39R5Zj831VCpvQ05QPBW5yb+w==
react-dom@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
dependencies:
loose-envify "^1.1.0"
scheduler "^0.22.0"
scheduler "^0.23.0"
react-error-boundary@^3.1.4:
version "3.1.4"
@ -7451,10 +7523,10 @@ react-fast-compare@^2.0.1:
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
react-hook-form@^7.31.3:
version "7.31.3"
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.31.3.tgz#b61bafb9a7435f91695351a7a9f714d8c4df0121"
integrity sha512-NVZdCWViIWXXXlQ3jxVQH0NuNfwPf8A/0KvuCxrM9qxtP1qYosfR2ZudarziFrVOC7eTUbWbm1T4OyYCwv9oSQ==
react-hook-form@^7.32.1:
version "7.32.1"
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.32.1.tgz#103de7b7ef3a7d295264433e4464bd17c8e4bdc9"
integrity sha512-A0bsgZZUnGdG68sXLBNMN7zRYKbYc/ESjDkjrJZ8PZ8/96EQ0IwMfYY3wpopt+yn2+Mm3APEUkw+JdjYQSRVJA==
react-hot-toast@^2.2.0:
version "2.2.0"
@ -7478,12 +7550,12 @@ react-is@^18.0.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67"
integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==
react-multi-select-component@^4.2.7:
react-multi-select-component@^4.2.9:
version "4.2.9"
resolved "https://registry.yarnpkg.com/react-multi-select-component/-/react-multi-select-component-4.2.9.tgz#e0e750bcd243f4e4d829a9b0d983bbc457fd90fe"
integrity sha512-ef++2OuhBhAQ6MMfwl5BvI9Jtq8wcnCTM3MHvcKKdv5OGoUtIZpj5PGqLmegwSi75ZhkJTp/AdE8MR0nv2zGxQ==
react-query@^3.39.0:
react-query@^3.39.1:
version "3.39.1"
resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.39.1.tgz#3876c0fdac7a3b5a84e195534e5fa8fbdd628847"
integrity sha512-qYKT1bavdDiQZbngWZyPotlBVzcBjDYEJg5RQLBa++5Ix5jjfbEYJmHSZRZD+USVHUSvl/ey9Hu+QfF1QAK80A==
@ -7600,10 +7672,10 @@ react-transition-group@^4.3.0:
loose-envify "^1.4.0"
prop-types "^15.6.2"
react@^18.1.0:
version "18.1.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.1.0.tgz#6f8620382decb17fdc5cc223a115e2adbf104890"
integrity sha512-4oL8ivCz5ZEPyclFQXaNksK3adutVS8l2xzZU0cqEFrE9Sb7fC0EFK5uEk74wIreL1DERyjvsU915j1pcT2uEQ==
react@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
dependencies:
loose-envify "^1.1.0"
@ -7884,10 +7956,10 @@ saxes@^5.0.1:
dependencies:
xmlchars "^2.2.0"
scheduler@^0.22.0:
version "0.22.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.22.0.tgz#83a5d63594edf074add9a7198b1bae76c3db01b8"
integrity sha512-6QAm1BgQI88NPYymgGQLCZgvep4FyePDWFpXVK+zNSUgHwlqpJy8VEh8Et0KxTACS4VWwMousBElAZOH9nkkoQ==
scheduler@^0.23.0:
version "0.23.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==
dependencies:
loose-envify "^1.1.0"
@ -8413,7 +8485,7 @@ symbol-tree@^3.2.4:
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
tailwindcss@^3.0.2, tailwindcss@^3.0.24:
tailwindcss@^3.0.2:
version "3.1.1"
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.1.1.tgz#58102595ddd5406c5015d831a344370be0995cda"
integrity sha512-F5VFj5FiS4QZqdXPE6T6RJFqbsmISQ2KBUp9bOQyws9TleGToHsa54X8kwXwVdHMQhNeXOlxI47lrRICEVuOvg==
@ -8441,6 +8513,34 @@ tailwindcss@^3.0.2, tailwindcss@^3.0.24:
quick-lru "^5.1.1"
resolve "^1.22.0"
tailwindcss@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.1.3.tgz#b9ef2c1ae537c339679e8e89635af8e143d1c7eb"
integrity sha512-PRJNYdSIthrb8hjmAyymEyEN8Yo61TMXpzyFUpxULeeyRn3Y3gpvuw6FlRTKrJvK7thSGKRnhT36VovVx4WeMA==
dependencies:
arg "^5.0.2"
chokidar "^3.5.3"
color-name "^1.1.4"
detective "^5.2.1"
didyoumean "^1.2.2"
dlv "^1.1.3"
fast-glob "^3.2.11"
glob-parent "^6.0.2"
is-glob "^4.0.3"
lilconfig "^2.0.5"
normalize-path "^3.0.0"
object-hash "^3.0.0"
picocolors "^1.0.0"
postcss "^8.4.14"
postcss-import "^14.1.0"
postcss-js "^4.0.0"
postcss-load-config "^3.1.4"
postcss-nested "5.0.6"
postcss-selector-parser "^6.0.10"
postcss-value-parser "^4.2.0"
quick-lru "^5.1.1"
resolve "^1.22.0"
tapable@^1.0.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
@ -8650,7 +8750,7 @@ typedarray-to-buffer@^3.1.5:
dependencies:
is-typedarray "^1.0.0"
typescript@^4.7.2:
typescript@^4.7.3:
version "4.7.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.3.tgz#8364b502d5257b540f9de4c40be84c98e23a129d"
integrity sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==
@ -8695,14 +8795,6 @@ unique-string@^2.0.0:
dependencies:
crypto-random-string "^2.0.0"
universal-cookie@^4.0.0:
version "4.0.4"
resolved "https://registry.yarnpkg.com/universal-cookie/-/universal-cookie-4.0.4.tgz#06e8b3625bf9af049569ef97109b4bb226ad798d"
integrity sha512-lbRVHoOMtItjWbM7TwDLdl8wug7izB0tq3/YVKhT/ahB4VDvWMyvnADfnJI8y6fSvsjh51Ix7lTGC6Tn4rMPhw==
dependencies:
"@types/cookie" "^0.3.3"
cookie "^0.4.0"
universalify@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"