feat: Create unified Configuration page with tabs

- Combine Library Management and S3 Configuration into single page
- Add tabbed interface with icons for better organization
- Move S3 Configuration from Music Storage to main Configuration page
- Use FiDatabase and FiSettings icons for visual clarity
- Increase max width to accommodate both configurations
- Remove S3 Configuration tab from Music Storage page
- Create cleaner, more organized configuration experience

All configuration options are now centralized in one place with
a clean tabbed interface for better user experience.
This commit is contained in:
Geert Rademakes 2025-08-06 15:51:57 +02:00
parent 7cc890557d
commit d16217eac1
2 changed files with 94 additions and 54 deletions

View File

@ -1,9 +1,35 @@
import { Box, Heading, VStack, Text, Button, OrderedList, ListItem, useDisclosure, Modal, ModalOverlay, ModalContent, ModalHeader, ModalBody, ModalFooter, useToast, IconButton, Flex } from "@chakra-ui/react"; import {
Box,
Heading,
VStack,
Text,
Button,
OrderedList,
ListItem,
useDisclosure,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalBody,
ModalFooter,
useToast,
IconButton,
Flex,
Tabs,
TabList,
TabPanels,
Tab,
TabPanel,
Icon,
HStack,
} from "@chakra-ui/react";
import { ChevronLeftIcon } from "@chakra-ui/icons"; import { ChevronLeftIcon } from "@chakra-ui/icons";
import { FiDatabase, FiSettings } from 'react-icons/fi';
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { useXmlParser } from "../hooks/useXmlParser"; import { useXmlParser } from "../hooks/useXmlParser";
import { StyledFileInput } from "../components/StyledFileInput"; import { StyledFileInput } from "../components/StyledFileInput";
import { S3Configuration } from "./S3Configuration";
import { api } from "../services/api"; import { api } from "../services/api";
export function Configuration() { export function Configuration() {
@ -57,7 +83,7 @@ export function Configuration() {
}, },
}} }}
> >
<VStack spacing={8} align="stretch" maxW="2xl" mx="auto"> <VStack spacing={8} align="stretch" maxW="4xl" mx="auto">
<Flex align="center" gap={4}> <Flex align="center" gap={4}>
<IconButton <IconButton
icon={<ChevronLeftIcon boxSize={6} />} icon={<ChevronLeftIcon boxSize={6} />}
@ -70,51 +96,74 @@ export function Configuration() {
<Heading size="lg">Configuration</Heading> <Heading size="lg">Configuration</Heading>
</Flex> </Flex>
<Box bg="gray.800" p={6} borderRadius="lg" borderWidth="1px" borderColor="gray.700"> <Tabs variant="enclosed" colorScheme="blue">
<Heading size="md" mb={4}>Library Management</Heading> <TabList bg="gray.800" borderColor="gray.700">
<Tab color="gray.300" _selected={{ bg: "gray.700", color: "white", borderColor: "gray.600" }}>
<HStack spacing={2}>
<Icon as={FiDatabase} />
<Text>Library Management</Text>
</HStack>
</Tab>
<Tab color="gray.300" _selected={{ bg: "gray.700", color: "white", borderColor: "gray.600" }}>
<HStack spacing={2}>
<Icon as={FiSettings} />
<Text>S3 Configuration</Text>
</HStack>
</Tab>
</TabList>
<VStack spacing={6} align="stretch"> <TabPanels>
<Box> {/* Library Management Tab */}
<Text color="gray.400" mb={4}> <TabPanel bg="gray.800" p={6} borderRadius="lg" borderWidth="1px" borderColor="gray.700">
To get started with Rekordbox Reader, you'll need to export your library from Rekordbox and import it here. <VStack spacing={6} align="stretch">
</Text> <Box>
<Text color="gray.400" mb={4}>
To get started with Rekordbox Reader, you'll need to export your library from Rekordbox and import it here.
</Text>
<OrderedList spacing={3} color="gray.400" mb={6}> <OrderedList spacing={3} color="gray.400" mb={6}>
<ListItem> <ListItem>
Open Rekordbox and go to <Text as="span" color="gray.300" fontWeight="medium">File Export Collection in xml format</Text> Open Rekordbox and go to <Text as="span" color="gray.300" fontWeight="medium">File Export Collection in xml format</Text>
</ListItem> </ListItem>
<ListItem> <ListItem>
Choose a location to save your XML file Choose a location to save your XML file
</ListItem> </ListItem>
<ListItem> <ListItem>
Click the button below to import your Rekordbox XML file Click the button below to import your Rekordbox XML file
</ListItem> </ListItem>
</OrderedList> </OrderedList>
</Box> </Box>
<Box> <Box>
<Text fontWeight="medium" mb={2}>Import Library</Text> <Text fontWeight="medium" mb={2}>Import Library</Text>
<StyledFileInput /> <StyledFileInput />
</Box> </Box>
<Box borderTopWidth="1px" borderColor="gray.700" pt={6} mt={4}>
<Text fontWeight="medium" mb={2}>Reset Database</Text>
<Text color="gray.400" mb={4}>
Clear all songs and playlists from the database. This action cannot be undone.
</Text>
<Button
onClick={onOpen}
width="full"
colorScheme="red"
variant="outline"
>
Reset Database
</Button>
</Box>
</VStack>
</TabPanel>
{/* S3 Configuration Tab */}
<Box borderTopWidth="1px" borderColor="gray.700" pt={6} mt={4}> <TabPanel bg="gray.800" p={0}>
<Text fontWeight="medium" mb={2}>Reset Database</Text> <Box p={6}>
<Text color="gray.400" mb={4}> <S3Configuration />
Clear all songs and playlists from the database. This action cannot be undone. </Box>
</Text> </TabPanel>
<Button </TabPanels>
onClick={onOpen} </Tabs>
width="full"
colorScheme="red"
variant="outline"
>
Reset Database
</Button>
</Box>
</VStack>
</Box>
</VStack> </VStack>
{/* Reset Database Confirmation Modal */} {/* Reset Database Confirmation Modal */}

View File

@ -25,7 +25,6 @@ import {
import { FiPlay, FiTrash2, FiMusic, FiRefreshCw } from 'react-icons/fi'; import { FiPlay, FiTrash2, FiMusic, FiRefreshCw } from 'react-icons/fi';
import { MusicUpload } from '../components/MusicUpload'; import { MusicUpload } from '../components/MusicUpload';
import { SongMatching } from '../components/SongMatching'; import { SongMatching } from '../components/SongMatching';
import { S3Configuration } from './S3Configuration';
import { useMusicPlayer } from '../contexts/MusicPlayerContext'; import { useMusicPlayer } from '../contexts/MusicPlayerContext';
import type { Song } from '../types/interfaces'; import type { Song } from '../types/interfaces';
@ -241,9 +240,6 @@ export const MusicStorage: React.FC = () => {
<Tab color="gray.300" _selected={{ bg: "gray.700", color: "white", borderColor: "gray.600" }}> <Tab color="gray.300" _selected={{ bg: "gray.700", color: "white", borderColor: "gray.600" }}>
Song Matching Song Matching
</Tab> </Tab>
<Tab color="gray.300" _selected={{ bg: "gray.700", color: "white", borderColor: "gray.600" }}>
S3 Configuration
</Tab>
</TabList> </TabList>
<TabPanels flex={1} overflow="hidden"> <TabPanels flex={1} overflow="hidden">
@ -382,11 +378,6 @@ export const MusicStorage: React.FC = () => {
<TabPanel bg="gray.900" height="100%" overflowY="auto"> <TabPanel bg="gray.900" height="100%" overflowY="auto">
<SongMatching /> <SongMatching />
</TabPanel> </TabPanel>
{/* S3 Configuration Tab */}
<TabPanel bg="gray.900" height="100%" overflowY="auto">
<S3Configuration />
</TabPanel>
</TabPanels> </TabPanels>
</Tabs> </Tabs>
</VStack> </VStack>