diff --git a/.gitignore b/.gitignore
index 3892bed..c9a9d6e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,4 @@ dist-ssr
*.sw?
.env
+package-lock.json
\ No newline at end of file
diff --git a/src/components/HelpModal/HelpSection.tsx b/src/components/HelpModal/HelpSection.tsx
index 9db17d2..b886287 100644
--- a/src/components/HelpModal/HelpSection.tsx
+++ b/src/components/HelpModal/HelpSection.tsx
@@ -1,8 +1,9 @@
import { Divider, Group } from '@mantine/core';
import { useCommonHooks } from 'hooks';
+import type { SearchShortcut } from 'types';
import HintItem from './HintItem';
-function HelpSection({ name, items }: { name: string; items: object[] }) {
+function HelpSection({ name, items }: { name: string; items: SearchShortcut[] }) {
const { theme } = useCommonHooks();
return (
<>
@@ -30,8 +31,10 @@ function HelpSection({ name, items }: { name: string; items: object[] }) {
}}
>
{items
- ?.toSorted((a: any, b: any) => (a.command > b.command ? 1 : -1))
- .map((item: any) => (
+ ?.toSorted((a: SearchShortcut, b: SearchShortcut) =>
+ a.command > b.command ? 1 : -1,
+ )
+ .map((item: SearchShortcut) => (
))}
diff --git a/src/components/WeatherModal/CurrentWeather.tsx b/src/components/WeatherModal/CurrentWeather.tsx
index 897a4a1..5b40579 100644
--- a/src/components/WeatherModal/CurrentWeather.tsx
+++ b/src/components/WeatherModal/CurrentWeather.tsx
@@ -5,7 +5,7 @@ import { useEffect, useState } from 'react';
import { FaLongArrowAltDown, FaLongArrowAltUp, FaWind } from 'react-icons/fa';
import { WiBarometer, WiHumidity, WiSunrise, WiSunset } from 'react-icons/wi';
import { themeIconClasses } from 'styles';
-import type { CurrentWeather as CW } from 'types';
+import type { CurrentWeather as CW, SunState } from 'types';
import WeatherIcon from './WeatherIcon';
export default function CurrentWeather({ current }: { current: CW }) {
@@ -15,12 +15,12 @@ export default function CurrentWeather({ current }: { current: CW }) {
lon: currentLocation.lon,
});
- const [sunStates, setSunStates] = useState([]);
+ const [sunStates, setSunStates] = useState([]);
useEffect(() => {
if (sunStateData) {
setSunStates(
- sunStateData.results.map((item: any) => {
+ sunStateData.results.map((item: SunState) => {
return {
date: item.date,
sunrise: item.sunrise,
diff --git a/src/components/WeatherModal/ExtendedForecast.tsx b/src/components/WeatherModal/ExtendedForecastCard.tsx
similarity index 83%
rename from src/components/WeatherModal/ExtendedForecast.tsx
rename to src/components/WeatherModal/ExtendedForecastCard.tsx
index c23c1de..db4c5a9 100644
--- a/src/components/WeatherModal/ExtendedForecast.tsx
+++ b/src/components/WeatherModal/ExtendedForecastCard.tsx
@@ -1,11 +1,15 @@
import { Group, Stack, Text } from '@mantine/core';
import { useCommonHooks } from 'hooks';
import { textClasses } from 'styles';
+import type { ExtendedForecast } from 'types';
import WeatherIcon from './WeatherIcon';
-export default function ExtendedForecast({ forecast }: any) {
- const day = forecast.slice(2, 14).filter((item: any) => item.isDaytime);
- const night = forecast.slice(2, 14).filter((item: any) => !item.isDaytime);
+export default function ExtendedForecastCard({
+ forecast,
+}: { forecast: ExtendedForecast[] }) {
+ const day = forecast.slice(2, 14).filter((item: ExtendedForecast) => item.isDaytime);
+ const night = forecast.slice(2, 14).filter((item: ExtendedForecast) => !item.isDaytime);
+
const { isMobile } = useCommonHooks();
return (
- {day.map((item: any, index: number) => {
+ {day.map((item: ExtendedForecast, index: number) => {
const short = item.shortForecast.includes('And')
? item.shortForecast.substring(0, item.shortForecast.indexOf('And'))
: item.shortForecast.includes('then')
diff --git a/src/components/WeatherModal/WeatherGraphs.tsx b/src/components/WeatherModal/WeatherGraphs.tsx
index 85a2586..b61e9a7 100644
--- a/src/components/WeatherModal/WeatherGraphs.tsx
+++ b/src/components/WeatherModal/WeatherGraphs.tsx
@@ -10,8 +10,11 @@ import {
XAxis,
YAxis,
} from 'recharts';
+import type { HourlyForecast } from 'types';
-export default function WeatherGraphs({ hourlyForecast }: any) {
+export default function WeatherGraphs({
+ hourlyForecast,
+}: { hourlyForecast: HourlyForecast[] }) {
function CustomTooltip({ payload, active }: any) {
if (active) {
return (
@@ -48,7 +51,7 @@ export default function WeatherGraphs({ hourlyForecast }: any) {
{
+ dataKey={(data: HourlyForecast) => {
return new Date(data.startTime).toLocaleTimeString('en-US', {
hour: 'numeric',
minute: 'numeric',
@@ -74,7 +77,7 @@ export default function WeatherGraphs({ hourlyForecast }: any) {
unit={'°F'}
type='monotone'
name='Dew Point'
- dataKey={(data: any) => {
+ dataKey={(data: HourlyForecast) => {
return (data.dewpoint.value * 9) / 5 + 32;
}}
stroke={'var(--color-text-acc)'}
@@ -88,7 +91,7 @@ export default function WeatherGraphs({ hourlyForecast }: any) {
{
+ dataKey={(data: HourlyForecast) => {
return new Date(data.startTime).toLocaleTimeString('en-US', {
hour: 'numeric',
minute: 'numeric',
@@ -102,7 +105,7 @@ export default function WeatherGraphs({ hourlyForecast }: any) {
unit={'%'}
type='monotone'
name='Precipitation'
- dataKey={(data: any) => {
+ dataKey={(data: HourlyForecast) => {
return data.probabilityOfPrecipitation.value;
}}
stroke={'var(--color-text-pri)'}
@@ -113,7 +116,7 @@ export default function WeatherGraphs({ hourlyForecast }: any) {
unit={'%'}
type='monotone'
name='Humidity'
- dataKey={(data: any) => {
+ dataKey={(data: HourlyForecast) => {
return data.relativeHumidity.value;
}}
stroke={'var(--color-text-acc)'}
diff --git a/src/components/WeatherModal/WeatherModal.tsx b/src/components/WeatherModal/WeatherModal.tsx
index 67f516b..c28f328 100644
--- a/src/components/WeatherModal/WeatherModal.tsx
+++ b/src/components/WeatherModal/WeatherModal.tsx
@@ -4,9 +4,9 @@ import { modalClasses } from 'styles';
import { useCommonHooks, useWeatherAPI } from 'hooks';
import { useEffect, useState } from 'react';
-import type { CurrentWeather as CW, ExtendedForecast as EF } from 'types';
+import type { CurrentWeather as CW, ExtendedForecast, HourlyForecast } from 'types';
import CurrentWeather from './CurrentWeather';
-import ExtendedForecast from './ExtendedForecast';
+import ExtendedForecastCard from './ExtendedForecastCard';
import WeatherGraphs from './WeatherGraphs';
export function WeatherModal({
@@ -19,7 +19,7 @@ export function WeatherModal({
closeWeatherModal,
}: {
current: CW;
- extendedForecast: EF[];
+ extendedForecast: ExtendedForecast[];
weatherModalOpened: boolean;
setSearchValue: (value: string) => void;
setProviderLabel: (label: string) => void;
@@ -33,14 +33,13 @@ export function WeatherModal({
x: currentLocation.x,
y: currentLocation.y,
});
- const [hourlyForecast, setHourlyForecast] = useState([]);
+ const [hourlyForecast, setHourlyForecast] = useState([]);
useEffect(() => {
if (hourly) {
setHourlyForecast(hourly.properties.periods.slice(1, 25));
}
}, [hourly]);
-
return (
-
+
diff --git a/src/hooks/useAPI.ts b/src/hooks/useAPI.ts
index 45bf56b..44f2bc9 100644
--- a/src/hooks/useAPI.ts
+++ b/src/hooks/useAPI.ts
@@ -3,12 +3,12 @@ import { useRef } from 'react';
import { Flip, toast } from 'react-toastify';
const url = `${import.meta.env.PROD ? import.meta.env.VITE_DOMAIN_PROD : import.meta.env.VITE_DOMAIN_DEV}/${import.meta.env.VITE_BASE_URL}`;
-const headers = {
+const headers: HeadersInit = {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
- 'Access-Control-Allow-Credentials': true,
+ 'Access-Control-Allow-Credentials': 'true',
'Sec-Fetch-Mode': 'no-cors',
'Sec-Fetch-Site': 'same-site',
};
@@ -49,7 +49,7 @@ export function useMutationAPI() {
endpoint: string,
body: object | undefined | null,
) => {
- const options: any = {
+ const options: { method: string; headers: HeadersInit | undefined; body: string } = {
method: method,
headers: headers,
body: JSON.stringify(body),
diff --git a/src/hooks/useCommonHooks.ts b/src/hooks/useCommonHooks.ts
index 8b1996f..1054826 100644
--- a/src/hooks/useCommonHooks.ts
+++ b/src/hooks/useCommonHooks.ts
@@ -13,7 +13,7 @@ export function useCommonHooks() {
key: 'theme',
defaultValue: 'blackboard',
});
- const [appFilter, setAppFilter] = useLocalStorage<[string]>({
+ const [appFilter, setAppFilter] = useLocalStorage({
key: 'appFilter',
defaultValue: ['All'],
});
@@ -29,7 +29,7 @@ export function useCommonHooks() {
key: 'bookmarkSort',
defaultValue: 'A>Z',
});
- const [bookmarkFilter, setBookmarkFilter] = useLocalStorage<[string]>({
+ const [bookmarkFilter, setBookmarkFilter] = useLocalStorage({
key: 'bookmarkFilter',
defaultValue: ['All'],
});
diff --git a/src/pages/homepage/Homepage.tsx b/src/pages/homepage/Homepage.tsx
index b8829f2..62f9c7d 100644
--- a/src/pages/homepage/Homepage.tsx
+++ b/src/pages/homepage/Homepage.tsx
@@ -7,6 +7,7 @@ import { stackClasses } from 'styles';
import type {
CurrentWeather as CW,
ExtendedForecast as EF,
+ ExtendedForecast,
Message,
PersonalData,
} from 'types';
@@ -177,7 +178,7 @@ export function Homepage() {
useEffect(() => {
if (forecast) {
setExtendedForecast(
- forecast.properties.periods.map((item: any) => ({
+ forecast.properties.periods.map((item: ExtendedForecast) => ({
detailedForecast: item.detailedForecast,
isDaytime: item.isDaytime,
name: item.name,
@@ -196,6 +197,7 @@ export function Homepage() {
});
}
}, [forecast]);
+
return (
a.enabled === 1)
- .sort((a: any, b: any) => {
+ .sort((a: Application, b: Application) => {
switch (appSort) {
case 'A>Z':
return a.name > b.name ? 1 : -1;
case 'Z>A':
return a.name < b.name ? 1 : -1;
case 'Newest':
- return a.id < b.id ? 1 : -1;
+ if (a.id && b.id) {
+ return a.id < b.id ? 1 : -1;
+ }
+
+ return -1;
case 'Oldest':
- return a.id > b.id ? 1 : -1;
+ if (a.id && b.id) {
+ return a.id > b.id ? 1 : -1;
+ }
+
+ return -1;
case 'Custom':
return a.index > b.index ? 1 : -1;
}
diff --git a/src/pages/homepage/components/Bookmarks/Bookmarks.tsx b/src/pages/homepage/components/Bookmarks/Bookmarks.tsx
index 93eb53e..6a80c5b 100644
--- a/src/pages/homepage/components/Bookmarks/Bookmarks.tsx
+++ b/src/pages/homepage/components/Bookmarks/Bookmarks.tsx
@@ -5,7 +5,7 @@ import { textClasses } from 'styles';
import type { Bookmark, BookmarkGroup } from 'types';
import LinkGroups from './LinkGroups';
-function Links({ contentType }: { contentType: [string] }) {
+function Links({ contentType }: { contentType: string[] }) {
const { data: linkData, isFetched: linksIsFetched } = useQueryAPI({
endpoint: 'api/links',
});
@@ -28,18 +28,26 @@ function Links({ contentType }: { contentType: [string] }) {
return category;
});
setGroups(
- groupList.sort((a: any, b: any) => {
+ groupList.sort((a: BookmarkGroup, b: BookmarkGroup) => {
switch (bookmarkSort) {
case 'A>Z':
return a.categoryName > b.categoryName ? 1 : -1;
case 'Z>A':
return a.categoryName < b.categoryName ? 1 : -1;
case 'Newest':
- return a.id < b.id ? 1 : -1;
+ if (a.id && b.id) {
+ return a.id < b.id ? 1 : -1;
+ }
+
+ return -1;
case 'Oldest':
- return a.id > b.id ? 1 : -1;
+ if (a.id && b.id) {
+ return a.id > b.id ? 1 : -1;
+ }
+
+ return -1;
case 'Custom':
- return a.index > b.index ? 1 : -1;
+ return a.categoryIndex > b.categoryIndex ? 1 : -1;
}
}),
);
diff --git a/src/pages/homepage/components/Header/Header.tsx b/src/pages/homepage/components/Header/Header.tsx
index ad7754c..404ad3c 100644
--- a/src/pages/homepage/components/Header/Header.tsx
+++ b/src/pages/homepage/components/Header/Header.tsx
@@ -2,7 +2,7 @@ import { Group, Stack, Text } from '@mantine/core';
import { useCommonHooks } from 'hooks';
import { useEffect, useState } from 'react';
import { textClasses } from 'styles';
-import type { CurrentWeather as CW } from 'types';
+import type { CurrentWeather } from 'types';
function Header({
greet,
@@ -15,8 +15,8 @@ function Header({
}: {
greet: string;
date: string;
- current: CW;
- setCurrent: (current: CW) => void;
+ current: CurrentWeather;
+ setCurrent: (current: CurrentWeather) => void;
weather: any;
basicWeather: any;
openWeatherModal: () => void;
diff --git a/src/pages/homepage/components/Search/Search.tsx b/src/pages/homepage/components/Search/Search.tsx
index 6dcb44a..ae1ee29 100644
--- a/src/pages/homepage/components/Search/Search.tsx
+++ b/src/pages/homepage/components/Search/Search.tsx
@@ -67,11 +67,11 @@ export default function Search({
const [placeholderValue, setPlaceholderValue] = useState('');
const [value, setValue] = useState(0);
- const handleSearchHistoryItem = (item: any) => {
+ const handleSearchHistoryItem = ({ option }: { option: SearchHistoryItem }) => {
const url =
- providers.find((provider: Provider) => provider.prefix === item.option.prefix)
- ?.url ?? 'https://www.google.com/search?q=';
- open(`${url}${item.option.searchTerm}`, '_self');
+ providers.find((provider: Provider) => provider.prefix === option.prefix)?.url ??
+ 'https://www.google.com/search?q=';
+ open(`${url}${option.searchTerm}`, '_self');
};
const handleAppSearchItem = (item: any) => {
@@ -425,7 +425,7 @@ export default function Search({
useEffect(() => {
const splittedSearch = searchValue.toLowerCase().trim().split(' ');
const filtered = searchHistory
- .filter((item: any) => {
+ .filter((item: SearchHistoryItem) => {
const option = `${item.prefix} ${item.searchTerm}`;
const words = option.toLowerCase().trim().split(' ');
return splittedSearch.every((searchWord) =>
@@ -450,7 +450,7 @@ export default function Search({
a.label.localeCompare(b.label)) ?? []
+ .toSorted((a: ComboboxItem, b: ComboboxItem) =>
+ a.label.localeCompare(b.label),
+ ) ?? []
}
w='92%'
classNames={{
@@ -262,7 +265,7 @@ function SettingsButton() {
option: selectClasses.menuSelectOption,
}}
comboboxProps={{ withinPortal: false }}
- onChange={(_value, option: any) => {
+ onChange={(_value, option: ComboboxItem) => {
setCurrentThemePlaylist(option.value);
if (option.value !== 'Time of Day') {
setThemeName('random');
@@ -281,7 +284,6 @@ function SettingsButton() {
);
}
}}
- onLoad={(option: any) => setCurrentThemePlaylist(option)}
/>
@@ -329,7 +331,7 @@ function SettingsButton() {
+ categories.toSorted((a: ComboboxItem, b: ComboboxItem) =>
a.label.localeCompare(b.label),
) ?? []
}
@@ -341,7 +343,7 @@ function SettingsButton() {
: 'No apps selected'
}
defaultValue={appFilter}
- onChange={(data: any) => {
+ onChange={(data: string[]) => {
setAppFilter(data);
}}
classNames={multiSelectClasses}
@@ -359,7 +361,7 @@ function SettingsButton() {
option: selectClasses.menuSelectOption,
}}
comboboxProps={{ withinPortal: false }}
- onChange={(_value, option: any) => {
+ onChange={(_value, option: ComboboxItem) => {
setAppSort(option.value);
}}
/>
@@ -408,7 +410,7 @@ function SettingsButton() {
+ categories.toSorted((a: ComboboxItem, b: ComboboxItem) =>
a.label.localeCompare(b.label),
) ?? []
}
@@ -420,7 +422,7 @@ function SettingsButton() {
: 'No bookmarks selected'
}
defaultValue={bookmarkFilter}
- onChange={(data: any) => {
+ onChange={(data: string[]) => {
setBookmarkFilter(data);
}}
classNames={multiSelectClasses}
@@ -438,7 +440,7 @@ function SettingsButton() {
option: selectClasses.menuSelectOption,
}}
comboboxProps={{ withinPortal: false }}
- onChange={(_value, option: any) => {
+ onChange={(_value, option: ComboboxItem) => {
setBookmarkSort(option.value);
}}
/>
diff --git a/src/pages/settings/components/Applications/Applications.tsx b/src/pages/settings/components/Applications/Applications.tsx
index c5fea80..bc499c1 100644
--- a/src/pages/settings/components/Applications/Applications.tsx
+++ b/src/pages/settings/components/Applications/Applications.tsx
@@ -3,6 +3,8 @@ import {
Box,
Button,
Card,
+ type ComboboxItem,
+ type ComboboxLikeRenderOptionInput,
Divider,
Grid,
GridCol,
@@ -179,13 +181,13 @@ const ApplicationSettings = () => {
zIndex: 3000,
withinPortal: false,
}}
- onChange={(event: any) => {
+ onChange={(value: string | null) => {
setNewApplication({
...newApplication,
- icon: event,
+ icon: value ?? '',
});
}}
- renderOption={(item: any) => {
+ renderOption={(item: ComboboxLikeRenderOptionInput) => {
const Icon = allIcons[item.option.value];
return (
diff --git a/src/pages/settings/components/Applications/DebouncedApplication.tsx b/src/pages/settings/components/Applications/DebouncedApplication.tsx
index a609376..21c225d 100644
--- a/src/pages/settings/components/Applications/DebouncedApplication.tsx
+++ b/src/pages/settings/components/Applications/DebouncedApplication.tsx
@@ -2,6 +2,8 @@ import {
ActionIcon,
Button,
Card,
+ type ComboboxItem,
+ type ComboboxLikeRenderOptionInput,
Group,
Select,
Stack,
@@ -194,13 +196,13 @@ function DebouncedApplication({
zIndex: 3000,
withinPortal: false,
}}
- onChange={(event: any) => {
+ onChange={(value: string | null) => {
setUpdate({
...app,
- icon: event,
+ icon: value,
});
}}
- renderOption={(item: any) => {
+ renderOption={(item: ComboboxLikeRenderOptionInput) => {
const Icon = allIcons[item.option.value];
return (
diff --git a/src/pages/settings/components/Bookmarks/Bookmarks.tsx b/src/pages/settings/components/Bookmarks/Bookmarks.tsx
index 8393a29..985f058 100644
--- a/src/pages/settings/components/Bookmarks/Bookmarks.tsx
+++ b/src/pages/settings/components/Bookmarks/Bookmarks.tsx
@@ -10,7 +10,7 @@ import SettingsHeader from '../Shared/SettingsHeader';
import DebouncedGroupSettingsItem from './DebouncedGroupSettingsItem';
const BookmarkSettings = () => {
const defaultGroup = {
- id: undefined,
+ id: null,
categoryName: '',
categoryIndex: 0,
filterName: '',
diff --git a/src/pages/settings/components/Shared/SettingsHeader.tsx b/src/pages/settings/components/Shared/SettingsHeader.tsx
index bfb2a0c..c287dfd 100644
--- a/src/pages/settings/components/Shared/SettingsHeader.tsx
+++ b/src/pages/settings/components/Shared/SettingsHeader.tsx
@@ -29,10 +29,14 @@ function SettingsHeader({
setSearchValue,
searchPlaceholder,
}: {
- setDragging: any;
+ setDragging: undefined | ((dragging: boolean) => void);
openModal: () => void;
title: string;
- tooltip: any;
+ tooltip: {
+ title: string;
+ highlightList: string[];
+ description: string;
+ };
searchValue: string | undefined;
setSearchValue: (searchValue: string) => void;
searchPlaceholder: string | undefined;
diff --git a/src/pages/settings/components/Theming/ThemeCard.tsx b/src/pages/settings/components/Theming/ThemeCard.tsx
index ed977f6..b9ff892 100644
--- a/src/pages/settings/components/Theming/ThemeCard.tsx
+++ b/src/pages/settings/components/Theming/ThemeCard.tsx
@@ -16,7 +16,7 @@ function ThemeCard({
cardTheme: Theme;
handleOpen: (cardTheme: Theme) => void;
allThemes: Theme[];
- themePlaylists: any;
+ themePlaylists: ThemePlaylist[];
}) {
const [hover, setHover] = useState(false);
const [shiftEdit, setShiftEdit] = useState(0);
@@ -274,8 +274,8 @@ function ThemeCard({
onClick={() => {
const themeList = JSON.parse(
themePlaylists?.find(
- (t: ThemePlaylist) => t.name === currentThemePlaylist,
- ).themeList,
+ (t: ThemePlaylist) => t?.name === currentThemePlaylist,
+ )?.themeList ?? '[]',
);
const filteredThemes = allThemes.filter((t: Theme) =>
themeList.includes(t.id),
diff --git a/src/pages/settings/components/Theming/ThemeModal.tsx b/src/pages/settings/components/Theming/ThemeModal.tsx
index 2124a70..ca36fd1 100644
--- a/src/pages/settings/components/Theming/ThemeModal.tsx
+++ b/src/pages/settings/components/Theming/ThemeModal.tsx
@@ -143,7 +143,7 @@ function ThemeModal({
- Name:
+ Name:
{themeList.length > 0 &&
themeList
- .sort((a: any, b: any) => (a > b ? 1 : -1))
+ .sort((a: number, b: number) => (a > b ? 1 : -1))
.map((item: number) => {
return (
diff --git a/src/pages/settings/components/Theming/ThemePlaylistModal.tsx b/src/pages/settings/components/Theming/ThemePlaylistModal.tsx
index 82144bf..126405e 100644
--- a/src/pages/settings/components/Theming/ThemePlaylistModal.tsx
+++ b/src/pages/settings/components/Theming/ThemePlaylistModal.tsx
@@ -10,7 +10,7 @@ import {
import { useCommonHooks } from 'hooks';
import { useEffect, useState } from 'react';
import { modalClasses, textInputClasses } from 'styles';
-import type { Theme } from 'types';
+import type { Theme, ThemePlaylist } from 'types';
import ThemeMiniCard from './ThemeMiniCard';
import TimeOfDay from './TimeOfDay';
@@ -19,6 +19,7 @@ function ThemePlaylistModal({
handleClose,
createPlaylist,
selectedPlaylist,
+ defaultPlaylist,
setSelectedPlaylist,
handleSavePlaylist,
allThemes,
@@ -26,13 +27,15 @@ function ThemePlaylistModal({
opened: boolean;
handleClose: () => void;
createPlaylist: any;
- selectedPlaylist: any;
- setSelectedPlaylist: (selectedPlaylist: any) => void;
+ selectedPlaylist: ThemePlaylist;
+ defaultPlaylist: ThemePlaylist;
+ setSelectedPlaylist: (selectedPlaylist: ThemePlaylist) => void;
handleSavePlaylist: () => void;
allThemes: Theme[];
}) {
const { theme, isMobile, modalStyle } = useCommonHooks();
- const [themeList, setThemeList] = useState('[]');
+ const [themeList, setThemeList] = useState([]);
+
useEffect(() => {
if (selectedPlaylist?.themeList) {
setThemeList(JSON.parse(selectedPlaylist?.themeList));
@@ -40,12 +43,8 @@ function ThemePlaylistModal({
}, [selectedPlaylist]);
if (selectedPlaylist?.name === undefined) {
- setSelectedPlaylist({
- name: 'New Playlist',
- themeList: '[]',
- });
+ setSelectedPlaylist(defaultPlaylist);
}
-
return (
- Name:
+ Name:
{
handleClose();
setThemeList('[]');
- setSelectedPlaylist({});
+ setSelectedPlaylist(defaultPlaylist);
}}
>
Cancel
diff --git a/src/pages/settings/components/Theming/ThemePlaylists.tsx b/src/pages/settings/components/Theming/ThemePlaylists.tsx
index 3375a0f..60a9792 100644
--- a/src/pages/settings/components/Theming/ThemePlaylists.tsx
+++ b/src/pages/settings/components/Theming/ThemePlaylists.tsx
@@ -18,9 +18,16 @@ function ThemePlaylists() {
const { data: themePlaylists } = useQueryAPI({
endpoint: themePlaylistsEndpoint,
});
+ const defaultPlaylist = {
+ id: undefined,
+ default: 0,
+ name: 'New Playlist',
+ themeList: '[]',
+ };
const { mutateAsync } = useMutationAPI();
const [opened, { open, close }] = useDisclosure(false);
- const [selectedPlaylist, setSelectedPlaylist] = useState();
+ const [selectedPlaylist, setSelectedPlaylist] =
+ useState(defaultPlaylist);
const { currentThemePlaylist, theme, isMobile } = useCommonHooks();
const [searchValue, setSearchValue] = useState('');
const [debouncedSearch] = useDebouncedValue(searchValue, 500);
@@ -31,7 +38,7 @@ function ThemePlaylists() {
};
const handleClose = () => {
- setSelectedPlaylist(undefined);
+ setSelectedPlaylist(defaultPlaylist);
close();
};
@@ -50,6 +57,7 @@ function ThemePlaylists() {
opened={opened}
handleClose={handleClose}
selectedPlaylist={selectedPlaylist}
+ defaultPlaylist={defaultPlaylist}
setSelectedPlaylist={setSelectedPlaylist}
handleSavePlaylist={handleSavePlaylist}
allThemes={allThemes}
diff --git a/src/pages/settings/components/Theming/ThemeSelect.tsx b/src/pages/settings/components/Theming/ThemeSelect.tsx
index 37b76dd..9eff2fe 100644
--- a/src/pages/settings/components/Theming/ThemeSelect.tsx
+++ b/src/pages/settings/components/Theming/ThemeSelect.tsx
@@ -1,5 +1,11 @@
-import { Group, Select, Text } from '@mantine/core';
-import type { Theme } from 'types';
+import {
+ type ComboboxItem,
+ type ComboboxLikeRenderOptionInput,
+ Group,
+ Select,
+ Text,
+} from '@mantine/core';
+import type { Theme, ThemePlaylist } from 'types';
function ThemeSelect({
allThemes,
@@ -10,14 +16,15 @@ function ThemeSelect({
timeIndex,
}: {
allThemes: Theme[];
- createPlaylist: any;
- themeList: any;
- selectedPlaylist: any;
- index: string;
+ createPlaylist: (arg0: object) => void;
+ themeList: Array;
+ selectedPlaylist: ThemePlaylist;
+ index: number;
timeIndex: string;
}) {
- const theme = allThemes.find((theme: Theme) => `${theme.id}` === themeList[index]);
-
+ const theme: Theme | undefined = allThemes.find(
+ (theme: Theme) => `${theme.id}` === themeList[index],
+ );
return (
{timeIndex}
@@ -34,7 +41,7 @@ function ThemeSelect({
})}
onChange={(data) => {
const newThemeList = themeList;
- newThemeList[index] = data;
+ newThemeList[index] = data as string;
createPlaylist({
method: 'PATCH',
endpoint: 'api/themePlaylists',
@@ -60,8 +67,10 @@ function ThemeSelect({
borderRadius: '8px',
},
}}
- renderOption={({ option }: any) => {
- const theme = allThemes?.find((theme: Theme) => `${theme.id}` === option.value);
+ renderOption={(item: ComboboxLikeRenderOptionInput) => {
+ const theme = allThemes?.find(
+ (theme: Theme) => `${theme.id}` === item.option.value,
+ );
return (
- {allThemes.find((theme: Theme) => `${theme.id}` === option.value)?.name}
+ {
+ allThemes.find((theme: Theme) => `${theme.id}` === item.option.value)
+ ?.name
+ }
);
diff --git a/src/pages/settings/components/Theming/Themes.tsx b/src/pages/settings/components/Theming/Themes.tsx
index a222771..faebd51 100644
--- a/src/pages/settings/components/Theming/Themes.tsx
+++ b/src/pages/settings/components/Theming/Themes.tsx
@@ -5,7 +5,7 @@ import { useEffect, useState } from 'react';
import { FaDice } from 'react-icons/fa';
import { FiChevronRight } from 'react-icons/fi';
import { switchClasses } from 'styles';
-import type { Theme } from 'types';
+import type { Theme, ThemePlaylist } from 'types';
import SettingsHeader from '../Shared/SettingsHeader';
import ThemeCard from './ThemeCard';
import ThemeModal from './ThemeModal';
@@ -19,9 +19,10 @@ function ThemesSettings() {
const { data: backgroundData, isFetched: isBackgroundFetched } = useQueryAPI({
endpoint: backgroundsEndpoint,
});
- const { data: themePlaylists } = useQueryAPI({
+ const { data: themePlaylistData } = useQueryAPI({
endpoint: 'api/themePlaylists',
});
+ const [themePlaylists, setThemePlaylists] = useState([]);
const { mutateAsync } = useMutationAPI();
const [opened, { open, close }] = useDisclosure(false);
const [colorId, setColorId] = useState('');
@@ -79,6 +80,13 @@ function ThemesSettings() {
setBackgroundList(['None', ...backgroundData]);
}
}, [backgroundData, isBackgroundFetched]);
+
+ useEffect(() => {
+ if (themePlaylistData) {
+ setThemePlaylists(themePlaylistData);
+ }
+ }, [themePlaylistData]);
+
return (
void;
+ themeList: Array;
+ allThemes: Theme[];
+ selectedPlaylist: ThemePlaylist;
+}) {
return (
diff --git a/src/types/bookmarkGroup.ts b/src/types/bookmarkGroup.ts
index 3640e40..284aa3b 100644
--- a/src/types/bookmarkGroup.ts
+++ b/src/types/bookmarkGroup.ts
@@ -1,5 +1,5 @@
export interface BookmarkGroup {
- id: number | undefined;
+ id: number | null;
categoryName: string;
categoryIndex: number;
filterName: string;
diff --git a/src/types/index.ts b/src/types/index.ts
index d251559..b6eb175 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -1,4 +1,10 @@
-export type { CurrentWeather, OutlookWeather, ExtendedForecast } from './weather';
+export type {
+ CurrentWeather,
+ OutlookWeather,
+ ExtendedForecast,
+ HourlyForecast,
+ SunState,
+} from './weather';
export type { Application, AppCategory } from './application';
export type { Bookmark } from './bookmark';
export type { BookmarkGroup } from './bookmarkGroup';
@@ -7,6 +13,6 @@ export type { Message } from './message';
export type { Provider } from './provider';
export type { Theme, ThemePlaylist } from './theme';
export type { WolClient } from './wolClient';
-export type { SearchHistoryItem } from './searchHistory';
+export type { SearchHistoryItem, SearchShortcut } from './search';
export type { User } from './user';
export type { Location } from './location';
diff --git a/src/types/searchHistory.ts b/src/types/search.ts
similarity index 67%
rename from src/types/searchHistory.ts
rename to src/types/search.ts
index 4095b4e..65f7304 100644
--- a/src/types/searchHistory.ts
+++ b/src/types/search.ts
@@ -5,3 +5,8 @@ export interface SearchHistoryItem {
searchTerm: string;
dateTimeStamp: string;
}
+
+export interface SearchShortcut {
+ name: string;
+ command: string;
+}
diff --git a/src/types/theme.ts b/src/types/theme.ts
index ea45f2c..acf4ace 100644
--- a/src/types/theme.ts
+++ b/src/types/theme.ts
@@ -14,5 +14,5 @@ export interface ThemePlaylist {
id: number | undefined;
name: string;
default: number;
- themeList: number[];
+ themeList: string;
}
diff --git a/src/types/weather.ts b/src/types/weather.ts
index d230f76..09b561d 100644
--- a/src/types/weather.ts
+++ b/src/types/weather.ts
@@ -31,3 +31,43 @@ export interface ExtendedForecast {
temperature: number;
temperatureUnit: string;
}
+
+export interface HourlyForecast {
+ detailedForecast: string;
+ dewpoint: DewPoint;
+ endTime: string;
+ icon: string;
+ isDaytime: boolean;
+ name: string;
+ number: number;
+ probabilityOfPrecipitation: ProbabilityOfPrecipitation;
+ relativeHumidity: RelativeHumidity;
+ shortForecast: string;
+ startTime: string;
+ temperature: number;
+ temperatureTrend: string;
+ temperatureUnit: string;
+ windDirection: string;
+ windSpeed: string;
+}
+
+export interface ProbabilityOfPrecipitation {
+ unitCode: string;
+ value: number;
+}
+
+export interface RelativeHumidity {
+ unitCode: string;
+ value: number;
+}
+
+export interface DewPoint {
+ unitCode: string;
+ value: number;
+}
+
+export interface SunState {
+ date: string;
+ sunrise: string;
+ sunset: string;
+}