import React, { ReactNode, useEffect, useState } from 'react' import jwt from 'jsonwebtoken'; import menuNavBar from '../menuNavBar' import NavBar from '../components/NavBar' import FooterBar from '../components/FooterBar' import { useAppDispatch, useAppSelector } from '../stores/hooks' import Search from '../components/Search'; import { useRouter } from 'next/router' import {findMe, logoutUser} from "../stores/authSlice"; import axios from 'axios'; import { mdiAlertCircle } from '@mdi/js'; import BaseIcon from '../components/BaseIcon'; import NavBarItemPlain from '../components/NavBarItemPlain'; import moment from 'moment'; import {hasPermission} from "../helpers/userPermissions"; type Props = { children: ReactNode permission?: string } export default function LayoutAuthenticated({ children, permission }: Props) { const dispatch = useAppDispatch() const router = useRouter() const { token, currentUser } = useAppSelector((state) => state.auth) const bgColor = useAppSelector((state) => state.style.bgLayoutColor); const [lockoutBanner, setLockoutBanner] = useState(null); let localToken if (typeof window !== 'undefined') { // Perform localStorage action localToken = localStorage.getItem('token') } const isTokenValid = () => { const token = localStorage.getItem('token'); if (!token) return; const date = new Date().getTime() / 1000; const data = jwt.decode(token); if (!data) return; return date < data.exp; }; useEffect(() => { dispatch(findMe()); if (!isTokenValid()) { dispatch(logoutUser()); router.push('/login'); } }, [token, localToken]); useEffect(() => { if (!permission || !currentUser) return; if (!hasPermission(currentUser, permission)) router.push('/error'); }, [currentUser, permission]); useEffect(() => { const checkLockout = async () => { try { const response = await axios.get('/app_settings'); const settings = response.data; if (settings.lockoutEnabled && settings.lockoutUntil && moment(settings.lockoutUntil).isAfter(moment())) { const allowed = settings.allowedUserIds?.includes(currentUser?.id); setLockoutBanner({ message: settings.lockoutMessage || `System is currently locked for reconciliation until ${moment(settings.lockoutUntil).format('LLL')}.`, until: settings.lockoutUntil }); } } catch (err) { // console.error(err); // Fail silently on frontend if fetch fails } }; if (currentUser) { checkLockout(); } }, [currentUser]); const darkMode = useAppSelector((state) => state.style.darkMode) return (