296 lines
7.3 KiB
TypeScript
296 lines
7.3 KiB
TypeScript
import {
|
|
ActionIcon,
|
|
Button,
|
|
Group,
|
|
Overlay,
|
|
ScrollArea,
|
|
Stack,
|
|
Text,
|
|
} from '@mantine/core';
|
|
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,
|
|
}: {
|
|
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'];
|
|
const { mutateAsync } = useMutationAPI();
|
|
const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false);
|
|
const themeList = JSON.parse(
|
|
cardPlaylist.themeList.name === 'Time of Day' ? '[]' : cardPlaylist.themeList,
|
|
);
|
|
|
|
return (
|
|
<Group
|
|
gap={0}
|
|
align='center'
|
|
justify='center'
|
|
display={'grid'}
|
|
pos={'relative'}
|
|
onMouseEnter={() => setHover(true)}
|
|
onMouseLeave={() => setHover(false)}
|
|
>
|
|
<DeleteItemModal
|
|
modalOpened={modalOpened}
|
|
handleClose={closeModal}
|
|
title='Delete Theme Playlist'
|
|
body={
|
|
<Stack gap={0} w={'100%'} h={'150px'} align='center'>
|
|
<Text>Are you sure you want to delete this Theme Playlist?</Text>
|
|
<Text
|
|
style={{
|
|
fontWeight: 'bold',
|
|
fontSize: '20px',
|
|
padding: '8px',
|
|
margin: '8px',
|
|
borderRadius: '10px',
|
|
backgroundColor: 'var(--color-text-acc)',
|
|
color: 'var(--color-background)',
|
|
}}
|
|
>{`"${cardPlaylist.name}"`}</Text>
|
|
<Text c='red'>This action cannot be undone!</Text>
|
|
<Group pos={'absolute'} bottom={8}>
|
|
<Button
|
|
color={'red'}
|
|
styles={{ label: { color: 'black' } }}
|
|
onClick={() => {
|
|
handleDelete(cardPlaylist, 'api/themePlaylists');
|
|
closeModal();
|
|
}}
|
|
>
|
|
Delete
|
|
</Button>
|
|
<Button
|
|
color={'grey'}
|
|
styles={{ label: { color: 'black' } }}
|
|
onClick={() => {
|
|
closeModal();
|
|
}}
|
|
>
|
|
Cancel
|
|
</Button>
|
|
</Group>
|
|
</Stack>
|
|
}
|
|
/>
|
|
<Text
|
|
style={{
|
|
position: 'absolute',
|
|
top: -10,
|
|
left: 6,
|
|
paddingRight: 4,
|
|
paddingLeft: 4,
|
|
backgroundColor: theme.borderColor,
|
|
borderRadius: '4px',
|
|
color:
|
|
theme.borderColor === theme.primaryColor
|
|
? theme.accentColor
|
|
: theme.backgroundColor,
|
|
zIndex: 3,
|
|
}}
|
|
>
|
|
{cardPlaylist.name}
|
|
</Text>
|
|
{syncableLists.includes(cardPlaylist.name) ? (
|
|
<ActionIcon
|
|
style={{
|
|
position: 'absolute',
|
|
top: -10,
|
|
right: 6,
|
|
paddingRight: 4,
|
|
paddingLeft: 4,
|
|
backgroundColor: theme.borderColor,
|
|
borderRadius: '4px',
|
|
color:
|
|
theme.borderColor === theme.primaryColor
|
|
? theme.accentColor
|
|
: theme.backgroundColor,
|
|
zIndex: 3,
|
|
}}
|
|
onClick={(event) => {
|
|
event.stopPropagation();
|
|
if (cardPlaylist.name === 'All') {
|
|
mutateAsync({
|
|
method: 'PATCH',
|
|
endpoint: 'api/themePlaylists',
|
|
body: {
|
|
id: cardPlaylist.id,
|
|
name: 'All',
|
|
themeList: JSON.stringify(allThemes.map((theme: Theme) => theme.id)),
|
|
},
|
|
});
|
|
}
|
|
if (cardPlaylist.name === 'Backgrounds') {
|
|
mutateAsync({
|
|
method: 'PATCH',
|
|
endpoint: 'api/themePlaylists',
|
|
body: {
|
|
id: cardPlaylist.id,
|
|
name: 'Backgrounds',
|
|
themeList: JSON.stringify(
|
|
allThemes
|
|
.filter(
|
|
(theme: Theme) => theme.backgroundImage.toLowerCase() !== 'none',
|
|
)
|
|
.map((theme: Theme) => theme.id),
|
|
),
|
|
},
|
|
});
|
|
}
|
|
if (cardPlaylist.name === 'No Backgrounds') {
|
|
mutateAsync({
|
|
method: 'PATCH',
|
|
endpoint: 'api/themePlaylists',
|
|
body: {
|
|
id: cardPlaylist.id,
|
|
name: 'No Backgrounds',
|
|
themeList: JSON.stringify(
|
|
allThemes
|
|
.filter(
|
|
(theme: Theme) => theme.backgroundImage.toLowerCase() === 'none',
|
|
)
|
|
.map((theme: Theme) => theme.id),
|
|
),
|
|
},
|
|
});
|
|
}
|
|
}}
|
|
>
|
|
<FiRefreshCcw />
|
|
</ActionIcon>
|
|
) : (
|
|
<>
|
|
<ActionIcon
|
|
style={{
|
|
position: 'absolute',
|
|
top: -10,
|
|
right: 6,
|
|
paddingRight: 4,
|
|
paddingLeft: 4,
|
|
backgroundColor: theme.borderColor,
|
|
borderRadius: '4px',
|
|
color:
|
|
theme.borderColor === theme.primaryColor
|
|
? theme.accentColor
|
|
: theme.backgroundColor,
|
|
zIndex: 3,
|
|
}}
|
|
onClick={() => {
|
|
handleOpen(cardPlaylist);
|
|
}}
|
|
>
|
|
<FiEdit />
|
|
</ActionIcon>
|
|
{cardPlaylist.default === 0 && (
|
|
<ActionIcon
|
|
style={{
|
|
position: 'absolute',
|
|
top: -10,
|
|
right: 40,
|
|
paddingRight: 4,
|
|
paddingLeft: 4,
|
|
backgroundColor: theme.borderColor,
|
|
borderRadius: '4px',
|
|
color:
|
|
theme.borderColor === theme.primaryColor
|
|
? theme.accentColor
|
|
: theme.backgroundColor,
|
|
zIndex: 3,
|
|
}}
|
|
onClick={() => {
|
|
openModal();
|
|
}}
|
|
>
|
|
<FiTrash />
|
|
</ActionIcon>
|
|
)}
|
|
</>
|
|
)}
|
|
<Button
|
|
w={'275px'}
|
|
h={'310px'}
|
|
style={{
|
|
backgroundSize: 'cover',
|
|
backgroundColor: theme.searchColor,
|
|
color: theme.accentColor,
|
|
border: `solid ${theme.borderColor}`,
|
|
}}
|
|
onClick={() => {
|
|
setCurrentThemePlaylist(cardPlaylist.name);
|
|
setThemeName('random');
|
|
}}
|
|
>
|
|
{hover && <Overlay opacity={0.5} zIndex={1} />}
|
|
<Stack h={'100%'} w={'100%'} align='center'>
|
|
{cardPlaylist.name !== 'Time of Day' ? (
|
|
<>
|
|
<Text
|
|
px={8}
|
|
mt={8}
|
|
mb={-8}
|
|
style={{
|
|
color: theme.backgroundColor,
|
|
backgroundColor: theme.primaryColor,
|
|
borderRadius: '4px',
|
|
}}
|
|
>
|
|
Count: {themeList.length}
|
|
</Text>
|
|
<ScrollArea h={'255px'} w={'100%'} style={{ zIndex: 2 }}>
|
|
<Stack gap={4}>
|
|
{themeList.length > 0 &&
|
|
themeList
|
|
.sort((a: any, b: any) => (a > b ? 1 : -1))
|
|
.map((item: number) => {
|
|
return (
|
|
<ThemeMiniCard key={item} item={item} allThemes={allThemes} />
|
|
);
|
|
})}
|
|
</Stack>
|
|
</ScrollArea>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Text
|
|
px={8}
|
|
mt={8}
|
|
mb={-8}
|
|
style={{
|
|
color: theme.backgroundColor,
|
|
backgroundColor: theme.primaryColor,
|
|
borderRadius: '4px',
|
|
}}
|
|
>
|
|
Timed Themes
|
|
</Text>
|
|
<ScrollArea h={'255px'} w={'100%'} style={{ zIndex: 2 }}>
|
|
<Stack gap={4}>
|
|
<ThemeMiniCard item={Number(themeList[0])} allThemes={allThemes} />
|
|
<ThemeMiniCard item={Number(themeList[1])} allThemes={allThemes} />
|
|
<ThemeMiniCard item={Number(themeList[2])} allThemes={allThemes} />
|
|
<ThemeMiniCard item={Number(themeList[3])} allThemes={allThemes} />
|
|
</Stack>
|
|
</ScrollArea>
|
|
</>
|
|
)}
|
|
</Stack>
|
|
</Button>
|
|
</Group>
|
|
);
|
|
}
|
|
|
|
export default ThemePlaylistCard;
|