UI improvements!
This commit is contained in:
parent
3e8141aeba
commit
5c62f9d147
@ -1,8 +1,7 @@
|
||||
#root {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.logo {
|
||||
@ -34,7 +33,7 @@
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 2em;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.read-the-docs {
|
||||
|
||||
@ -56,16 +56,24 @@ export default function RekordboxReader() {
|
||||
}
|
||||
|
||||
return (
|
||||
<Box p={5}>
|
||||
<Heading mb={4}>Rekordbox Reader</Heading>
|
||||
<Input
|
||||
type="file"
|
||||
accept=".xml"
|
||||
onChange={handleFileUpload}
|
||||
mb={4}
|
||||
/>
|
||||
<Flex gap={4}>
|
||||
<Box w="250px">
|
||||
<Box>
|
||||
<Flex direction="column" gap={2} mb={4}>
|
||||
<Heading size="md">Rekordbox Reader</Heading>
|
||||
<Input
|
||||
type="file"
|
||||
accept=".xml"
|
||||
onChange={handleFileUpload}
|
||||
size="sm"
|
||||
width="auto"
|
||||
/>
|
||||
{songs.length > 0 && (
|
||||
<Button onClick={handleExport} size="sm" colorScheme="blue" width="auto">
|
||||
Export XML
|
||||
</Button>
|
||||
)}
|
||||
</Flex>
|
||||
<Flex gap={4} alignItems="start">
|
||||
<Box w="200px">
|
||||
<PlaylistManager
|
||||
playlists={playlists}
|
||||
selectedItem={selectedItem}
|
||||
@ -81,11 +89,6 @@ export default function RekordboxReader() {
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
{songs.length > 0 && (
|
||||
<Button onClick={handleExport} mt={4} colorScheme="blue">
|
||||
Export XML
|
||||
</Button>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import {
|
||||
Button,
|
||||
Input,
|
||||
Flex,
|
||||
Text,
|
||||
Stack,
|
||||
useDisclosure,
|
||||
CloseButton,
|
||||
} from "@chakra-ui/react";
|
||||
import {
|
||||
Modal,
|
||||
@ -12,7 +12,6 @@ import {
|
||||
ModalHeader,
|
||||
ModalFooter,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
} from "@chakra-ui/modal";
|
||||
import { useState } from "react";
|
||||
import { Playlist } from "../types/interfaces";
|
||||
@ -30,23 +29,24 @@ export const PlaylistManager: React.FC<PlaylistManagerProps> = ({
|
||||
onPlaylistCreate,
|
||||
onPlaylistSelect,
|
||||
}) => {
|
||||
const disclosure = useDisclosure();
|
||||
const { open, onOpen, onClose } = useDisclosure();
|
||||
const [newPlaylistName, setNewPlaylistName] = useState("");
|
||||
|
||||
const handleCreatePlaylist = () => {
|
||||
if (newPlaylistName.trim()) {
|
||||
onPlaylistCreate(newPlaylistName);
|
||||
setNewPlaylistName("");
|
||||
disclosure.onClose();
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex direction="column" gap={2}>
|
||||
<Stack gap={2}>
|
||||
<Button
|
||||
onClick={() => onPlaylistSelect("All Songs")}
|
||||
colorScheme={selectedItem === "All Songs" ? "blue" : "gray"}
|
||||
size="sm"
|
||||
>
|
||||
All Songs
|
||||
</Button>
|
||||
@ -55,32 +55,72 @@ export const PlaylistManager: React.FC<PlaylistManagerProps> = ({
|
||||
key={playlist.name}
|
||||
onClick={() => onPlaylistSelect(playlist.name)}
|
||||
colorScheme={selectedItem === playlist.name ? "blue" : "gray"}
|
||||
size="sm"
|
||||
>
|
||||
{playlist.name}
|
||||
</Button>
|
||||
))}
|
||||
<Button onClick={disclosure.onOpen} colorScheme="green">
|
||||
<Button onClick={onOpen} colorScheme="green" size="sm">
|
||||
Create New Playlist
|
||||
</Button>
|
||||
</Flex>
|
||||
</Stack>
|
||||
|
||||
<Modal isOpen={disclosure.open} onClose={disclosure.onClose}>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>Create New Playlist</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody>
|
||||
<Modal
|
||||
isOpen={open}
|
||||
onClose={onClose}
|
||||
isCentered
|
||||
motionPreset="slideInBottom"
|
||||
>
|
||||
<ModalOverlay
|
||||
style={{
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.4)',
|
||||
backdropFilter: 'blur(2px)'
|
||||
}}
|
||||
/>
|
||||
<ModalContent
|
||||
padding={"1rem"}
|
||||
bg="gray.20"
|
||||
bgColor={"rgba(0, 0, 0, 1)"}
|
||||
maxW="500px"
|
||||
w="90%"
|
||||
borderRadius={25}
|
||||
boxShadow={100}
|
||||
margin="0 auto"
|
||||
marginTop="10%"
|
||||
>
|
||||
<ModalHeader color="gray.800" fontSize="lg" fontWeight="bold" pt={6} px={6}>
|
||||
Create New Playlist
|
||||
</ModalHeader>
|
||||
<CloseButton
|
||||
position="absolute"
|
||||
right={'1rem'}
|
||||
top={'1rem'}
|
||||
onClick={onClose}
|
||||
color="gray.600"
|
||||
/>
|
||||
<ModalBody px={6} py={8} paddingTop="2rem">
|
||||
<Input
|
||||
value={newPlaylistName}
|
||||
onChange={(e) => setNewPlaylistName(e.target.value)}
|
||||
placeholder="Playlist name"
|
||||
placeholder="Enter playlist name"
|
||||
autoFocus
|
||||
size="lg"
|
||||
color="gray.800"
|
||||
_placeholder={{ color: 'gray.400' }}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
handleCreatePlaylist();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button colorScheme="blue" mr={3} onClick={handleCreatePlaylist}>
|
||||
<ModalFooter px={6} py={4} borderTop="1px" borderColor="gray.100">
|
||||
<Button colorScheme="blue" mr={3} onClick={handleCreatePlaylist} size="md" px={8}>
|
||||
Create
|
||||
</Button>
|
||||
<Button onClick={disclosure.onClose}>Cancel</Button>
|
||||
<Button onClick={onClose} size="md" variant="ghost" color="gray.600">
|
||||
Cancel
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { Box, Flex, Text } from "@chakra-ui/react";
|
||||
import { Song } from "../types/interfaces";
|
||||
import { ChangeEvent } from "react";
|
||||
|
||||
interface SongListProps {
|
||||
songs: Song[];
|
||||
@ -9,22 +10,32 @@ interface SongListProps {
|
||||
|
||||
export const SongList: React.FC<SongListProps> = ({ songs, onAddToPlaylist, playlists }) => {
|
||||
return (
|
||||
<Flex direction="column" gap={4}>
|
||||
<Flex direction="column" gap={2}>
|
||||
{songs.map((song) => (
|
||||
<Box key={song.id} borderWidth="1px" borderRadius="lg" p={4} shadow="md">
|
||||
<Text fontWeight="bold">{song.title}</Text>
|
||||
<Text color="gray.500">{song.artist}</Text>
|
||||
<select
|
||||
onChange={(e) => onAddToPlaylist(song.id, e.target.value)}
|
||||
value=""
|
||||
>
|
||||
<option value="" disabled>Add to playlist</option>
|
||||
{playlists.map((playlist) => (
|
||||
<option key={playlist.name} value={playlist.name}>
|
||||
{playlist.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<Box key={song.id} borderWidth="1px" borderRadius="md" p={2} shadow="sm">
|
||||
<Flex justify="space-between" align="center">
|
||||
<Box>
|
||||
<Text fontWeight="bold" fontSize="sm">{song.title}</Text>
|
||||
<Text color="gray.500" fontSize="xs">{song.artist}</Text>
|
||||
</Box>
|
||||
<select
|
||||
onChange={(e: ChangeEvent<HTMLSelectElement>) => onAddToPlaylist(song.id, e.target.value)}
|
||||
value=""
|
||||
style={{
|
||||
padding: '0.25rem',
|
||||
fontSize: '0.875rem',
|
||||
borderRadius: '0.375rem',
|
||||
border: '1px solid #E2E8F0'
|
||||
}}
|
||||
>
|
||||
<option value="" disabled>Add to playlist</option>
|
||||
{playlists.map((playlist) => (
|
||||
<option key={playlist.name} value={playlist.name}>
|
||||
{playlist.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</Flex>
|
||||
</Box>
|
||||
))}
|
||||
</Flex>
|
||||
|
||||
@ -24,21 +24,20 @@ a:hover {
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
font-size: 2em;
|
||||
line-height: 1.1;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
padding: 0.4em 0.8em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user