MainLayout for theme persistence
This commit is contained in:
@@ -55,7 +55,7 @@ export function Homepage({ theme }: any) {
|
||||
if (data) {
|
||||
setDisplayedGreeting(greet(data));
|
||||
}
|
||||
}, [isFetching]);
|
||||
}, [data, isFetching]);
|
||||
|
||||
useEffect(() => {
|
||||
if (weather && basicWeather) {
|
||||
|
||||
@@ -8,10 +8,10 @@ function Applications({ contentType, isMobile }: any) {
|
||||
const { data, isFetching } = useQueryAPI({ endpoint: 'api/apps' });
|
||||
const [applications, setApplications] = useState([]);
|
||||
useEffect(() => {
|
||||
if (!isFetching) {
|
||||
if (data && !isFetching) {
|
||||
setApplications(data);
|
||||
}
|
||||
}, [isFetching]);
|
||||
}, [data, isFetching]);
|
||||
return (
|
||||
<>
|
||||
{applications.length > 0 && contentType.length > 0 && (
|
||||
|
||||
@@ -16,7 +16,6 @@ function Header({
|
||||
weatherModalOpened,
|
||||
closeWeatherModal,
|
||||
openWeatherModal,
|
||||
setValue,
|
||||
setProviderLabel,
|
||||
setProviderURL,
|
||||
}: any) {
|
||||
@@ -155,7 +154,6 @@ function Header({
|
||||
hourly={hourly}
|
||||
closeWeatherModal={closeWeatherModal}
|
||||
weatherModalOpened={weatherModalOpened}
|
||||
setValue={setValue}
|
||||
setProviderLabel={setProviderLabel}
|
||||
setProviderURL={setProviderURL}
|
||||
isMobile={isMobile}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Button, Menu, MultiSelect, NavLink } from '@mantine/core';
|
||||
import { useQueryAPI } from 'hooks';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { FiMenu, FiMonitor } from 'react-icons/fi';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { buttonClasses, menuClasses, navLinkClasses, selectClasses } from 'styles';
|
||||
|
||||
function SettingsButton({
|
||||
@@ -12,7 +13,7 @@ function SettingsButton({
|
||||
}: any) {
|
||||
const { data, isFetched } = useQueryAPI({ endpoint: 'api/appCategories' });
|
||||
const [categories, setCategories] = useState([{ value: 'All', label: 'All' }]);
|
||||
|
||||
const navigate = useNavigate();
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
const list: [any] =
|
||||
@@ -42,9 +43,9 @@ function SettingsButton({
|
||||
<NavLink
|
||||
label='Settings'
|
||||
component='a'
|
||||
href={`/${import.meta.env.VITE_BASE_URL}/settings`}
|
||||
className={navLinkClasses.defaultNavLink}
|
||||
classNames={navLinkClasses}
|
||||
onClick={() => navigate(`/${import.meta.env.VITE_BASE_URL}/settings`)}
|
||||
/>
|
||||
<NavLink
|
||||
label='Quick Actions'
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
FiSearch,
|
||||
FiUser,
|
||||
} from 'react-icons/fi';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { actionIconClasses, tabClasses, textClasses } from 'styles';
|
||||
import Applications from './components/Applications';
|
||||
import Bookmarks from './components/Bookmarks';
|
||||
@@ -18,8 +19,9 @@ import Personalization from './components/Personalization';
|
||||
import SearchProviders from './components/SearchProviders';
|
||||
import Themes from './components/Themes';
|
||||
|
||||
export function Settings({ theme }: any) {
|
||||
export function Settings({ theme, setTheme, allThemes }: any) {
|
||||
const isMobile = window.matchMedia('(max-width: 600px)').matches;
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<Stack px={'2rem'}>
|
||||
<Group gap={0}>
|
||||
@@ -27,7 +29,7 @@ export function Settings({ theme }: any) {
|
||||
className={actionIconClasses.backButton}
|
||||
classNames={actionIconClasses}
|
||||
component='a'
|
||||
href={`/${import.meta.env.VITE_BASE_URL}`}
|
||||
onClick={() => navigate(`/${import.meta.env.VITE_BASE_URL}`)}
|
||||
>
|
||||
<FiArrowLeftCircle />
|
||||
</ActionIcon>
|
||||
@@ -74,7 +76,7 @@ export function Settings({ theme }: any) {
|
||||
<Categories />
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value='themes'>
|
||||
<Themes theme={theme} />
|
||||
<Themes theme={theme} setTheme={setTheme} allThemes={allThemes} />
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value='providers'>
|
||||
<SearchProviders />
|
||||
|
||||
@@ -7,12 +7,15 @@ function ThemeCard({
|
||||
handleOpen,
|
||||
handleDeleteTheme,
|
||||
theme,
|
||||
allThemes,
|
||||
setTheme,
|
||||
cardTheme,
|
||||
currentTheme,
|
||||
setValue,
|
||||
createTheme,
|
||||
}: any) {
|
||||
const [hover, setHover] = useState(false);
|
||||
const [shift, setShift] = useState<number>(0);
|
||||
return (
|
||||
<Group
|
||||
gap={0}
|
||||
@@ -51,7 +54,7 @@ function ThemeCard({
|
||||
backgroundColor: cardTheme.backgroundColor,
|
||||
border: `solid ${cardTheme.borderColor}`,
|
||||
}}
|
||||
data-cardTheme={cardTheme.name}
|
||||
// data-cardTheme={cardTheme.name}
|
||||
onClick={() => {
|
||||
setValue(cardTheme.name);
|
||||
}}
|
||||
@@ -145,23 +148,46 @@ function ThemeCard({
|
||||
</Button>
|
||||
{currentTheme === 'random' && cardTheme.name === theme.name ? (
|
||||
<Group
|
||||
onMouseEnter={() => {
|
||||
setShift(2);
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
setShift(0);
|
||||
}}
|
||||
onClick={() => {
|
||||
setShift(0);
|
||||
}}
|
||||
gap={0}
|
||||
style={{
|
||||
zIndex: 300,
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
backgroundColor: 'white',
|
||||
top: 27 - shift,
|
||||
backgroundColor: shift === 0 ? 'white' : 'var(--color-background)',
|
||||
borderRadius: '50%',
|
||||
padding: '8px',
|
||||
margin: '4px',
|
||||
border: 'solid 2px black',
|
||||
border: 'solid 2px',
|
||||
borderColor: shift === 0 ? 'black' : 'var(--color-text-pri)',
|
||||
transition: 'all 0.2s',
|
||||
}}
|
||||
>
|
||||
<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]);
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
fontSize: '2em',
|
||||
fontWeight: 'bold',
|
||||
color: 'black',
|
||||
color: shift === 0 ? 'black' : 'var(--color-text-pri)',
|
||||
}}
|
||||
/>
|
||||
</Group>
|
||||
|
||||
@@ -9,7 +9,7 @@ import { modals } from '@mantine/modals';
|
||||
import { buttonClasses, textClasses } from 'styles';
|
||||
import ThemeCard from './ThemeCard';
|
||||
import ThemeModal from './ThemeModal';
|
||||
function ThemesSettings({ theme }: any) {
|
||||
function ThemesSettings({ theme, setTheme, allThemes }: any) {
|
||||
const [opened, { open, close }] = useDisclosure(false);
|
||||
const [pickerOpen, { open: openPicker, close: closePicker }] = useDisclosure(false);
|
||||
const [colorId, setColorId] = useState<string>('');
|
||||
@@ -18,23 +18,14 @@ function ThemesSettings({ theme }: any) {
|
||||
key: 'theme',
|
||||
defaultValue: 'blackboard',
|
||||
});
|
||||
const { data, isFetched } = useQueryAPI({
|
||||
endpoint: 'api/themes',
|
||||
});
|
||||
const { data: backgrounds, isFetched: isBackgroundFetched } = useQueryAPI({
|
||||
endpoint: 'api/backgrounds',
|
||||
});
|
||||
const [themesList, setThemesList] = useState([]);
|
||||
const [backgroundList, setBackgroundList] = useState<any>(['None']);
|
||||
const [selectedTheme, setSelectedTheme] = useState<any>({});
|
||||
const { mutateAsync: createTheme } = useMutationAPI();
|
||||
const { mutateAsync: deleteTheme } = useMutationAPI();
|
||||
|
||||
useEffect(() => {
|
||||
if (isFetched) {
|
||||
setThemesList(data);
|
||||
}
|
||||
}, [data, isFetched]);
|
||||
const isMobile = window.matchMedia('(max-width: 600px)').matches;
|
||||
|
||||
useEffect(() => {
|
||||
if (backgrounds && isBackgroundFetched) {
|
||||
@@ -128,7 +119,7 @@ function ThemesSettings({ theme }: any) {
|
||||
color={theme.primaryColor}
|
||||
/>
|
||||
</Group>
|
||||
<Group justify='center' pos={'relative'}>
|
||||
<Group justify='center' align='center' pos={'relative'}>
|
||||
<Overlay
|
||||
display={currentTheme === 'random' ? 'flex' : 'none'}
|
||||
blur={5}
|
||||
@@ -136,10 +127,12 @@ function ThemesSettings({ theme }: any) {
|
||||
borderRadius: '10px',
|
||||
marginTop: '-15px',
|
||||
marginBottom: '-10px',
|
||||
marginRight: isMobile ? '0' : '50px',
|
||||
marginLeft: isMobile ? '0' : '50px',
|
||||
}}
|
||||
pos={'absolute'}
|
||||
/>
|
||||
{themesList.map((cardTheme: any) => (
|
||||
{allThemes?.map((cardTheme: any) => (
|
||||
<Group key={cardTheme.name} pos={'relative'}>
|
||||
{cardTheme.name === currentTheme && (
|
||||
<FiChevronRight
|
||||
@@ -166,6 +159,8 @@ function ThemesSettings({ theme }: any) {
|
||||
>
|
||||
<ThemeCard
|
||||
theme={theme}
|
||||
allThemes={allThemes}
|
||||
setTheme={setTheme}
|
||||
cardTheme={cardTheme}
|
||||
currentTheme={currentTheme}
|
||||
handleOpen={handleOpen}
|
||||
|
||||
Reference in New Issue
Block a user