More typing
This commit is contained in:
@@ -4,10 +4,20 @@ 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 type { Theme, ThemePlaylist } from 'types';
|
||||
import DeleteItemModal from '../Shared/DeleteItemModal';
|
||||
|
||||
function ThemeCard({ cardTheme, handleOpen, allThemes, themePlaylists }: any) {
|
||||
function ThemeCard({
|
||||
cardTheme,
|
||||
handleOpen,
|
||||
allThemes,
|
||||
themePlaylists,
|
||||
}: {
|
||||
cardTheme: Theme;
|
||||
handleOpen: (cardTheme: Theme) => void;
|
||||
allThemes: Theme[];
|
||||
themePlaylists: any;
|
||||
}) {
|
||||
const [hover, setHover] = useState(false);
|
||||
const [shiftEdit, setShiftEdit] = useState<number>(0);
|
||||
const [shiftShuffle, setShiftShuffle] = useState<number>(0);
|
||||
@@ -263,11 +273,11 @@ function ThemeCard({ cardTheme, handleOpen, allThemes, themePlaylists }: any) {
|
||||
<FiShuffle
|
||||
onClick={() => {
|
||||
const themeList = JSON.parse(
|
||||
themePlaylists.find(
|
||||
themePlaylists?.find(
|
||||
(t: ThemePlaylist) => t.name === currentThemePlaylist,
|
||||
).themeList,
|
||||
);
|
||||
const filteredThemes = allThemes.filter((t: any) =>
|
||||
const filteredThemes = allThemes.filter((t: Theme) =>
|
||||
themeList.includes(t.id),
|
||||
);
|
||||
handleThemeChange(filteredThemes, false);
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import { Group, Text } from '@mantine/core';
|
||||
function ThemeMiniCard({ allThemes, item }: any) {
|
||||
const theme = allThemes.find((theme: any) => theme.id === item);
|
||||
import type { Theme } from 'types';
|
||||
function ThemeMiniCard({
|
||||
allThemes,
|
||||
item,
|
||||
}: {
|
||||
allThemes: Theme[];
|
||||
item: number;
|
||||
}) {
|
||||
const theme = allThemes.find((theme: Theme) => theme.id === item);
|
||||
|
||||
return (
|
||||
<Group
|
||||
@@ -12,23 +19,23 @@ function ThemeMiniCard({ allThemes, item }: any) {
|
||||
w={'175px'}
|
||||
h={'60px'}
|
||||
style={{
|
||||
background: `linear-gradient(${theme.backgroundColor}33, ${theme.backgroundColor}33), no-repeat center url(/backgrounds/${theme.backgroundImage})`,
|
||||
background: `linear-gradient(${theme?.backgroundColor}33, ${theme?.backgroundColor}33), no-repeat center url(/backgrounds/${theme?.backgroundImage})`,
|
||||
backgroundSize: 'cover',
|
||||
backgroundColor: theme.backgroundColor,
|
||||
border: `solid ${theme.borderColor}`,
|
||||
backgroundColor: theme?.backgroundColor,
|
||||
border: `solid ${theme?.borderColor}`,
|
||||
borderRadius: '8px',
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
bg={theme.backgroundColor}
|
||||
c={theme.primaryColor}
|
||||
bg={theme?.backgroundColor}
|
||||
c={theme?.primaryColor}
|
||||
size='md'
|
||||
style={{
|
||||
padding: 4,
|
||||
borderRadius: '8px',
|
||||
}}
|
||||
>
|
||||
{allThemes.find((theme: any) => theme.id === item)?.name}
|
||||
{allThemes.find((theme: Theme) => theme.id === item)?.name}
|
||||
</Text>
|
||||
</Group>
|
||||
);
|
||||
|
||||
@@ -15,6 +15,7 @@ import { useCommonHooks } from 'hooks';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { FiSave, FiX } from 'react-icons/fi';
|
||||
import { modalClasses, textClasses, textInputClasses } from 'styles';
|
||||
import type { Theme } from 'types';
|
||||
import ThemeModalContent from './ThemeModalContent';
|
||||
|
||||
function ThemeModal({
|
||||
@@ -22,38 +23,40 @@ function ThemeModal({
|
||||
handleClose,
|
||||
selectedTheme,
|
||||
setSelectedTheme,
|
||||
setColorId,
|
||||
colorId,
|
||||
setColorId,
|
||||
colorValue,
|
||||
setColorValue,
|
||||
openPicker,
|
||||
backgroundList,
|
||||
pickerOpen,
|
||||
colorValue,
|
||||
closePicker,
|
||||
handleSaveTheme,
|
||||
}: any) {
|
||||
}: {
|
||||
opened: boolean;
|
||||
handleClose: () => void;
|
||||
selectedTheme: Theme;
|
||||
setSelectedTheme: (selectedTheme: Theme) => void;
|
||||
colorId: string;
|
||||
setColorId: (colorId: string) => void;
|
||||
colorValue: string;
|
||||
setColorValue: (colorValue: string) => void;
|
||||
openPicker: () => void;
|
||||
backgroundList: string[];
|
||||
pickerOpen: boolean;
|
||||
closePicker: () => void;
|
||||
handleSaveTheme: () => void;
|
||||
}) {
|
||||
const { theme, isMobile } = useCommonHooks();
|
||||
const viewportRef = useRef<HTMLDivElement>(null);
|
||||
const [query, setQuery] = useState('');
|
||||
const [hovered, setHovered] = useState(-1);
|
||||
const filtered = backgroundList.filter((item: any) =>
|
||||
const filtered = backgroundList.filter((item: string) =>
|
||||
item.toLowerCase().includes(query.toLowerCase()),
|
||||
);
|
||||
if (selectedTheme.name === undefined) {
|
||||
setSelectedTheme({
|
||||
id: undefined,
|
||||
name: 'default',
|
||||
backgroundImage: 'none',
|
||||
backgroundColor: '#EEEEEE',
|
||||
searchColor: '#00000033',
|
||||
primaryColor: '#222222',
|
||||
accentColor: '#5c5c5c',
|
||||
borderColor: '#5c5c5c',
|
||||
});
|
||||
}
|
||||
|
||||
const re = /(?:\.([^.]+))?$/;
|
||||
const items = filtered.map((item: any, index: any) => (
|
||||
const items = filtered.map((item: string, index: number) => (
|
||||
<UnstyledButton
|
||||
data-list-item
|
||||
key={item}
|
||||
|
||||
@@ -2,9 +2,10 @@ import { Box, Group, Stack, Text } from '@mantine/core';
|
||||
import { useState } from 'react';
|
||||
import { FiCheck } from 'react-icons/fi';
|
||||
import { stackClasses } from 'styles';
|
||||
import type { Theme } from 'types';
|
||||
|
||||
export default function ThemeModalContent({ selectedTheme }: any) {
|
||||
const ExampleApp = (previewTheme: any) => {
|
||||
export default function ThemeModalContent({ selectedTheme }: { selectedTheme: Theme }) {
|
||||
const ExampleApp = ({ theme }: { theme: Theme }) => {
|
||||
const [textDecoration, setTextDecoration] = useState<string>('none');
|
||||
|
||||
return (
|
||||
@@ -22,11 +23,7 @@ export default function ThemeModalContent({ selectedTheme }: any) {
|
||||
paddingTop: '15px',
|
||||
}}
|
||||
>
|
||||
<FiCheck
|
||||
style={{ color: previewTheme.theme.primaryColor }}
|
||||
height={32}
|
||||
width={32}
|
||||
/>
|
||||
<FiCheck style={{ color: theme.primaryColor }} height={32} width={32} />
|
||||
</Stack>
|
||||
<Stack
|
||||
style={{
|
||||
@@ -43,7 +40,7 @@ export default function ThemeModalContent({ selectedTheme }: any) {
|
||||
fontWeight: 400,
|
||||
fontSize: 11,
|
||||
fontStyle: 'normal',
|
||||
color: previewTheme.theme.primaryColor,
|
||||
color: theme.primaryColor,
|
||||
fontFamily:
|
||||
'-apple-system, Jost, BlinkMacSystemFont, Helvetica Neue, Roboto, sans-serif !important',
|
||||
margin: 0,
|
||||
@@ -56,7 +53,7 @@ export default function ThemeModalContent({ selectedTheme }: any) {
|
||||
fontWeight: 400,
|
||||
fontSize: 11,
|
||||
fontStyle: 'italic',
|
||||
color: previewTheme.theme.accentColor,
|
||||
color: theme.accentColor,
|
||||
fontFamily:
|
||||
'-apple-system, Jost, BlinkMacSystemFont, Helvetica Neue, Roboto, sans-serif !important',
|
||||
margin: 0,
|
||||
|
||||
@@ -11,10 +11,19 @@ import { useDisclosure } from '@mantine/hooks';
|
||||
import { useCommonHooks, useMutationAPI } from 'hooks';
|
||||
import { useState } from 'react';
|
||||
import { FiEdit, FiRefreshCcw, FiTrash } from 'react-icons/fi';
|
||||
import type { Theme, ThemePlaylist } from 'types';
|
||||
import DeleteItemModal from '../Shared/DeleteItemModal';
|
||||
import ThemeMiniCard from './ThemeMiniCard';
|
||||
|
||||
function ThemePlaylistCard({ cardPlaylist, handleOpen, allThemes }: any) {
|
||||
function ThemePlaylistCard({
|
||||
cardPlaylist,
|
||||
handleOpen,
|
||||
allThemes,
|
||||
}: {
|
||||
cardPlaylist: any;
|
||||
handleOpen: (cardPlaylist: ThemePlaylist) => void;
|
||||
allThemes: Theme[];
|
||||
}) {
|
||||
const [hover, setHover] = useState(false);
|
||||
const { setThemeName, setCurrentThemePlaylist, theme, handleDelete } = useCommonHooks();
|
||||
const syncableLists = ['All', 'Backgrounds', 'No Backgrounds'];
|
||||
@@ -36,7 +45,7 @@ function ThemePlaylistCard({ cardPlaylist, handleOpen, allThemes }: any) {
|
||||
>
|
||||
<DeleteItemModal
|
||||
modalOpened={modalOpened}
|
||||
closeModal={closeModal}
|
||||
handleClose={closeModal}
|
||||
title='Delete Theme Playlist'
|
||||
body={
|
||||
<Stack gap={0} w={'100%'} h={'150px'} align='center'>
|
||||
@@ -120,7 +129,7 @@ function ThemePlaylistCard({ cardPlaylist, handleOpen, allThemes }: any) {
|
||||
body: {
|
||||
id: cardPlaylist.id,
|
||||
name: 'All',
|
||||
themeList: JSON.stringify(allThemes.map((theme: any) => theme.id)),
|
||||
themeList: JSON.stringify(allThemes.map((theme: Theme) => theme.id)),
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -134,9 +143,9 @@ function ThemePlaylistCard({ cardPlaylist, handleOpen, allThemes }: any) {
|
||||
themeList: JSON.stringify(
|
||||
allThemes
|
||||
.filter(
|
||||
(theme: any) => theme.backgroundImage.toLowerCase() !== 'none',
|
||||
(theme: Theme) => theme.backgroundImage.toLowerCase() !== 'none',
|
||||
)
|
||||
.map((theme: any) => theme.id),
|
||||
.map((theme: Theme) => theme.id),
|
||||
),
|
||||
},
|
||||
});
|
||||
@@ -151,9 +160,9 @@ function ThemePlaylistCard({ cardPlaylist, handleOpen, allThemes }: any) {
|
||||
themeList: JSON.stringify(
|
||||
allThemes
|
||||
.filter(
|
||||
(theme: any) => theme.backgroundImage.toLowerCase() === 'none',
|
||||
(theme: Theme) => theme.backgroundImage.toLowerCase() === 'none',
|
||||
)
|
||||
.map((theme: any) => theme.id),
|
||||
.map((theme: Theme) => theme.id),
|
||||
),
|
||||
},
|
||||
});
|
||||
@@ -243,7 +252,7 @@ function ThemePlaylistCard({ cardPlaylist, handleOpen, allThemes }: any) {
|
||||
<ScrollArea h={'255px'} w={'100%'} style={{ zIndex: 2 }}>
|
||||
<Stack gap={4}>
|
||||
{themeList.length > 0 &&
|
||||
themeList.map((item: any) => {
|
||||
themeList.map((item: number) => {
|
||||
return (
|
||||
<ThemeMiniCard key={item} item={item} allThemes={allThemes} />
|
||||
);
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
import { useCommonHooks } from 'hooks';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { modalClasses, selectClasses, textInputClasses } from 'styles';
|
||||
import type { Theme } from 'types';
|
||||
import ThemeMiniCard from './ThemeMiniCard';
|
||||
|
||||
function ThemePlaylistModal({
|
||||
@@ -22,8 +23,16 @@ function ThemePlaylistModal({
|
||||
setSelectedPlaylist,
|
||||
handleSavePlaylist,
|
||||
allThemes,
|
||||
}: any) {
|
||||
const { theme, isMobile } = useCommonHooks();
|
||||
}: {
|
||||
opened: boolean;
|
||||
handleClose: () => void;
|
||||
createPlaylist: any;
|
||||
selectedPlaylist: any;
|
||||
setSelectedPlaylist: (selectedPlaylist: any) => void;
|
||||
handleSavePlaylist: () => void;
|
||||
allThemes: Theme[];
|
||||
}) {
|
||||
const { theme, isMobile, modalStyle } = useCommonHooks();
|
||||
const [themeList, setThemeList] = useState<any>('[]');
|
||||
useEffect(() => {
|
||||
if (selectedPlaylist.themeList) {
|
||||
@@ -50,14 +59,7 @@ function ThemePlaylistModal({
|
||||
handleClose();
|
||||
setThemeList('[]');
|
||||
}}
|
||||
style={{
|
||||
'--color-text-pri': theme.primaryColor,
|
||||
'--color-text-acc': theme.accentColor,
|
||||
'--color-background': theme.backgroundColor,
|
||||
'--color-border': theme.borderColor,
|
||||
'--color-search-background': theme.searchColor,
|
||||
'--image-background': `url("${theme.backgroundImage}")`,
|
||||
}}
|
||||
style={modalStyle}
|
||||
>
|
||||
<Modal.Overlay style={{ backdropFilter: 'blur(5px)' }} />
|
||||
<Modal.Content>
|
||||
@@ -95,7 +97,7 @@ function ThemePlaylistModal({
|
||||
labelProps={{ display: 'none' }}
|
||||
placeholder='Select Theme'
|
||||
defaultValue={themeList['0']}
|
||||
data={allThemes?.map((theme: any) => {
|
||||
data={allThemes?.map((theme: Theme) => {
|
||||
return {
|
||||
value: `${theme.id}`,
|
||||
label: theme.name,
|
||||
@@ -128,7 +130,7 @@ function ThemePlaylistModal({
|
||||
labelProps={{ display: 'none' }}
|
||||
placeholder='Select Theme'
|
||||
defaultValue={themeList['1']}
|
||||
data={allThemes?.map((theme: any) => {
|
||||
data={allThemes?.map((theme: Theme) => {
|
||||
return {
|
||||
value: `${theme.id}`,
|
||||
label: theme.name,
|
||||
@@ -161,7 +163,7 @@ function ThemePlaylistModal({
|
||||
labelProps={{ display: 'none' }}
|
||||
placeholder='Select Theme'
|
||||
defaultValue={themeList['2']}
|
||||
data={allThemes?.map((theme: any) => {
|
||||
data={allThemes?.map((theme: Theme) => {
|
||||
return {
|
||||
value: `${theme.id}`,
|
||||
label: theme.name,
|
||||
@@ -194,7 +196,7 @@ function ThemePlaylistModal({
|
||||
labelProps={{ display: 'none' }}
|
||||
placeholder='Select Theme'
|
||||
defaultValue={themeList['3']}
|
||||
data={allThemes?.map((theme: any) => {
|
||||
data={allThemes?.map((theme: Theme) => {
|
||||
return {
|
||||
value: `${theme.id}`,
|
||||
label: theme.name,
|
||||
@@ -225,7 +227,7 @@ function ThemePlaylistModal({
|
||||
) : (
|
||||
<SimpleGrid cols={3}>
|
||||
{selectedPlaylist.name !== 'Time of Day' &&
|
||||
allThemes?.map((miniTheme: any) => {
|
||||
allThemes.map((miniTheme: Theme) => {
|
||||
const newThemeList = themeList;
|
||||
return (
|
||||
<Group
|
||||
@@ -248,7 +250,7 @@ function ThemePlaylistModal({
|
||||
setSelectedPlaylist(newSelectedPlaylist);
|
||||
}}
|
||||
>
|
||||
<ThemeMiniCard allThemes={allThemes} item={miniTheme.id} />
|
||||
<ThemeMiniCard allThemes={allThemes} item={Number(miniTheme.id)} />
|
||||
</Group>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -21,12 +21,11 @@ function ThemePlaylists() {
|
||||
const { mutateAsync } = useMutationAPI();
|
||||
const [opened, { open, close }] = useDisclosure(false);
|
||||
const [selectedPlaylist, setSelectedPlaylist] = useState<any>({});
|
||||
const { currentThemePlaylist, setCurrentThemePlaylist, theme, isMobile } =
|
||||
useCommonHooks();
|
||||
const { currentThemePlaylist, theme, isMobile } = useCommonHooks();
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const [debouncedSearch] = useDebouncedValue(searchValue, 500);
|
||||
|
||||
const handleOpen = (playlist: any) => {
|
||||
const handleOpen = (playlist: ThemePlaylist) => {
|
||||
setSelectedPlaylist(playlist);
|
||||
open();
|
||||
};
|
||||
@@ -106,8 +105,6 @@ function ThemePlaylists() {
|
||||
<ThemePlaylistCard
|
||||
cardPlaylist={cardPlaylist}
|
||||
handleOpen={handleOpen}
|
||||
currentThemePlaylist={currentThemePlaylist}
|
||||
setCurrentThemePlaylist={setCurrentThemePlaylist}
|
||||
allThemes={allThemes}
|
||||
/>
|
||||
</Box>
|
||||
@@ -131,7 +128,7 @@ function ThemePlaylists() {
|
||||
?.filter((a: ThemePlaylist) =>
|
||||
a.name.toLowerCase().includes(debouncedSearch.toLowerCase()),
|
||||
)
|
||||
.sort((a: any, b: any) => (a.name > b.name ? 1 : -1))
|
||||
.sort((a: ThemePlaylist, b: ThemePlaylist) => (a.name > b.name ? 1 : -1))
|
||||
.map((cardPlaylist: ThemePlaylist) => {
|
||||
return (
|
||||
<Group key={cardPlaylist.name} pos={'relative'}>
|
||||
|
||||
@@ -9,6 +9,7 @@ import type { Theme } from 'types';
|
||||
import SettingsHeader from '../Shared/SettingsHeader';
|
||||
import ThemeCard from './ThemeCard';
|
||||
import ThemeModal from './ThemeModal';
|
||||
|
||||
function ThemesSettings() {
|
||||
const themesEndpoint = 'api/themes';
|
||||
const backgroundsEndpoint = 'api/backgrounds';
|
||||
@@ -26,7 +27,17 @@ function ThemesSettings() {
|
||||
const [colorId, setColorId] = useState<string>('');
|
||||
const [colorValue, setColorValue] = useState('#000000');
|
||||
const [backgroundList, setBackgroundList] = useState<string[]>(['None']);
|
||||
const [selectedTheme, setSelectedTheme] = useState<any>({});
|
||||
const [selectedTheme, setSelectedTheme] = useState<Theme>({
|
||||
id: undefined,
|
||||
name: 'default',
|
||||
backgroundImage: 'none',
|
||||
backgroundColor: '#EEEEEE',
|
||||
searchColor: '#00000033',
|
||||
primaryColor: '#222222',
|
||||
accentColor: '#5c5c5c',
|
||||
borderColor: '#5c5c5c',
|
||||
randomEnabled: 0,
|
||||
});
|
||||
const [pickerOpen, { open: openPicker, close: closePicker }] = useDisclosure(false);
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const [debouncedSearch] = useDebouncedValue(searchValue, 500);
|
||||
@@ -41,12 +52,22 @@ function ThemesSettings() {
|
||||
const handleClose = () => {
|
||||
close();
|
||||
closePicker();
|
||||
setSelectedTheme({});
|
||||
setSelectedTheme({
|
||||
id: undefined,
|
||||
name: 'default',
|
||||
backgroundImage: 'none',
|
||||
backgroundColor: '#EEEEEE',
|
||||
searchColor: '#00000033',
|
||||
primaryColor: '#222222',
|
||||
accentColor: '#5c5c5c',
|
||||
borderColor: '#5c5c5c',
|
||||
randomEnabled: 0,
|
||||
});
|
||||
};
|
||||
|
||||
const handleSaveTheme = () => {
|
||||
mutateAsync({
|
||||
method: selectedTheme.id === undefined ? 'POST' : 'PATCH',
|
||||
method: selectedTheme?.id === undefined ? 'POST' : 'PATCH',
|
||||
endpoint: themesEndpoint,
|
||||
body: selectedTheme,
|
||||
});
|
||||
@@ -65,7 +86,6 @@ function ThemesSettings() {
|
||||
handleClose={handleClose}
|
||||
selectedTheme={selectedTheme}
|
||||
setSelectedTheme={setSelectedTheme}
|
||||
theme={theme}
|
||||
setColorId={setColorId}
|
||||
colorId={colorId}
|
||||
setColorValue={setColorValue}
|
||||
|
||||
Reference in New Issue
Block a user