Files
TriggerFrontend/src/App.tsx
2026-01-28 14:27:27 -06:00

153 lines
4.2 KiB
TypeScript

import {
colorsTuple,
createTheme,
DEFAULT_THEME,
MantineProvider,
mergeMantineTheme,
} from '@mantine/core';
import { Notifications } from '@mantine/notifications';
import { useCommonHooks, useQueryAPI } from 'hooks';
import { useEffect, useState } from 'react';
import {
createBrowserRouter,
createRoutesFromElements,
Navigate,
Route,
RouterProvider,
} from 'react-router-dom';
import { Loading, MainLayout } from './components';
import '@mantine/core/styles.css';
import '@mantine/dates/styles.css';
import '@mantine/notifications/styles.css';
import 'react-fontpicker-ts/dist/index.css';
import '@gfazioli/mantine-text-animate/styles.css';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { Homepage, Settings } from 'pages';
import type { Theme, ThemePlaylist } from 'types';
function App() {
const { data: allThemes, isFetched: isAllThemesFetched } = useQueryAPI({
endpoint: 'api/themes',
});
const { data: themePlaylists, isFetched: isThemePlaylistsFetched } = useQueryAPI({
endpoint: 'api/themePlaylists',
});
const { data: personalData, isFetched: isPersonalDataFetched } = useQueryAPI({
endpoint: 'api/personalData',
});
const {
theme,
setTheme,
themeName,
setThemeName,
handleThemeChange,
currentThemePlaylist,
} = useCommonHooks();
const [loaded, setLoaded] = useState<boolean>(false);
const overrides = createTheme({
primaryColor: 'primary',
colors: {
primary: colorsTuple(theme.primaryColor),
accent: colorsTuple(theme.accentColor),
background: colorsTuple(theme.backgroundColor),
border: colorsTuple(theme.borderColor),
search: colorsTuple(theme.searchColor),
},
white: theme?.backgroundColor,
fontFamily: `${personalData?.[0]?.defaultFont},Helvetica Neue,Roboto,system-ui,sans-serif`,
autoContrast: true,
});
const mantineTheme = mergeMantineTheme(DEFAULT_THEME, overrides);
const router = createBrowserRouter(
createRoutesFromElements(
<Route>
<Route path='' element={<MainLayout />}>
<Route
path='/'
element={<Navigate to={`/${import.meta.env.VITE_BASE_URL}`} />}
/>
<Route path={`/${import.meta.env.VITE_BASE_URL}`} element={<Homepage />} />
<Route
path={`/${import.meta.env.VITE_BASE_URL}/settings`}
element={<Settings />}
/>
<Route
path={`/${import.meta.env.VITE_BASE_URL}/settings/:tabValue`}
element={<Settings />}
/>
</Route>
</Route>,
),
);
useEffect(() => {
if (
allThemes &&
themeName &&
Object.keys(personalData).length > 0 &&
isThemePlaylistsFetched
) {
if (currentThemePlaylist === 'All') {
if (themeName === 'random') {
handleThemeChange(allThemes, false);
} else {
const temp = allThemes.find((t: Theme) => t.name === themeName);
setTheme(temp);
}
} else if (currentThemePlaylist === 'Time of Day') {
const themeList = JSON.parse(
themePlaylists?.find((t: ThemePlaylist) => t.name === currentThemePlaylist)
.themeList,
);
setTheme(
allThemes.find(
(t: Theme) =>
t.id === Number(themeList[Math.floor(new Date().getHours() / 6)]),
),
);
} else if (currentThemePlaylist === 'Backgrounds') {
handleThemeChange(
allThemes.filter((a: any) => !a.backgroundImage.toLowerCase().includes('none')),
false,
);
} else if (currentThemePlaylist === 'No Backgrounds') {
handleThemeChange(
allThemes.filter((a: any) => a.backgroundImage.toLowerCase().includes('none')),
false,
);
} else {
const themeList = JSON.parse(
themePlaylists?.find((t: ThemePlaylist) => t.name === currentThemePlaylist)
.themeList,
);
const filteredThemes = allThemes.filter((t: Theme) => themeList.includes(t.id));
setThemeName('random');
handleThemeChange(filteredThemes, false);
}
setLoaded(true);
}
}, [
isAllThemesFetched,
themeName,
allThemes,
currentThemePlaylist,
isThemePlaylistsFetched,
isPersonalDataFetched,
]);
return (
<>
{theme && (
<MantineProvider theme={mantineTheme}>
<Notifications />
<Loading loaded={loaded} />
<RouterProvider router={router} />
<ReactQueryDevtools initialIsOpen={false} />
</MantineProvider>
)}
</>
);
}
export default App;