Updates to help modal
All checks were successful
Deploy to production / build (push) Successful in 1m7s
All checks were successful
Deploy to production / build (push) Successful in 1m7s
This commit is contained in:
@@ -43,9 +43,24 @@ export function HelpModal({
|
||||
<Modal.CloseButton />
|
||||
</Modal.Header>
|
||||
<Modal.Body pb={'2rem'}>
|
||||
<Stack
|
||||
gap={0}
|
||||
w={'100%'}
|
||||
align='center'
|
||||
style={{
|
||||
width: '100%',
|
||||
backgroundColor: 'var(--mantine-color-search-0)',
|
||||
borderRadius: '8px',
|
||||
padding: '1rem',
|
||||
marginBottom: '1rem',
|
||||
}}
|
||||
>
|
||||
Expand each of the sections below to find available Search Bar commands.
|
||||
</Stack>
|
||||
<Stack gap={0} w={'100%'} align='center'>
|
||||
<HelpSection
|
||||
name={'Search Providers'}
|
||||
prefix={'/'}
|
||||
items={providerData.map((provider: Provider) => {
|
||||
return {
|
||||
name: provider.name,
|
||||
@@ -56,6 +71,7 @@ export function HelpModal({
|
||||
<Stack my={'.5rem'} />
|
||||
<HelpSection
|
||||
name={'Available Applications'}
|
||||
prefix={'!'}
|
||||
items={applicationData.map((application: Application) => {
|
||||
return {
|
||||
name: application.url,
|
||||
@@ -66,6 +82,7 @@ export function HelpModal({
|
||||
<Stack my={'.5rem'} />
|
||||
<HelpSection
|
||||
name={'Available Clients'}
|
||||
prefix={'>'}
|
||||
items={clientData.map((client: GuacamoleClient) => {
|
||||
return {
|
||||
name: `${client.clientName} (${client.clientIdentifier})`,
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
import { Group, Text } from '@mantine/core';
|
||||
import { ActionIcon, Group, Text } from '@mantine/core';
|
||||
import { useCommonHooks } from 'hooks';
|
||||
import { useState } from 'react';
|
||||
import { FiChevronDown, FiChevronUp } from 'react-icons/fi';
|
||||
import { textClasses } from 'styles';
|
||||
import type { SearchShortcut } from 'types';
|
||||
import HintItem from './HintItem';
|
||||
|
||||
function HelpSection({ name, items }: { name: string; items: SearchShortcut[] }) {
|
||||
function HelpSection({
|
||||
name,
|
||||
prefix,
|
||||
items,
|
||||
}: {
|
||||
name: string;
|
||||
prefix: string;
|
||||
items: SearchShortcut[];
|
||||
}) {
|
||||
const { theme } = useCommonHooks();
|
||||
const [expand, setExpand] = useState(false);
|
||||
return (
|
||||
<Group gap={4}>
|
||||
<Group gap={4} style={{ width: '100%' }}>
|
||||
<Text
|
||||
className={textClasses.helpTitle}
|
||||
classNames={textClasses}
|
||||
@@ -17,23 +28,50 @@ function HelpSection({ name, items }: { name: string; items: SearchShortcut[] })
|
||||
: undefined,
|
||||
}}
|
||||
>
|
||||
{name}
|
||||
{name}{' '}
|
||||
<ActionIcon onClick={() => setExpand(!expand)}>
|
||||
{expand ? <FiChevronUp /> : <FiChevronDown />}
|
||||
</ActionIcon>
|
||||
</Text>
|
||||
<Group
|
||||
style={{
|
||||
height: expand ? '100%' : '0px',
|
||||
overflow: expand ? 'visible' : 'hidden',
|
||||
width: '100%',
|
||||
backgroundColor: 'var(--mantine-color-search-0)',
|
||||
borderRadius: '8px',
|
||||
padding: '1.5rem',
|
||||
marginLeft: '1rem',
|
||||
marginRight: '1rem',
|
||||
}}
|
||||
>
|
||||
{items
|
||||
?.toSorted((a: SearchShortcut, b: SearchShortcut) =>
|
||||
a.command > b.command ? 1 : -1,
|
||||
)
|
||||
.map((item: SearchShortcut) => (
|
||||
<HintItem key={item.command} command={item.command} name={item.name} />
|
||||
))}
|
||||
{expand ? (
|
||||
items
|
||||
?.toSorted((a: SearchShortcut, b: SearchShortcut) =>
|
||||
a.command > b.command ? 1 : -1,
|
||||
)
|
||||
.map((item: SearchShortcut) => (
|
||||
<HintItem key={item.command} command={item.command} name={item.name} />
|
||||
))
|
||||
) : (
|
||||
<Group
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
justifyContent: 'center',
|
||||
marginTop: '-1.5rem',
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color:
|
||||
'color-mix(in srgb, var(--mantine-color-primary-0), transparent 75%)',
|
||||
}}
|
||||
>
|
||||
Command prefix: {prefix}
|
||||
</Text>
|
||||
</Group>
|
||||
)}
|
||||
</Group>
|
||||
</Group>
|
||||
);
|
||||
|
||||
@@ -69,6 +69,10 @@ export function useCommonHooks() {
|
||||
key: 'providerIcon',
|
||||
defaultValue: 'FaGoogle',
|
||||
});
|
||||
const [timeFormat, setTimeFormat] = useLocalStorage<string>({
|
||||
key: 'timeFormat',
|
||||
defaultValue: '12h',
|
||||
});
|
||||
const [searchValue, setSearchValue] = useState<string | number>('');
|
||||
const [providerLabel, setProviderLabel] = useState(defaultProviderLabel);
|
||||
const [providerURL, setProviderURL] = useState(defaultProviderURL);
|
||||
@@ -268,6 +272,8 @@ export function useCommonHooks() {
|
||||
setDefaultProviderPrefix,
|
||||
defaultProviderIcon,
|
||||
setDefaultProviderIcon,
|
||||
timeFormat,
|
||||
setTimeFormat,
|
||||
currentUser,
|
||||
setCurrentUser,
|
||||
currentLocation,
|
||||
|
||||
@@ -92,6 +92,8 @@ export function Homepage() {
|
||||
windDirection: 0,
|
||||
pressure: 0,
|
||||
});
|
||||
const [providerModalOpened, { open: openProviderModal, close: closeProviderModal }] =
|
||||
useDisclosure(false);
|
||||
const extendedForecast = forecast?.properties?.periods.map(
|
||||
(item: ExtendedForecast) => ({
|
||||
detailedForecast: item.detailedForecast,
|
||||
@@ -209,6 +211,9 @@ export function Homepage() {
|
||||
openWeatherModal={openWeatherModal}
|
||||
position='top'
|
||||
personal={personal}
|
||||
providerModalOpened={providerModalOpened}
|
||||
openProviderModal={openProviderModal}
|
||||
closeProviderModal={closeProviderModal}
|
||||
/>
|
||||
<Header
|
||||
greet={displayedGreeting}
|
||||
@@ -235,10 +240,13 @@ export function Homepage() {
|
||||
openWeatherModal={openWeatherModal}
|
||||
position='center'
|
||||
personal={personal}
|
||||
providerModalOpened={providerModalOpened}
|
||||
openProviderModal={openProviderModal}
|
||||
closeProviderModal={closeProviderModal}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
<SettingsButton />
|
||||
<SettingsButton openProviderModal={openProviderModal} />
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ function Header({
|
||||
theme,
|
||||
textShadowStyle,
|
||||
largeTextShadowStyle,
|
||||
timeFormat,
|
||||
setTimeFormat,
|
||||
} = useCommonHooks();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -119,14 +121,19 @@ function Header({
|
||||
style={{
|
||||
textShadow: theme.textShadowsEnabled ? textShadowStyle : undefined,
|
||||
}}
|
||||
onClick={() =>
|
||||
timeFormat === '12h' ? setTimeFormat('24h') : setTimeFormat('12h')
|
||||
}
|
||||
>
|
||||
{`${
|
||||
time.getHours() === 0
|
||||
? 12
|
||||
: time.getHours() > 12
|
||||
? time.getHours() - 12
|
||||
: time.getHours()
|
||||
}:${fixDigits(time.getMinutes())} ${time.getHours() >= 12 ? 'PM' : 'AM'}`}
|
||||
{timeFormat === '12h'
|
||||
? `${
|
||||
time.getHours() === 0
|
||||
? 12
|
||||
: time.getHours() > 12
|
||||
? time.getHours() - 12
|
||||
: time.getHours()
|
||||
}:${fixDigits(time.getMinutes())} ${time.getHours() >= 12 ? 'PM' : 'AM'}`
|
||||
: `${fixDigits(time.getHours())}:${fixDigits(time.getMinutes())}`}
|
||||
</Text>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -12,6 +12,8 @@ function LargeHeader({ greet, date }: { greet: string | undefined; date: string
|
||||
theme,
|
||||
textShadowStyle,
|
||||
largeTextShadowStyle,
|
||||
timeFormat,
|
||||
setTimeFormat,
|
||||
} = useCommonHooks();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -58,15 +60,21 @@ function LargeHeader({ greet, date }: { greet: string | undefined; date: string
|
||||
classNames={textClasses}
|
||||
style={{
|
||||
textShadow: theme.textShadowsEnabled ? textShadowStyle : undefined,
|
||||
zIndex: 1,
|
||||
}}
|
||||
onClick={() =>
|
||||
timeFormat === '12h' ? setTimeFormat('24h') : setTimeFormat('12h')
|
||||
}
|
||||
>
|
||||
{`${
|
||||
time.getHours() === 0
|
||||
? 12
|
||||
: time.getHours() > 12
|
||||
? time.getHours() - 12
|
||||
: time.getHours()
|
||||
}:${fixDigits(time.getMinutes())} ${time.getHours() >= 12 ? 'PM' : 'AM'}`}
|
||||
{timeFormat === '12h'
|
||||
? `${
|
||||
time.getHours() === 0
|
||||
? 12
|
||||
: time.getHours() > 12
|
||||
? time.getHours() - 12
|
||||
: time.getHours()
|
||||
}:${fixDigits(time.getMinutes())} ${time.getHours() >= 12 ? 'PM' : 'AM'}`
|
||||
: `${fixDigits(time.getHours())}:${fixDigits(time.getMinutes())}`}
|
||||
</Text>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -38,6 +38,9 @@ export default function Search({
|
||||
openWeatherModal,
|
||||
position,
|
||||
personal,
|
||||
providerModalOpened,
|
||||
openProviderModal,
|
||||
closeProviderModal,
|
||||
}: {
|
||||
current: CurrentWeather;
|
||||
extendedForecast: ExtendedForecast[];
|
||||
@@ -46,6 +49,9 @@ export default function Search({
|
||||
openWeatherModal: () => void;
|
||||
position: string;
|
||||
personal: PersonalData;
|
||||
providerModalOpened: boolean;
|
||||
openProviderModal: () => void;
|
||||
closeProviderModal: () => void;
|
||||
}) {
|
||||
const {
|
||||
isMobile,
|
||||
@@ -138,8 +144,6 @@ export default function Search({
|
||||
const [historyMultiplier, setHistoryMultiplier] = useState(1);
|
||||
|
||||
const [dropdownOpened, { open: openDropdown, close: closeDropdown }] = useDisclosure();
|
||||
const [providerModalOpened, { open: openProviderModal, close: closeProviderModal }] =
|
||||
useDisclosure(false);
|
||||
|
||||
const handleResetSearch = () => {
|
||||
setSearchValue('');
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Box, Button, Group, Menu, Overlay, Stack } from '@mantine/core';
|
||||
import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks';
|
||||
import { useState } from 'react';
|
||||
import { FiMenu, FiSettings } from 'react-icons/fi';
|
||||
import { FiHelpCircle, FiMenu, FiSettings } from 'react-icons/fi';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { buttonClasses, menuClasses } from 'styles';
|
||||
import type { AppCategory, WolClient } from 'types';
|
||||
@@ -9,7 +9,7 @@ import SettingsCard from './SettingsCard';
|
||||
import ThemingCard from './ThemingCard';
|
||||
import WakeOnLan from './WakeOnLanCard';
|
||||
|
||||
function SettingsButton() {
|
||||
function SettingsButton({ openProviderModal }: { openProviderModal: () => void }) {
|
||||
const { data: appCategoryData } = useQueryAPI({
|
||||
endpoint: 'api/appCategories',
|
||||
});
|
||||
@@ -32,7 +32,7 @@ function SettingsButton() {
|
||||
: [{ value: 'All', label: 'All' }];
|
||||
const [selectedClient, setSelectedClient] = useState<WolClient>(wolClientData?.[0]);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const {
|
||||
theme,
|
||||
isMobile,
|
||||
@@ -72,10 +72,16 @@ function SettingsButton() {
|
||||
withOverlay
|
||||
overlayProps={{
|
||||
blur: 5,
|
||||
onClick: () => setIsOpen(false),
|
||||
}}
|
||||
opened={isOpen}
|
||||
>
|
||||
<Menu.Target>
|
||||
<Button className={buttonClasses.settingsButton} classNames={buttonClasses}>
|
||||
<Button
|
||||
className={buttonClasses.settingsButton}
|
||||
classNames={buttonClasses}
|
||||
onClick={() => setIsOpen(true)}
|
||||
>
|
||||
<FiMenu />
|
||||
</Button>
|
||||
</Menu.Target>
|
||||
@@ -149,6 +155,17 @@ function SettingsButton() {
|
||||
>
|
||||
Settings
|
||||
</Button>
|
||||
<Button
|
||||
leftSection={<FiHelpCircle />}
|
||||
className={buttonClasses.settingsMenuButton}
|
||||
classNames={buttonClasses}
|
||||
onClick={() => {
|
||||
setIsOpen(false);
|
||||
openProviderModal();
|
||||
}}
|
||||
>
|
||||
Help
|
||||
</Button>
|
||||
</Group>
|
||||
</Menu.Dropdown>
|
||||
</Menu>
|
||||
|
||||
Reference in New Issue
Block a user