[admin] add toast status & better error handling with visual feedback (related #12)

This commit is contained in:
Grant 2024-05-30 16:42:48 -06:00
parent 6294a28c56
commit 0f545ee233
5 changed files with 32 additions and 6 deletions

1
package-lock.json generated
View File

@ -15753,6 +15753,7 @@
"react-apexcharts": "^1.4.1", "react-apexcharts": "^1.4.1",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-router-dom": "^6.22.1", "react-router-dom": "^6.22.1",
"react-toastify": "^10.0.5",
"sort-by": "^1.2.0" "sort-by": "^1.2.0"
}, },
"devDependencies": { "devDependencies": {

View File

@ -22,6 +22,7 @@
"react-apexcharts": "^1.4.1", "react-apexcharts": "^1.4.1",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-router-dom": "^6.22.1", "react-router-dom": "^6.22.1",
"react-toastify": "^10.0.5",
"sort-by": "^1.2.0" "sort-by": "^1.2.0"
}, },
"devDependencies": { "devDependencies": {

View File

@ -1,3 +1,5 @@
import { toast } from "react-toastify";
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
export const api = async <T = any>( export const api = async <T = any>(
endpoint: string, endpoint: string,
@ -32,3 +34,18 @@ export const api = async <T = any>(
data, data,
}; };
}; };
export const handleError = (
...props: [
status: number,
data: { success: true } | { success: false; error: string },
]
) => {
console.error(...props);
if (typeof props[0] === "number") {
const [status, data] = props;
toast.error(
`${status} ${"error" in data ? data.error : JSON.stringify(data)}`
);
}
};

View File

@ -8,6 +8,7 @@ import { Root } from "./Root.tsx";
import { HomePage } from "./pages/Home/page.tsx"; import { HomePage } from "./pages/Home/page.tsx";
import { AccountsPage } from "./pages/Accounts/Accounts/page.tsx"; import { AccountsPage } from "./pages/Accounts/Accounts/page.tsx";
import { ServiceSettingsPage } from "./pages/Service/settings.tsx"; import { ServiceSettingsPage } from "./pages/Service/settings.tsx";
import { ToastContainer } from "react-toastify";
const router = createBrowserRouter( const router = createBrowserRouter(
[ [
@ -40,6 +41,8 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
<NextUIProvider> <NextUIProvider>
<ThemeProvider defaultTheme="system"> <ThemeProvider defaultTheme="system">
<RouterProvider router={router} /> <RouterProvider router={router} />
<ToastContainer position="bottom-right" />
</ThemeProvider> </ThemeProvider>
</NextUIProvider> </NextUIProvider>
</React.StrictMode> </React.StrictMode>

View File

@ -1,7 +1,8 @@
import { BreadcrumbItem, Breadcrumbs, Button, Input } from "@nextui-org/react"; import { BreadcrumbItem, Breadcrumbs, Button, Input } from "@nextui-org/react";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { api } from "../../lib/utils"; import { api, handleError } from "../../lib/utils";
import { LoadingOverlay } from "../../components/LoadingOverlay"; import { LoadingOverlay } from "../../components/LoadingOverlay";
import { toast } from "react-toastify";
export const ServiceSettingsPage = () => { export const ServiceSettingsPage = () => {
return ( return (
@ -31,10 +32,10 @@ const CanvasSettings = () => {
setWidth(data.size.width + ""); setWidth(data.size.width + "");
setHeight(data.size.height + ""); setHeight(data.size.height + "");
} else { } else {
console.error(status, data); handleError(status, data);
} }
} else { } else {
console.error(status, data); handleError(status, data);
} }
}) })
.finally(() => { .finally(() => {
@ -52,12 +53,12 @@ const CanvasSettings = () => {
.then(({ status, data }) => { .then(({ status, data }) => {
if (status === 200) { if (status === 200) {
if (data.success) { if (data.success) {
alert("good"); toast.success("Canvas size has been changed");
} else { } else {
console.error(status, data); handleError(status, data);
} }
} else { } else {
console.error(status, data); handleError(status, data);
} }
}) })
.finally(() => { .finally(() => {
@ -70,6 +71,9 @@ const CanvasSettings = () => {
<h4 className="text-l font-semibold">Canvas</h4> <h4 className="text-l font-semibold">Canvas</h4>
<div className="relative"> <div className="relative">
{loading && <LoadingOverlay />} {loading && <LoadingOverlay />}
<b>
Canvas size is resource intensive, this will take a minute to complete
</b>
<Input <Input
type="number" type="number"
size="sm" size="sm"