Slight refactor

This commit is contained in:
Sean Edmunds
2025-01-17 16:16:31 -06:00
parent eef30a84e3
commit 265981bee7
27 changed files with 398 additions and 352 deletions

View File

@@ -1,6 +1,6 @@
import { Stack } from '@mantine/core';
import { useDisclosure, useLocalStorage } from '@mantine/hooks';
import { date, greet, useQueryAPI, useWeatherAPI } from 'hooks';
import { useDisclosure } from '@mantine/hooks';
import { date, greet, useCommonHooks } from 'hooks';
import { useEffect, useState } from 'react';
import { stackClasses } from 'styles';
import type { CurrentWeather, OutlookWeather } from 'types';
@@ -10,21 +10,18 @@ import Header from './components/Header/Header';
import Search from './components/Search/Search';
import SettingsButton from './components/SettingsButton';
export function Homepage({ theme }: any) {
const [appFilter, setAppFilter] = useLocalStorage<[any]>({
key: 'appFilter',
defaultValue: ['All'],
});
const [bookmarkFilter, setBookmarkFilter] = useLocalStorage<[any]>({
key: 'bookmarkFilter',
defaultValue: ['All'],
});
const { data, isFetching } = useQueryAPI({ endpoint: 'api/messages' });
const { data: basicWeather } = useWeatherAPI({ endpoint: 'baseline' });
const { data: weather } = useWeatherAPI({ endpoint: 'current' });
const { data: forecast } = useWeatherAPI({ endpoint: 'forecast' });
const { data: hourly } = useWeatherAPI({ endpoint: 'hourly' });
export function Homepage() {
const [displayedGreeting, setDisplayedGreeting] = useState('');
const {
appFilter,
bookmarkFilter,
isMobile,
messages,
isMessagesFetching,
weather,
basicWeather,
forecast,
} = useCommonHooks();
const [current, setCurrent] = useState<CurrentWeather>({
icon: '',
temperature: 0,
@@ -47,17 +44,14 @@ export function Homepage({ theme }: any) {
windDirection: 'N',
},
]);
const isMobile = window.matchMedia('(max-width: 600px)').matches;
const [weatherModalOpened, { open: openWeatherModal, close: closeWeatherModal }] =
useDisclosure(false);
const [providerLabel, setProviderLabel] = useState('Google Search');
const [providerURL, setProviderURL] = useState('https://www.google.com/search?q=');
const [value, setValue] = useState('');
useEffect(() => {
if (data) {
setDisplayedGreeting(greet(data));
if (messages) {
setDisplayedGreeting(greet(messages));
}
}, [data, isFetching]);
}, [messages, isMessagesFetching]);
useEffect(() => {
if (weather && basicWeather) {
@@ -119,19 +113,7 @@ export function Homepage({ theme }: any) {
<Stack gap={0} className={stackClasses.containerStack} justify='center'>
<Search
current={current}
setCurrent={setCurrent}
outlook={outlook}
setOutlook={setOutlook}
weather={weather}
basicWeather={basicWeather}
forecast={forecast}
hourly={hourly}
providerLabel={providerLabel}
setProviderLabel={setProviderLabel}
providerURL={providerURL}
setProviderURL={setProviderURL}
value={value}
setValue={setValue}
weatherModalOpened={weatherModalOpened}
closeWeatherModal={closeWeatherModal}
openWeatherModal={openWeatherModal}
@@ -139,30 +121,16 @@ export function Homepage({ theme }: any) {
<Header
date={date(isMobile)}
greet={displayedGreeting}
isMobile={isMobile}
current={current}
setCurrent={setCurrent}
outlook={outlook}
weather={weather}
basicWeather={basicWeather}
forecast={forecast}
hourly={hourly}
setProviderLabel={setProviderLabel}
setProviderURL={setProviderURL}
setValue={setValue}
weatherModalOpened={weatherModalOpened}
closeWeatherModal={closeWeatherModal}
openWeatherModal={openWeatherModal}
/>
<Applications contentType={appFilter} isMobile={isMobile} />
<Bookmarks contentType={bookmarkFilter} isMobile={isMobile} />
<SettingsButton
theme={theme}
setAppFilter={setAppFilter}
appFilter={appFilter}
setBookmarkFilter={setBookmarkFilter}
bookmarkFilter={bookmarkFilter}
/>
<Applications contentType={appFilter} />
<Bookmarks contentType={bookmarkFilter} />
<SettingsButton />
</Stack>
);
}

View File

@@ -1,10 +1,12 @@
import { Icon } from '@iconify/react';
import { Box, Stack, Text } from '@mantine/core';
import { useCommonHooks } from 'hooks';
import { useState } from 'react';
import { stackClasses, textClasses } from 'styles';
function AppItem({ url, icon, name, isMobile }: any) {
function AppItem({ url, icon, name }: any) {
const [textDecoration, setTextDecoration] = useState<string>('none');
const { isMobile } = useCommonHooks();
return (
<Box
@@ -15,11 +17,11 @@ function AppItem({ url, icon, name, isMobile }: any) {
className={stackClasses.appItemBox}
>
<Stack
align={isMobile && 'center'}
justify={isMobile && 'center'}
align={isMobile ? 'center' : undefined}
justify={isMobile ? 'center' : undefined}
style={{
height: '64px',
width: isMobile && '100%',
width: isMobile ? '100%' : undefined,
marginRight: isMobile ? '0' : '1em',
marginLeft: isMobile ? '0' : '1em',
paddingTop: isMobile ? '0' : '15px',

View File

@@ -1,20 +1,13 @@
import { Stack, Text } from '@mantine/core';
import { useQueryAPI } from 'hooks';
import { useEffect, useState } from 'react';
import { useCommonHooks } from 'hooks';
import { textClasses } from 'styles';
import AppItem from './AppItem';
function Applications({ contentType, isMobile }: any) {
const { data, isFetching } = useQueryAPI({ endpoint: 'api/apps' });
const [applications, setApplications] = useState([]);
useEffect(() => {
if (data && !isFetching) {
setApplications(data);
}
}, [data, isFetching]);
function Applications({ contentType }: any) {
const { isMobile, applicationData } = useCommonHooks();
return (
<>
{applications.length > 0 && contentType.length > 0 && (
{applicationData.length > 0 && contentType.length > 0 && (
<Stack id='apps' style={{ gap: 0 }}>
<Text className={textClasses.sectionTitle} classNames={textClasses}>
Applications
@@ -32,7 +25,7 @@ function Applications({ contentType, isMobile }: any) {
paddingBottom: 'var(--module-spacing)',
}}
>
{applications?.map((application: any) => {
{applicationData?.map((application: any) => {
if (
contentType.includes(application.filterName) ||
contentType.includes('All')
@@ -44,7 +37,6 @@ function Applications({ contentType, isMobile }: any) {
url={application.url}
icon={application.icon}
category={application.category}
isMobile={isMobile}
/>
);
})}

View File

@@ -1,30 +1,16 @@
import { Stack, Text } from '@mantine/core';
import { useQueryAPI } from 'hooks';
import { useEffect, useState } from 'react';
import { useCommonHooks } from 'hooks';
import { textClasses } from 'styles';
import LinkGroups from './LinkGroups';
function Links({ contentType, isMobile }: any) {
const { data: linkData, isFetched: linksIsFetched } = useQueryAPI({
endpoint: 'api/links',
});
const { data: groupData, isFetched: groupsIsFetched } = useQueryAPI({
endpoint: 'api/categories',
});
const [bookmarks, setBookmarks] = useState([]);
const [categories, setCategories] = useState([]);
useEffect(() => {
if (linksIsFetched && groupsIsFetched) {
setBookmarks(linkData);
setCategories(groupData);
}
}, [linksIsFetched, groupsIsFetched]);
function Links({ contentType }: any) {
const { isMobile, linksIsFetched, groupsIsFetched, groups, bookmarkData } =
useCommonHooks();
return (
<>
{groupsIsFetched &&
linksIsFetched &&
categories?.length > 0 &&
groups?.length > 0 &&
contentType.length > 0 && (
<Stack id='links' style={{ gap: 0 }}>
<Text className={textClasses.sectionTitle} classNames={textClasses}>
@@ -40,19 +26,18 @@ function Links({ contentType, isMobile }: any) {
gridTemplateRows: 'auto',
}}
>
{categories.map((category: any) => {
{groups.map((category: any) => {
if (
contentType.includes(category.filterName) ||
contentType.includes('All')
) {
return (
<LinkGroups
key={category.id}
key={category}
category={category.categoryName}
links={bookmarks.filter(
(bookmark: any) => bookmark.category === category.categoryName,
links={bookmarkData.filter(
(bookmark: any) => bookmark.category === category,
)}
isMobile={isMobile}
/>
);
}

View File

@@ -2,7 +2,7 @@ import { Stack, Text } from '@mantine/core';
import { textClasses } from 'styles';
import LinkItem from './LinkItem';
function LinkGroups({ links, category, isMobile }: any) {
function LinkGroups({ links, category }: any) {
return (
<Stack
style={{
@@ -16,7 +16,7 @@ function LinkGroups({ links, category, isMobile }: any) {
{category}
</Text>
{links?.map((link: any) => (
<LinkItem key={link.name} link={link} isMobile={isMobile} />
<LinkItem key={link.name} link={link} />
))}
</Stack>
);

View File

@@ -1,25 +1,20 @@
import { Group, Stack, Text } from '@mantine/core';
import { WeatherModal } from 'components';
import { useCommonHooks } from 'hooks';
import { useEffect, useState } from 'react';
import { textClasses } from 'styles';
function Header({
greet,
date,
isMobile,
current,
setCurrent,
weather,
basicWeather,
outlook,
hourly,
weatherModalOpened,
closeWeatherModal,
openWeatherModal,
setProviderLabel,
setProviderURL,
setValue,
}: any) {
const { isMobile, weather, basicWeather } = useCommonHooks();
const [time, setTime] = useState(new Date());
function fixDigits(k: any) {
if (k < 10) {
@@ -80,7 +75,7 @@ function Header({
<Text
className={textClasses.greeting}
classNames={textClasses}
fz={isMobile && 24}
fz={isMobile ? 24 : undefined}
>
{greet}
</Text>
@@ -152,13 +147,8 @@ function Header({
<WeatherModal
current={current}
outlook={outlook}
hourly={hourly}
closeWeatherModal={closeWeatherModal}
weatherModalOpened={weatherModalOpened}
setProviderLabel={setProviderLabel}
setProviderURL={setProviderURL}
setValue={setValue}
isMobile={isMobile}
/>
</Stack>
);

View File

@@ -1,25 +1,26 @@
import { Stack, TextInput } from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import { HelpModal } from '../../../../components/HelpModal/HelpModal';
import { WeatherModal } from '../../../../components/WeatherModal/WeatherModal';
import { containsProtocol, useQueryAPI, validURL } from '../../../../hooks';
import { textInputClasses } from '../../../../styles';
import { HelpModal, WeatherModal } from 'components';
import { containsProtocol, useCommonHooks, validURL } from 'hooks';
import { textInputClasses } from 'styles';
export default function Search({
current,
outlook,
hourly,
weatherModalOpened,
closeWeatherModal,
openWeatherModal,
providerLabel,
setProviderLabel,
providerURL,
setProviderURL,
value,
setValue,
}: any) {
const { data: providers } = useQueryAPI({ endpoint: 'api/providers' });
const {
providerLabel,
setProviderLabel,
providerURL,
setProviderURL,
searchValue,
setSearchValue,
providers,
} = useCommonHooks();
const [providerModalOpened, { open: openProviderModal, close: closeProviderModal }] =
useDisclosure(false);
@@ -72,10 +73,10 @@ export default function Search({
classNames={textInputClasses}
spellCheck='true'
leftSection={providerLabel}
value={value}
data-active={value !== ''}
value={searchValue}
data-active={searchValue !== ''}
onChange={(item: any) => {
setValue(item.currentTarget.value);
setSearchValue(item.currentTarget.value);
if (
item.target.value === '/?' ||
item.target.value === '!help' ||
@@ -104,22 +105,14 @@ export default function Search({
}}
/>
<HelpModal
providers={providers}
providerModalOpened={providerModalOpened}
closeProviderModal={closeProviderModal}
setValue={setValue}
setProviderLabel={setProviderLabel}
setProviderURL={setProviderURL}
/>
<WeatherModal
current={current}
outlook={outlook}
hourly={hourly}
closeWeatherModal={closeWeatherModal}
weatherModalOpened={weatherModalOpened}
setValue={setValue}
setProviderLabel={setProviderLabel}
setProviderURL={setProviderURL}
/>
</Stack>
);

View File

@@ -1,19 +1,26 @@
import { Button, Menu, MultiSelect, NavLink } from '@mantine/core';
import { useQueryAPI } from 'hooks';
import { Button, Menu, MultiSelect, NavLink, Switch } from '@mantine/core';
import { runWakeCommand, useCommonHooks, useQueryAPI } from 'hooks';
import { useEffect, useState } from 'react';
import { FiMenu, FiMonitor } from 'react-icons/fi';
import { FiMenu, FiMonitor, FiShuffle } from 'react-icons/fi';
import { useNavigate } from 'react-router-dom';
import { buttonClasses, menuClasses, navLinkClasses, selectClasses } from 'styles';
function SettingsButton({
appFilter,
setAppFilter,
bookmarkFilter,
setBookmarkFilter,
}: any) {
function SettingsButton() {
const { data, isFetched } = useQueryAPI({ endpoint: 'api/appCategories' });
const [categories, setCategories] = useState([{ value: 'All', label: 'All' }]);
const navigate = useNavigate();
const {
currentTheme,
setCurrentTheme,
handleThemeChange,
theme,
allThemes,
appFilter,
setAppFilter,
bookmarkFilter,
setBookmarkFilter,
} = useCommonHooks();
useEffect(() => {
if (data) {
const list: [any] =
@@ -25,13 +32,6 @@ function SettingsButton({
}
}, [data, isFetched]);
function runWakeCommand() {
const requestOptions = {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
};
fetch(`/${import.meta.env.VITE_BASE_URL}/api/wakeDakota`, requestOptions);
}
return (
<Menu withinPortal={false} withArrow shadow='md' position='top'>
<Menu.Target>
@@ -59,6 +59,31 @@ function SettingsButton({
className={navLinkClasses.defaultNavLink}
classNames={navLinkClasses}
/>
<NavLink
label='Shuffle Themes'
leftSection={
<Switch
labelPosition='left'
checked={currentTheme === 'random'}
onChange={(e) => {
setCurrentTheme(e.target.checked ? 'random' : theme.name);
}}
color={theme.primaryColor}
/>
}
onClick={() => {}}
className={navLinkClasses.defaultNavLink}
classNames={navLinkClasses}
/>
<NavLink
label='Random Theme'
leftSection={<FiShuffle />}
onClick={() => {
handleThemeChange(allThemes, true);
}}
className={navLinkClasses.defaultNavLink}
classNames={navLinkClasses}
/>
</NavLink>
<MultiSelect
label='App Filter'