diff --git a/src/App.tsx b/src/App.tsx index ca6d386..8317db1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,9 +4,8 @@ import { createTheme, mergeMantineTheme, } from '@mantine/core'; -import { useLocalStorage } from '@mantine/hooks'; import { ModalsProvider } from '@mantine/modals'; -import { useQueryAPI } from 'hooks'; +import { useCommonHooks, useQueryAPI } from 'hooks'; import { useEffect } from 'react'; import { Navigate, @@ -20,66 +19,47 @@ import '@mantine/core/styles.css'; //import Mantine V7 styles needed by MRT import '@mantine/dates/styles.css'; //if using mantine date picker features import 'mantine-react-table/styles.css'; //import MRT styles import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; -import { appTheme } from 'contexts'; -import { useAtom } from 'jotai'; import './index.css'; import { Homepage, Settings } from 'pages'; function App() { - const { data, isFetched } = useQueryAPI({ + const { data: allThemes, isFetched: isAllThemesFetched } = useQueryAPI({ endpoint: 'api/themes', }); - - const [themeName, _] = useLocalStorage({ - key: 'theme', - defaultValue: 'blackboard', - }); - - const [theme, setTheme] = useAtom(appTheme); + const { theme, setTheme, themeName, handleThemeChange } = useCommonHooks(); useEffect(() => { - if (data && themeName) { + if (allThemes && themeName) { if (themeName !== 'random') { - const temp = data.find((t: any) => t.name === themeName); + const temp = allThemes.find((t: any) => t.name === themeName); setTheme(temp); } else { - const enabled = data.filter((t: any) => t.randomEnabled); - if (enabled.length === 0) { - setTheme(data[0]); - } else { - const index = Math.floor(Math.random() * enabled.length); - setTheme(enabled[index]); - } + handleThemeChange(allThemes, false); } } - }, [isFetched, themeName]); - + }, [isAllThemesFetched, themeName]); const router = createBrowserRouter( createRoutesFromElements( - }> + }> } /> - } - /> + } /> } + element={} /> , ), ); - const overrides = createTheme({ white: theme?.backgroundColor, fontFamily: '-apple-system,Jost,BlinkMacSystemFont,Helvetica Neue,Roboto,sans-serif', }); - const mantineTheme = mergeMantineTheme(DEFAULT_THEME, overrides); + return ( <> {theme && ( diff --git a/src/components/DataTable/DataTable.tsx b/src/components/DataTable/DataTable.tsx index 1180815..afe33b7 100644 --- a/src/components/DataTable/DataTable.tsx +++ b/src/components/DataTable/DataTable.tsx @@ -9,9 +9,7 @@ import '../../../src/dataTableStyles.css'; import { ActionIcon, Button, Flex, Text } from '@mantine/core'; import { modals } from '@mantine/modals'; import { IconEdit, IconTrash } from '@tabler/icons-react'; -import { appTheme } from 'contexts'; -import { useMutationAPI } from 'hooks'; -import { useAtom } from 'jotai'; +import { useCommonHooks, useMutationAPI } from 'hooks'; import { FiPlus } from 'react-icons/fi'; import { actionIconClasses, buttonClasses } from 'styles'; @@ -30,7 +28,7 @@ export function DataTableComponent({ isLoading: boolean; endpoint: string; }) { - const [theme, _] = useAtom(appTheme); + const { theme } = useCommonHooks(); const { mutateAsync: createRow } = useMutationAPI(); const { mutateAsync: editRow } = useMutationAPI(); const { mutateAsync: deleteRow } = useMutationAPI(); @@ -112,7 +110,6 @@ export function DataTableComponent({ }, }, }, - renderCreateRowModalContent: ({ row }) => undefined, renderTopToolbarCustomActions: ({ table }) => { return ( <> diff --git a/src/components/HelpModal/HelpModal.tsx b/src/components/HelpModal/HelpModal.tsx index e0c4f57..620ea15 100644 --- a/src/components/HelpModal/HelpModal.tsx +++ b/src/components/HelpModal/HelpModal.tsx @@ -1,17 +1,11 @@ import { Divider, Group, Modal, Stack, Text } from '@mantine/core'; -import { appTheme } from 'contexts'; -import { useAtom } from 'jotai'; +import { useCommonHooks } from 'hooks'; import { modalClasses } from 'styles'; -export function HelpModal({ - setValue, - setProviderLabel, - setProviderURL, - providers, - providerModalOpened, - closeProviderModal, -}: any) { - const [theme, _] = useAtom(appTheme); +export function HelpModal({ providerModalOpened, closeProviderModal }: any) { + const { theme, providers, setSearchValue, setProviderLabel, setProviderURL } = + useCommonHooks(); + return ( { closeProviderModal(); - setValue(''); + setSearchValue(''); setProviderLabel('Google Search'); setProviderURL('https://www.google.com/search?q='); }} diff --git a/src/components/MainLayout.tsx b/src/components/MainLayout.tsx index 13623ab..5b41879 100644 --- a/src/components/MainLayout.tsx +++ b/src/components/MainLayout.tsx @@ -1,7 +1,9 @@ import { Box } from '@mantine/core'; +import { useCommonHooks } from 'hooks'; import { Outlet } from 'react-router-dom'; -export function MainLayout({ theme }: any) { +export function MainLayout() { + const { theme } = useCommonHooks(); return ( ([]); const [sunset, setSunset] = useState(100); - + const { theme, isMobile, hourly, setProviderLabel, setSearchValue, setProviderURL } = + useCommonHooks(); useEffect(() => { if (hourly) { setHourlyForecast(hourly.properties.periods.slice(1, 13)); @@ -51,7 +45,7 @@ export function WeatherModal({ onClose={() => { closeWeatherModal(); setProviderLabel('Google Search'); - setValue(''); + setSearchValue(''); setProviderURL('https://www.google.com/search?q='); }} style={{ @@ -119,9 +113,7 @@ export function WeatherModal({ > {hourlyForecast.length > 0 && hourlyForecast.map((h: any) => { - return ( - - ); + return ; })} diff --git a/src/hooks/helpers.ts b/src/hooks/helpers.ts index 269ff2b..fc7f8c7 100644 --- a/src/hooks/helpers.ts +++ b/src/hooks/helpers.ts @@ -45,3 +45,11 @@ export function containsProtocol(str: any) { const pattern = /^(https?:\/\/).*/i; return !!pattern.test(str); } + +export function runWakeCommand() { + const requestOptions = { + method: 'GET', + headers: { 'Content-Type': 'application/json' }, + }; + fetch(`/${import.meta.env.VITE_BASE_URL}/api/wakeDakota`, requestOptions); +} diff --git a/src/hooks/index.ts b/src/hooks/index.ts index de1742b..4e18b62 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -1,3 +1,3 @@ export { useQueryAPI, useWeatherAPI, useMutationAPI } from './useAPI'; -export { date, greet } from './helpers'; -export { validURL, containsProtocol } from './helpers'; +export { date, greet, runWakeCommand, validURL, containsProtocol } from './helpers'; +export { useCommonHooks } from './useCommonHooks'; diff --git a/src/hooks/useCommonHooks.ts b/src/hooks/useCommonHooks.ts new file mode 100644 index 0000000..3ef31ab --- /dev/null +++ b/src/hooks/useCommonHooks.ts @@ -0,0 +1,204 @@ +import { useLocalStorage } from '@mantine/hooks'; +import { appTheme } from 'contexts'; +import { useAtom } from 'jotai'; +import { useEffect, useState } from 'react'; +import { useQueryAPI, useWeatherAPI } from './useAPI'; + +export function useCommonHooks() { + const isMobile = window.matchMedia('(max-width: 600px)').matches; + const { + data: apps, + isFetching: isAppsFetching, + isLoading: isAppsLoading, + } = useQueryAPI({ endpoint: 'api/apps' }); + const { data: allThemes, isFetched: isAllThemesFetched } = useQueryAPI({ + endpoint: 'api/themes', + }); + const { data: backgrounds, isFetched: isBackgroundFetched } = useQueryAPI({ + endpoint: 'api/backgrounds', + }); + const { + data: messages, + isFetching: isMessagesFetching, + isFetched: isMessagesFetched, + isLoading: isMessagesLoading, + } = useQueryAPI({ + endpoint: 'api/messages', + }); + const { + data: linkData, + isFetched: linksIsFetched, + isFetching: linksIsFetching, + isLoading: linksIsLoading, + } = useQueryAPI({ + endpoint: 'api/links', + }); + const { + data: groupData, + isFetched: groupsIsFetched, + isFetching: groupsIsFetching, + isLoading: groupsIsLoading, + } = useQueryAPI({ + endpoint: 'api/categories', + }); + const { + data: personal, + isFetched: personalIsFetched, + isFetching: personalIsFetching, + isLoading: personalIsLoading, + } = useQueryAPI({ + endpoint: 'api/personalData', + }); + const { + data: providers, + isFetched: providersIsFetched, + isFetching: providersIsFetching, + isLoading: providersIsLoading, + } = useQueryAPI({ endpoint: 'api/providers' }); + const { data: basicWeather } = useWeatherAPI({ endpoint: 'baseline' }); + const { data: weather } = useWeatherAPI({ endpoint: 'current' }); + const { data: forecast } = useWeatherAPI({ endpoint: 'forecast' }); + const { data: hourly } = useWeatherAPI({ endpoint: 'hourly' }); + const [theme, setTheme] = useAtom(appTheme); + const [themeName, setThemeName] = useLocalStorage({ + key: 'theme', + defaultValue: 'blackboard', + }); + const [appFilter, setAppFilter] = useLocalStorage<[any]>({ + key: 'appFilter', + defaultValue: ['All'], + }); + const [bookmarkFilter, setBookmarkFilter] = useLocalStorage<[any]>({ + key: 'bookmarkFilter', + defaultValue: ['All'], + }); + const [currentTheme, setCurrentTheme] = useLocalStorage({ + key: 'theme', + defaultValue: 'blackboard', + }); + const [searchValue, setSearchValue] = useState(''); + const [providerLabel, setProviderLabel] = useState('Google Search'); + const [providerURL, setProviderURL] = useState('https://www.google.com/search?q='); + const handleThemeChange = (themes: any, save: any) => { + const enabled = themes + .filter((t: any) => t.randomEnabled) + .filter((t: any) => t.name !== theme.name); + if (enabled.length === 0) { + setTheme(themes[0]); + save && setThemeName(themes[0].name); + } else { + const index = Math.floor(Math.random() * enabled.length); + setTheme(enabled[index]); + save && setThemeName(enabled[index].name); + } + }; + + const [applicationData, setApplicationData] = useState([]); + + useEffect(() => { + if (apps && !isAppsFetching) { + setApplicationData(apps); + } + }, [apps, isAppsFetching]); + + const [bookmarkData, setBookmarkData] = useState([]); + + const [groups, setGroups] = useState([]); + + useEffect(() => { + if (linkData && linksIsFetched) { + setBookmarkData(linkData); + } + }, [linksIsFetched, linkData]); + + useEffect(() => { + if (groupData && groupsIsFetched) { + const groupList = groupData?.map((category: any) => { + return category.categoryName; + }); + setGroups(groupList); + } + }, [groupData, groupsIsFetched]); + + const [messageData, setMessageData] = useState([]); + + useEffect(() => { + if (messages && isMessagesFetched) { + setMessageData(messages); + } + }, [messages, isMessagesFetched]); + + const [personalData, setPersonalData] = useState([]); + + useEffect(() => { + if (personal && personalIsFetched) { + setPersonalData(personal); + } + }, [personal, personalIsFetched]); + + const [providerData, setProviderData] = useState([]); + + useEffect(() => { + if (providers && providersIsFetched) { + setProviderData(providers); + } + }, [providers, providersIsFetched]); + + return { + isMobile, + theme, + setTheme, + allThemes, + backgrounds, + isBackgroundFetched, + isAllThemesFetched, + messages, + isMessagesFetching, + basicWeather, + weather, + forecast, + hourly, + handleThemeChange, + themeName, + setThemeName, + appFilter, + setAppFilter, + bookmarkFilter, + setBookmarkFilter, + currentTheme, + setCurrentTheme, + searchValue, + setSearchValue, + providerLabel, + setProviderLabel, + providerURL, + setProviderURL, + providers, + providerData, + providersIsFetched, + providersIsFetching, + providersIsLoading, + linkData, + linksIsFetched, + groupData, + groupsIsFetched, + apps, + isAppsFetching, + isAppsLoading, + applicationData, + bookmarkData, + groups, + linksIsFetching, + linksIsLoading, + groupsIsFetching, + groupsIsLoading, + messageData, + isMessagesFetched, + isMessagesLoading, + personal, + personalData, + personalIsFetched, + personalIsFetching, + personalIsLoading, + }; +} diff --git a/src/pages/homepage/Homepage.tsx b/src/pages/homepage/Homepage.tsx index b98d83e..6e2f24f 100644 --- a/src/pages/homepage/Homepage.tsx +++ b/src/pages/homepage/Homepage.tsx @@ -1,6 +1,6 @@ import { Stack } from '@mantine/core'; -import { useDisclosure, useLocalStorage } from '@mantine/hooks'; -import { date, greet, useQueryAPI, useWeatherAPI } from 'hooks'; +import { useDisclosure } from '@mantine/hooks'; +import { date, greet, useCommonHooks } from 'hooks'; import { useEffect, useState } from 'react'; import { stackClasses } from 'styles'; import type { CurrentWeather, OutlookWeather } from 'types'; @@ -10,21 +10,18 @@ import Header from './components/Header/Header'; import Search from './components/Search/Search'; import SettingsButton from './components/SettingsButton'; -export function Homepage({ theme }: any) { - const [appFilter, setAppFilter] = useLocalStorage<[any]>({ - key: 'appFilter', - defaultValue: ['All'], - }); - const [bookmarkFilter, setBookmarkFilter] = useLocalStorage<[any]>({ - key: 'bookmarkFilter', - defaultValue: ['All'], - }); - const { data, isFetching } = useQueryAPI({ endpoint: 'api/messages' }); - const { data: basicWeather } = useWeatherAPI({ endpoint: 'baseline' }); - const { data: weather } = useWeatherAPI({ endpoint: 'current' }); - const { data: forecast } = useWeatherAPI({ endpoint: 'forecast' }); - const { data: hourly } = useWeatherAPI({ endpoint: 'hourly' }); +export function Homepage() { const [displayedGreeting, setDisplayedGreeting] = useState(''); + const { + appFilter, + bookmarkFilter, + isMobile, + messages, + isMessagesFetching, + weather, + basicWeather, + forecast, + } = useCommonHooks(); const [current, setCurrent] = useState({ icon: '', temperature: 0, @@ -47,17 +44,14 @@ export function Homepage({ theme }: any) { windDirection: 'N', }, ]); - const isMobile = window.matchMedia('(max-width: 600px)').matches; const [weatherModalOpened, { open: openWeatherModal, close: closeWeatherModal }] = useDisclosure(false); - const [providerLabel, setProviderLabel] = useState('Google Search'); - const [providerURL, setProviderURL] = useState('https://www.google.com/search?q='); - const [value, setValue] = useState(''); + useEffect(() => { - if (data) { - setDisplayedGreeting(greet(data)); + if (messages) { + setDisplayedGreeting(greet(messages)); } - }, [data, isFetching]); + }, [messages, isMessagesFetching]); useEffect(() => { if (weather && basicWeather) { @@ -119,19 +113,7 @@ export function Homepage({ theme }: any) { - - - + + + ); } diff --git a/src/pages/homepage/components/Applications/AppItem.tsx b/src/pages/homepage/components/Applications/AppItem.tsx index 004478d..8244533 100644 --- a/src/pages/homepage/components/Applications/AppItem.tsx +++ b/src/pages/homepage/components/Applications/AppItem.tsx @@ -1,10 +1,12 @@ import { Icon } from '@iconify/react'; import { Box, Stack, Text } from '@mantine/core'; +import { useCommonHooks } from 'hooks'; import { useState } from 'react'; import { stackClasses, textClasses } from 'styles'; -function AppItem({ url, icon, name, isMobile }: any) { +function AppItem({ url, icon, name }: any) { const [textDecoration, setTextDecoration] = useState('none'); + const { isMobile } = useCommonHooks(); return ( { - if (data && !isFetching) { - setApplications(data); - } - }, [data, isFetching]); +function Applications({ contentType }: any) { + const { isMobile, applicationData } = useCommonHooks(); return ( <> - {applications.length > 0 && contentType.length > 0 && ( + {applicationData.length > 0 && contentType.length > 0 && ( Applications @@ -32,7 +25,7 @@ function Applications({ contentType, isMobile }: any) { paddingBottom: 'var(--module-spacing)', }} > - {applications?.map((application: any) => { + {applicationData?.map((application: any) => { if ( contentType.includes(application.filterName) || contentType.includes('All') @@ -44,7 +37,6 @@ function Applications({ contentType, isMobile }: any) { url={application.url} icon={application.icon} category={application.category} - isMobile={isMobile} /> ); })} diff --git a/src/pages/homepage/components/Bookmarks/Bookmarks.tsx b/src/pages/homepage/components/Bookmarks/Bookmarks.tsx index 7d9d332..84aa080 100644 --- a/src/pages/homepage/components/Bookmarks/Bookmarks.tsx +++ b/src/pages/homepage/components/Bookmarks/Bookmarks.tsx @@ -1,30 +1,16 @@ import { Stack, Text } from '@mantine/core'; -import { useQueryAPI } from 'hooks'; -import { useEffect, useState } from 'react'; +import { useCommonHooks } from 'hooks'; import { textClasses } from 'styles'; import LinkGroups from './LinkGroups'; -function Links({ contentType, isMobile }: any) { - const { data: linkData, isFetched: linksIsFetched } = useQueryAPI({ - endpoint: 'api/links', - }); - const { data: groupData, isFetched: groupsIsFetched } = useQueryAPI({ - endpoint: 'api/categories', - }); - const [bookmarks, setBookmarks] = useState([]); - const [categories, setCategories] = useState([]); - - useEffect(() => { - if (linksIsFetched && groupsIsFetched) { - setBookmarks(linkData); - setCategories(groupData); - } - }, [linksIsFetched, groupsIsFetched]); +function Links({ contentType }: any) { + const { isMobile, linksIsFetched, groupsIsFetched, groups, bookmarkData } = + useCommonHooks(); return ( <> {groupsIsFetched && linksIsFetched && - categories?.length > 0 && + groups?.length > 0 && contentType.length > 0 && ( @@ -40,19 +26,18 @@ function Links({ contentType, isMobile }: any) { gridTemplateRows: 'auto', }} > - {categories.map((category: any) => { + {groups.map((category: any) => { if ( contentType.includes(category.filterName) || contentType.includes('All') ) { return ( bookmark.category === category.categoryName, + links={bookmarkData.filter( + (bookmark: any) => bookmark.category === category, )} - isMobile={isMobile} /> ); } diff --git a/src/pages/homepage/components/Bookmarks/LinkGroups.tsx b/src/pages/homepage/components/Bookmarks/LinkGroups.tsx index a540aa5..86e53c0 100644 --- a/src/pages/homepage/components/Bookmarks/LinkGroups.tsx +++ b/src/pages/homepage/components/Bookmarks/LinkGroups.tsx @@ -2,7 +2,7 @@ import { Stack, Text } from '@mantine/core'; import { textClasses } from 'styles'; import LinkItem from './LinkItem'; -function LinkGroups({ links, category, isMobile }: any) { +function LinkGroups({ links, category }: any) { return ( {links?.map((link: any) => ( - + ))} ); diff --git a/src/pages/homepage/components/Header/Header.tsx b/src/pages/homepage/components/Header/Header.tsx index ebeb8a4..c59c3f0 100644 --- a/src/pages/homepage/components/Header/Header.tsx +++ b/src/pages/homepage/components/Header/Header.tsx @@ -1,25 +1,20 @@ import { Group, Stack, Text } from '@mantine/core'; import { WeatherModal } from 'components'; +import { useCommonHooks } from 'hooks'; import { useEffect, useState } from 'react'; import { textClasses } from 'styles'; function Header({ greet, date, - isMobile, current, setCurrent, - weather, - basicWeather, outlook, - hourly, weatherModalOpened, closeWeatherModal, openWeatherModal, - setProviderLabel, - setProviderURL, - setValue, }: any) { + const { isMobile, weather, basicWeather } = useCommonHooks(); const [time, setTime] = useState(new Date()); function fixDigits(k: any) { if (k < 10) { @@ -80,7 +75,7 @@ function Header({ {greet} @@ -152,13 +147,8 @@ function Header({ ); diff --git a/src/pages/homepage/components/Search/Search.tsx b/src/pages/homepage/components/Search/Search.tsx index c71031e..90dec40 100644 --- a/src/pages/homepage/components/Search/Search.tsx +++ b/src/pages/homepage/components/Search/Search.tsx @@ -1,25 +1,26 @@ import { Stack, TextInput } from '@mantine/core'; import { useDisclosure } from '@mantine/hooks'; -import { HelpModal } from '../../../../components/HelpModal/HelpModal'; -import { WeatherModal } from '../../../../components/WeatherModal/WeatherModal'; -import { containsProtocol, useQueryAPI, validURL } from '../../../../hooks'; -import { textInputClasses } from '../../../../styles'; +import { HelpModal, WeatherModal } from 'components'; +import { containsProtocol, useCommonHooks, validURL } from 'hooks'; +import { textInputClasses } from 'styles'; export default function Search({ current, outlook, - hourly, weatherModalOpened, closeWeatherModal, openWeatherModal, - providerLabel, - setProviderLabel, - providerURL, - setProviderURL, - value, - setValue, }: any) { - const { data: providers } = useQueryAPI({ endpoint: 'api/providers' }); + const { + providerLabel, + setProviderLabel, + providerURL, + setProviderURL, + searchValue, + setSearchValue, + providers, + } = useCommonHooks(); + const [providerModalOpened, { open: openProviderModal, close: closeProviderModal }] = useDisclosure(false); @@ -72,10 +73,10 @@ export default function Search({ classNames={textInputClasses} spellCheck='true' leftSection={providerLabel} - value={value} - data-active={value !== ''} + value={searchValue} + data-active={searchValue !== ''} onChange={(item: any) => { - setValue(item.currentTarget.value); + setSearchValue(item.currentTarget.value); if ( item.target.value === '/?' || item.target.value === '!help' || @@ -104,22 +105,14 @@ export default function Search({ }} /> ); diff --git a/src/pages/homepage/components/SettingsButton.tsx b/src/pages/homepage/components/SettingsButton.tsx index eaba864..870e3a9 100644 --- a/src/pages/homepage/components/SettingsButton.tsx +++ b/src/pages/homepage/components/SettingsButton.tsx @@ -1,19 +1,26 @@ -import { Button, Menu, MultiSelect, NavLink } from '@mantine/core'; -import { useQueryAPI } from 'hooks'; +import { Button, Menu, MultiSelect, NavLink, Switch } from '@mantine/core'; +import { runWakeCommand, useCommonHooks, useQueryAPI } from 'hooks'; import { useEffect, useState } from 'react'; -import { FiMenu, FiMonitor } from 'react-icons/fi'; +import { FiMenu, FiMonitor, FiShuffle } from 'react-icons/fi'; import { useNavigate } from 'react-router-dom'; import { buttonClasses, menuClasses, navLinkClasses, selectClasses } from 'styles'; -function SettingsButton({ - appFilter, - setAppFilter, - bookmarkFilter, - setBookmarkFilter, -}: any) { +function SettingsButton() { const { data, isFetched } = useQueryAPI({ endpoint: 'api/appCategories' }); const [categories, setCategories] = useState([{ value: 'All', label: 'All' }]); const navigate = useNavigate(); + const { + currentTheme, + setCurrentTheme, + handleThemeChange, + theme, + allThemes, + appFilter, + setAppFilter, + bookmarkFilter, + setBookmarkFilter, + } = useCommonHooks(); + useEffect(() => { if (data) { const list: [any] = @@ -25,13 +32,6 @@ function SettingsButton({ } }, [data, isFetched]); - function runWakeCommand() { - const requestOptions = { - method: 'GET', - headers: { 'Content-Type': 'application/json' }, - }; - fetch(`/${import.meta.env.VITE_BASE_URL}/api/wakeDakota`, requestOptions); - } return ( @@ -59,6 +59,31 @@ function SettingsButton({ className={navLinkClasses.defaultNavLink} classNames={navLinkClasses} /> + { + setCurrentTheme(e.target.checked ? 'random' : theme.name); + }} + color={theme.primaryColor} + /> + } + onClick={() => {}} + className={navLinkClasses.defaultNavLink} + classNames={navLinkClasses} + /> + } + onClick={() => { + handleThemeChange(allThemes, true); + }} + className={navLinkClasses.defaultNavLink} + classNames={navLinkClasses} + /> @@ -76,7 +77,7 @@ export function Settings({ theme, setTheme, allThemes }: any) { - + diff --git a/src/pages/settings/components/Applications.tsx b/src/pages/settings/components/Applications.tsx index 07360c6..be0f119 100644 --- a/src/pages/settings/components/Applications.tsx +++ b/src/pages/settings/components/Applications.tsx @@ -1,21 +1,11 @@ import { Stack, Text } from '@mantine/core'; import { ApplicationColumns, DataTable } from 'components'; -import { useQueryAPI } from 'hooks'; -import { useEffect, useState } from 'react'; +import { useCommonHooks } from 'hooks'; import { textClasses } from 'styles'; const ApplicationSettings = () => { const endpoint = 'api/apps'; - const { data, isFetching, isLoading, isFetched } = useQueryAPI({ - endpoint: endpoint, - }); - const [applicationData, setApplicationData] = useState([]); - - useEffect(() => { - if (isFetched) { - setApplicationData(data); - } - }, [data, isFetching]); + const { isAppsFetching, isAppsLoading, applicationData } = useCommonHooks(); return ( @@ -26,8 +16,8 @@ const ApplicationSettings = () => { tableName='Applications' columns={ApplicationColumns()} tableData={applicationData} - isFetching={isFetching} - isLoading={isLoading} + isFetching={isAppsFetching} + isLoading={isAppsLoading} endpoint={endpoint} /> diff --git a/src/pages/settings/components/Bookmarks.tsx b/src/pages/settings/components/Bookmarks.tsx index 09d5899..876e8ee 100644 --- a/src/pages/settings/components/Bookmarks.tsx +++ b/src/pages/settings/components/Bookmarks.tsx @@ -1,31 +1,11 @@ import { Stack, Text } from '@mantine/core'; import { BookmarkColumns, DataTable } from 'components'; -import { useQueryAPI } from 'hooks'; -import { useEffect, useState } from 'react'; +import { useCommonHooks } from 'hooks'; import { textClasses } from 'styles'; const BookmarkSettings = () => { const endpoint = 'api/links'; - const { data, isFetching, isLoading, isFetched } = useQueryAPI({ - endpoint: endpoint, - }); - const { data: groupData } = useQueryAPI({ endpoint: 'api/categories' }); - const [bookmarkData, setBookmarkData] = useState([]); - const [groups, setGroups] = useState([]); + const { groups, bookmarkData, linksIsFetching, linksIsLoading } = useCommonHooks(); - useEffect(() => { - if (isFetched) { - setBookmarkData(data); - } - }); - - useEffect(() => { - if (groupData) { - const groupList = groupData?.map((category: any) => { - return category.categoryName; - }); - setGroups(groupList); - } - }, [groupData]); return ( @@ -35,8 +15,8 @@ const BookmarkSettings = () => { tableName='Applications' columns={BookmarkColumns(groups)} tableData={bookmarkData} - isFetching={isFetching} - isLoading={isLoading} + isFetching={linksIsFetching} + isLoading={linksIsLoading} endpoint={endpoint} /> diff --git a/src/pages/settings/components/Categories.tsx b/src/pages/settings/components/Categories.tsx index 8f519eb..54f8d44 100644 --- a/src/pages/settings/components/Categories.tsx +++ b/src/pages/settings/components/Categories.tsx @@ -1,21 +1,10 @@ import { Stack, Text } from '@mantine/core'; import { CategoryColumns, DataTable } from 'components'; -import { useEffect, useState } from 'react'; -import { useQueryAPI } from '../../../hooks/useAPI'; +import { useCommonHooks } from 'hooks'; import { textClasses } from '../../../styles'; const CategorySettings = () => { const endpoint = 'api/categories'; - const { data, isFetching, isLoading, isFetched } = useQueryAPI({ - endpoint: endpoint, - }); - const [categoryData, setCategoryData] = useState([]); - - useEffect(() => { - if (data && isFetched) { - setCategoryData(data); - } - }, [data, isFetched]); - + const { groupData, groupsIsFetching, groupsIsLoading } = useCommonHooks(); return ( @@ -24,9 +13,9 @@ const CategorySettings = () => { diff --git a/src/pages/settings/components/Messages.tsx b/src/pages/settings/components/Messages.tsx index 2c6fc32..23284e0 100644 --- a/src/pages/settings/components/Messages.tsx +++ b/src/pages/settings/components/Messages.tsx @@ -1,21 +1,10 @@ import { Stack, Text } from '@mantine/core'; import { DataTable, MessagesColumns } from 'components'; -import { useQueryAPI } from 'hooks'; -import { useEffect, useState } from 'react'; +import { useCommonHooks } from 'hooks'; import { textClasses } from 'styles'; const MessageSettings = () => { const endpoint = 'api/messages'; - const { data, isFetching, isLoading, isFetched } = useQueryAPI({ - endpoint: endpoint, - }); - const [messageData, setMessageData] = useState([]); - - useEffect(() => { - if (isFetched) { - setMessageData(data); - } - }); - + const { messageData, isMessagesFetching, isMessagesLoading } = useCommonHooks(); return ( @@ -25,8 +14,8 @@ const MessageSettings = () => { tableName='Messages' columns={MessagesColumns()} tableData={messageData} - isFetching={isFetching} - isLoading={isLoading} + isFetching={isMessagesFetching} + isLoading={isMessagesLoading} endpoint={endpoint} /> diff --git a/src/pages/settings/components/Personalization.tsx b/src/pages/settings/components/Personalization.tsx index 49b59e6..834a5c4 100644 --- a/src/pages/settings/components/Personalization.tsx +++ b/src/pages/settings/components/Personalization.tsx @@ -1,20 +1,10 @@ import { Text } from '@mantine/core'; import { DataTable, PersonalizationColumns } from 'components'; -import { useQueryAPI } from 'hooks'; -import { useEffect, useState } from 'react'; +import { useCommonHooks } from 'hooks'; import { textClasses } from 'styles'; const PersonalizationSettings = () => { const endpoint = 'api/personalData'; - const { data, isFetching, isLoading, isFetched } = useQueryAPI({ - endpoint: endpoint, - }); - const [personalData, setPersonalData] = useState([]); - - useEffect(() => { - if (isFetched) { - setPersonalData(data); - } - }); + const { personalData, personalIsFetching, personalIsLoading } = useCommonHooks(); return ( <> @@ -25,8 +15,8 @@ const PersonalizationSettings = () => { tableName='Personalization' columns={PersonalizationColumns()} tableData={personalData} - isFetching={isFetching} - isLoading={isLoading} + isFetching={personalIsFetching} + isLoading={personalIsLoading} endpoint={endpoint} /> diff --git a/src/pages/settings/components/SearchProviders.tsx b/src/pages/settings/components/SearchProviders.tsx index 07d2fac..06d4827 100644 --- a/src/pages/settings/components/SearchProviders.tsx +++ b/src/pages/settings/components/SearchProviders.tsx @@ -1,21 +1,11 @@ import { Stack, Text } from '@mantine/core'; import { DataTable, SearchProviderColumns } from 'components'; -import { useQueryAPI } from 'hooks'; -import { useEffect, useState } from 'react'; +import { useCommonHooks } from 'hooks'; import { textClasses } from 'styles'; const SearchProviderSettings = () => { const endpoint = 'api/providers'; - const { data, isFetching, isLoading, isFetched } = useQueryAPI({ - endpoint: endpoint, - }); - const [providerData, setProviderData] = useState([]); - - useEffect(() => { - if (isFetched) { - setProviderData(data); - } - }); + const { providerData, providersIsFetching, providersIsLoading } = useCommonHooks(); return ( @@ -26,8 +16,8 @@ const SearchProviderSettings = () => { tableName='Categories' columns={SearchProviderColumns()} tableData={providerData} - isFetching={isFetching} - isLoading={isLoading} + isFetching={providersIsFetching} + isLoading={providersIsLoading} endpoint={endpoint} /> diff --git a/src/pages/settings/components/ThemeCard.tsx b/src/pages/settings/components/ThemeCard.tsx index 0e6c5dc..686d50d 100644 --- a/src/pages/settings/components/ThemeCard.tsx +++ b/src/pages/settings/components/ThemeCard.tsx @@ -1,21 +1,14 @@ import { ActionIcon, Box, Button, Group, Overlay, Stack, Text } from '@mantine/core'; +import { useCommonHooks } from 'hooks'; import { useState } from 'react'; import { FiEdit, FiShuffle, FiTrash, FiX } from 'react-icons/fi'; import { actionIconClasses } from 'styles'; -function ThemeCard({ - handleOpen, - handleDeleteTheme, - theme, - allThemes, - setTheme, - cardTheme, - currentTheme, - setValue, - createTheme, -}: any) { +function ThemeCard({ cardTheme, handleOpen, handleDeleteTheme, createTheme }: any) { const [hover, setHover] = useState(false); const [shift, setShift] = useState(0); + const { handleThemeChange, currentTheme, setCurrentTheme, theme, allThemes } = + useCommonHooks(); return ( { - setValue(cardTheme.name); + setCurrentTheme(cardTheme.name); }} > {hover && currentTheme !== 'random' && } @@ -174,15 +166,7 @@ function ThemeCard({ > { - const enabled = allThemes - .filter((t: any) => t.randomEnabled) - .filter((t: any) => t.name !== theme.name); - if (enabled.length === 0) { - setTheme(allThemes[0]); - } else { - const index = Math.floor(Math.random() * enabled.length); - setTheme(enabled[index]); - } + handleThemeChange(allThemes, false); }} style={{ fontSize: '2em', diff --git a/src/pages/settings/components/ThemeModal.tsx b/src/pages/settings/components/ThemeModal.tsx index 2619bac..3ad94db 100644 --- a/src/pages/settings/components/ThemeModal.tsx +++ b/src/pages/settings/components/ThemeModal.tsx @@ -13,6 +13,7 @@ import { Text, TextInput, } from '@mantine/core'; +import { useCommonHooks } from 'hooks'; import { FiSave, FiX } from 'react-icons/fi'; import { modalClasses, selectClasses, textClasses } from 'styles'; import ThemeModalContent from './ThemeModalContent'; @@ -22,7 +23,6 @@ function ThemeModal({ handleClose, selectedTheme, setSelectedTheme, - theme, setColorId, colorId, setColorValue, @@ -33,6 +33,7 @@ function ThemeModal({ closePicker, handleSaveTheme, }: any) { + const { theme } = useCommonHooks(); return ( (''); const [colorValue, setColorValue] = useState('#000000'); - const [currentTheme, setValue] = useLocalStorage({ - key: 'theme', - defaultValue: 'blackboard', - }); - const { data: backgrounds, isFetched: isBackgroundFetched } = useQueryAPI({ - endpoint: 'api/backgrounds', - }); + const [backgroundList, setBackgroundList] = useState(['None']); const [selectedTheme, setSelectedTheme] = useState({}); const { mutateAsync: createTheme } = useMutationAPI(); const { mutateAsync: deleteTheme } = useMutationAPI(); - const isMobile = window.matchMedia('(max-width: 600px)').matches; + + const { + currentTheme, + setCurrentTheme, + backgrounds, + isBackgroundFetched, + isMobile, + theme, + allThemes, + } = useCommonHooks(); useEffect(() => { if (backgrounds && isBackgroundFetched) { @@ -114,7 +117,7 @@ function ThemesSettings({ theme, setTheme, allThemes }: any) { labelPosition='left' checked={currentTheme === 'random'} onChange={(e) => { - setValue(e.target.checked ? 'random' : theme.name); + setCurrentTheme(e.target.checked ? 'random' : theme.name); }} color={theme.primaryColor} /> @@ -158,14 +161,9 @@ function ThemesSettings({ theme, setTheme, allThemes }: any) { }} >