Split 401
This commit is contained in:
parent
73c7dc1b5e
commit
96bdbfc62a
1
exam/dist/assets/index-B93xlZhH.js
vendored
Normal file
1
exam/dist/assets/index-B93xlZhH.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
exam/dist/assets/index-tFNBNNKb.js
vendored
1
exam/dist/assets/index-tFNBNNKb.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
exam/dist/index.html
vendored
4
exam/dist/index.html
vendored
@ -5,10 +5,10 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/phpCourse/exam/dist/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + React + TS</title>
|
||||
<script type="module" crossorigin src="/phpCourse/exam/dist/assets/index-tFNBNNKb.js"></script>
|
||||
<script type="module" crossorigin src="/phpCourse/exam/dist/assets/index-B93xlZhH.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/phpCourse/exam/dist/assets/react-C_FdcE2X.js">
|
||||
<link rel="modulepreload" crossorigin href="/phpCourse/exam/dist/assets/mui-C4H8cxTH.js">
|
||||
<link rel="modulepreload" crossorigin href="/phpCourse/exam/dist/assets/tanstack-Duf7jkFs.js">
|
||||
<link rel="modulepreload" crossorigin href="/phpCourse/exam/dist/assets/tanstack-C0csOcmc.js">
|
||||
<link rel="modulepreload" crossorigin href="/phpCourse/exam/dist/assets/i18n-DyW0LrNj.js">
|
||||
<link rel="stylesheet" crossorigin href="/phpCourse/exam/dist/assets/mui-CKDNpdid.css">
|
||||
<link rel="stylesheet" crossorigin href="/phpCourse/exam/dist/assets/index-D83Ey19k.css">
|
||||
|
||||
10
exam/dist/locales/de/translation.json
vendored
10
exam/dist/locales/de/translation.json
vendored
@ -1,23 +1,23 @@
|
||||
{
|
||||
"Unauthorized": "Keine Berechtigung",
|
||||
|
||||
"Unauthorized_login": "Ungültige E-Mail oder Passwort",
|
||||
"NotAllowed_login": "Ungültige E-Mail oder Passwort",
|
||||
"NotFound_user:login": "Benutzer existiert nicht",
|
||||
"MissingField_email:login": "E-Mail darf nicht leer sein",
|
||||
"MissingField_password:login": "Passwort darf nicht leer sein",
|
||||
|
||||
"Unauthorized_deletePost": "Keine Berechtigung",
|
||||
"NotAllowed_deletePost": "Keine Berechtigung",
|
||||
"NotFound_post:deletePost": "Post nicht gefunden",
|
||||
|
||||
"Unauthorized_userUpdate": "Keine Berechtigung",
|
||||
"NotAllowed_userUpdate": "Keine Berechtigung",
|
||||
"NotFound_user:userUpdate": "Benutzer nicht gefunden",
|
||||
"FailedUpdate_Duplicate:username:userUpdate": "Ein Benutzer mit diesem Benutzernamen existiert schon",
|
||||
"FailedUpdate_Duplicate:email:userUpdate": "Ein Benutzer mit dieser E-Mail existiert schon",
|
||||
|
||||
"Unauthorized_newPost": "Keine Berechtigung",
|
||||
"NotAllowed_newPost": "Keine Berechtigung",
|
||||
"MissingField_content:newPost": "Beitrag darf nicht leer sein",
|
||||
|
||||
"Unauthorized_postUpdate": "Keine Berechtigung",
|
||||
"NotAllowed_postUpdate": "Keine Berechtigung",
|
||||
"NotFound_post:postUpdate": "Post nicht gefunden",
|
||||
|
||||
"Duplicate_user:register": "Ein Benutzer mit diesem Benutzernamen oder E-Mail existiert schon",
|
||||
|
||||
12
exam/dist/locales/en/translation.json
vendored
12
exam/dist/locales/en/translation.json
vendored
@ -1,23 +1,23 @@
|
||||
{
|
||||
"Unauthorized": "Unauthorized",
|
||||
"Unauthorized": "NotAllowed",
|
||||
|
||||
"Unauthorized_login": "Invalid email or password",
|
||||
"NotAllowed_login": "Invalid email or password",
|
||||
"NotFound_user:login": "User does not exist",
|
||||
"MissingField_email:login": "E-Mail required",
|
||||
"MissingField_password:login": "Password required",
|
||||
|
||||
"Unauthorized_deletPost": "Unauthorized",
|
||||
"NotAllowed_deletPost": "NotAllowed",
|
||||
"NotFound_post:deletePost": "Post not found",
|
||||
|
||||
"Unauthorized_userUpdate": "Unauthorized",
|
||||
"NotAllowed_userUpdate": "NotAllowed",
|
||||
"NotFound_user:userUpdate": "User not found",
|
||||
"FailedUpdate_Duplicate:userUpdate": "A user with this username already exists",
|
||||
"FailedUpdate_Duplicate:email:userUpdate": "A user with this email already exists",
|
||||
|
||||
"Unauthorized_newPost": "Unauthorized",
|
||||
"NotAllowed_newPost": "NotAllowed",
|
||||
"MissingField_content:newPost": "Content required",
|
||||
|
||||
"Unauthorized_postUpdate": "Unauthorized",
|
||||
"NotAllowed_postUpdate": "NotAllowed",
|
||||
"NotFound_post:postUpdate": "Post not found",
|
||||
|
||||
"Duplicate_user:register": "A user with this username or email already exists",
|
||||
|
||||
2
exam/dist/stats.html
vendored
2
exam/dist/stats.html
vendored
File diff suppressed because one or more lines are too long
@ -1,23 +1,23 @@
|
||||
{
|
||||
"Unauthorized": "Keine Berechtigung",
|
||||
|
||||
"Unauthorized_login": "Ungültige E-Mail oder Passwort",
|
||||
"NotAllowed_login": "Ungültige E-Mail oder Passwort",
|
||||
"NotFound_user:login": "Benutzer existiert nicht",
|
||||
"MissingField_email:login": "E-Mail darf nicht leer sein",
|
||||
"MissingField_password:login": "Passwort darf nicht leer sein",
|
||||
|
||||
"Unauthorized_deletePost": "Keine Berechtigung",
|
||||
"NotAllowed_deletePost": "Keine Berechtigung",
|
||||
"NotFound_post:deletePost": "Post nicht gefunden",
|
||||
|
||||
"Unauthorized_userUpdate": "Keine Berechtigung",
|
||||
"NotAllowed_userUpdate": "Keine Berechtigung",
|
||||
"NotFound_user:userUpdate": "Benutzer nicht gefunden",
|
||||
"FailedUpdate_Duplicate:username:userUpdate": "Ein Benutzer mit diesem Benutzernamen existiert schon",
|
||||
"FailedUpdate_Duplicate:email:userUpdate": "Ein Benutzer mit dieser E-Mail existiert schon",
|
||||
|
||||
"Unauthorized_newPost": "Keine Berechtigung",
|
||||
"NotAllowed_newPost": "Keine Berechtigung",
|
||||
"MissingField_content:newPost": "Beitrag darf nicht leer sein",
|
||||
|
||||
"Unauthorized_postUpdate": "Keine Berechtigung",
|
||||
"NotAllowed_postUpdate": "Keine Berechtigung",
|
||||
"NotFound_post:postUpdate": "Post nicht gefunden",
|
||||
|
||||
"Duplicate_user:register": "Ein Benutzer mit diesem Benutzernamen oder E-Mail existiert schon",
|
||||
|
||||
@ -1,23 +1,23 @@
|
||||
{
|
||||
"Unauthorized": "Unauthorized",
|
||||
"Unauthorized": "NotAllowed",
|
||||
|
||||
"Unauthorized_login": "Invalid email or password",
|
||||
"NotAllowed_login": "Invalid email or password",
|
||||
"NotFound_user:login": "User does not exist",
|
||||
"MissingField_email:login": "E-Mail required",
|
||||
"MissingField_password:login": "Password required",
|
||||
|
||||
"Unauthorized_deletPost": "Unauthorized",
|
||||
"NotAllowed_deletPost": "NotAllowed",
|
||||
"NotFound_post:deletePost": "Post not found",
|
||||
|
||||
"Unauthorized_userUpdate": "Unauthorized",
|
||||
"NotAllowed_userUpdate": "NotAllowed",
|
||||
"NotFound_user:userUpdate": "User not found",
|
||||
"FailedUpdate_Duplicate:userUpdate": "A user with this username already exists",
|
||||
"FailedUpdate_Duplicate:email:userUpdate": "A user with this email already exists",
|
||||
|
||||
"Unauthorized_newPost": "Unauthorized",
|
||||
"NotAllowed_newPost": "NotAllowed",
|
||||
"MissingField_content:newPost": "Content required",
|
||||
|
||||
"Unauthorized_postUpdate": "Unauthorized",
|
||||
"NotAllowed_postUpdate": "NotAllowed",
|
||||
"NotFound_post:postUpdate": "Post not found",
|
||||
|
||||
"Duplicate_user:register": "A user with this username or email already exists",
|
||||
|
||||
@ -44,7 +44,8 @@ class ApiImpl {
|
||||
|
||||
public logOut = async (): Promise<boolean> => {
|
||||
try {
|
||||
return await (await this.postAuth('logout')).json();
|
||||
if (this.token) return await (await this.postAuth('logout')).json();
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
} finally {
|
||||
|
||||
@ -19,7 +19,7 @@ const ErrorComponent: FC<Props> = ({ error, context, color = 'error.main' }) =>
|
||||
switch (error.code) {
|
||||
case ERRORS.NOT_FOUND:
|
||||
return <Typography color={color}>{t(error.code, { context: `${error.entity}:${context}` })}</Typography>;
|
||||
case ERRORS.UNAUTHORIZED:
|
||||
case ERRORS.NOT_ALLOWED:
|
||||
return <Typography color={color}>{t(error.code, { context })}</Typography>;
|
||||
case ERRORS.FAILED_UPDATE:
|
||||
return error.fields.map((field: string, index: number) => (
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
export enum ERRORS {
|
||||
NOT_FOUND = 'NotFound',
|
||||
UNAUTHORIZED = 'Unauthorized',
|
||||
NOT_ALLOWED = 'NotAllowed',
|
||||
FAILED_UPDATE = 'FailedUpdate',
|
||||
MISSING_FIELD = 'MissingField',
|
||||
DUPLICATE = 'Duplicate',
|
||||
|
||||
@ -71,11 +71,9 @@ const UserMenu: FC<Props> = ({ anchorEl, handleClose }) => {
|
||||
</MenuItem>,
|
||||
]
|
||||
) : register ? (
|
||||
<>
|
||||
<RegisterDialog open={register} onClose={() => setRegister(false)} />
|
||||
</>
|
||||
<RegisterDialog open={register} onClose={() => setRegister(false)} />
|
||||
) : (
|
||||
<>
|
||||
<Box>
|
||||
<LoginForm handleClose={_handleClose} />
|
||||
<Box sx={{ padding: 1 }}>
|
||||
<Trans i18nKey="Register prompt">
|
||||
@ -92,7 +90,7 @@ const UserMenu: FC<Props> = ({ anchorEl, handleClose }) => {
|
||||
<Typography component="span" />
|
||||
</Trans>
|
||||
</Box>
|
||||
</>
|
||||
</Box>
|
||||
)}
|
||||
</Menu>
|
||||
);
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { RouterProvider, createRouter } from '@tanstack/react-router';
|
||||
import { StrictMode } from 'react';
|
||||
import { QueryClient, QueryClientProvider, useQueryClient, useQueryErrorResetBoundary } from '@tanstack/react-query';
|
||||
import { ErrorRouteComponent, RouterProvider, createRouter, useRouter } from '@tanstack/react-router';
|
||||
import { StrictMode, useEffect } from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import Api from './api/Api';
|
||||
import { ERRORS } from './components/Error/Errors';
|
||||
|
||||
// Import the generated route tree
|
||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
||||
@ -19,6 +21,40 @@ import '@fontsource/roboto/700.css';
|
||||
// Query Client
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
//TODO: REAUTH HERE
|
||||
|
||||
//TODO: Make nice
|
||||
export const Error: ErrorRouteComponent = ({ error }) => {
|
||||
const router = useRouter();
|
||||
const queryErrorResetBoundary = useQueryErrorResetBoundary();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
useEffect(() => {
|
||||
// Reset the query error boundary
|
||||
queryErrorResetBoundary.reset();
|
||||
}, [queryErrorResetBoundary]);
|
||||
|
||||
//TODO: Split display, show something went wrong with retry on all, show session expired and back to main on auth
|
||||
if ('code' in error && error.code === ERRORS.NOT_ALLOWED) {
|
||||
Api.logOut().finally(() => {
|
||||
queryClient.clear();
|
||||
router.invalidate();
|
||||
});
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
{error.message}
|
||||
<button
|
||||
onClick={() => {
|
||||
router.invalidate();
|
||||
}}
|
||||
>
|
||||
retry
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Create a new router instance
|
||||
const router = createRouter({
|
||||
routeTree,
|
||||
@ -30,6 +66,7 @@ const router = createRouter({
|
||||
// This will ensure that the loader is always called when the route is preloaded or visited
|
||||
defaultPreloadStaleTime: 0,
|
||||
basepath: process.env.NODE_ENV === 'development' ? 'phpCourse/exam/dist' : '/phpCourse/exam',
|
||||
defaultErrorComponent: Error,
|
||||
});
|
||||
|
||||
// Register the router instance for type safety
|
||||
@ -47,7 +84,7 @@ if (!rootElement.innerHTML) {
|
||||
<StrictMode>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<RouterProvider router={router} />
|
||||
<ReactQueryDevtools initialIsOpen={false} />
|
||||
{process.env.NODE_ENV === 'development' && <ReactQueryDevtools initialIsOpen={false} />}
|
||||
</QueryClientProvider>
|
||||
</StrictMode>
|
||||
);
|
||||
|
||||
@ -1,16 +1,10 @@
|
||||
import { Box } from '@mui/material';
|
||||
import { QueryClient, useQueryErrorResetBoundary } from '@tanstack/react-query';
|
||||
import { createRootRouteWithContext, ErrorRouteComponent, Outlet, redirect, useRouter } from '@tanstack/react-router';
|
||||
import { QueryClient } from '@tanstack/react-query';
|
||||
import { createRootRouteWithContext, Outlet } from '@tanstack/react-router';
|
||||
import { TanStackRouterDevtools } from '@tanstack/router-devtools';
|
||||
import { useEffect } from 'react';
|
||||
import Api from '../api/Api';
|
||||
import { ERRORS } from '../components/Error/Errors';
|
||||
import Header from '../components/Header/Header';
|
||||
import { ROUTES } from '../types/Routes';
|
||||
|
||||
const Root = () => {
|
||||
//TODO: REAUTH HERE
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
@ -24,35 +18,6 @@ const Root = () => {
|
||||
);
|
||||
};
|
||||
|
||||
//TODO: Make nice
|
||||
const Error: ErrorRouteComponent = ({ error }) => {
|
||||
const router = useRouter();
|
||||
const queryErrorResetBoundary = useQueryErrorResetBoundary();
|
||||
|
||||
useEffect(() => {
|
||||
// Reset the query error boundary
|
||||
queryErrorResetBoundary.reset();
|
||||
}, [queryErrorResetBoundary]);
|
||||
|
||||
if ('code' in error && error.code === ERRORS.UNAUTHORIZED) {
|
||||
Api.logOut();
|
||||
redirect({ to: ROUTES.INDEX });
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
{error.message}
|
||||
<button
|
||||
onClick={() => {
|
||||
router.invalidate();
|
||||
}}
|
||||
>
|
||||
retry
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const Route = createRootRouteWithContext<{ queryClient: QueryClient }>()({
|
||||
component: Root,
|
||||
errorComponent: Error,
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user