Skip to content
Snippets Groups Projects
App.tsx 2.54 KiB
Newer Older
Luka's avatar
Luka committed
import React, { useEffect, useState } from 'react';
import { Helmet } from 'react-helmet';
import { useMatch, Router, navigate, RouteComponentProps, Redirect } from '@reach/router';
import { Toaster } from 'react-hot-toast';

import { isValid } from 'src/services/api';
import { useAuth } from 'src/services/auth';
import { Apps, Dashboard, Users, Login, AppSingle } from './modules';
import { Layout } from './components';

type AppProps = RouteComponentProps;

// eslint-disable-next-line @typescript-eslint/no-unused-vars
function App(_: AppProps) {
  const { auth } = useAuth();
  const isLoginPage = useMatch('/login');

  const [initialized, setInitialized] = useState(false);
  const [initializedToken, setInitializedToken] = useState<string | null>(null);

  useEffect(() => {
    if (!isValid(auth) && !isLoginPage) {
      navigate('/login');
    }
  }, [auth, isLoginPage]);

  useEffect(() => {
    if (isValid(auth) && (!initialized || initializedToken !== auth.token)) {
      setInitialized(true);
      setInitializedToken(auth.token);
    }
  }, [auth, initialized, initializedToken]);

  return (
    <>
      <Helmet>
        <title>Stackspin</title>
        <meta name="description" content="Stackspin" />
        <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
        <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
        <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
        <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">
        {!isValid(auth) ? (
          <Router>
            <Login path="/login" />
          </Router>
        ) : (
          <Layout>
            <Router>
              <Dashboard path="/dashboard" />
              <Users path="/users" />
              <Apps path="/apps" />
              <AppSingle path="/apps/:id" />
            </Router>
          </Layout>
        )}

        {isValid(auth) ? <Redirect from="/" to="/dashboard" noThrow /> : <Redirect from="/" to="/login" noThrow />}

        {/* 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;