code cleanup

This commit is contained in:
mengstabketemaw
2026-06-05 15:19:30 +03:00
parent 4a4e82f6b0
commit 47b36cf91d
7 changed files with 80 additions and 18 deletions

View File

@@ -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 { 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 { AppProviders } from './providers/AppProviders';
import { AppRouter } from './router'; import { AppRouter } from './router';
configureIam({ apiUrl: 'http://localhost:3001/api' }); // configureIam({ apiUrl: 'http://localhost:3001/api' });
export function App() { export function App() {
return ( return (

View 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;
}
}

View File

@@ -49,13 +49,13 @@ export function LoginPage() {
url: '/auth/login', url: '/auth/login',
method: 'POST', method: 'POST',
body: values, body: values,
}).unwrap() as LoginPayload; }).unwrap();
dispatch(loginSuccess(data)); dispatch(loginSuccess(data));
const me = await meTrigger({ const me = await meTrigger({
url: '/auth/me', url: '/auth/me',
method: 'GET', method: 'GET',
}).unwrap() as AuthUser; }).unwrap();
dispatch(setUser(me)); dispatch(setUser(me));
if (me.status === 'accepted') { if (me.status === 'accepted') {

View File

@@ -83,7 +83,7 @@ export function SignupPage() {
url: '/auth/signup-with-pwd', url: '/auth/signup-with-pwd',
method: 'POST', method: 'POST',
body: payload, body: payload,
}).unwrap() as { token: string; refreshToken: string; isPhoneNumberVerified: boolean }; }).unwrap();
dispatch( dispatch(
loginSuccess({ loginSuccess({

View File

@@ -4,6 +4,7 @@ import { AuthProvider } from '@tria-plc/iamui-common';
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import { store } from '../store'; import { store } from '../store';
import { MantineThemeProvider } from './MantineThemeProvider'; import { MantineThemeProvider } from './MantineThemeProvider';
import { ErrorBoundary } from '../components/ErrorBoundary';
const queryClient = new QueryClient({ const queryClient = new QueryClient({
defaultOptions: { queries: { retry: 1, staleTime: 1000 * 60 * 5 } }, defaultOptions: { queries: { retry: 1, staleTime: 1000 * 60 * 5 } },
@@ -11,12 +12,14 @@ const queryClient = new QueryClient({
export function AppProviders({ children }: { children: ReactNode }) { export function AppProviders({ children }: { children: ReactNode }) {
return ( return (
<Provider store={store}> <ErrorBoundary>
<QueryClientProvider client={queryClient}> <Provider store={store}>
<AuthProvider> <QueryClientProvider client={queryClient}>
<MantineThemeProvider>{children}</MantineThemeProvider> <AuthProvider>
</AuthProvider> <MantineThemeProvider>{children}</MantineThemeProvider>
</QueryClientProvider> </AuthProvider>
</Provider> </QueryClientProvider>
</Provider>
</ErrorBoundary>
); );
} }

View File

@@ -5,13 +5,11 @@ import { LoginPage } from './features/auth/pages/LoginPage';
import { SignupPage } from './features/auth/pages/SignupPage'; import { SignupPage } from './features/auth/pages/SignupPage';
import { OTPVerificationPage } from './features/auth/pages/OTPVerificationPage'; import { OTPVerificationPage } from './features/auth/pages/OTPVerificationPage';
import { DashboardPage } from './features/dashboard/pages/DashboardPage'; import { DashboardPage } from './features/dashboard/pages/DashboardPage';
import { useAppSelector } from './store/hooks';
function getToken(): string | null {
return localStorage.getItem('ema-portal-auth-token');
}
function ProtectedRoute({ children }: { children: ReactNode }) { 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}</>; return <>{children}</>;
} }

View File

@@ -1,12 +1,23 @@
import { configureStore } from '@reduxjs/toolkit'; import { configureStore } from '@reduxjs/toolkit';
import { baseApi } from '@ema-platform/api'; import { baseApi } from '@ema-platform/api';
import { authReducer } from '../features/auth/store/auth.slice'; 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({ export const store = configureStore({
reducer: { reducer: {
auth: authReducer, auth: authReducer,
[baseApi.reducerPath]: baseApi.reducer, [baseApi.reducerPath]: baseApi.reducer,
}, },
preloadedState: preloadedAuth ? { auth: preloadedAuth } : undefined,
middleware: (getDefaultMiddleware) => middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(baseApi.middleware), getDefaultMiddleware().concat(baseApi.middleware),
}); });