mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-26 19:12:50 +00:00
add iam module usermanagment ui
This commit is contained in:
@@ -1,7 +1,17 @@
|
||||
import { useEffect } from 'react';
|
||||
import { configureIam } from '@tria-plc/iamui-common';
|
||||
import { AppProviders } from './providers/AppProviders';
|
||||
import { AppRouter } from './router';
|
||||
|
||||
const BASE_API_URL =
|
||||
(import.meta as { env?: Record<string, string> }).env?.['VITE_BASE_API_URL'] ??
|
||||
'http://localhost:3001/api';
|
||||
|
||||
export function App() {
|
||||
useEffect(() => {
|
||||
configureIam({ apiUrl: BASE_API_URL });
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<AppProviders>
|
||||
<AppRouter />
|
||||
|
||||
@@ -6,13 +6,32 @@ const KEYS = {
|
||||
user: 'ema-backoffice-auth-user',
|
||||
} as const;
|
||||
|
||||
const COOKIE_ATTRS = 'path=/;max-age=86400';
|
||||
|
||||
function setCookie(name: string, value: string) {
|
||||
document.cookie = `${name}=${encodeURIComponent(value)};${COOKIE_ATTRS}`;
|
||||
}
|
||||
|
||||
function removeCookie(name: string) {
|
||||
document.cookie = `${name}=;path=/;max-age=0`;
|
||||
}
|
||||
|
||||
export const authStorage = {
|
||||
getToken: () => localStorage.getItem(KEYS.token) ?? undefined,
|
||||
setToken: (token: string) => localStorage.setItem(KEYS.token, token),
|
||||
removeToken: () => localStorage.removeItem(KEYS.token),
|
||||
setToken: (token: string) => {
|
||||
localStorage.setItem(KEYS.token, token);
|
||||
setCookie('auth-token', token);
|
||||
},
|
||||
removeToken: () => {
|
||||
localStorage.removeItem(KEYS.token);
|
||||
removeCookie('auth-token');
|
||||
},
|
||||
|
||||
getRefreshToken: () => localStorage.getItem(KEYS.refreshToken) ?? undefined,
|
||||
setRefreshToken: (token: string) => localStorage.setItem(KEYS.refreshToken, token),
|
||||
setRefreshToken: (token: string) => {
|
||||
localStorage.setItem(KEYS.refreshToken, token);
|
||||
setCookie('refresh-token', token);
|
||||
},
|
||||
|
||||
getUser: (): AuthUser | null => {
|
||||
const raw = localStorage.getItem(KEYS.user);
|
||||
@@ -24,5 +43,9 @@ export const authStorage = {
|
||||
},
|
||||
setUser: (user: AuthUser) => localStorage.setItem(KEYS.user, JSON.stringify(user)),
|
||||
|
||||
clear: () => Object.values(KEYS).forEach((k) => localStorage.removeItem(k)),
|
||||
clear: () => {
|
||||
Object.values(KEYS).forEach((k) => localStorage.removeItem(k));
|
||||
removeCookie('auth-token');
|
||||
removeCookie('refresh-token');
|
||||
},
|
||||
};
|
||||
|
||||
31
apps/backoffice/src/app/iam/IamProviders.tsx
Normal file
31
apps/backoffice/src/app/iam/IamProviders.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import {
|
||||
AuthProvider,
|
||||
PermissionProvider,
|
||||
BrandingProvider,
|
||||
BreadcrumbProvider,
|
||||
UnitProvider,
|
||||
UserProvider,
|
||||
} from '@tria-plc/iamui-common';
|
||||
|
||||
interface IamProvidersProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export function IamProviders({ children }: IamProvidersProps) {
|
||||
return (
|
||||
<AuthProvider>
|
||||
<BrandingProvider>
|
||||
<BreadcrumbProvider>
|
||||
<PermissionProvider>
|
||||
<UnitProvider>
|
||||
<UserProvider>
|
||||
{children}
|
||||
</UserProvider>
|
||||
</UnitProvider>
|
||||
</PermissionProvider>
|
||||
</BreadcrumbProvider>
|
||||
</BrandingProvider>
|
||||
</AuthProvider>
|
||||
);
|
||||
}
|
||||
14
apps/backoffice/src/app/iam/pages/AuditLogPage.tsx
Normal file
14
apps/backoffice/src/app/iam/pages/AuditLogPage.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import { AuditLogPage } from '@tria-plc/iamui-common';
|
||||
import { IamProviders } from '../IamProviders';
|
||||
|
||||
export function AuditLogPageWrapper() {
|
||||
return (
|
||||
<IamProviders>
|
||||
<AuditLogPage
|
||||
moduleKey="backoffice"
|
||||
title="Audit Log"
|
||||
subtitle="Track all activities and changes in the backoffice"
|
||||
/>
|
||||
</IamProviders>
|
||||
);
|
||||
}
|
||||
@@ -1,10 +1,17 @@
|
||||
import { NavLink, Stack } from '@mantine/core';
|
||||
import { IconDashboard, IconBox } from '@tabler/icons-react';
|
||||
import {
|
||||
IconDashboard,
|
||||
IconBox,
|
||||
IconUsers,
|
||||
IconClipboardList,
|
||||
} from '@tabler/icons-react';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
|
||||
const NAV_ITEMS = [
|
||||
{ label: 'Dashboard', icon: IconDashboard, path: '/dashboard' },
|
||||
{ label: 'Items', icon: IconBox, path: '/items' },
|
||||
{ label: 'User Management', icon: IconUsers, path: '/users' },
|
||||
{ label: 'Audit Log', icon: IconClipboardList, path: '/audit-log' },
|
||||
];
|
||||
|
||||
export function AppSidebar() {
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
import { createBrowserRouter, RouterProvider, Navigate } from 'react-router-dom';
|
||||
import {
|
||||
UserManagementLayout,
|
||||
UserManagementPage,
|
||||
BulkUploadPage,
|
||||
ArchivedUsersPage,
|
||||
PositionManagementPage,
|
||||
CreatePositionPage,
|
||||
EditPositionPage,
|
||||
} from '@tria-plc/iamui-common';
|
||||
import { ProtectedRoute } from './ProtectedRoute';
|
||||
import { BackofficeLayout } from '../layouts/BackofficeLayout';
|
||||
import { AuthLayout } from '../layouts/AuthLayout';
|
||||
@@ -7,6 +16,8 @@ import { SignupPage } from '../features/auth/pages/SignupPage';
|
||||
import { SetPasswordPage } from '../features/auth/pages/SetPasswordPage';
|
||||
import { DashboardPage } from '../features/dashboard/pages/DashboardPage';
|
||||
import { ItemPage } from '../features/item/pages/ItemPage';
|
||||
import { AuditLogPageWrapper } from '../iam/pages/AuditLogPage';
|
||||
import { IamProviders } from '../iam/IamProviders';
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
@@ -18,6 +29,23 @@ const router = createBrowserRouter([
|
||||
{ path: '/', element: <Navigate to="/dashboard" replace /> },
|
||||
{ path: '/dashboard', element: <DashboardPage /> },
|
||||
{ path: '/items', element: <ItemPage /> },
|
||||
{
|
||||
path: '/users',
|
||||
element: (
|
||||
<IamProviders>
|
||||
<UserManagementLayout />
|
||||
</IamProviders>
|
||||
),
|
||||
children: [
|
||||
{ index: true, element: <UserManagementPage /> },
|
||||
{ path: 'bulk-upload', element: <BulkUploadPage /> },
|
||||
{ path: 'archived', element: <ArchivedUsersPage /> },
|
||||
{ path: 'position-management', element: <PositionManagementPage /> },
|
||||
{ path: 'position-management/new', element: <CreatePositionPage /> },
|
||||
{ path: 'position-management/edit/:id', element: <EditPositionPage /> },
|
||||
],
|
||||
},
|
||||
{ path: '/audit-log', element: <AuditLogPageWrapper /> },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -3,6 +3,7 @@ import { createRoot } from 'react-dom/client';
|
||||
import '@mantine/core/styles.css';
|
||||
import '@mantine/notifications/styles.css';
|
||||
import '@mantine/dates/styles.css';
|
||||
import '@tria-plc/iamui-common/styles.css';
|
||||
import './styles.css';
|
||||
import { App } from './app/app';
|
||||
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
import { AppProviders } from './providers/AppProviders';
|
||||
// src/main.tsx or App.tsx
|
||||
import { AppProviders, configureIam } from "@tria-plc/iamui-common";
|
||||
import "@tria-plc/iamui-common/styles.css";
|
||||
// import { AppProviders } from './providers/AppProviders';
|
||||
import { AppRouter } from './router';
|
||||
configureIam({ apiUrl: 'http://localhost:3001/api'});
|
||||
// import './styles.css';
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
// 2. Wrap with Providers so hooks like useAuthUser() work
|
||||
<AppProviders>
|
||||
<AppRouter />
|
||||
</AppProviders>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createBrowserRouter, RouterProvider, Navigate } from 'react-router-dom';
|
||||
import { createBrowserRouter, RouterProvider, Navigate, Route, Routes } from 'react-router-dom';
|
||||
import type { ReactNode } from 'react';
|
||||
import { PortalLayout } from './layouts/PortalLayout';
|
||||
import { LoginPage } from './features/auth/pages/LoginPage';
|
||||
@@ -6,6 +6,8 @@ import { SignupPage } from './features/auth/pages/SignupPage';
|
||||
import { SetPasswordPage } from './features/auth/pages/SetPasswordPage';
|
||||
import { DashboardPage } from './features/dashboard/pages/DashboardPage';
|
||||
|
||||
import { UserManagementPage, UserManagementLayout, Login} from "@tria-plc/iamui-common";
|
||||
|
||||
function getToken(): string | null {
|
||||
return localStorage.getItem('ema-portal-auth-token');
|
||||
}
|
||||
@@ -16,6 +18,12 @@ function ProtectedRoute({ children }: { children: ReactNode }) {
|
||||
}
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
element: <UserManagementLayout />,
|
||||
children: [
|
||||
{path: '/user', element: <UserManagementPage />}
|
||||
]
|
||||
},
|
||||
{ path: '/login', element: <LoginPage /> },
|
||||
{ path: '/signup', element: <SignupPage /> },
|
||||
{ path: '/set-password', element: <SetPasswordPage /> },
|
||||
@@ -37,5 +45,12 @@ const router = createBrowserRouter([
|
||||
]);
|
||||
|
||||
export function AppRouter() {
|
||||
return <RouterProvider router={router} />;
|
||||
return (
|
||||
<Routes>
|
||||
<Route path='/login' element={<Login/>}/>
|
||||
<Route element={<UserManagementLayout />}>
|
||||
<Route path="/users" element={<UserManagementPage />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@ import { StrictMode } from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import '@mantine/core/styles.css';
|
||||
import '@mantine/notifications/styles.css';
|
||||
import './styles.css';
|
||||
import "@tria-plc/iamui-common/styles.css";
|
||||
|
||||
import { configureIam } from "@tria-plc/iamui-common";
|
||||
import { App } from './app/app';
|
||||
|
||||
const root = document.getElementById('root');
|
||||
|
||||
Reference in New Issue
Block a user