Files
tasknote/client/src/App.tsx
T
CopilotGitHubcopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>RMCamposrmcampos
02fae25d12 fix: prevent premature route resolution before initial auth check completes (#45)
* Initial plan

* fix: add loading state to AuthContext to prevent premature route resolution

Agent-Logs-Url: https://github.com/RMCampos/tasknote/sessions/8b02c4fd-b37e-4d34-8910-6d075bde6b4b

Co-authored-by: RMCampos <2219519+RMCampos@users.noreply.github.com>

* restore: revert package-lock.json to original state

Co-authored-by: RMCampos <2219519+RMCampos@users.noreply.github.com>

* fix: add catch before finally in initial auth check useEffect

Agent-Logs-Url: https://github.com/RMCampos/tasknote/sessions/8b02c4fd-b37e-4d34-8910-6d075bde6b4b

Co-authored-by: RMCampos <2219519+RMCampos@users.noreply.github.com>

* test: address test warning missing act

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: RMCampos <2219519+RMCampos@users.noreply.github.com>
Co-authored-by: Ricardo Campos <ricardompcampos@gmail.com>
2026-05-07 11:54:21 -03:00

143 lines
3.3 KiB
TypeScript

import React, { useContext, useEffect, useState } from 'react';
import {
createBrowserRouter,
Navigate,
RouteObject,
RouterProvider
} from 'react-router';
import AuthContext from './context/AuthContext';
import BrowserRoutes from './routes';
import ProtectedRoute from './routes/ProtectedRoute';
import PrivateLayout from './layout/PrivateLayout';
import Landing from './views/Landing';
import Login from './views/Login';
import NotFound from './views/NotFound';
import Register from './views/Register';
import EmailConfirmation from './views/EmailConfirmation';
import ResetPassword from './views/ResetPassword';
import CompleteResetPassword from './views/CompleteResetPassword';
import SharedNote from './views/SharedNote';
import './styles/custom.scss';
/**
* The main application component that sets up routing based on the
* user's authentication status.
*
* @component
* @returns {React.ReactNode} The rendered component.
*/
function App(): React.ReactNode {
const { signed, loading } = useContext(AuthContext);
const [theme, setTheme] = useState(() => {
return localStorage.getItem('theme') ?? 'light';
});
/**
* Routes for the users who are not signed in.
* @type {RouteObject[]}
*/
const notSignedRouter: RouteObject[] = [
{
path: '/',
element: <Landing />
},
{
path: '/login',
element: <Login />
},
{
path: '/register',
element: <Register />
},
{
path: '/home',
element: <Navigate to="/login" replace />
},
{
path: '/email-confirmation',
element: <EmailConfirmation />
},
{
// The reset-password is where the password reset workflow starts
path: '/reset-password',
element: <ResetPassword />
},
{
path: '/finish-reset-password',
element: <CompleteResetPassword />
},
{
path: '/public/notes/:token',
element: <SharedNote />
},
{
path: '*',
element: <Navigate to="/" replace />
}
];
/**
* Routes for users who are signed in.
* @type {RouteObject[]}
*/
const signedRouter: RouteObject[] = [
{
path: '/',
element: <ProtectedRoute />,
children: [
{
element: <PrivateLayout />,
children: BrowserRoutes
}
]
},
{
path: '/public/notes/:token',
element: <SharedNote />
},
{
path: '*',
element: <NotFound />
}
];
/**
* Determines the appropriate router based on the user's authentication status.
* @returns {Router} The configured router.
*/
const getBrowserRouter = () => {
if (signed) {
return createBrowserRouter(signedRouter);
}
return createBrowserRouter(notSignedRouter);
};
const browserRouter = getBrowserRouter();
useEffect(() => {
document.body.setAttribute('data-bs-theme', theme);
localStorage.setItem('theme', theme);
}, [theme]);
const toggleTheme = () => {
setTheme(prev => (prev === 'light' ? 'dark' : 'light'));
};
return (
<>
<button
type="button"
className="btn btn-dark"
onClick={toggleTheme}
>
{theme === 'dark' ? '☀ Light Mode' : '🌙 Dark Mode'}
</button>
{/* Your routes or content here */}
{!loading && <RouterProvider router={browserRouter} />}
</>
);
};
export default App;