Updates to personalization

This commit is contained in:
Sean Edmunds
2025-12-29 16:01:14 -06:00
parent c3cbf43647
commit c5f71b468c
13 changed files with 216 additions and 72 deletions

View File

@@ -1,5 +1,6 @@
import { ActionIcon, Divider, Group, ScrollArea, Stack, Tabs, Text } from '@mantine/core';
import { useCommonHooks } from 'hooks';
import { useCommonHooks, useQueryAPI } from 'hooks';
import { useEffect, useState } from 'react';
import { FaPaintBrush, FaRegListAlt } from 'react-icons/fa';
import {
FiArrowLeftCircle,
@@ -12,6 +13,7 @@ import {
} from 'react-icons/fi';
import { useNavigate, useParams } from 'react-router-dom';
import { actionIconClasses, scrollAreaClasses, tabClasses, textClasses } from 'styles';
import type { PersonalData } from 'types';
import Applications from './components/Applications/Applications';
import Bookmarks from './components/Bookmarks/Bookmarks';
import GuacamoleClients from './components/GuacamoleClients/GuacamoleClients';
@@ -24,9 +26,20 @@ import { Themes } from './components/Theming/Themes';
import WolClients from './components/WoL/WolClients';
export function Settings() {
const endpoint = 'api/personalData';
const { data: personalData, isFetched: personalDataIsFetched } = useQueryAPI({
endpoint: endpoint,
});
const [personal, setPersonal] = useState<PersonalData>();
const { isMobile, theme } = useCommonHooks();
const navigate = useNavigate();
const { tabValue } = useParams();
useEffect(() => {
if (personalData && personalDataIsFetched) {
setPersonal(personalData[0]);
}
}, [personalData, personalDataIsFetched]);
return (
<Stack h={'100%'} gap={0}>
<Group gap={0} style={{ position: 'relative', paddingBottom: '1rem' }}>
@@ -142,7 +155,7 @@ export function Settings() {
<Tabs.Tab px={isMobile ? '.9rem' : undefined} value='history'>
{isMobile ? <FiSearch /> : 'Search History'}
</Tabs.Tab>
{!isMobile && (
{!isMobile && (personal?.enableWol || personal?.enableGuacamole) ? (
<Group w={'100%'} gap={0} justify='center'>
<Divider
label='Extras'
@@ -159,13 +172,17 @@ export function Settings() {
}}
/>
</Group>
)}
<Tabs.Tab px={isMobile ? '.9rem' : undefined} value='wolClients'>
{isMobile ? <FiMonitor /> : 'WoL Clients'}
</Tabs.Tab>
<Tabs.Tab px={isMobile ? '.9rem' : undefined} value='guacamoleClients'>
{isMobile ? <FiMonitor /> : 'Guacamole Clients'}
</Tabs.Tab>
) : null}
{personal?.enableWol ? (
<Tabs.Tab px={isMobile ? '.9rem' : undefined} value='wolClients'>
{isMobile ? <FiMonitor /> : 'WoL Clients'}
</Tabs.Tab>
) : null}
{personal?.enableGuacamole ? (
<Tabs.Tab px={isMobile ? '.9rem' : undefined} value='guacamoleClients'>
{isMobile ? <FiMonitor /> : 'Guacamole Clients'}
</Tabs.Tab>
) : null}
</Tabs.List>
<Tabs.Panel value='personalization'>
<ScrollArea
@@ -231,22 +248,26 @@ export function Settings() {
<SearchHistory />
</ScrollArea>
</Tabs.Panel>
<Tabs.Panel value='wolClients'>
<ScrollArea
className={scrollAreaClasses.default}
classNames={scrollAreaClasses}
>
<WolClients />
</ScrollArea>
</Tabs.Panel>
<Tabs.Panel value='guacamoleClients'>
<ScrollArea
className={scrollAreaClasses.default}
classNames={scrollAreaClasses}
>
<GuacamoleClients />
</ScrollArea>
</Tabs.Panel>
{personal?.enableWol ? (
<Tabs.Panel value='wolClients'>
<ScrollArea
className={scrollAreaClasses.default}
classNames={scrollAreaClasses}
>
<WolClients />
</ScrollArea>
</Tabs.Panel>
) : null}
{personal?.enableGuacamole ? (
<Tabs.Panel value='guacamoleClients'>
<ScrollArea
className={scrollAreaClasses.default}
classNames={scrollAreaClasses}
>
<GuacamoleClients />
</ScrollArea>
</Tabs.Panel>
) : null}
</Tabs>
</Stack>
);

View File

@@ -1,9 +1,18 @@
import { Card, Grid, GridCol, LoadingOverlay, Stack, TextInput } from '@mantine/core';
import {
Card,
Grid,
GridCol,
LoadingOverlay,
Stack,
Switch,
Text,
TextInput,
} from '@mantine/core';
import { useDebouncedValue } from '@mantine/hooks';
import { SettingsHeader } from 'components';
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
import { useEffect, useState } from 'react';
import { cardClasses, textInputClasses } from 'styles';
import { cardClasses, switchClasses, textClasses, textInputClasses } from 'styles';
import type { PersonalData } from 'types';
const PersonalizationSettings = () => {
@@ -40,7 +49,6 @@ const PersonalizationSettings = () => {
setPersonal(update);
}
}, [update]);
return (
<Stack>
<SettingsHeader
@@ -175,6 +183,66 @@ const PersonalizationSettings = () => {
</Card>
</GridCol>
</Grid>
<Card
w={'75%'}
className={cardClasses.settingsItem}
classNames={cardClasses}
style={{ overflow: 'visible' }}
>
<Stack w={'100%'} px={16}>
<Text top={-12} className={textClasses.currentTheme} classNames={textClasses}>
Extras
</Text>
<Switch
label={'Enable Wake on LAN'}
className={switchClasses.default}
classNames={switchClasses}
checked={personal?.enableWol === 1}
onChange={(event) => {
const updatedPersonal = {
...personal,
enableWol: event.target.checked ? 1 : 0,
};
setUpdate(updatedPersonal);
}}
/>
<Switch
label={'Enable Guacamole Clients'}
className={switchClasses.default}
classNames={switchClasses}
checked={personal?.enableGuacamole === 1}
onChange={(event) => {
const updatedPersonal = {
...personal,
enableGuacamole: event.target.checked ? 1 : 0,
};
setUpdate(updatedPersonal);
}}
/>
{personal?.enableGuacamole === 1 && (
<TextInput
label={'Guacamole Host'}
className={textInputClasses.settingsItem}
classNames={textInputClasses}
defaultValue={personal?.guacamoleHost}
onChange={(event) => {
const updatedPersonal = {
...personal,
guacamoleHost: event.currentTarget.value,
};
setUpdate(updatedPersonal);
}}
styles={
theme.textShadowsEnabled
? {
label: { boxShadow: '2px 2px var(--mantine-color-border-0)' },
}
: undefined
}
/>
)}
</Stack>
</Card>
</Stack>
</Stack>
);