Updated header and bug fixes
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { ActionIcon, Group, Stack, Tabs, Text } from '@mantine/core';
|
||||
import { ActionIcon, Group, ScrollArea, Stack, Tabs, Text } from '@mantine/core';
|
||||
import { useCommonHooks } from 'hooks';
|
||||
import { FaPaintBrush, FaRegListAlt } from 'react-icons/fa';
|
||||
import {
|
||||
@@ -26,8 +26,8 @@ export function Settings() {
|
||||
const navigate = useNavigate();
|
||||
const { tabValue } = useParams();
|
||||
return (
|
||||
<Stack px={'2rem'}>
|
||||
<Group gap={0}>
|
||||
<Stack h={'100%'}>
|
||||
<Group gap={0} pl={'2rem'}>
|
||||
<ActionIcon
|
||||
className={actionIconClasses.backButton}
|
||||
classNames={actionIconClasses}
|
||||
@@ -47,9 +47,13 @@ export function Settings() {
|
||||
classNames={tabClasses}
|
||||
keepMounted={false}
|
||||
value={tabValue}
|
||||
h={'100%'}
|
||||
onChange={(value) =>
|
||||
navigate(`/${import.meta.env.VITE_BASE_URL}/settings/${value}`)
|
||||
}
|
||||
style={{
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<Tabs.List style={{ justifyContent: isMobile ? 'space-between' : undefined }}>
|
||||
<Tabs.Tab px={isMobile ? '.9rem' : undefined} value='personalization'>
|
||||
@@ -78,28 +82,44 @@ export function Settings() {
|
||||
</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel value='personalization'>
|
||||
<Personalization />
|
||||
<ScrollArea h={'100%'}>
|
||||
<Personalization />
|
||||
</ScrollArea>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value='messages'>
|
||||
<Messages />
|
||||
<ScrollArea h={'100%'}>
|
||||
<Messages />
|
||||
</ScrollArea>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value='applications'>
|
||||
<Applications />
|
||||
<ScrollArea h={'100%'}>
|
||||
<Applications />
|
||||
</ScrollArea>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value='bookmarks'>
|
||||
<Bookmarks />
|
||||
<ScrollArea h={'100%'}>
|
||||
<Bookmarks />
|
||||
</ScrollArea>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value='themes'>
|
||||
<Themes />
|
||||
<ScrollArea h={'100%'}>
|
||||
<Themes />
|
||||
</ScrollArea>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value='themePlaylists'>
|
||||
<ThemePlaylists />
|
||||
<ScrollArea h={'100%'}>
|
||||
<ThemePlaylists />
|
||||
</ScrollArea>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value='providers'>
|
||||
<SearchProviders />
|
||||
<ScrollArea h={'100%'}>
|
||||
<SearchProviders />
|
||||
</ScrollArea>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value='wolClients'>
|
||||
<WolClients />
|
||||
<ScrollArea h={'100%'}>
|
||||
<WolClients />
|
||||
</ScrollArea>
|
||||
</Tabs.Panel>
|
||||
</Tabs>
|
||||
</Stack>
|
||||
|
||||
@@ -10,7 +10,7 @@ function AppSettingsItem({ url, icon, name, enabled }: any) {
|
||||
const [hover, setHover] = useState<boolean>(false);
|
||||
const { isMobile, theme } = useCommonHooks();
|
||||
return (
|
||||
<>
|
||||
<Box pos={'relative'}>
|
||||
{enabled === 0 && (
|
||||
<Tooltip label={<Text c={theme.primaryColor}>This app is disabled</Text>}>
|
||||
<ActionIcon
|
||||
@@ -85,7 +85,7 @@ function AppSettingsItem({ url, icon, name, enabled }: any) {
|
||||
</Text>
|
||||
</Stack>
|
||||
</Box>
|
||||
</>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -240,7 +240,7 @@ const ApplicationSettings = () => {
|
||||
/>
|
||||
{dragging ? (
|
||||
<DragDropContext onDragEnd={onDragEnd}>
|
||||
<Stack w={'100%'} align='center'>
|
||||
<Stack mt={'6rem'} mb={'1rem'} w={'100%'} align='center'>
|
||||
<Droppable droppableId={'groupList'}>
|
||||
{(provided) => (
|
||||
<Stack
|
||||
@@ -316,7 +316,7 @@ const ApplicationSettings = () => {
|
||||
</Stack>
|
||||
</DragDropContext>
|
||||
) : (
|
||||
<Stack w={'100%'} align='center'>
|
||||
<Stack mt={'6rem'} mb={'1rem'} w={'100%'} align='center'>
|
||||
<Grid columns={18} w={'75%'}>
|
||||
{applicationData?.map((application: Application) => (
|
||||
<GridCol span={6} key={application.id}>
|
||||
|
||||
@@ -182,7 +182,7 @@ const BookmarkSettings = () => {
|
||||
/>
|
||||
{dragging ? (
|
||||
<DragDropContext onDragEnd={onDragEnd}>
|
||||
<Stack w={'100%'} align='center'>
|
||||
<Stack mt={'6rem'} mb={'1rem'} w={'100%'} align='center'>
|
||||
<Droppable droppableId={'groupList'}>
|
||||
{(provided) => (
|
||||
<Stack
|
||||
@@ -258,7 +258,7 @@ const BookmarkSettings = () => {
|
||||
</Stack>
|
||||
</DragDropContext>
|
||||
) : (
|
||||
<Stack w={'100%'} align='center'>
|
||||
<Stack mt={'6rem'} mb={'1rem'} w={'100%'} align='center'>
|
||||
<Group w={isMobile ? undefined : '75%'} align='start'>
|
||||
{groups?.map((group: BookmarkGroup) => (
|
||||
<DebouncedGroupSettingsItem
|
||||
|
||||
@@ -47,6 +47,19 @@ const MessageSettings = () => {
|
||||
|
||||
return (
|
||||
<Stack w={'100%'}>
|
||||
<SettingsHeader
|
||||
setDragging={undefined}
|
||||
openModal={openModal}
|
||||
title={'Messages'}
|
||||
tooltip={{
|
||||
title: 'These custom messages will be displayed in the header on the homepage.',
|
||||
highlightList: ['$firstName', '$lastName', '$^firstName', '$^lastName'],
|
||||
description:
|
||||
'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.',
|
||||
}}
|
||||
searchValue={searchValue}
|
||||
setSearchValue={setSearchValue}
|
||||
/>
|
||||
<AddItemModal
|
||||
modalOpened={modalOpened}
|
||||
handleClose={handleClose}
|
||||
@@ -94,20 +107,7 @@ const MessageSettings = () => {
|
||||
</Stack>
|
||||
}
|
||||
/>
|
||||
<SettingsHeader
|
||||
setDragging={undefined}
|
||||
openModal={openModal}
|
||||
title={'Messages'}
|
||||
tooltip={{
|
||||
title: 'These custom messages will be displayed in the header on the homepage.',
|
||||
highlightList: ['$firstName', '$lastName', '$^firstName', '$^lastName'],
|
||||
description:
|
||||
'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.',
|
||||
}}
|
||||
searchValue={searchValue}
|
||||
setSearchValue={setSearchValue}
|
||||
/>
|
||||
<Stack w={'100%'} align='center'>
|
||||
<Stack mt={'6rem'} mb={'1rem'} w={'100%'} align='center'>
|
||||
<Grid w={'75%'}>
|
||||
{messages?.map((message: Message) => (
|
||||
<GridCol span={isMobile ? 12 : 6} key={message.id}>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Card, Grid, GridCol, Overlay, Stack, Text, TextInput } from '@mantine/core';
|
||||
import { Card, Grid, GridCol, Overlay, Stack, TextInput } from '@mantine/core';
|
||||
import { useDebouncedValue } from '@mantine/hooks';
|
||||
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { cardClasses, textClasses, textInputClasses } from 'styles';
|
||||
import { cardClasses, textInputClasses } from 'styles';
|
||||
import type { PersonalData } from 'types';
|
||||
import SettingsHeader from '../Shared/SettingsHeader';
|
||||
const PersonalizationSettings = () => {
|
||||
const endpoint = 'api/personalData';
|
||||
const {
|
||||
@@ -39,11 +40,30 @@ const PersonalizationSettings = () => {
|
||||
}, [update]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
||||
Personalization
|
||||
</Text>
|
||||
<Stack w={'100%'} align='center'>
|
||||
<Stack>
|
||||
<SettingsHeader
|
||||
setDragging={undefined}
|
||||
openModal={() => {}}
|
||||
title={'Personalization'}
|
||||
tooltip={{
|
||||
title: 'The personalization section allows you to update basic information.',
|
||||
highlightList: [
|
||||
'Applications',
|
||||
'apps',
|
||||
'application',
|
||||
'name',
|
||||
'base url',
|
||||
'url',
|
||||
'icon',
|
||||
'filter',
|
||||
],
|
||||
description:
|
||||
'The first and last name fields will be used for greetings, and the physical address field will be used for weather.',
|
||||
}}
|
||||
searchValue={undefined}
|
||||
setSearchValue={() => {}}
|
||||
/>
|
||||
<Stack mt={'6rem'} mb={'1rem'} w={'100%'} align='center'>
|
||||
<Grid w={'75%'} pos={'relative'}>
|
||||
{personalIsFetching && (
|
||||
<Overlay
|
||||
@@ -124,7 +144,7 @@ const PersonalizationSettings = () => {
|
||||
</GridCol>
|
||||
</Grid>
|
||||
</Stack>
|
||||
</>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
export default PersonalizationSettings;
|
||||
|
||||
@@ -148,7 +148,7 @@ const SearchProviderSettings = () => {
|
||||
searchValue={searchValue}
|
||||
setSearchValue={setSearchValue}
|
||||
/>
|
||||
<Stack w={'100%'} align='center'>
|
||||
<Stack mt={'6rem'} mb={'1rem'} w={'100%'} align='center'>
|
||||
<Grid columns={18} w={'75%'}>
|
||||
{providerData?.map((provider: Provider) => (
|
||||
<GridCol span={isMobile ? 18 : 6} key={provider.id}>
|
||||
|
||||
@@ -23,12 +23,22 @@ function SettingsHeader({
|
||||
}: any) {
|
||||
const { isMobile, theme } = useCommonHooks();
|
||||
return (
|
||||
<Group align='center' justify='center' mt={'1rem'}>
|
||||
<Group
|
||||
py={'1.5rem'}
|
||||
pl={'1rem'}
|
||||
h={'min-content'}
|
||||
w={'100%'}
|
||||
align='center'
|
||||
mt={0}
|
||||
justify='center'
|
||||
pos={'absolute'}
|
||||
style={{ backdropFilter: 'blur(10px) brightness(.5)', zIndex: 1 }}
|
||||
>
|
||||
<Group w={isMobile ? undefined : '100%'}>
|
||||
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
||||
{title}
|
||||
</Text>
|
||||
<Popover withArrow withOverlay withinPortal={false}>
|
||||
<Popover withArrow withOverlay withinPortal={true}>
|
||||
<Popover.Target>
|
||||
<ActionIcon
|
||||
className={actionIconClasses.settingsTooltip}
|
||||
@@ -65,26 +75,33 @@ function SettingsHeader({
|
||||
</Stack>
|
||||
</Popover.Dropdown>
|
||||
</Popover>
|
||||
<Button
|
||||
className={buttonClasses.tableButton}
|
||||
classNames={buttonClasses}
|
||||
onClick={openModal}
|
||||
>
|
||||
<FiPlus />
|
||||
</Button>
|
||||
{searchValue !== undefined && (
|
||||
<Button
|
||||
className={buttonClasses.tableButton}
|
||||
classNames={buttonClasses}
|
||||
onClick={openModal}
|
||||
>
|
||||
<FiPlus />
|
||||
</Button>
|
||||
)}
|
||||
</Group>
|
||||
<TextInput
|
||||
w={isMobile ? undefined : '35%'}
|
||||
pos={isMobile ? undefined : 'absolute'}
|
||||
className={textInputClasses.settingsItem}
|
||||
classNames={textInputClasses}
|
||||
autoFocus={!isMobile}
|
||||
placeholder='Search...'
|
||||
value={searchValue}
|
||||
onInput={(event: any) => {
|
||||
setSearchValue(event.target.value);
|
||||
}}
|
||||
/>
|
||||
{searchValue !== undefined && (
|
||||
<TextInput
|
||||
w={isMobile ? undefined : '35%'}
|
||||
pos={isMobile ? undefined : 'absolute'}
|
||||
className={textInputClasses.settingsItem}
|
||||
classNames={textInputClasses}
|
||||
autoFocus={!isMobile}
|
||||
placeholder='Search...'
|
||||
value={searchValue}
|
||||
onInput={(event: any) => {
|
||||
setSearchValue(event.target.value);
|
||||
}}
|
||||
style={{
|
||||
zIndex: 100,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{setDragging && (
|
||||
<Switch
|
||||
label={<Text c={theme.primaryColor}>Reorder</Text>}
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
import { ActionIcon, Box, Button, Group, Overlay, Stack, Text } from '@mantine/core';
|
||||
import { useDisclosure } from '@mantine/hooks';
|
||||
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
|
||||
import { useCommonHooks, useMutationAPI } from 'hooks';
|
||||
import { useState } from 'react';
|
||||
import { FiEdit, FiShuffle, FiTrash, FiX } from 'react-icons/fi';
|
||||
import { actionIconClasses } from 'styles';
|
||||
import type { ThemePlaylist } from 'types';
|
||||
import DeleteItemModal from '../Shared/DeleteItemModal';
|
||||
|
||||
function ThemeCard({ cardTheme, handleOpen, allThemes }: any) {
|
||||
const { data: themePlaylists } = useQueryAPI({
|
||||
endpoint: 'api/themePlaylists',
|
||||
});
|
||||
function ThemeCard({ cardTheme, handleOpen, allThemes, themePlaylists }: any) {
|
||||
const [hover, setHover] = useState(false);
|
||||
const [shiftEdit, setShiftEdit] = useState<number>(0);
|
||||
const [shiftShuffle, setShiftShuffle] = useState<number>(0);
|
||||
|
||||
@@ -69,7 +69,7 @@ function ThemePlaylists() {
|
||||
searchValue={searchValue}
|
||||
setSearchValue={setSearchValue}
|
||||
/>
|
||||
<Group justify='center' align='center' pos={'relative'}>
|
||||
<Group mt={'6rem'} justify='center' align='center' pos={'relative'}>
|
||||
<Text p={0} className={textClasses.settingsSubTitle} classNames={textClasses}>
|
||||
Defaults
|
||||
</Text>
|
||||
|
||||
@@ -17,6 +17,9 @@ function ThemesSettings() {
|
||||
const { data: backgroundData, isFetched: isBackgroundFetched } = useQueryAPI({
|
||||
endpoint: backgroundsEndpoint,
|
||||
});
|
||||
const { data: themePlaylists } = useQueryAPI({
|
||||
endpoint: 'api/themePlaylists',
|
||||
});
|
||||
const { mutateAsync } = useMutationAPI();
|
||||
const [opened, { open, close }] = useDisclosure(false);
|
||||
const [colorId, setColorId] = useState<string>('');
|
||||
@@ -97,15 +100,18 @@ function ThemesSettings() {
|
||||
labelPosition='left'
|
||||
pos={'absolute'}
|
||||
right={isMobile ? '2rem' : '1rem'}
|
||||
top={isMobile ? '9.5rem' : '7rem'}
|
||||
top={isMobile ? '9.5rem' : '2rem'}
|
||||
checked={currentTheme === 'random'}
|
||||
onChange={(e) => {
|
||||
setCurrentTheme(e.target.checked ? 'random' : theme.name);
|
||||
setCurrentThemePlaylist('All');
|
||||
}}
|
||||
color={theme.primaryColor}
|
||||
style={{
|
||||
zIndex: 1,
|
||||
}}
|
||||
/>
|
||||
<Group justify='center' align='center' pos={'relative'} mt={'1rem'}>
|
||||
<Group justify='center' align='center' pos={'relative'} mt={'10rem'}>
|
||||
<Overlay
|
||||
display={currentTheme === 'random' ? 'flex' : 'none'}
|
||||
blur={5}
|
||||
@@ -152,6 +158,7 @@ function ThemesSettings() {
|
||||
allThemes={allThemes}
|
||||
cardTheme={cardTheme}
|
||||
handleOpen={handleOpen}
|
||||
themePlaylists={themePlaylists}
|
||||
/>
|
||||
</Box>
|
||||
</Group>
|
||||
|
||||
@@ -131,7 +131,7 @@ const WolClientSettings = () => {
|
||||
searchValue={searchValue}
|
||||
setSearchValue={setSearchValue}
|
||||
/>
|
||||
<Stack w={'100%'} align='center'>
|
||||
<Stack mt={'6rem'} mb={'1rem'} w={'100%'} align='center'>
|
||||
<Grid columns={18} w={'75%'}>
|
||||
{wolClients?.map((client: WolClient) => (
|
||||
<GridCol w={'100%'} span={isMobile ? 18 : 6} key={client.id}>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
}
|
||||
}
|
||||
.panel {
|
||||
padding-left: 2rem;
|
||||
border-top: solid 2px var(--color-text-acc);
|
||||
}
|
||||
.tab {
|
||||
color: var(--color-text-pri);
|
||||
@@ -18,6 +18,12 @@
|
||||
border-color: var(--color-text-pri);
|
||||
}
|
||||
}
|
||||
.list {
|
||||
border-top: solid 2px var(--color-text-acc);
|
||||
padding-left: 2rem;
|
||||
padding-top: 2rem;
|
||||
height: 100%;
|
||||
}
|
||||
.list::before {
|
||||
border-color: var(--color-text-acc);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user