diff --git a/src/components/WeatherModal/WeatherIcon.tsx b/src/components/WeatherModal/WeatherIcon.tsx
index adf74df..92cf5ef 100644
--- a/src/components/WeatherModal/WeatherIcon.tsx
+++ b/src/components/WeatherModal/WeatherIcon.tsx
@@ -41,6 +41,22 @@ export default function WeatherIcon({ textDescription }: { textDescription: stri
alt='RainIcon'
/>
);
+ case 'Chance Showers':
+ return (
+
+ );
+ case 'Slight Chance Showers':
+ return (
+
+ );
case 'Clear':
return (
{
-
-
-
- Applications
-
-
-
-
-
-
-
-
-
-
- {'Applications are the apps that will be displayed on the homepage.'}
-
-
- {
- 'Applications contain a name, base url, url, icon and filter. Currently the icon must be the mdi icon name. URLs can contain either http(s):// or not. Base URLs should start with /, otherwise they will cause errors.'
- }
-
-
-
-
-
-
- {
- setSearchValue(event.target.value);
- }}
- />
- Reorder}
- labelPosition='left'
- pos={'absolute'}
- right={isMobile ? '2rem' : '1rem'}
- top={isMobile ? '10rem' : undefined}
- onChange={(e) => {
- setDragging(e.target.checked);
- }}
- color={theme.primaryColor}
- styles={{
- label: {
- color: theme.primaryColor,
- top: isMobile ? -22 : 0,
- left: isMobile ? -8 : 0,
- position: isMobile ? 'absolute' : undefined,
- },
- }}
- />
-
+
{dragging ? (
diff --git a/src/pages/settings/components/Bookmarks/Bookmarks.tsx b/src/pages/settings/components/Bookmarks/Bookmarks.tsx
index 0eb4e71..4cd5cf3 100644
--- a/src/pages/settings/components/Bookmarks/Bookmarks.tsx
+++ b/src/pages/settings/components/Bookmarks/Bookmarks.tsx
@@ -1,32 +1,21 @@
import { DragDropContext, Draggable, Droppable } from '@hello-pangea/dnd';
import {
- ActionIcon,
Box,
Button,
Card,
Divider,
Group,
- Highlight,
Modal,
- Popover,
Stack,
- Switch,
Text,
TextInput,
} from '@mantine/core';
import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
import { useEffect, useState } from 'react';
-import { FiHelpCircle, FiPlus } from 'react-icons/fi';
-import {
- actionIconClasses,
- buttonClasses,
- cardClasses,
- modalClasses,
- textClasses,
- textInputClasses,
-} from 'styles';
+import { cardClasses, modalClasses, textInputClasses } from 'styles';
import type { Bookmark, BookmarkGroup } from 'types';
+import SettingsHeader from '../Shared/SettingsHeader';
import DebouncedGroupSettingsItem from './DebouncedGroupSettingsItem';
const BookmarkSettings = () => {
const { data: linkData, isFetched: linksIsFetched } = useQueryAPI({
@@ -190,99 +179,28 @@ const BookmarkSettings = () => {
-
-
-
- Bookmarks
-
-
-
-
-
-
-
-
-
-
- {'Bookmarks are the links that will be displayed on the homepage.'}
-
-
- {
- 'Bookmarks can only belong to a single category, and will be displayed under that category on the homepage.'
- }
-
-
-
-
-
-
- {
- setSearchValue(event.target.value);
- }}
- />
- Reorder}
- labelPosition='left'
- pos={'absolute'}
- right={isMobile ? '2rem' : '1rem'}
- top={isMobile ? '10rem' : undefined}
- onChange={(e) => {
- setDragging(e.target.checked);
- }}
- color={theme.primaryColor}
- styles={{
- label: {
- color: theme.primaryColor,
- top: isMobile ? -22 : 0,
- left: isMobile ? -8 : 0,
- position: isMobile ? 'absolute' : undefined,
- },
- }}
- />
-
+
{dragging ? (
diff --git a/src/pages/settings/components/Messages/Messages.tsx b/src/pages/settings/components/Messages/Messages.tsx
index 21d562f..53a2c8c 100644
--- a/src/pages/settings/components/Messages/Messages.tsx
+++ b/src/pages/settings/components/Messages/Messages.tsx
@@ -1,38 +1,27 @@
import {
- ActionIcon,
Button,
Card,
Divider,
Grid,
GridCol,
Group,
- Highlight,
Modal,
- Popover,
Stack,
- Text,
TextInput,
} from '@mantine/core';
import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
import DebouncedMessage from 'pages/settings/components/Messages/DebouncedMessage';
import { useEffect, useState } from 'react';
-import { FiHelpCircle, FiPlus } from 'react-icons/fi';
-import {
- actionIconClasses,
- buttonClasses,
- cardClasses,
- modalClasses,
- textClasses,
- textInputClasses,
-} from 'styles';
+import { cardClasses, modalClasses, textInputClasses } from 'styles';
import type { Message } from 'types';
+import SettingsHeader from '../Shared/SettingsHeader';
const MessageSettings = () => {
const endpoint = 'api/messages';
const { data: messageData, isFetched: isMessagesFetched } = useQueryAPI({
endpoint: endpoint,
});
- const { theme, isMobile, modalStyle } = useCommonHooks();
+ const { isMobile, modalStyle } = useCommonHooks();
const { mutateAsync } = useMutationAPI();
const [messages, setMessages] = useState([]);
const [newMessage, setNewMessage] = useState('');
@@ -129,73 +118,19 @@ const MessageSettings = () => {
-
-
-
- Messages
-
-
-
-
-
-
-
-
-
-
- {
- 'These custom messages will be displayed in the header on the homepage.'
- }
-
-
- {
- 'Built-in variables include $firstName and $lastName. To force the text to upper case, use a carat (^), ie, $^firstName. Messages may contain any unicode text.'
- }
-
-
-
-
-
-
- {
- setSearchValue(event.target.value);
- }}
- />
-
+
{messages?.map((message: Message) => (
diff --git a/src/pages/settings/components/Search/SearchProviders.tsx b/src/pages/settings/components/Search/SearchProviders.tsx
index b7949f9..2f3e408 100644
--- a/src/pages/settings/components/Search/SearchProviders.tsx
+++ b/src/pages/settings/components/Search/SearchProviders.tsx
@@ -1,5 +1,4 @@
import {
- ActionIcon,
Box,
Button,
Card,
@@ -7,26 +6,17 @@ import {
Grid,
GridCol,
Group,
- Highlight,
Modal,
Popover,
Stack,
- Text,
TextInput,
} from '@mantine/core';
import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
import { useEffect, useState } from 'react';
-import { FiHelpCircle, FiPlus } from 'react-icons/fi';
-import {
- actionIconClasses,
- buttonClasses,
- cardClasses,
- modalClasses,
- textClasses,
- textInputClasses,
-} from 'styles';
+import { cardClasses, modalClasses, textInputClasses } from 'styles';
import type { Provider } from 'types';
+import SettingsHeader from '../Shared/SettingsHeader';
import DebouncedSearchProvider from './DebouncedSearchProvider';
import SearchProviderSettingsItem from './SearchProviderSettingsItem';
@@ -36,7 +26,7 @@ const SearchProviderSettings = () => {
endpoint: endpoint,
});
const [providerData, setProviderData] = useState([]);
- const { theme, isMobile, modalStyle } = useCommonHooks();
+ const { isMobile, modalStyle } = useCommonHooks();
const { mutateAsync } = useMutationAPI();
const [newProvider, setNewProvider] = useState({
id: undefined,
@@ -160,71 +150,19 @@ const SearchProviderSettings = () => {
-
-
-
- Search Providers
-
-
-
-
-
-
-
-
-
-
- {'Search providers and shortcuts can be configured here.'}
-
-
- {
- 'Providers can be used in the search bar. By starting a search with the prefix, it will be redirected to the url of the provider to complete the search.'
- }
-
-
-
-
-
-
- {
- setSearchValue(event.target.value);
- }}
- />
-
+
{providerData?.map((provider: Provider) => (
diff --git a/src/pages/settings/components/Shared/SettingsHeader.tsx b/src/pages/settings/components/Shared/SettingsHeader.tsx
new file mode 100644
index 0000000..55b2092
--- /dev/null
+++ b/src/pages/settings/components/Shared/SettingsHeader.tsx
@@ -0,0 +1,113 @@
+import {
+ ActionIcon,
+ Button,
+ Group,
+ Highlight,
+ Popover,
+ Stack,
+ Switch,
+ Text,
+ TextInput,
+} from '@mantine/core';
+import { useCommonHooks } from 'hooks';
+import { FiHelpCircle, FiPlus } from 'react-icons/fi';
+import { actionIconClasses, buttonClasses, textClasses, textInputClasses } from 'styles';
+
+function SettingsHeader({
+ setDragging,
+ openModal,
+ title,
+ tooltip,
+ searchValue,
+ setSearchValue,
+}: any) {
+ const { isMobile, theme } = useCommonHooks();
+ return (
+
+
+
+ {title}
+
+
+
+
+
+
+
+
+
+
+ {tooltip.title}
+
+
+ {tooltip.description}
+
+
+
+
+
+
+ {
+ setSearchValue(event.target.value);
+ }}
+ />
+ {setDragging && (
+ Reorder}
+ labelPosition='left'
+ pos={'absolute'}
+ right={isMobile ? '2rem' : '1rem'}
+ top={isMobile ? '10rem' : undefined}
+ onChange={(e) => {
+ setDragging(e.target.checked);
+ }}
+ color={theme.primaryColor}
+ styles={{
+ label: {
+ color: theme.primaryColor,
+ top: isMobile ? -22 : 0,
+ left: isMobile ? -8 : 0,
+ position: isMobile ? 'absolute' : undefined,
+ },
+ }}
+ />
+ )}
+
+ );
+}
+
+export default SettingsHeader;
diff --git a/src/pages/settings/components/Theming/ThemeModal.tsx b/src/pages/settings/components/Theming/ThemeModal.tsx
index 401ca40..3e0bd5a 100644
--- a/src/pages/settings/components/Theming/ThemeModal.tsx
+++ b/src/pages/settings/components/Theming/ThemeModal.tsx
@@ -39,6 +39,19 @@ function ThemeModal({
const filtered = backgroundList.filter((item: any) =>
item.toLowerCase().includes(query.toLowerCase()),
);
+ if (selectedTheme.name === undefined) {
+ setSelectedTheme({
+ id: undefined,
+ name: 'default',
+ backgroundImage: 'none',
+ backgroundColor: '#EEEEEE',
+ searchColor: '#00000033',
+ primaryColor: '#222222',
+ accentColor: '#5c5c5c',
+ borderColor: '#5c5c5c',
+ });
+ }
+
const re = /(?:\.([^.]+))?$/;
const items = filtered.map((item: any, index: any) => (
{
handleClose();
setThemeList('[]');
- setSelectedPlaylist({});
}}
style={{
'--color-text-pri': theme.primaryColor,
diff --git a/src/pages/settings/components/Theming/ThemePlaylists.tsx b/src/pages/settings/components/Theming/ThemePlaylists.tsx
index e83829a..6c28edd 100644
--- a/src/pages/settings/components/Theming/ThemePlaylists.tsx
+++ b/src/pages/settings/components/Theming/ThemePlaylists.tsx
@@ -1,20 +1,11 @@
-import {
- ActionIcon,
- Box,
- Button,
- Group,
- Highlight,
- Popover,
- Stack,
- Text,
- TextInput,
-} from '@mantine/core';
+import { Box, Group, Stack, Text } from '@mantine/core';
import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
import { useState } from 'react';
-import { FiChevronRight, FiHelpCircle, FiPlus } from 'react-icons/fi';
-import { actionIconClasses, buttonClasses, textClasses, textInputClasses } from 'styles';
+import { FiChevronRight } from 'react-icons/fi';
+import { textClasses } from 'styles';
import type { ThemePlaylist } from 'types';
+import SettingsHeader from '../Shared/SettingsHeader';
import ThemePlaylistCard from './ThemePlaylistCard';
import ThemePlaylistModal from './ThemePlaylistModal';
@@ -28,8 +19,7 @@ function ThemePlaylists() {
const { mutateAsync } = useMutationAPI();
const [opened, { open, close }] = useDisclosure(false);
const [selectedPlaylist, setSelectedPlaylist] = useState({});
- const { currentThemePlaylist, setCurrentThemePlaylist, theme, isMobile } =
- useCommonHooks();
+ const { currentThemePlaylist, setCurrentThemePlaylist, theme } = useCommonHooks();
const [searchValue, setSearchValue] = useState('');
const [debouncedSearch] = useDebouncedValue(searchValue, 500);
@@ -39,6 +29,7 @@ function ThemePlaylists() {
};
const handleClose = () => {
+ setSelectedPlaylist({});
close();
};
@@ -52,7 +43,7 @@ function ThemePlaylists() {
};
return (
- <>
+
-
-
-
- Theme Playlists
-
-
-
-
-
-
-
-
-
-
- {'Theme playlists can be created here and applied to the homepage.'}
-
-
- {
- 'Playlists are lists of themes. They can be enabled either here or in the settings button on the homepage. When a playlist is enabled, it will shuffle the included themes on the homepage. If a theme is part of a playlist, it will appear while the playlist is active, regardless of random/shuffle.'
- }
-
-
-
-
-
-
- {
- setSearchValue(event.target.value);
- }}
- />
-
+
Defaults
@@ -222,7 +155,7 @@ function ThemePlaylists() {
})}
- >
+
);
}
diff --git a/src/pages/settings/components/Theming/Themes.tsx b/src/pages/settings/components/Theming/Themes.tsx
index 348e3bd..f0ce445 100644
--- a/src/pages/settings/components/Theming/Themes.tsx
+++ b/src/pages/settings/components/Theming/Themes.tsx
@@ -1,25 +1,13 @@
-import {
- ActionIcon,
- Box,
- Button,
- Group,
- Highlight,
- Overlay,
- Popover,
- Stack,
- Switch,
- Text,
- TextInput,
-} from '@mantine/core';
+import { Box, Group, Overlay, Stack, Switch, Text } from '@mantine/core';
import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
import { useEffect, useState } from 'react';
-import { FiChevronRight, FiHelpCircle, FiPlus } from 'react-icons/fi';
+import { FiChevronRight } from 'react-icons/fi';
import '@mantine/core/styles/ModalBase.css';
import '@mantine/core/styles/Modal.css';
import { FaDice } from 'react-icons/fa';
-import { actionIconClasses, buttonClasses, textClasses, textInputClasses } from 'styles';
import type { Theme } from 'types';
+import SettingsHeader from '../Shared/SettingsHeader';
import ThemeCard from './ThemeCard';
import ThemeModal from './ThemeModal';
function ThemesSettings() {
@@ -49,6 +37,7 @@ function ThemesSettings() {
const handleClose = () => {
close();
closePicker();
+ setSelectedTheme({});
};
const handleSaveTheme = () => {
@@ -66,7 +55,7 @@ function ThemesSettings() {
}
}, [backgroundData, isBackgroundFetched]);
return (
- <>
+
-
-
-
- Themes
-
-
-
-
-
-
-
-
-
-
- {'Themes can be created here and applied to the homepage.'}
-
-
- {
- 'Themes are combinations of 5 colors and a background image, and can be added to a playlist. If a theme has been disabled, it will only be disabled with random/shuffle is enabled. If a theme is part of a playlist, it will appear while the playlist is active, regardless of random/shuffle.'
- }
-
-
-
-
-
-
- {
- setSearchValue(event.target.value);
- }}
- />
-
- ) : (
- Random Theme
- )
- }
- labelPosition='left'
- pos={'absolute'}
- right={isMobile ? '2rem' : '1rem'}
- top={isMobile ? '9.5rem' : undefined}
- checked={currentTheme === 'random'}
- onChange={(e) => {
- setCurrentTheme(e.target.checked ? 'random' : theme.name);
- setCurrentThemePlaylist('All');
- }}
- color={theme.primaryColor}
- />
-
+
+
+ ) : (
+ Random Theme
+ )
+ }
+ labelPosition='left'
+ pos={'absolute'}
+ right={isMobile ? '2rem' : '1rem'}
+ top={isMobile ? '9.5rem' : '7rem'}
+ checked={currentTheme === 'random'}
+ onChange={(e) => {
+ setCurrentTheme(e.target.checked ? 'random' : theme.name);
+ setCurrentThemePlaylist('All');
+ }}
+ color={theme.primaryColor}
+ />
- >
+
);
}
export default ThemesSettings;
diff --git a/src/pages/settings/components/WoL/WolClients.tsx b/src/pages/settings/components/WoL/WolClients.tsx
index 356b795..452d753 100644
--- a/src/pages/settings/components/WoL/WolClients.tsx
+++ b/src/pages/settings/components/WoL/WolClients.tsx
@@ -1,31 +1,21 @@
import {
- ActionIcon,
Button,
Card,
Divider,
Grid,
GridCol,
Group,
- Highlight,
Modal,
Popover,
Stack,
- Text,
TextInput,
} from '@mantine/core';
import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
import { useEffect, useState } from 'react';
-import { FiHelpCircle, FiPlus } from 'react-icons/fi';
-import {
- actionIconClasses,
- buttonClasses,
- cardClasses,
- modalClasses,
- textClasses,
- textInputClasses,
-} from 'styles';
+import { cardClasses, modalClasses, textInputClasses } from 'styles';
import type { WolClient } from 'types';
+import SettingsHeader from '../Shared/SettingsHeader';
import DebouncedWolClient from './DebouncedWolClient';
import WolClientSettingsItem from './WolClientSettingsItem';
@@ -36,7 +26,7 @@ const WolClientSettings = () => {
});
const [wolClients, setWolClients] = useState([]);
const { mutateAsync } = useMutationAPI();
- const { theme, isMobile, modalStyle } = useCommonHooks();
+ const { isMobile, modalStyle } = useCommonHooks();
const [newWolClient, setNewWolClient] = useState({
id: undefined,
hostname: '',
@@ -141,69 +131,18 @@ const WolClientSettings = () => {
-
-
-
- WoL Clients
-
-
-
-
-
-
-
-
-
-
- {'Wake on Lan clients can be configured here.'}
-
-
- {'Clients can be powered on from the settings button the homepage.'}
-
-
-
-
-
-
- {
- setSearchValue(event.target.value);
- }}
- />
-
+
{wolClients?.map((client: WolClient) => (