mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-26 19:12:50 +00:00
code cleanup
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import { configureIam } from "@tria-plc/iamui-common";
|
||||
// import { configureIam } from "@tria-plc/iamui-common";
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import "@tria-plc/iamui-common/styles.css";
|
||||
// import "@tria-plc/iamui-common/styles.css";
|
||||
import { AppProviders } from './providers/AppProviders';
|
||||
import { AppRouter } from './router';
|
||||
|
||||
configureIam({ apiUrl: 'http://localhost:3001/api' });
|
||||
// configureIam({ apiUrl: 'http://localhost:3001/api' });
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
|
||||
50
apps/portal/src/app/components/ErrorBoundary.tsx
Normal file
50
apps/portal/src/app/components/ErrorBoundary.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import { Component } from 'react';
|
||||
import type { ReactNode, ErrorInfo } from 'react';
|
||||
import { Center, Paper, Title, Text, Button } from '@mantine/core';
|
||||
|
||||
interface Props {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
interface State {
|
||||
hasError: boolean;
|
||||
error: Error | null;
|
||||
}
|
||||
|
||||
export class ErrorBoundary extends Component<Props, State> {
|
||||
state: State = { hasError: false, error: null };
|
||||
|
||||
static getDerivedStateFromError(error: Error): State {
|
||||
return { hasError: true, error };
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, info: ErrorInfo) {
|
||||
console.error('ErrorBoundary caught:', error, info);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
return (
|
||||
<Center h="100vh">
|
||||
<Paper p="xl" shadow="md" radius="md" w={400}>
|
||||
<Title order={3} mb="sm">Something went wrong</Title>
|
||||
<Text c="dimmed" size="sm" mb="lg">
|
||||
{this.state.error?.message || 'An unexpected error occurred.'}
|
||||
</Text>
|
||||
<Button
|
||||
fullWidth
|
||||
onClick={() => {
|
||||
this.setState({ hasError: false, error: null });
|
||||
window.location.href = '/';
|
||||
}}
|
||||
>
|
||||
Reload page
|
||||
</Button>
|
||||
</Paper>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
@@ -49,13 +49,13 @@ export function LoginPage() {
|
||||
url: '/auth/login',
|
||||
method: 'POST',
|
||||
body: values,
|
||||
}).unwrap() as LoginPayload;
|
||||
}).unwrap();
|
||||
dispatch(loginSuccess(data));
|
||||
|
||||
const me = await meTrigger({
|
||||
url: '/auth/me',
|
||||
method: 'GET',
|
||||
}).unwrap() as AuthUser;
|
||||
}).unwrap();
|
||||
dispatch(setUser(me));
|
||||
|
||||
if (me.status === 'accepted') {
|
||||
|
||||
@@ -83,7 +83,7 @@ export function SignupPage() {
|
||||
url: '/auth/signup-with-pwd',
|
||||
method: 'POST',
|
||||
body: payload,
|
||||
}).unwrap() as { token: string; refreshToken: string; isPhoneNumberVerified: boolean };
|
||||
}).unwrap();
|
||||
|
||||
dispatch(
|
||||
loginSuccess({
|
||||
|
||||
@@ -4,6 +4,7 @@ import { AuthProvider } from '@tria-plc/iamui-common';
|
||||
import type { ReactNode } from 'react';
|
||||
import { store } from '../store';
|
||||
import { MantineThemeProvider } from './MantineThemeProvider';
|
||||
import { ErrorBoundary } from '../components/ErrorBoundary';
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: { queries: { retry: 1, staleTime: 1000 * 60 * 5 } },
|
||||
@@ -11,12 +12,14 @@ const queryClient = new QueryClient({
|
||||
|
||||
export function AppProviders({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<AuthProvider>
|
||||
<MantineThemeProvider>{children}</MantineThemeProvider>
|
||||
</AuthProvider>
|
||||
</QueryClientProvider>
|
||||
</Provider>
|
||||
<ErrorBoundary>
|
||||
<Provider store={store}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<AuthProvider>
|
||||
<MantineThemeProvider>{children}</MantineThemeProvider>
|
||||
</AuthProvider>
|
||||
</QueryClientProvider>
|
||||
</Provider>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,13 +5,11 @@ import { LoginPage } from './features/auth/pages/LoginPage';
|
||||
import { SignupPage } from './features/auth/pages/SignupPage';
|
||||
import { OTPVerificationPage } from './features/auth/pages/OTPVerificationPage';
|
||||
import { DashboardPage } from './features/dashboard/pages/DashboardPage';
|
||||
|
||||
function getToken(): string | null {
|
||||
return localStorage.getItem('ema-portal-auth-token');
|
||||
}
|
||||
import { useAppSelector } from './store/hooks';
|
||||
|
||||
function ProtectedRoute({ children }: { children: ReactNode }) {
|
||||
if (!getToken()) return <Navigate to="/login" replace />;
|
||||
const isAuthenticated = useAppSelector((s) => s.auth.isAuthenticated);
|
||||
if (!isAuthenticated) return <Navigate to="/login" replace />;
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
import { configureStore } from '@reduxjs/toolkit';
|
||||
import { baseApi } from '@ema-platform/api';
|
||||
import { authReducer } from '../features/auth/store/auth.slice';
|
||||
import { authStorage } from '../features/auth/utils/auth-storage';
|
||||
|
||||
const preloadedAuth = (() => {
|
||||
const token = authStorage.getToken();
|
||||
const user = authStorage.getUser();
|
||||
if (token && user) {
|
||||
return { token, user, isAuthenticated: true };
|
||||
}
|
||||
return undefined;
|
||||
})();
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
auth: authReducer,
|
||||
[baseApi.reducerPath]: baseApi.reducer,
|
||||
},
|
||||
preloadedState: preloadedAuth ? { auth: preloadedAuth } : undefined,
|
||||
middleware: (getDefaultMiddleware) =>
|
||||
getDefaultMiddleware().concat(baseApi.middleware),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user