85 lines
3.0 KiB
TypeScript
85 lines
3.0 KiB
TypeScript
import React, { useEffect } from 'react';
|
|
import { Helmet } from 'react-helmet';
|
|
import { Toaster } from 'react-hot-toast';
|
|
import { Navigate, Outlet, Route, Routes } from 'react-router-dom';
|
|
|
|
import { useAuth } from 'src/services/auth';
|
|
import { Dashboard } from './modules';
|
|
import { Layout } from './components';
|
|
import { AppIframe } from './modules/dashboard/AppIframe';
|
|
import { LoginCallback } from './modules/login/LoginCallback';
|
|
import { useApps } from './services/apps';
|
|
import { Login } from './modules/login';
|
|
import { Users } from './modules/users/Users';
|
|
import { AppSingle } from './modules/apps/AppSingle';
|
|
import { Apps } from './modules/apps/Apps';
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
function App() {
|
|
const { authToken, currentUser, isAdmin } = useAuth();
|
|
const redirectToLogin = !authToken || !currentUser?.app_roles;
|
|
|
|
const ProtectedRoute = () => {
|
|
return isAdmin ? <Outlet /> : <Navigate to="/dashboard" />;
|
|
};
|
|
|
|
const { apps, loadApps } = useApps();
|
|
|
|
useEffect(() => {
|
|
loadApps();
|
|
}, []);
|
|
|
|
return (
|
|
<>
|
|
<Helmet>
|
|
<title>Dashboard</title>
|
|
<meta name="description" content="Stackspin" />
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon_lit_transp.png" />
|
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/lit_logos/lit_transp_32x32.png" />
|
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/lit_logos/lit_transp_16x16" />
|
|
<link rel="manifest" href="/site.webmanifest" />
|
|
<meta name="msapplication-TileColor" content="#da532c" />
|
|
<meta name="theme-color" content="#ffffff" />
|
|
</Helmet>
|
|
|
|
<div className="app bg-gray-50 min-h-screen flex flex-col">
|
|
{redirectToLogin ? (
|
|
<Routes>
|
|
<Route path="/login" element={<Login />} />
|
|
<Route path="/login-callback" element={<LoginCallback />} />
|
|
<Route path="*" element={<Navigate to="/login" />} />
|
|
</Routes>
|
|
) : (
|
|
<Layout>
|
|
<Routes>
|
|
<Route path="/dashboard" element={<Dashboard />} />
|
|
{apps.map((app) => (
|
|
<Route key={app.name} path={app.slug} element={<AppIframe app={app} />} />
|
|
))}
|
|
<Route path="/users" element={<ProtectedRoute />}>
|
|
<Route index element={<Users />} />
|
|
</Route>
|
|
<Route path="/apps" element={<ProtectedRoute />}>
|
|
<Route path=":slug" element={<AppSingle />} />
|
|
<Route index element={<Apps />} />
|
|
</Route>
|
|
<Route path="*" element={<Navigate to="/dashboard" />} />
|
|
</Routes>
|
|
</Layout>
|
|
)}
|
|
|
|
{/* Place to load notifications */}
|
|
<div
|
|
aria-live="assertive"
|
|
className="fixed inset-0 flex items-end px-4 py-6 pointer-events-none sm:p-6 sm:items-start"
|
|
>
|
|
<div className="w-full flex flex-col items-center space-y-4 sm:items-end" />
|
|
</div>
|
|
</div>
|
|
<Toaster />
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default App;
|