Slight refactor
This commit is contained in:
42
src/App.tsx
42
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<any>({
|
||||
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(
|
||||
<Route>
|
||||
<Route path='' element={<MainLayout theme={theme} />}>
|
||||
<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 theme={theme} />}
|
||||
/>
|
||||
<Route path={`/${import.meta.env.VITE_BASE_URL}`} element={<Homepage />} />
|
||||
<Route
|
||||
path={`/${import.meta.env.VITE_BASE_URL}/settings`}
|
||||
element={<Settings theme={theme} setTheme={setTheme} allThemes={data} />}
|
||||
element={<Settings />}
|
||||
/>
|
||||
</Route>
|
||||
</Route>,
|
||||
),
|
||||
);
|
||||
|
||||
const overrides = createTheme({
|
||||
white: theme?.backgroundColor,
|
||||
fontFamily: '-apple-system,Jost,BlinkMacSystemFont,Helvetica Neue,Roboto,sans-serif',
|
||||
});
|
||||
|
||||
const mantineTheme = mergeMantineTheme(DEFAULT_THEME, overrides);
|
||||
|
||||
return (
|
||||
<>
|
||||
{theme && (
|
||||
|
||||
@@ -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 (
|
||||
<>
|
||||
|
||||
@@ -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 (
|
||||
<Modal.Root
|
||||
size={'60%'}
|
||||
@@ -20,7 +14,7 @@ export function HelpModal({
|
||||
opened={providerModalOpened}
|
||||
onClose={() => {
|
||||
closeProviderModal();
|
||||
setValue('');
|
||||
setSearchValue('');
|
||||
setProviderLabel('Google Search');
|
||||
setProviderURL('https://www.google.com/search?q=');
|
||||
}}
|
||||
|
||||
@@ -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 (
|
||||
<Box
|
||||
style={{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Icon } from '@iconify/react/dist/iconify.js';
|
||||
import { Box, Card, Center, Group, Image, Stack, Text } from '@mantine/core';
|
||||
import { useCommonHooks } from 'hooks';
|
||||
|
||||
export enum WindDirection {
|
||||
N = 0,
|
||||
@@ -12,7 +13,8 @@ export enum WindDirection {
|
||||
NW = 315,
|
||||
}
|
||||
|
||||
export default function HourlyCard({ weather, isMobile }: any) {
|
||||
export default function HourlyCard({ weather }: any) {
|
||||
const { isMobile } = useCommonHooks();
|
||||
return (
|
||||
<Stack gap={0} align='center' mx={isMobile ? '.25rem' : 0}>
|
||||
<Card
|
||||
|
||||
@@ -1,28 +1,22 @@
|
||||
import { Box, Center, Divider, Group, Modal, Stack } from '@mantine/core';
|
||||
import { useAtom } from 'jotai';
|
||||
import { modalClasses } from 'styles';
|
||||
import SmallOutlookCard from './SmallOutlookCard';
|
||||
import SmallWeatherCard from './SmallWeatherCard';
|
||||
|
||||
import { useCommonHooks } from 'hooks';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { appTheme } from '../../contexts/theme';
|
||||
import HourlyCard from './HourlyCard';
|
||||
|
||||
export function WeatherModal({
|
||||
current,
|
||||
outlook,
|
||||
hourly,
|
||||
closeWeatherModal,
|
||||
weatherModalOpened,
|
||||
setProviderLabel,
|
||||
setProviderURL,
|
||||
setValue,
|
||||
isMobile,
|
||||
}: any) {
|
||||
const [theme, _] = useAtom(appTheme);
|
||||
const [hourlyForecast, setHourlyForecast] = useState<any>([]);
|
||||
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 (
|
||||
<HourlyCard key={h.number} weather={h} isMobile={isMobile} />
|
||||
);
|
||||
return <HourlyCard key={h.number} weather={h} />;
|
||||
})}
|
||||
</Box>
|
||||
</Group>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
204
src/hooks/useCommonHooks.ts
Normal file
204
src/hooks/useCommonHooks.ts
Normal file
@@ -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<any>({
|
||||
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<any>({
|
||||
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<any>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (apps && !isAppsFetching) {
|
||||
setApplicationData(apps);
|
||||
}
|
||||
}, [apps, isAppsFetching]);
|
||||
|
||||
const [bookmarkData, setBookmarkData] = useState<any>([]);
|
||||
|
||||
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<any>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (messages && isMessagesFetched) {
|
||||
setMessageData(messages);
|
||||
}
|
||||
}, [messages, isMessagesFetched]);
|
||||
|
||||
const [personalData, setPersonalData] = useState<any>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (personal && personalIsFetched) {
|
||||
setPersonalData(personal);
|
||||
}
|
||||
}, [personal, personalIsFetched]);
|
||||
|
||||
const [providerData, setProviderData] = useState<any>([]);
|
||||
|
||||
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,
|
||||
};
|
||||
}
|
||||
@@ -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<CurrentWeather>({
|
||||
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) {
|
||||
<Stack gap={0} className={stackClasses.containerStack} justify='center'>
|
||||
<Search
|
||||
current={current}
|
||||
setCurrent={setCurrent}
|
||||
outlook={outlook}
|
||||
setOutlook={setOutlook}
|
||||
weather={weather}
|
||||
basicWeather={basicWeather}
|
||||
forecast={forecast}
|
||||
hourly={hourly}
|
||||
providerLabel={providerLabel}
|
||||
setProviderLabel={setProviderLabel}
|
||||
providerURL={providerURL}
|
||||
setProviderURL={setProviderURL}
|
||||
value={value}
|
||||
setValue={setValue}
|
||||
weatherModalOpened={weatherModalOpened}
|
||||
closeWeatherModal={closeWeatherModal}
|
||||
openWeatherModal={openWeatherModal}
|
||||
@@ -139,30 +121,16 @@ export function Homepage({ theme }: any) {
|
||||
<Header
|
||||
date={date(isMobile)}
|
||||
greet={displayedGreeting}
|
||||
isMobile={isMobile}
|
||||
current={current}
|
||||
setCurrent={setCurrent}
|
||||
outlook={outlook}
|
||||
weather={weather}
|
||||
basicWeather={basicWeather}
|
||||
forecast={forecast}
|
||||
hourly={hourly}
|
||||
setProviderLabel={setProviderLabel}
|
||||
setProviderURL={setProviderURL}
|
||||
setValue={setValue}
|
||||
weatherModalOpened={weatherModalOpened}
|
||||
closeWeatherModal={closeWeatherModal}
|
||||
openWeatherModal={openWeatherModal}
|
||||
/>
|
||||
<Applications contentType={appFilter} isMobile={isMobile} />
|
||||
<Bookmarks contentType={bookmarkFilter} isMobile={isMobile} />
|
||||
<SettingsButton
|
||||
theme={theme}
|
||||
setAppFilter={setAppFilter}
|
||||
appFilter={appFilter}
|
||||
setBookmarkFilter={setBookmarkFilter}
|
||||
bookmarkFilter={bookmarkFilter}
|
||||
/>
|
||||
<Applications contentType={appFilter} />
|
||||
<Bookmarks contentType={bookmarkFilter} />
|
||||
<SettingsButton />
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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<string>('none');
|
||||
const { isMobile } = useCommonHooks();
|
||||
|
||||
return (
|
||||
<Box
|
||||
@@ -15,11 +17,11 @@ function AppItem({ url, icon, name, isMobile }: any) {
|
||||
className={stackClasses.appItemBox}
|
||||
>
|
||||
<Stack
|
||||
align={isMobile && 'center'}
|
||||
justify={isMobile && 'center'}
|
||||
align={isMobile ? 'center' : undefined}
|
||||
justify={isMobile ? 'center' : undefined}
|
||||
style={{
|
||||
height: '64px',
|
||||
width: isMobile && '100%',
|
||||
width: isMobile ? '100%' : undefined,
|
||||
marginRight: isMobile ? '0' : '1em',
|
||||
marginLeft: isMobile ? '0' : '1em',
|
||||
paddingTop: isMobile ? '0' : '15px',
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
import { Stack, Text } from '@mantine/core';
|
||||
import { useQueryAPI } from 'hooks';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useCommonHooks } from 'hooks';
|
||||
import { textClasses } from 'styles';
|
||||
import AppItem from './AppItem';
|
||||
|
||||
function Applications({ contentType, isMobile }: any) {
|
||||
const { data, isFetching } = useQueryAPI({ endpoint: 'api/apps' });
|
||||
const [applications, setApplications] = useState([]);
|
||||
useEffect(() => {
|
||||
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 && (
|
||||
<Stack id='apps' style={{ gap: 0 }}>
|
||||
<Text className={textClasses.sectionTitle} classNames={textClasses}>
|
||||
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}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -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 && (
|
||||
<Stack id='links' style={{ gap: 0 }}>
|
||||
<Text className={textClasses.sectionTitle} classNames={textClasses}>
|
||||
@@ -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 (
|
||||
<LinkGroups
|
||||
key={category.id}
|
||||
key={category}
|
||||
category={category.categoryName}
|
||||
links={bookmarks.filter(
|
||||
(bookmark: any) => bookmark.category === category.categoryName,
|
||||
links={bookmarkData.filter(
|
||||
(bookmark: any) => bookmark.category === category,
|
||||
)}
|
||||
isMobile={isMobile}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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 (
|
||||
<Stack
|
||||
style={{
|
||||
@@ -16,7 +16,7 @@ function LinkGroups({ links, category, isMobile }: any) {
|
||||
{category}
|
||||
</Text>
|
||||
{links?.map((link: any) => (
|
||||
<LinkItem key={link.name} link={link} isMobile={isMobile} />
|
||||
<LinkItem key={link.name} link={link} />
|
||||
))}
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -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({
|
||||
<Text
|
||||
className={textClasses.greeting}
|
||||
classNames={textClasses}
|
||||
fz={isMobile && 24}
|
||||
fz={isMobile ? 24 : undefined}
|
||||
>
|
||||
{greet}
|
||||
</Text>
|
||||
@@ -152,13 +147,8 @@ function Header({
|
||||
<WeatherModal
|
||||
current={current}
|
||||
outlook={outlook}
|
||||
hourly={hourly}
|
||||
closeWeatherModal={closeWeatherModal}
|
||||
weatherModalOpened={weatherModalOpened}
|
||||
setProviderLabel={setProviderLabel}
|
||||
setProviderURL={setProviderURL}
|
||||
setValue={setValue}
|
||||
isMobile={isMobile}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -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({
|
||||
}}
|
||||
/>
|
||||
<HelpModal
|
||||
providers={providers}
|
||||
providerModalOpened={providerModalOpened}
|
||||
closeProviderModal={closeProviderModal}
|
||||
setValue={setValue}
|
||||
setProviderLabel={setProviderLabel}
|
||||
setProviderURL={setProviderURL}
|
||||
/>
|
||||
<WeatherModal
|
||||
current={current}
|
||||
outlook={outlook}
|
||||
hourly={hourly}
|
||||
closeWeatherModal={closeWeatherModal}
|
||||
weatherModalOpened={weatherModalOpened}
|
||||
setValue={setValue}
|
||||
setProviderLabel={setProviderLabel}
|
||||
setProviderURL={setProviderURL}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -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 (
|
||||
<Menu withinPortal={false} withArrow shadow='md' position='top'>
|
||||
<Menu.Target>
|
||||
@@ -59,6 +59,31 @@ function SettingsButton({
|
||||
className={navLinkClasses.defaultNavLink}
|
||||
classNames={navLinkClasses}
|
||||
/>
|
||||
<NavLink
|
||||
label='Shuffle Themes'
|
||||
leftSection={
|
||||
<Switch
|
||||
labelPosition='left'
|
||||
checked={currentTheme === 'random'}
|
||||
onChange={(e) => {
|
||||
setCurrentTheme(e.target.checked ? 'random' : theme.name);
|
||||
}}
|
||||
color={theme.primaryColor}
|
||||
/>
|
||||
}
|
||||
onClick={() => {}}
|
||||
className={navLinkClasses.defaultNavLink}
|
||||
classNames={navLinkClasses}
|
||||
/>
|
||||
<NavLink
|
||||
label='Random Theme'
|
||||
leftSection={<FiShuffle />}
|
||||
onClick={() => {
|
||||
handleThemeChange(allThemes, true);
|
||||
}}
|
||||
className={navLinkClasses.defaultNavLink}
|
||||
classNames={navLinkClasses}
|
||||
/>
|
||||
</NavLink>
|
||||
<MultiSelect
|
||||
label='App Filter'
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ActionIcon, Group, Stack, Tabs, Text } from '@mantine/core';
|
||||
import { useCommonHooks } from 'hooks';
|
||||
import {
|
||||
FiArrowLeftCircle,
|
||||
FiBook,
|
||||
@@ -19,8 +20,8 @@ import Personalization from './components/Personalization';
|
||||
import SearchProviders from './components/SearchProviders';
|
||||
import Themes from './components/Themes';
|
||||
|
||||
export function Settings({ theme, setTheme, allThemes }: any) {
|
||||
const isMobile = window.matchMedia('(max-width: 600px)').matches;
|
||||
export function Settings() {
|
||||
const { isMobile } = useCommonHooks();
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<Stack px={'2rem'}>
|
||||
@@ -76,7 +77,7 @@ export function Settings({ theme, setTheme, allThemes }: any) {
|
||||
<Categories />
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value='themes'>
|
||||
<Themes theme={theme} setTheme={setTheme} allThemes={allThemes} />
|
||||
<Themes />
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value='providers'>
|
||||
<SearchProviders />
|
||||
|
||||
@@ -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<any>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isFetched) {
|
||||
setApplicationData(data);
|
||||
}
|
||||
}, [data, isFetching]);
|
||||
const { isAppsFetching, isAppsLoading, applicationData } = useCommonHooks();
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
@@ -26,8 +16,8 @@ const ApplicationSettings = () => {
|
||||
tableName='Applications'
|
||||
columns={ApplicationColumns()}
|
||||
tableData={applicationData}
|
||||
isFetching={isFetching}
|
||||
isLoading={isLoading}
|
||||
isFetching={isAppsFetching}
|
||||
isLoading={isAppsLoading}
|
||||
endpoint={endpoint}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
@@ -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<any>([]);
|
||||
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 (
|
||||
<Stack>
|
||||
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
||||
@@ -35,8 +15,8 @@ const BookmarkSettings = () => {
|
||||
tableName='Applications'
|
||||
columns={BookmarkColumns(groups)}
|
||||
tableData={bookmarkData}
|
||||
isFetching={isFetching}
|
||||
isLoading={isLoading}
|
||||
isFetching={linksIsFetching}
|
||||
isLoading={linksIsLoading}
|
||||
endpoint={endpoint}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
@@ -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<any>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (data && isFetched) {
|
||||
setCategoryData(data);
|
||||
}
|
||||
}, [data, isFetched]);
|
||||
|
||||
const { groupData, groupsIsFetching, groupsIsLoading } = useCommonHooks();
|
||||
return (
|
||||
<Stack>
|
||||
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
||||
@@ -24,9 +13,9 @@ const CategorySettings = () => {
|
||||
<DataTable
|
||||
tableName='Categories'
|
||||
columns={CategoryColumns()}
|
||||
tableData={categoryData}
|
||||
isFetching={isFetching}
|
||||
isLoading={isLoading}
|
||||
tableData={groupData ?? []}
|
||||
isFetching={groupsIsFetching}
|
||||
isLoading={groupsIsLoading}
|
||||
endpoint={endpoint}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
@@ -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<any>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isFetched) {
|
||||
setMessageData(data);
|
||||
}
|
||||
});
|
||||
|
||||
const { messageData, isMessagesFetching, isMessagesLoading } = useCommonHooks();
|
||||
return (
|
||||
<Stack>
|
||||
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
||||
@@ -25,8 +14,8 @@ const MessageSettings = () => {
|
||||
tableName='Messages'
|
||||
columns={MessagesColumns()}
|
||||
tableData={messageData}
|
||||
isFetching={isFetching}
|
||||
isLoading={isLoading}
|
||||
isFetching={isMessagesFetching}
|
||||
isLoading={isMessagesLoading}
|
||||
endpoint={endpoint}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
@@ -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<any>([]);
|
||||
|
||||
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}
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -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<any>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isFetched) {
|
||||
setProviderData(data);
|
||||
}
|
||||
});
|
||||
const { providerData, providersIsFetching, providersIsLoading } = useCommonHooks();
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
@@ -26,8 +16,8 @@ const SearchProviderSettings = () => {
|
||||
tableName='Categories'
|
||||
columns={SearchProviderColumns()}
|
||||
tableData={providerData}
|
||||
isFetching={isFetching}
|
||||
isLoading={isLoading}
|
||||
isFetching={providersIsFetching}
|
||||
isLoading={providersIsLoading}
|
||||
endpoint={endpoint}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
@@ -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<number>(0);
|
||||
const { handleThemeChange, currentTheme, setCurrentTheme, theme, allThemes } =
|
||||
useCommonHooks();
|
||||
return (
|
||||
<Group
|
||||
gap={0}
|
||||
@@ -54,9 +47,8 @@ function ThemeCard({
|
||||
backgroundColor: cardTheme.backgroundColor,
|
||||
border: `solid ${cardTheme.borderColor}`,
|
||||
}}
|
||||
// data-cardTheme={cardTheme.name}
|
||||
onClick={() => {
|
||||
setValue(cardTheme.name);
|
||||
setCurrentTheme(cardTheme.name);
|
||||
}}
|
||||
>
|
||||
{hover && currentTheme !== 'random' && <Overlay opacity={0.5} zIndex={0} />}
|
||||
@@ -174,15 +166,7 @@ function ThemeCard({
|
||||
>
|
||||
<FiShuffle
|
||||
onClick={() => {
|
||||
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',
|
||||
|
||||
@@ -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 (
|
||||
<Modal.Root
|
||||
size={'50%'}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Box, Button, Group, Overlay, Stack, Switch, Text } from '@mantine/core';
|
||||
import { useDisclosure, useLocalStorage } from '@mantine/hooks';
|
||||
import { useMutationAPI, useQueryAPI } from 'hooks';
|
||||
import { useDisclosure } from '@mantine/hooks';
|
||||
import { useCommonHooks, useMutationAPI } from 'hooks';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { FiChevronRight, FiPlus } from 'react-icons/fi';
|
||||
import '@mantine/core/styles/ModalBase.css';
|
||||
@@ -9,23 +9,26 @@ import { modals } from '@mantine/modals';
|
||||
import { buttonClasses, textClasses } from 'styles';
|
||||
import ThemeCard from './ThemeCard';
|
||||
import ThemeModal from './ThemeModal';
|
||||
function ThemesSettings({ theme, setTheme, allThemes }: any) {
|
||||
function ThemesSettings() {
|
||||
const [opened, { open, close }] = useDisclosure(false);
|
||||
const [pickerOpen, { open: openPicker, close: closePicker }] = useDisclosure(false);
|
||||
const [colorId, setColorId] = useState<string>('');
|
||||
const [colorValue, setColorValue] = useState('#000000');
|
||||
const [currentTheme, setValue] = useLocalStorage<any>({
|
||||
key: 'theme',
|
||||
defaultValue: 'blackboard',
|
||||
});
|
||||
const { data: backgrounds, isFetched: isBackgroundFetched } = useQueryAPI({
|
||||
endpoint: 'api/backgrounds',
|
||||
});
|
||||
|
||||
const [backgroundList, setBackgroundList] = useState<any>(['None']);
|
||||
const [selectedTheme, setSelectedTheme] = useState<any>({});
|
||||
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) {
|
||||
}}
|
||||
>
|
||||
<ThemeCard
|
||||
theme={theme}
|
||||
allThemes={allThemes}
|
||||
setTheme={setTheme}
|
||||
cardTheme={cardTheme}
|
||||
currentTheme={currentTheme}
|
||||
handleOpen={handleOpen}
|
||||
handleDeleteTheme={handleDeleteTheme}
|
||||
setValue={setValue}
|
||||
createTheme={createTheme}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user