Slight refactor
This commit is contained in:
42
src/App.tsx
42
src/App.tsx
@@ -4,9 +4,8 @@ import {
|
|||||||
createTheme,
|
createTheme,
|
||||||
mergeMantineTheme,
|
mergeMantineTheme,
|
||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
import { useLocalStorage } from '@mantine/hooks';
|
|
||||||
import { ModalsProvider } from '@mantine/modals';
|
import { ModalsProvider } from '@mantine/modals';
|
||||||
import { useQueryAPI } from 'hooks';
|
import { useCommonHooks, useQueryAPI } from 'hooks';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import {
|
import {
|
||||||
Navigate,
|
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/dates/styles.css'; //if using mantine date picker features
|
||||||
import 'mantine-react-table/styles.css'; //import MRT styles
|
import 'mantine-react-table/styles.css'; //import MRT styles
|
||||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
||||||
import { appTheme } from 'contexts';
|
|
||||||
import { useAtom } from 'jotai';
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
import { Homepage, Settings } from 'pages';
|
import { Homepage, Settings } from 'pages';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const { data, isFetched } = useQueryAPI({
|
const { data: allThemes, isFetched: isAllThemesFetched } = useQueryAPI({
|
||||||
endpoint: 'api/themes',
|
endpoint: 'api/themes',
|
||||||
});
|
});
|
||||||
|
const { theme, setTheme, themeName, handleThemeChange } = useCommonHooks();
|
||||||
const [themeName, _] = useLocalStorage<any>({
|
|
||||||
key: 'theme',
|
|
||||||
defaultValue: 'blackboard',
|
|
||||||
});
|
|
||||||
|
|
||||||
const [theme, setTheme] = useAtom(appTheme);
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data && themeName) {
|
if (allThemes && themeName) {
|
||||||
if (themeName !== 'random') {
|
if (themeName !== 'random') {
|
||||||
const temp = data.find((t: any) => t.name === themeName);
|
const temp = allThemes.find((t: any) => t.name === themeName);
|
||||||
setTheme(temp);
|
setTheme(temp);
|
||||||
} else {
|
} else {
|
||||||
const enabled = data.filter((t: any) => t.randomEnabled);
|
handleThemeChange(allThemes, false);
|
||||||
if (enabled.length === 0) {
|
|
||||||
setTheme(data[0]);
|
|
||||||
} else {
|
|
||||||
const index = Math.floor(Math.random() * enabled.length);
|
|
||||||
setTheme(enabled[index]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [isFetched, themeName]);
|
}, [isAllThemesFetched, themeName]);
|
||||||
|
|
||||||
const router = createBrowserRouter(
|
const router = createBrowserRouter(
|
||||||
createRoutesFromElements(
|
createRoutesFromElements(
|
||||||
<Route>
|
<Route>
|
||||||
<Route path='' element={<MainLayout theme={theme} />}>
|
<Route path='' element={<MainLayout />}>
|
||||||
<Route
|
<Route
|
||||||
path='/'
|
path='/'
|
||||||
element={<Navigate to={`/${import.meta.env.VITE_BASE_URL}`} />}
|
element={<Navigate to={`/${import.meta.env.VITE_BASE_URL}`} />}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route path={`/${import.meta.env.VITE_BASE_URL}`} element={<Homepage />} />
|
||||||
path={`/${import.meta.env.VITE_BASE_URL}`}
|
|
||||||
element={<Homepage theme={theme} />}
|
|
||||||
/>
|
|
||||||
<Route
|
<Route
|
||||||
path={`/${import.meta.env.VITE_BASE_URL}/settings`}
|
path={`/${import.meta.env.VITE_BASE_URL}/settings`}
|
||||||
element={<Settings theme={theme} setTheme={setTheme} allThemes={data} />}
|
element={<Settings />}
|
||||||
/>
|
/>
|
||||||
</Route>
|
</Route>
|
||||||
</Route>,
|
</Route>,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
const overrides = createTheme({
|
const overrides = createTheme({
|
||||||
white: theme?.backgroundColor,
|
white: theme?.backgroundColor,
|
||||||
fontFamily: '-apple-system,Jost,BlinkMacSystemFont,Helvetica Neue,Roboto,sans-serif',
|
fontFamily: '-apple-system,Jost,BlinkMacSystemFont,Helvetica Neue,Roboto,sans-serif',
|
||||||
});
|
});
|
||||||
|
|
||||||
const mantineTheme = mergeMantineTheme(DEFAULT_THEME, overrides);
|
const mantineTheme = mergeMantineTheme(DEFAULT_THEME, overrides);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{theme && (
|
{theme && (
|
||||||
|
|||||||
@@ -9,9 +9,7 @@ import '../../../src/dataTableStyles.css';
|
|||||||
import { ActionIcon, Button, Flex, Text } from '@mantine/core';
|
import { ActionIcon, Button, Flex, Text } from '@mantine/core';
|
||||||
import { modals } from '@mantine/modals';
|
import { modals } from '@mantine/modals';
|
||||||
import { IconEdit, IconTrash } from '@tabler/icons-react';
|
import { IconEdit, IconTrash } from '@tabler/icons-react';
|
||||||
import { appTheme } from 'contexts';
|
import { useCommonHooks, useMutationAPI } from 'hooks';
|
||||||
import { useMutationAPI } from 'hooks';
|
|
||||||
import { useAtom } from 'jotai';
|
|
||||||
import { FiPlus } from 'react-icons/fi';
|
import { FiPlus } from 'react-icons/fi';
|
||||||
import { actionIconClasses, buttonClasses } from 'styles';
|
import { actionIconClasses, buttonClasses } from 'styles';
|
||||||
|
|
||||||
@@ -30,7 +28,7 @@ export function DataTableComponent({
|
|||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
endpoint: string;
|
endpoint: string;
|
||||||
}) {
|
}) {
|
||||||
const [theme, _] = useAtom(appTheme);
|
const { theme } = useCommonHooks();
|
||||||
const { mutateAsync: createRow } = useMutationAPI();
|
const { mutateAsync: createRow } = useMutationAPI();
|
||||||
const { mutateAsync: editRow } = useMutationAPI();
|
const { mutateAsync: editRow } = useMutationAPI();
|
||||||
const { mutateAsync: deleteRow } = useMutationAPI();
|
const { mutateAsync: deleteRow } = useMutationAPI();
|
||||||
@@ -112,7 +110,6 @@ export function DataTableComponent({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
renderCreateRowModalContent: ({ row }) => undefined,
|
|
||||||
renderTopToolbarCustomActions: ({ table }) => {
|
renderTopToolbarCustomActions: ({ table }) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,17 +1,11 @@
|
|||||||
import { Divider, Group, Modal, Stack, Text } from '@mantine/core';
|
import { Divider, Group, Modal, Stack, Text } from '@mantine/core';
|
||||||
import { appTheme } from 'contexts';
|
import { useCommonHooks } from 'hooks';
|
||||||
import { useAtom } from 'jotai';
|
|
||||||
import { modalClasses } from 'styles';
|
import { modalClasses } from 'styles';
|
||||||
|
|
||||||
export function HelpModal({
|
export function HelpModal({ providerModalOpened, closeProviderModal }: any) {
|
||||||
setValue,
|
const { theme, providers, setSearchValue, setProviderLabel, setProviderURL } =
|
||||||
setProviderLabel,
|
useCommonHooks();
|
||||||
setProviderURL,
|
|
||||||
providers,
|
|
||||||
providerModalOpened,
|
|
||||||
closeProviderModal,
|
|
||||||
}: any) {
|
|
||||||
const [theme, _] = useAtom(appTheme);
|
|
||||||
return (
|
return (
|
||||||
<Modal.Root
|
<Modal.Root
|
||||||
size={'60%'}
|
size={'60%'}
|
||||||
@@ -20,7 +14,7 @@ export function HelpModal({
|
|||||||
opened={providerModalOpened}
|
opened={providerModalOpened}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
closeProviderModal();
|
closeProviderModal();
|
||||||
setValue('');
|
setSearchValue('');
|
||||||
setProviderLabel('Google Search');
|
setProviderLabel('Google Search');
|
||||||
setProviderURL('https://www.google.com/search?q=');
|
setProviderURL('https://www.google.com/search?q=');
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { Box } from '@mantine/core';
|
import { Box } from '@mantine/core';
|
||||||
|
import { useCommonHooks } from 'hooks';
|
||||||
import { Outlet } from 'react-router-dom';
|
import { Outlet } from 'react-router-dom';
|
||||||
|
|
||||||
export function MainLayout({ theme }: any) {
|
export function MainLayout() {
|
||||||
|
const { theme } = useCommonHooks();
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Icon } from '@iconify/react/dist/iconify.js';
|
import { Icon } from '@iconify/react/dist/iconify.js';
|
||||||
import { Box, Card, Center, Group, Image, Stack, Text } from '@mantine/core';
|
import { Box, Card, Center, Group, Image, Stack, Text } from '@mantine/core';
|
||||||
|
import { useCommonHooks } from 'hooks';
|
||||||
|
|
||||||
export enum WindDirection {
|
export enum WindDirection {
|
||||||
N = 0,
|
N = 0,
|
||||||
@@ -12,7 +13,8 @@ export enum WindDirection {
|
|||||||
NW = 315,
|
NW = 315,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function HourlyCard({ weather, isMobile }: any) {
|
export default function HourlyCard({ weather }: any) {
|
||||||
|
const { isMobile } = useCommonHooks();
|
||||||
return (
|
return (
|
||||||
<Stack gap={0} align='center' mx={isMobile ? '.25rem' : 0}>
|
<Stack gap={0} align='center' mx={isMobile ? '.25rem' : 0}>
|
||||||
<Card
|
<Card
|
||||||
|
|||||||
@@ -1,28 +1,22 @@
|
|||||||
import { Box, Center, Divider, Group, Modal, Stack } from '@mantine/core';
|
import { Box, Center, Divider, Group, Modal, Stack } from '@mantine/core';
|
||||||
import { useAtom } from 'jotai';
|
|
||||||
import { modalClasses } from 'styles';
|
import { modalClasses } from 'styles';
|
||||||
import SmallOutlookCard from './SmallOutlookCard';
|
import SmallOutlookCard from './SmallOutlookCard';
|
||||||
import SmallWeatherCard from './SmallWeatherCard';
|
import SmallWeatherCard from './SmallWeatherCard';
|
||||||
|
|
||||||
|
import { useCommonHooks } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { appTheme } from '../../contexts/theme';
|
|
||||||
import HourlyCard from './HourlyCard';
|
import HourlyCard from './HourlyCard';
|
||||||
|
|
||||||
export function WeatherModal({
|
export function WeatherModal({
|
||||||
current,
|
current,
|
||||||
outlook,
|
outlook,
|
||||||
hourly,
|
|
||||||
closeWeatherModal,
|
closeWeatherModal,
|
||||||
weatherModalOpened,
|
weatherModalOpened,
|
||||||
setProviderLabel,
|
|
||||||
setProviderURL,
|
|
||||||
setValue,
|
|
||||||
isMobile,
|
|
||||||
}: any) {
|
}: any) {
|
||||||
const [theme, _] = useAtom(appTheme);
|
|
||||||
const [hourlyForecast, setHourlyForecast] = useState<any>([]);
|
const [hourlyForecast, setHourlyForecast] = useState<any>([]);
|
||||||
const [sunset, setSunset] = useState(100);
|
const [sunset, setSunset] = useState(100);
|
||||||
|
const { theme, isMobile, hourly, setProviderLabel, setSearchValue, setProviderURL } =
|
||||||
|
useCommonHooks();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (hourly) {
|
if (hourly) {
|
||||||
setHourlyForecast(hourly.properties.periods.slice(1, 13));
|
setHourlyForecast(hourly.properties.periods.slice(1, 13));
|
||||||
@@ -51,7 +45,7 @@ export function WeatherModal({
|
|||||||
onClose={() => {
|
onClose={() => {
|
||||||
closeWeatherModal();
|
closeWeatherModal();
|
||||||
setProviderLabel('Google Search');
|
setProviderLabel('Google Search');
|
||||||
setValue('');
|
setSearchValue('');
|
||||||
setProviderURL('https://www.google.com/search?q=');
|
setProviderURL('https://www.google.com/search?q=');
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
@@ -119,9 +113,7 @@ export function WeatherModal({
|
|||||||
>
|
>
|
||||||
{hourlyForecast.length > 0 &&
|
{hourlyForecast.length > 0 &&
|
||||||
hourlyForecast.map((h: any) => {
|
hourlyForecast.map((h: any) => {
|
||||||
return (
|
return <HourlyCard key={h.number} weather={h} />;
|
||||||
<HourlyCard key={h.number} weather={h} isMobile={isMobile} />
|
|
||||||
);
|
|
||||||
})}
|
})}
|
||||||
</Box>
|
</Box>
|
||||||
</Group>
|
</Group>
|
||||||
|
|||||||
@@ -45,3 +45,11 @@ export function containsProtocol(str: any) {
|
|||||||
const pattern = /^(https?:\/\/).*/i;
|
const pattern = /^(https?:\/\/).*/i;
|
||||||
return !!pattern.test(str);
|
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 { useQueryAPI, useWeatherAPI, useMutationAPI } from './useAPI';
|
||||||
export { date, greet } from './helpers';
|
export { date, greet, runWakeCommand, validURL, containsProtocol } from './helpers';
|
||||||
export { 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 { Stack } from '@mantine/core';
|
||||||
import { useDisclosure, useLocalStorage } from '@mantine/hooks';
|
import { useDisclosure } from '@mantine/hooks';
|
||||||
import { date, greet, useQueryAPI, useWeatherAPI } from 'hooks';
|
import { date, greet, useCommonHooks } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { stackClasses } from 'styles';
|
import { stackClasses } from 'styles';
|
||||||
import type { CurrentWeather, OutlookWeather } from 'types';
|
import type { CurrentWeather, OutlookWeather } from 'types';
|
||||||
@@ -10,21 +10,18 @@ import Header from './components/Header/Header';
|
|||||||
import Search from './components/Search/Search';
|
import Search from './components/Search/Search';
|
||||||
import SettingsButton from './components/SettingsButton';
|
import SettingsButton from './components/SettingsButton';
|
||||||
|
|
||||||
export function Homepage({ theme }: any) {
|
export function Homepage() {
|
||||||
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' });
|
|
||||||
const [displayedGreeting, setDisplayedGreeting] = useState('');
|
const [displayedGreeting, setDisplayedGreeting] = useState('');
|
||||||
|
const {
|
||||||
|
appFilter,
|
||||||
|
bookmarkFilter,
|
||||||
|
isMobile,
|
||||||
|
messages,
|
||||||
|
isMessagesFetching,
|
||||||
|
weather,
|
||||||
|
basicWeather,
|
||||||
|
forecast,
|
||||||
|
} = useCommonHooks();
|
||||||
const [current, setCurrent] = useState<CurrentWeather>({
|
const [current, setCurrent] = useState<CurrentWeather>({
|
||||||
icon: '',
|
icon: '',
|
||||||
temperature: 0,
|
temperature: 0,
|
||||||
@@ -47,17 +44,14 @@ export function Homepage({ theme }: any) {
|
|||||||
windDirection: 'N',
|
windDirection: 'N',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
const isMobile = window.matchMedia('(max-width: 600px)').matches;
|
|
||||||
const [weatherModalOpened, { open: openWeatherModal, close: closeWeatherModal }] =
|
const [weatherModalOpened, { open: openWeatherModal, close: closeWeatherModal }] =
|
||||||
useDisclosure(false);
|
useDisclosure(false);
|
||||||
const [providerLabel, setProviderLabel] = useState('Google Search');
|
|
||||||
const [providerURL, setProviderURL] = useState('https://www.google.com/search?q=');
|
|
||||||
const [value, setValue] = useState('');
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (messages) {
|
||||||
setDisplayedGreeting(greet(data));
|
setDisplayedGreeting(greet(messages));
|
||||||
}
|
}
|
||||||
}, [data, isFetching]);
|
}, [messages, isMessagesFetching]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (weather && basicWeather) {
|
if (weather && basicWeather) {
|
||||||
@@ -119,19 +113,7 @@ export function Homepage({ theme }: any) {
|
|||||||
<Stack gap={0} className={stackClasses.containerStack} justify='center'>
|
<Stack gap={0} className={stackClasses.containerStack} justify='center'>
|
||||||
<Search
|
<Search
|
||||||
current={current}
|
current={current}
|
||||||
setCurrent={setCurrent}
|
|
||||||
outlook={outlook}
|
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}
|
weatherModalOpened={weatherModalOpened}
|
||||||
closeWeatherModal={closeWeatherModal}
|
closeWeatherModal={closeWeatherModal}
|
||||||
openWeatherModal={openWeatherModal}
|
openWeatherModal={openWeatherModal}
|
||||||
@@ -139,30 +121,16 @@ export function Homepage({ theme }: any) {
|
|||||||
<Header
|
<Header
|
||||||
date={date(isMobile)}
|
date={date(isMobile)}
|
||||||
greet={displayedGreeting}
|
greet={displayedGreeting}
|
||||||
isMobile={isMobile}
|
|
||||||
current={current}
|
current={current}
|
||||||
setCurrent={setCurrent}
|
setCurrent={setCurrent}
|
||||||
outlook={outlook}
|
outlook={outlook}
|
||||||
weather={weather}
|
|
||||||
basicWeather={basicWeather}
|
|
||||||
forecast={forecast}
|
|
||||||
hourly={hourly}
|
|
||||||
setProviderLabel={setProviderLabel}
|
|
||||||
setProviderURL={setProviderURL}
|
|
||||||
setValue={setValue}
|
|
||||||
weatherModalOpened={weatherModalOpened}
|
weatherModalOpened={weatherModalOpened}
|
||||||
closeWeatherModal={closeWeatherModal}
|
closeWeatherModal={closeWeatherModal}
|
||||||
openWeatherModal={openWeatherModal}
|
openWeatherModal={openWeatherModal}
|
||||||
/>
|
/>
|
||||||
<Applications contentType={appFilter} isMobile={isMobile} />
|
<Applications contentType={appFilter} />
|
||||||
<Bookmarks contentType={bookmarkFilter} isMobile={isMobile} />
|
<Bookmarks contentType={bookmarkFilter} />
|
||||||
<SettingsButton
|
<SettingsButton />
|
||||||
theme={theme}
|
|
||||||
setAppFilter={setAppFilter}
|
|
||||||
appFilter={appFilter}
|
|
||||||
setBookmarkFilter={setBookmarkFilter}
|
|
||||||
bookmarkFilter={bookmarkFilter}
|
|
||||||
/>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import { Icon } from '@iconify/react';
|
import { Icon } from '@iconify/react';
|
||||||
import { Box, Stack, Text } from '@mantine/core';
|
import { Box, Stack, Text } from '@mantine/core';
|
||||||
|
import { useCommonHooks } from 'hooks';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { stackClasses, textClasses } from 'styles';
|
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 [textDecoration, setTextDecoration] = useState<string>('none');
|
||||||
|
const { isMobile } = useCommonHooks();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@@ -15,11 +17,11 @@ function AppItem({ url, icon, name, isMobile }: any) {
|
|||||||
className={stackClasses.appItemBox}
|
className={stackClasses.appItemBox}
|
||||||
>
|
>
|
||||||
<Stack
|
<Stack
|
||||||
align={isMobile && 'center'}
|
align={isMobile ? 'center' : undefined}
|
||||||
justify={isMobile && 'center'}
|
justify={isMobile ? 'center' : undefined}
|
||||||
style={{
|
style={{
|
||||||
height: '64px',
|
height: '64px',
|
||||||
width: isMobile && '100%',
|
width: isMobile ? '100%' : undefined,
|
||||||
marginRight: isMobile ? '0' : '1em',
|
marginRight: isMobile ? '0' : '1em',
|
||||||
marginLeft: isMobile ? '0' : '1em',
|
marginLeft: isMobile ? '0' : '1em',
|
||||||
paddingTop: isMobile ? '0' : '15px',
|
paddingTop: isMobile ? '0' : '15px',
|
||||||
|
|||||||
@@ -1,20 +1,13 @@
|
|||||||
import { Stack, Text } from '@mantine/core';
|
import { Stack, Text } from '@mantine/core';
|
||||||
import { useQueryAPI } from 'hooks';
|
import { useCommonHooks } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
import AppItem from './AppItem';
|
import AppItem from './AppItem';
|
||||||
|
|
||||||
function Applications({ contentType, isMobile }: any) {
|
function Applications({ contentType }: any) {
|
||||||
const { data, isFetching } = useQueryAPI({ endpoint: 'api/apps' });
|
const { isMobile, applicationData } = useCommonHooks();
|
||||||
const [applications, setApplications] = useState([]);
|
|
||||||
useEffect(() => {
|
|
||||||
if (data && !isFetching) {
|
|
||||||
setApplications(data);
|
|
||||||
}
|
|
||||||
}, [data, isFetching]);
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{applications.length > 0 && contentType.length > 0 && (
|
{applicationData.length > 0 && contentType.length > 0 && (
|
||||||
<Stack id='apps' style={{ gap: 0 }}>
|
<Stack id='apps' style={{ gap: 0 }}>
|
||||||
<Text className={textClasses.sectionTitle} classNames={textClasses}>
|
<Text className={textClasses.sectionTitle} classNames={textClasses}>
|
||||||
Applications
|
Applications
|
||||||
@@ -32,7 +25,7 @@ function Applications({ contentType, isMobile }: any) {
|
|||||||
paddingBottom: 'var(--module-spacing)',
|
paddingBottom: 'var(--module-spacing)',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{applications?.map((application: any) => {
|
{applicationData?.map((application: any) => {
|
||||||
if (
|
if (
|
||||||
contentType.includes(application.filterName) ||
|
contentType.includes(application.filterName) ||
|
||||||
contentType.includes('All')
|
contentType.includes('All')
|
||||||
@@ -44,7 +37,6 @@ function Applications({ contentType, isMobile }: any) {
|
|||||||
url={application.url}
|
url={application.url}
|
||||||
icon={application.icon}
|
icon={application.icon}
|
||||||
category={application.category}
|
category={application.category}
|
||||||
isMobile={isMobile}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -1,30 +1,16 @@
|
|||||||
import { Stack, Text } from '@mantine/core';
|
import { Stack, Text } from '@mantine/core';
|
||||||
import { useQueryAPI } from 'hooks';
|
import { useCommonHooks } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
import LinkGroups from './LinkGroups';
|
import LinkGroups from './LinkGroups';
|
||||||
|
|
||||||
function Links({ contentType, isMobile }: any) {
|
function Links({ contentType }: any) {
|
||||||
const { data: linkData, isFetched: linksIsFetched } = useQueryAPI({
|
const { isMobile, linksIsFetched, groupsIsFetched, groups, bookmarkData } =
|
||||||
endpoint: 'api/links',
|
useCommonHooks();
|
||||||
});
|
|
||||||
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]);
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{groupsIsFetched &&
|
{groupsIsFetched &&
|
||||||
linksIsFetched &&
|
linksIsFetched &&
|
||||||
categories?.length > 0 &&
|
groups?.length > 0 &&
|
||||||
contentType.length > 0 && (
|
contentType.length > 0 && (
|
||||||
<Stack id='links' style={{ gap: 0 }}>
|
<Stack id='links' style={{ gap: 0 }}>
|
||||||
<Text className={textClasses.sectionTitle} classNames={textClasses}>
|
<Text className={textClasses.sectionTitle} classNames={textClasses}>
|
||||||
@@ -40,19 +26,18 @@ function Links({ contentType, isMobile }: any) {
|
|||||||
gridTemplateRows: 'auto',
|
gridTemplateRows: 'auto',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{categories.map((category: any) => {
|
{groups.map((category: any) => {
|
||||||
if (
|
if (
|
||||||
contentType.includes(category.filterName) ||
|
contentType.includes(category.filterName) ||
|
||||||
contentType.includes('All')
|
contentType.includes('All')
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<LinkGroups
|
<LinkGroups
|
||||||
key={category.id}
|
key={category}
|
||||||
category={category.categoryName}
|
category={category.categoryName}
|
||||||
links={bookmarks.filter(
|
links={bookmarkData.filter(
|
||||||
(bookmark: any) => bookmark.category === category.categoryName,
|
(bookmark: any) => bookmark.category === category,
|
||||||
)}
|
)}
|
||||||
isMobile={isMobile}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Stack, Text } from '@mantine/core';
|
|||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
import LinkItem from './LinkItem';
|
import LinkItem from './LinkItem';
|
||||||
|
|
||||||
function LinkGroups({ links, category, isMobile }: any) {
|
function LinkGroups({ links, category }: any) {
|
||||||
return (
|
return (
|
||||||
<Stack
|
<Stack
|
||||||
style={{
|
style={{
|
||||||
@@ -16,7 +16,7 @@ function LinkGroups({ links, category, isMobile }: any) {
|
|||||||
{category}
|
{category}
|
||||||
</Text>
|
</Text>
|
||||||
{links?.map((link: any) => (
|
{links?.map((link: any) => (
|
||||||
<LinkItem key={link.name} link={link} isMobile={isMobile} />
|
<LinkItem key={link.name} link={link} />
|
||||||
))}
|
))}
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,25 +1,20 @@
|
|||||||
import { Group, Stack, Text } from '@mantine/core';
|
import { Group, Stack, Text } from '@mantine/core';
|
||||||
import { WeatherModal } from 'components';
|
import { WeatherModal } from 'components';
|
||||||
|
import { useCommonHooks } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
|
|
||||||
function Header({
|
function Header({
|
||||||
greet,
|
greet,
|
||||||
date,
|
date,
|
||||||
isMobile,
|
|
||||||
current,
|
current,
|
||||||
setCurrent,
|
setCurrent,
|
||||||
weather,
|
|
||||||
basicWeather,
|
|
||||||
outlook,
|
outlook,
|
||||||
hourly,
|
|
||||||
weatherModalOpened,
|
weatherModalOpened,
|
||||||
closeWeatherModal,
|
closeWeatherModal,
|
||||||
openWeatherModal,
|
openWeatherModal,
|
||||||
setProviderLabel,
|
|
||||||
setProviderURL,
|
|
||||||
setValue,
|
|
||||||
}: any) {
|
}: any) {
|
||||||
|
const { isMobile, weather, basicWeather } = useCommonHooks();
|
||||||
const [time, setTime] = useState(new Date());
|
const [time, setTime] = useState(new Date());
|
||||||
function fixDigits(k: any) {
|
function fixDigits(k: any) {
|
||||||
if (k < 10) {
|
if (k < 10) {
|
||||||
@@ -80,7 +75,7 @@ function Header({
|
|||||||
<Text
|
<Text
|
||||||
className={textClasses.greeting}
|
className={textClasses.greeting}
|
||||||
classNames={textClasses}
|
classNames={textClasses}
|
||||||
fz={isMobile && 24}
|
fz={isMobile ? 24 : undefined}
|
||||||
>
|
>
|
||||||
{greet}
|
{greet}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -152,13 +147,8 @@ function Header({
|
|||||||
<WeatherModal
|
<WeatherModal
|
||||||
current={current}
|
current={current}
|
||||||
outlook={outlook}
|
outlook={outlook}
|
||||||
hourly={hourly}
|
|
||||||
closeWeatherModal={closeWeatherModal}
|
closeWeatherModal={closeWeatherModal}
|
||||||
weatherModalOpened={weatherModalOpened}
|
weatherModalOpened={weatherModalOpened}
|
||||||
setProviderLabel={setProviderLabel}
|
|
||||||
setProviderURL={setProviderURL}
|
|
||||||
setValue={setValue}
|
|
||||||
isMobile={isMobile}
|
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,25 +1,26 @@
|
|||||||
import { Stack, TextInput } from '@mantine/core';
|
import { Stack, TextInput } from '@mantine/core';
|
||||||
import { useDisclosure } from '@mantine/hooks';
|
import { useDisclosure } from '@mantine/hooks';
|
||||||
import { HelpModal } from '../../../../components/HelpModal/HelpModal';
|
import { HelpModal, WeatherModal } from 'components';
|
||||||
import { WeatherModal } from '../../../../components/WeatherModal/WeatherModal';
|
import { containsProtocol, useCommonHooks, validURL } from 'hooks';
|
||||||
import { containsProtocol, useQueryAPI, validURL } from '../../../../hooks';
|
import { textInputClasses } from 'styles';
|
||||||
import { textInputClasses } from '../../../../styles';
|
|
||||||
|
|
||||||
export default function Search({
|
export default function Search({
|
||||||
current,
|
current,
|
||||||
outlook,
|
outlook,
|
||||||
hourly,
|
|
||||||
weatherModalOpened,
|
weatherModalOpened,
|
||||||
closeWeatherModal,
|
closeWeatherModal,
|
||||||
openWeatherModal,
|
openWeatherModal,
|
||||||
providerLabel,
|
|
||||||
setProviderLabel,
|
|
||||||
providerURL,
|
|
||||||
setProviderURL,
|
|
||||||
value,
|
|
||||||
setValue,
|
|
||||||
}: any) {
|
}: any) {
|
||||||
const { data: providers } = useQueryAPI({ endpoint: 'api/providers' });
|
const {
|
||||||
|
providerLabel,
|
||||||
|
setProviderLabel,
|
||||||
|
providerURL,
|
||||||
|
setProviderURL,
|
||||||
|
searchValue,
|
||||||
|
setSearchValue,
|
||||||
|
providers,
|
||||||
|
} = useCommonHooks();
|
||||||
|
|
||||||
const [providerModalOpened, { open: openProviderModal, close: closeProviderModal }] =
|
const [providerModalOpened, { open: openProviderModal, close: closeProviderModal }] =
|
||||||
useDisclosure(false);
|
useDisclosure(false);
|
||||||
|
|
||||||
@@ -72,10 +73,10 @@ export default function Search({
|
|||||||
classNames={textInputClasses}
|
classNames={textInputClasses}
|
||||||
spellCheck='true'
|
spellCheck='true'
|
||||||
leftSection={providerLabel}
|
leftSection={providerLabel}
|
||||||
value={value}
|
value={searchValue}
|
||||||
data-active={value !== ''}
|
data-active={searchValue !== ''}
|
||||||
onChange={(item: any) => {
|
onChange={(item: any) => {
|
||||||
setValue(item.currentTarget.value);
|
setSearchValue(item.currentTarget.value);
|
||||||
if (
|
if (
|
||||||
item.target.value === '/?' ||
|
item.target.value === '/?' ||
|
||||||
item.target.value === '!help' ||
|
item.target.value === '!help' ||
|
||||||
@@ -104,22 +105,14 @@ export default function Search({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<HelpModal
|
<HelpModal
|
||||||
providers={providers}
|
|
||||||
providerModalOpened={providerModalOpened}
|
providerModalOpened={providerModalOpened}
|
||||||
closeProviderModal={closeProviderModal}
|
closeProviderModal={closeProviderModal}
|
||||||
setValue={setValue}
|
|
||||||
setProviderLabel={setProviderLabel}
|
|
||||||
setProviderURL={setProviderURL}
|
|
||||||
/>
|
/>
|
||||||
<WeatherModal
|
<WeatherModal
|
||||||
current={current}
|
current={current}
|
||||||
outlook={outlook}
|
outlook={outlook}
|
||||||
hourly={hourly}
|
|
||||||
closeWeatherModal={closeWeatherModal}
|
closeWeatherModal={closeWeatherModal}
|
||||||
weatherModalOpened={weatherModalOpened}
|
weatherModalOpened={weatherModalOpened}
|
||||||
setValue={setValue}
|
|
||||||
setProviderLabel={setProviderLabel}
|
|
||||||
setProviderURL={setProviderURL}
|
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,19 +1,26 @@
|
|||||||
import { Button, Menu, MultiSelect, NavLink } from '@mantine/core';
|
import { Button, Menu, MultiSelect, NavLink, Switch } from '@mantine/core';
|
||||||
import { useQueryAPI } from 'hooks';
|
import { runWakeCommand, useCommonHooks, useQueryAPI } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
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 { useNavigate } from 'react-router-dom';
|
||||||
import { buttonClasses, menuClasses, navLinkClasses, selectClasses } from 'styles';
|
import { buttonClasses, menuClasses, navLinkClasses, selectClasses } from 'styles';
|
||||||
|
|
||||||
function SettingsButton({
|
function SettingsButton() {
|
||||||
appFilter,
|
|
||||||
setAppFilter,
|
|
||||||
bookmarkFilter,
|
|
||||||
setBookmarkFilter,
|
|
||||||
}: any) {
|
|
||||||
const { data, isFetched } = useQueryAPI({ endpoint: 'api/appCategories' });
|
const { data, isFetched } = useQueryAPI({ endpoint: 'api/appCategories' });
|
||||||
const [categories, setCategories] = useState([{ value: 'All', label: 'All' }]);
|
const [categories, setCategories] = useState([{ value: 'All', label: 'All' }]);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const {
|
||||||
|
currentTheme,
|
||||||
|
setCurrentTheme,
|
||||||
|
handleThemeChange,
|
||||||
|
theme,
|
||||||
|
allThemes,
|
||||||
|
appFilter,
|
||||||
|
setAppFilter,
|
||||||
|
bookmarkFilter,
|
||||||
|
setBookmarkFilter,
|
||||||
|
} = useCommonHooks();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
const list: [any] =
|
const list: [any] =
|
||||||
@@ -25,13 +32,6 @@ function SettingsButton({
|
|||||||
}
|
}
|
||||||
}, [data, isFetched]);
|
}, [data, isFetched]);
|
||||||
|
|
||||||
function runWakeCommand() {
|
|
||||||
const requestOptions = {
|
|
||||||
method: 'GET',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
};
|
|
||||||
fetch(`/${import.meta.env.VITE_BASE_URL}/api/wakeDakota`, requestOptions);
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<Menu withinPortal={false} withArrow shadow='md' position='top'>
|
<Menu withinPortal={false} withArrow shadow='md' position='top'>
|
||||||
<Menu.Target>
|
<Menu.Target>
|
||||||
@@ -59,6 +59,31 @@ function SettingsButton({
|
|||||||
className={navLinkClasses.defaultNavLink}
|
className={navLinkClasses.defaultNavLink}
|
||||||
classNames={navLinkClasses}
|
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>
|
</NavLink>
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
label='App Filter'
|
label='App Filter'
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { ActionIcon, Group, Stack, Tabs, Text } from '@mantine/core';
|
import { ActionIcon, Group, Stack, Tabs, Text } from '@mantine/core';
|
||||||
|
import { useCommonHooks } from 'hooks';
|
||||||
import {
|
import {
|
||||||
FiArrowLeftCircle,
|
FiArrowLeftCircle,
|
||||||
FiBook,
|
FiBook,
|
||||||
@@ -19,8 +20,8 @@ import Personalization from './components/Personalization';
|
|||||||
import SearchProviders from './components/SearchProviders';
|
import SearchProviders from './components/SearchProviders';
|
||||||
import Themes from './components/Themes';
|
import Themes from './components/Themes';
|
||||||
|
|
||||||
export function Settings({ theme, setTheme, allThemes }: any) {
|
export function Settings() {
|
||||||
const isMobile = window.matchMedia('(max-width: 600px)').matches;
|
const { isMobile } = useCommonHooks();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
return (
|
return (
|
||||||
<Stack px={'2rem'}>
|
<Stack px={'2rem'}>
|
||||||
@@ -76,7 +77,7 @@ export function Settings({ theme, setTheme, allThemes }: any) {
|
|||||||
<Categories />
|
<Categories />
|
||||||
</Tabs.Panel>
|
</Tabs.Panel>
|
||||||
<Tabs.Panel value='themes'>
|
<Tabs.Panel value='themes'>
|
||||||
<Themes theme={theme} setTheme={setTheme} allThemes={allThemes} />
|
<Themes />
|
||||||
</Tabs.Panel>
|
</Tabs.Panel>
|
||||||
<Tabs.Panel value='providers'>
|
<Tabs.Panel value='providers'>
|
||||||
<SearchProviders />
|
<SearchProviders />
|
||||||
|
|||||||
@@ -1,21 +1,11 @@
|
|||||||
import { Stack, Text } from '@mantine/core';
|
import { Stack, Text } from '@mantine/core';
|
||||||
import { ApplicationColumns, DataTable } from 'components';
|
import { ApplicationColumns, DataTable } from 'components';
|
||||||
import { useQueryAPI } from 'hooks';
|
import { useCommonHooks } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
|
|
||||||
const ApplicationSettings = () => {
|
const ApplicationSettings = () => {
|
||||||
const endpoint = 'api/apps';
|
const endpoint = 'api/apps';
|
||||||
const { data, isFetching, isLoading, isFetched } = useQueryAPI({
|
const { isAppsFetching, isAppsLoading, applicationData } = useCommonHooks();
|
||||||
endpoint: endpoint,
|
|
||||||
});
|
|
||||||
const [applicationData, setApplicationData] = useState<any>([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isFetched) {
|
|
||||||
setApplicationData(data);
|
|
||||||
}
|
|
||||||
}, [data, isFetching]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
@@ -26,8 +16,8 @@ const ApplicationSettings = () => {
|
|||||||
tableName='Applications'
|
tableName='Applications'
|
||||||
columns={ApplicationColumns()}
|
columns={ApplicationColumns()}
|
||||||
tableData={applicationData}
|
tableData={applicationData}
|
||||||
isFetching={isFetching}
|
isFetching={isAppsFetching}
|
||||||
isLoading={isLoading}
|
isLoading={isAppsLoading}
|
||||||
endpoint={endpoint}
|
endpoint={endpoint}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -1,31 +1,11 @@
|
|||||||
import { Stack, Text } from '@mantine/core';
|
import { Stack, Text } from '@mantine/core';
|
||||||
import { BookmarkColumns, DataTable } from 'components';
|
import { BookmarkColumns, DataTable } from 'components';
|
||||||
import { useQueryAPI } from 'hooks';
|
import { useCommonHooks } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
const BookmarkSettings = () => {
|
const BookmarkSettings = () => {
|
||||||
const endpoint = 'api/links';
|
const endpoint = 'api/links';
|
||||||
const { data, isFetching, isLoading, isFetched } = useQueryAPI({
|
const { groups, bookmarkData, linksIsFetching, linksIsLoading } = useCommonHooks();
|
||||||
endpoint: endpoint,
|
|
||||||
});
|
|
||||||
const { data: groupData } = useQueryAPI({ endpoint: 'api/categories' });
|
|
||||||
const [bookmarkData, setBookmarkData] = useState<any>([]);
|
|
||||||
const [groups, setGroups] = useState([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isFetched) {
|
|
||||||
setBookmarkData(data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (groupData) {
|
|
||||||
const groupList = groupData?.map((category: any) => {
|
|
||||||
return category.categoryName;
|
|
||||||
});
|
|
||||||
setGroups(groupList);
|
|
||||||
}
|
|
||||||
}, [groupData]);
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
||||||
@@ -35,8 +15,8 @@ const BookmarkSettings = () => {
|
|||||||
tableName='Applications'
|
tableName='Applications'
|
||||||
columns={BookmarkColumns(groups)}
|
columns={BookmarkColumns(groups)}
|
||||||
tableData={bookmarkData}
|
tableData={bookmarkData}
|
||||||
isFetching={isFetching}
|
isFetching={linksIsFetching}
|
||||||
isLoading={isLoading}
|
isLoading={linksIsLoading}
|
||||||
endpoint={endpoint}
|
endpoint={endpoint}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -1,21 +1,10 @@
|
|||||||
import { Stack, Text } from '@mantine/core';
|
import { Stack, Text } from '@mantine/core';
|
||||||
import { CategoryColumns, DataTable } from 'components';
|
import { CategoryColumns, DataTable } from 'components';
|
||||||
import { useEffect, useState } from 'react';
|
import { useCommonHooks } from 'hooks';
|
||||||
import { useQueryAPI } from '../../../hooks/useAPI';
|
|
||||||
import { textClasses } from '../../../styles';
|
import { textClasses } from '../../../styles';
|
||||||
const CategorySettings = () => {
|
const CategorySettings = () => {
|
||||||
const endpoint = 'api/categories';
|
const endpoint = 'api/categories';
|
||||||
const { data, isFetching, isLoading, isFetched } = useQueryAPI({
|
const { groupData, groupsIsFetching, groupsIsLoading } = useCommonHooks();
|
||||||
endpoint: endpoint,
|
|
||||||
});
|
|
||||||
const [categoryData, setCategoryData] = useState<any>([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (data && isFetched) {
|
|
||||||
setCategoryData(data);
|
|
||||||
}
|
|
||||||
}, [data, isFetched]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
||||||
@@ -24,9 +13,9 @@ const CategorySettings = () => {
|
|||||||
<DataTable
|
<DataTable
|
||||||
tableName='Categories'
|
tableName='Categories'
|
||||||
columns={CategoryColumns()}
|
columns={CategoryColumns()}
|
||||||
tableData={categoryData}
|
tableData={groupData ?? []}
|
||||||
isFetching={isFetching}
|
isFetching={groupsIsFetching}
|
||||||
isLoading={isLoading}
|
isLoading={groupsIsLoading}
|
||||||
endpoint={endpoint}
|
endpoint={endpoint}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -1,21 +1,10 @@
|
|||||||
import { Stack, Text } from '@mantine/core';
|
import { Stack, Text } from '@mantine/core';
|
||||||
import { DataTable, MessagesColumns } from 'components';
|
import { DataTable, MessagesColumns } from 'components';
|
||||||
import { useQueryAPI } from 'hooks';
|
import { useCommonHooks } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
const MessageSettings = () => {
|
const MessageSettings = () => {
|
||||||
const endpoint = 'api/messages';
|
const endpoint = 'api/messages';
|
||||||
const { data, isFetching, isLoading, isFetched } = useQueryAPI({
|
const { messageData, isMessagesFetching, isMessagesLoading } = useCommonHooks();
|
||||||
endpoint: endpoint,
|
|
||||||
});
|
|
||||||
const [messageData, setMessageData] = useState<any>([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isFetched) {
|
|
||||||
setMessageData(data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
||||||
@@ -25,8 +14,8 @@ const MessageSettings = () => {
|
|||||||
tableName='Messages'
|
tableName='Messages'
|
||||||
columns={MessagesColumns()}
|
columns={MessagesColumns()}
|
||||||
tableData={messageData}
|
tableData={messageData}
|
||||||
isFetching={isFetching}
|
isFetching={isMessagesFetching}
|
||||||
isLoading={isLoading}
|
isLoading={isMessagesLoading}
|
||||||
endpoint={endpoint}
|
endpoint={endpoint}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -1,20 +1,10 @@
|
|||||||
import { Text } from '@mantine/core';
|
import { Text } from '@mantine/core';
|
||||||
import { DataTable, PersonalizationColumns } from 'components';
|
import { DataTable, PersonalizationColumns } from 'components';
|
||||||
import { useQueryAPI } from 'hooks';
|
import { useCommonHooks } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
const PersonalizationSettings = () => {
|
const PersonalizationSettings = () => {
|
||||||
const endpoint = 'api/personalData';
|
const endpoint = 'api/personalData';
|
||||||
const { data, isFetching, isLoading, isFetched } = useQueryAPI({
|
const { personalData, personalIsFetching, personalIsLoading } = useCommonHooks();
|
||||||
endpoint: endpoint,
|
|
||||||
});
|
|
||||||
const [personalData, setPersonalData] = useState<any>([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isFetched) {
|
|
||||||
setPersonalData(data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -25,8 +15,8 @@ const PersonalizationSettings = () => {
|
|||||||
tableName='Personalization'
|
tableName='Personalization'
|
||||||
columns={PersonalizationColumns()}
|
columns={PersonalizationColumns()}
|
||||||
tableData={personalData}
|
tableData={personalData}
|
||||||
isFetching={isFetching}
|
isFetching={personalIsFetching}
|
||||||
isLoading={isLoading}
|
isLoading={personalIsLoading}
|
||||||
endpoint={endpoint}
|
endpoint={endpoint}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,21 +1,11 @@
|
|||||||
import { Stack, Text } from '@mantine/core';
|
import { Stack, Text } from '@mantine/core';
|
||||||
import { DataTable, SearchProviderColumns } from 'components';
|
import { DataTable, SearchProviderColumns } from 'components';
|
||||||
import { useQueryAPI } from 'hooks';
|
import { useCommonHooks } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
|
|
||||||
const SearchProviderSettings = () => {
|
const SearchProviderSettings = () => {
|
||||||
const endpoint = 'api/providers';
|
const endpoint = 'api/providers';
|
||||||
const { data, isFetching, isLoading, isFetched } = useQueryAPI({
|
const { providerData, providersIsFetching, providersIsLoading } = useCommonHooks();
|
||||||
endpoint: endpoint,
|
|
||||||
});
|
|
||||||
const [providerData, setProviderData] = useState<any>([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isFetched) {
|
|
||||||
setProviderData(data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
@@ -26,8 +16,8 @@ const SearchProviderSettings = () => {
|
|||||||
tableName='Categories'
|
tableName='Categories'
|
||||||
columns={SearchProviderColumns()}
|
columns={SearchProviderColumns()}
|
||||||
tableData={providerData}
|
tableData={providerData}
|
||||||
isFetching={isFetching}
|
isFetching={providersIsFetching}
|
||||||
isLoading={isLoading}
|
isLoading={providersIsLoading}
|
||||||
endpoint={endpoint}
|
endpoint={endpoint}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -1,21 +1,14 @@
|
|||||||
import { ActionIcon, Box, Button, Group, Overlay, Stack, Text } from '@mantine/core';
|
import { ActionIcon, Box, Button, Group, Overlay, Stack, Text } from '@mantine/core';
|
||||||
|
import { useCommonHooks } from 'hooks';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { FiEdit, FiShuffle, FiTrash, FiX } from 'react-icons/fi';
|
import { FiEdit, FiShuffle, FiTrash, FiX } from 'react-icons/fi';
|
||||||
import { actionIconClasses } from 'styles';
|
import { actionIconClasses } from 'styles';
|
||||||
|
|
||||||
function ThemeCard({
|
function ThemeCard({ cardTheme, handleOpen, handleDeleteTheme, createTheme }: any) {
|
||||||
handleOpen,
|
|
||||||
handleDeleteTheme,
|
|
||||||
theme,
|
|
||||||
allThemes,
|
|
||||||
setTheme,
|
|
||||||
cardTheme,
|
|
||||||
currentTheme,
|
|
||||||
setValue,
|
|
||||||
createTheme,
|
|
||||||
}: any) {
|
|
||||||
const [hover, setHover] = useState(false);
|
const [hover, setHover] = useState(false);
|
||||||
const [shift, setShift] = useState<number>(0);
|
const [shift, setShift] = useState<number>(0);
|
||||||
|
const { handleThemeChange, currentTheme, setCurrentTheme, theme, allThemes } =
|
||||||
|
useCommonHooks();
|
||||||
return (
|
return (
|
||||||
<Group
|
<Group
|
||||||
gap={0}
|
gap={0}
|
||||||
@@ -54,9 +47,8 @@ function ThemeCard({
|
|||||||
backgroundColor: cardTheme.backgroundColor,
|
backgroundColor: cardTheme.backgroundColor,
|
||||||
border: `solid ${cardTheme.borderColor}`,
|
border: `solid ${cardTheme.borderColor}`,
|
||||||
}}
|
}}
|
||||||
// data-cardTheme={cardTheme.name}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setValue(cardTheme.name);
|
setCurrentTheme(cardTheme.name);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{hover && currentTheme !== 'random' && <Overlay opacity={0.5} zIndex={0} />}
|
{hover && currentTheme !== 'random' && <Overlay opacity={0.5} zIndex={0} />}
|
||||||
@@ -174,15 +166,7 @@ function ThemeCard({
|
|||||||
>
|
>
|
||||||
<FiShuffle
|
<FiShuffle
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const enabled = allThemes
|
handleThemeChange(allThemes, false);
|
||||||
.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]);
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
fontSize: '2em',
|
fontSize: '2em',
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
TextInput,
|
TextInput,
|
||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
|
import { useCommonHooks } from 'hooks';
|
||||||
import { FiSave, FiX } from 'react-icons/fi';
|
import { FiSave, FiX } from 'react-icons/fi';
|
||||||
import { modalClasses, selectClasses, textClasses } from 'styles';
|
import { modalClasses, selectClasses, textClasses } from 'styles';
|
||||||
import ThemeModalContent from './ThemeModalContent';
|
import ThemeModalContent from './ThemeModalContent';
|
||||||
@@ -22,7 +23,6 @@ function ThemeModal({
|
|||||||
handleClose,
|
handleClose,
|
||||||
selectedTheme,
|
selectedTheme,
|
||||||
setSelectedTheme,
|
setSelectedTheme,
|
||||||
theme,
|
|
||||||
setColorId,
|
setColorId,
|
||||||
colorId,
|
colorId,
|
||||||
setColorValue,
|
setColorValue,
|
||||||
@@ -33,6 +33,7 @@ function ThemeModal({
|
|||||||
closePicker,
|
closePicker,
|
||||||
handleSaveTheme,
|
handleSaveTheme,
|
||||||
}: any) {
|
}: any) {
|
||||||
|
const { theme } = useCommonHooks();
|
||||||
return (
|
return (
|
||||||
<Modal.Root
|
<Modal.Root
|
||||||
size={'50%'}
|
size={'50%'}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Box, Button, Group, Overlay, Stack, Switch, Text } from '@mantine/core';
|
import { Box, Button, Group, Overlay, Stack, Switch, Text } from '@mantine/core';
|
||||||
import { useDisclosure, useLocalStorage } from '@mantine/hooks';
|
import { useDisclosure } from '@mantine/hooks';
|
||||||
import { useMutationAPI, useQueryAPI } from 'hooks';
|
import { useCommonHooks, useMutationAPI } from 'hooks';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { FiChevronRight, FiPlus } from 'react-icons/fi';
|
import { FiChevronRight, FiPlus } from 'react-icons/fi';
|
||||||
import '@mantine/core/styles/ModalBase.css';
|
import '@mantine/core/styles/ModalBase.css';
|
||||||
@@ -9,23 +9,26 @@ import { modals } from '@mantine/modals';
|
|||||||
import { buttonClasses, textClasses } from 'styles';
|
import { buttonClasses, textClasses } from 'styles';
|
||||||
import ThemeCard from './ThemeCard';
|
import ThemeCard from './ThemeCard';
|
||||||
import ThemeModal from './ThemeModal';
|
import ThemeModal from './ThemeModal';
|
||||||
function ThemesSettings({ theme, setTheme, allThemes }: any) {
|
function ThemesSettings() {
|
||||||
const [opened, { open, close }] = useDisclosure(false);
|
const [opened, { open, close }] = useDisclosure(false);
|
||||||
const [pickerOpen, { open: openPicker, close: closePicker }] = useDisclosure(false);
|
const [pickerOpen, { open: openPicker, close: closePicker }] = useDisclosure(false);
|
||||||
const [colorId, setColorId] = useState<string>('');
|
const [colorId, setColorId] = useState<string>('');
|
||||||
const [colorValue, setColorValue] = useState('#000000');
|
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 [backgroundList, setBackgroundList] = useState<any>(['None']);
|
||||||
const [selectedTheme, setSelectedTheme] = useState<any>({});
|
const [selectedTheme, setSelectedTheme] = useState<any>({});
|
||||||
const { mutateAsync: createTheme } = useMutationAPI();
|
const { mutateAsync: createTheme } = useMutationAPI();
|
||||||
const { mutateAsync: deleteTheme } = useMutationAPI();
|
const { mutateAsync: deleteTheme } = useMutationAPI();
|
||||||
const isMobile = window.matchMedia('(max-width: 600px)').matches;
|
|
||||||
|
const {
|
||||||
|
currentTheme,
|
||||||
|
setCurrentTheme,
|
||||||
|
backgrounds,
|
||||||
|
isBackgroundFetched,
|
||||||
|
isMobile,
|
||||||
|
theme,
|
||||||
|
allThemes,
|
||||||
|
} = useCommonHooks();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (backgrounds && isBackgroundFetched) {
|
if (backgrounds && isBackgroundFetched) {
|
||||||
@@ -114,7 +117,7 @@ function ThemesSettings({ theme, setTheme, allThemes }: any) {
|
|||||||
labelPosition='left'
|
labelPosition='left'
|
||||||
checked={currentTheme === 'random'}
|
checked={currentTheme === 'random'}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setValue(e.target.checked ? 'random' : theme.name);
|
setCurrentTheme(e.target.checked ? 'random' : theme.name);
|
||||||
}}
|
}}
|
||||||
color={theme.primaryColor}
|
color={theme.primaryColor}
|
||||||
/>
|
/>
|
||||||
@@ -158,14 +161,9 @@ function ThemesSettings({ theme, setTheme, allThemes }: any) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ThemeCard
|
<ThemeCard
|
||||||
theme={theme}
|
|
||||||
allThemes={allThemes}
|
|
||||||
setTheme={setTheme}
|
|
||||||
cardTheme={cardTheme}
|
cardTheme={cardTheme}
|
||||||
currentTheme={currentTheme}
|
|
||||||
handleOpen={handleOpen}
|
handleOpen={handleOpen}
|
||||||
handleDeleteTheme={handleDeleteTheme}
|
handleDeleteTheme={handleDeleteTheme}
|
||||||
setValue={setValue}
|
|
||||||
createTheme={createTheme}
|
createTheme={createTheme}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
Reference in New Issue
Block a user