Error page - WIP (#191)

This commit is contained in:
Christian Benincasa
2024-03-22 09:53:46 -04:00
committed by GitHub
parent dfd3bd2724
commit 1e0b323dd3
9 changed files with 135 additions and 5 deletions

BIN
design/error.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

7
pnpm-lock.yaml generated
View File

@@ -374,6 +374,9 @@ importers:
axios:
specifier: ^1.6.0
version: 1.6.0
bowser:
specifier: ^2.11.0
version: 2.11.0
dayjs:
specifier: ^1.11.10
version: 1.11.10
@@ -3508,6 +3511,10 @@ packages:
- supports-color
dev: false
/bowser@2.11.0:
resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==}
dev: false
/brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
dependencies:

View File

@@ -26,6 +26,7 @@
"@uidotdev/usehooks": "^2.4.1",
"@zodios/core": "^10.9.6",
"axios": "^1.6.0",
"bowser": "^2.11.0",
"dayjs": "^1.11.10",
"hls.js": "^1.4.12",
"immer": "^10.0.3",

View File

@@ -40,3 +40,20 @@
.read-the-docs {
color: #888;
} */
@-moz-keyframes spin {
100% {
-moz-transform: rotate(360deg);
}
}
@-webkit-keyframes spin {
100% {
-webkit-transform: rotate(360deg);
}
}
@keyframes spin {
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}

View File

@@ -47,7 +47,7 @@ interface NavItem {
icon?: ReactNode;
}
export function Root() {
export function Root({ children }: { children?: React.ReactNode }) {
const [open, setOpen] = useState(false);
const toggleDrawerOpen = () => {
@@ -333,7 +333,7 @@ export function Root() {
settings.
</Alert>
) : null}
<Outlet />
{children ?? <Outlet />}
</Container>
</Box>
</Box>

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -0,0 +1,94 @@
import GitHub from '@mui/icons-material/GitHub';
import Loop from '@mui/icons-material/Loop';
import Refresh from '@mui/icons-material/Refresh';
import {
Box,
Button,
Collapse,
Stack,
Typography,
styled,
} from '@mui/material';
import Bowser from 'bowser';
import { isError } from 'lodash-es';
import { useMemo } from 'react';
import { useRouteError } from 'react-router-dom';
import errorImage from '../assets/error_this_is_fine.png';
import { useVersion } from '../hooks/useVersion';
const browser = Bowser.getParser(window.navigator.userAgent);
const RotatingLoopIcon = styled(Loop)({
animation: 'spin 2s linear infinite',
});
export function ErrorPage() {
const { data: version, isLoading: versionLoading } = useVersion();
const error = useRouteError();
const stack = (isError(error) ? error.stack : '') ?? '';
const bugReportLink = useMemo(() => {
const url = new URL(`https://github.com/chrisbenincasa/tunarr/issues/new`);
let browserString = browser.getBrowserName();
if (browser.getBrowserVersion()) {
browserString += ` (${browser.getBrowserVersion()})`;
}
let osString = browser.getOSName();
if (browser.getOSVersion()) {
osString += ` (${browser.getOSVersion()})`;
}
url.searchParams.append('template', 'bug_report.yaml');
url.searchParams.append('browser', browserString);
url.searchParams.append('os', osString);
url.searchParams.append('version', version?.tunarr ?? '');
url.searchParams.append('logs', stack);
return url;
}, [version]);
return (
<Box sx={{ width: '100%' }}>
<Box
sx={{ margin: 'auto', display: 'block', pl: 3 }}
component="img"
src={errorImage}
/>
<p style={{ textAlign: 'center' }}>
<Typography variant="h2" sx={{ pb: 1 }}>
Oops!
</Typography>
<Typography>Looks like something went wrong.</Typography>
</p>
<Stack direction="row" sx={{ justifyContent: 'center' }} gap={2}>
<Button
onClick={() => window.location.reload()}
variant="contained"
startIcon={<Refresh />}
>
Refresh Page
</Button>
<Button
component="a"
href={bugReportLink.toString()}
target="_blank"
variant="contained"
startIcon={versionLoading ? <RotatingLoopIcon /> : <GitHub />}
disabled={versionLoading}
>
{versionLoading
? 'Generating Bug Report Link...'
: 'File a Bug Report'}
</Button>
</Stack>
{stack && (
<Collapse in={true}>
<Box
component="pre"
sx={{ width: '100%', overflowX: 'scroll', p: 1 }}
>
{stack}
</Box>
</Collapse>
)}
</Box>
);
}

View File

@@ -1,6 +1,7 @@
import { QueryClient } from '@tanstack/react-query';
import { createBrowserRouter } from 'react-router-dom';
import { Root } from './App.tsx';
import { ErrorPage } from './pages/ErrorPage.tsx';
import ChannelProgrammingPage from './pages/channels/ChannelProgrammingPage.tsx';
import ChannelsPage from './pages/channels/ChannelsPage.tsx';
import EditChannelPage from './pages/channels/EditChannelPage.tsx';
@@ -46,14 +47,24 @@ export const router = createBrowserRouter(
{
path: '/',
element: <Root />,
ErrorBoundary: function Error() {
return <div>Error</div>;
},
errorElement: (
<Root>
<ErrorPage />
</Root>
),
children: [
{
path: '*',
errorElement: <ErrorPage />,
},
{
element: <GuidePage />,
index: true,
},
{
element: <GuidePage />,
path: '/guide',
},
{
path: '/welcome',
element: <WelcomePage />,