first commit

This commit is contained in:
2025-02-26 23:42:19 +01:00
commit 777ea98be1
283 changed files with 88266 additions and 0 deletions
@@ -0,0 +1,154 @@
import React, { useEffect, useState } from "react";
import NavLayout from "./NavLayout.tsx";
import { Route, Routes, useNavigate } from "react-router-dom";
import Home from "../Home.tsx";
import './MainLayout.css';
import { validateToken, GetUserPrivileges, TokenPayload, UnAuthorized } from '../Auth/Auth.tsx';
import '../LoadingScreen.css'
import AccountDropdown from "./AccountDropdown.tsx";
import AccountSettings from "../Auth/AccountSetting.tsx";
import { Api as Auth } from '../client/auth_client.ts';
import '../Pages/NotFound.tsx';
import NotFound from "../Pages/NotFound.tsx";
import "../Pages/UserAccountList.tsx";
import UserAccountList from "../Pages/UserAccountList.tsx";
const MainLayout: React.FC = () => {
const [tokenPayload, setTokenPayload] = useState<TokenPayload | null>(null);
const [tokenExpiryTime, setTokenExpiryTime] = useState<number | null>(null);
const [isAuthenticating, setIsAuthenticating] = useState(true);
const [privilegesList, setPrivilegesList] = useState<string[]>();
const [isTokenRegenerating, setIsTokenRegenerating] = useState<boolean>(false);
const navigate = useNavigate();
useEffect(() => {
const validateAndSetToken = async () => {
if (isTokenRegenerating) return;
const token = localStorage.getItem('authToken');
if (token) {
const payload = await validateToken(token);
if (payload) {
setTokenPayload(payload);
setTokenExpiryTime(payload.exp);
setIsAuthenticating(false);
} else {
localStorage.removeItem('authToken');
navigate('/login');
}
} else {
navigate('/login');
}
};
const getUserPrivileges = async () => {
const privileges = await GetUserPrivileges(navigate);
setPrivilegesList(privileges);
};
getUserPrivileges().then();
validateAndSetToken().then();
}, [navigate, isTokenRegenerating]);
useEffect(() => {
if (tokenExpiryTime) {
const currentTime = Math.floor(Date.now() / 1000);
const timeUntilExpiry = tokenExpiryTime - currentTime;
if (timeUntilExpiry > 900) {
const timeoutId = setTimeout(() => {
regenerateToken().then();
}, (timeUntilExpiry - 900) * 1000);
return () => clearTimeout(timeoutId);
} else {
regenerateToken().then();
}
}
}, [tokenExpiryTime]);
const regenerateToken = async () => {
if (isTokenRegenerating) return;
setIsTokenRegenerating(true);
const token = localStorage.getItem('authToken');
if (token) {
const client = new Auth({
baseUrl: 'auth',
securityWorker: () => ({ headers: { Authorization: `Bearer ${token}` } }),
});
try {
const responseToken = await client.regenerateToken.regenerateTokenList();
if (responseToken.status === 401) {
await UnAuthorized(navigate);
} else if (responseToken.data.token) {
const newToken = responseToken.data.token;
localStorage.setItem('authToken', newToken);
const newPayload = await validateToken(newToken);
if (newPayload) {
setTokenPayload(newPayload);
setTokenExpiryTime(newPayload.exp);
} else {
await validateToken(newToken);
}
}
} catch (error) {
console.error('Token regeneration failed', error);
localStorage.removeItem('authToken');
navigate('/login');
} finally {
setIsTokenRegenerating(false);
}
} else {
setIsTokenRegenerating(false);
navigate('/login');
}
};
if (isAuthenticating) {
return (
<div className="loading-screen">
<div className="spinner">
<div className="lds-ring">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
</div>
);
}
return (
<div className="page">
<div className="sidebar">
<NavLayout privilegeList={privilegesList} />
</div>
<main className="main-content">
<div className="top-row px-4">
{tokenPayload && (
<AccountDropdown
tokenPayload={tokenPayload}
privilegeList={privilegesList}
/>
)}
</div>
<div className="content px-4">
<Routes>
<Route path="/" element={<Home tokenPayload={tokenPayload} />} />
<Route
path="/accountSettings/"
element={<AccountSettings />}
/>
<Route path="/accounts/" element={<UserAccountList />} />
<Route path="/*" element={<NotFound />} />
</Routes>
</div>
</main>
</div>
);
};
export default MainLayout;