[FEAT] add edit of album and artist
Missing cover that might be studied
This commit is contained in:
parent
3377f80fbc
commit
091390e025
184
front2/src/components/popup/AlbumEditPopUp.tsx
Normal file
184
front2/src/components/popup/AlbumEditPopUp.tsx
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
import { useRef, useState } from 'react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Flex,
|
||||||
|
Modal,
|
||||||
|
ModalBody,
|
||||||
|
ModalCloseButton,
|
||||||
|
ModalContent,
|
||||||
|
ModalFooter,
|
||||||
|
ModalHeader,
|
||||||
|
ModalOverlay,
|
||||||
|
Text,
|
||||||
|
useDisclosure,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import {
|
||||||
|
MdAdminPanelSettings,
|
||||||
|
MdDeleteForever,
|
||||||
|
MdEdit,
|
||||||
|
MdWarning,
|
||||||
|
} from 'react-icons/md';
|
||||||
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { Album, AlbumResource } from '@/back-api';
|
||||||
|
import { FormGroup } from '@/components/form/FormGroup';
|
||||||
|
import { FormInput } from '@/components/form/FormInput';
|
||||||
|
import { FormTextarea } from '@/components/form/FormTextarea';
|
||||||
|
import { useFormidable } from '@/components/form/Formidable';
|
||||||
|
import { ConfirmPopUp } from '@/components/popup/ConfirmPopUp';
|
||||||
|
import { useAlbumService, useSpecificAlbum } from '@/service/Album';
|
||||||
|
import { useServiceContext } from '@/service/ServiceContext';
|
||||||
|
import { useCountTracksWithAlbumId } from '@/service/Track';
|
||||||
|
import { isNullOrUndefined } from '@/utils/validator';
|
||||||
|
|
||||||
|
export type AlbumEditPopUpProps = {};
|
||||||
|
|
||||||
|
export const AlbumEditPopUp = ({}: AlbumEditPopUpProps) => {
|
||||||
|
const { albumId } = useParams();
|
||||||
|
const albumIdInt = isNullOrUndefined(albumId)
|
||||||
|
? undefined
|
||||||
|
: parseInt(albumId, 10);
|
||||||
|
const { session } = useServiceContext();
|
||||||
|
const { countTracksOfAnAlbum } = useCountTracksWithAlbumId(albumIdInt);
|
||||||
|
const { store } = useAlbumService();
|
||||||
|
const { dataAlbum } = useSpecificAlbum(albumIdInt);
|
||||||
|
const [admin, setAdmin] = useState(false);
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const disclosure = useDisclosure();
|
||||||
|
const onClose = () => {
|
||||||
|
navigate('../../', { relative: 'path' });
|
||||||
|
};
|
||||||
|
const onRemove = () => {
|
||||||
|
if (isNullOrUndefined(albumIdInt)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
store.remove(
|
||||||
|
albumIdInt,
|
||||||
|
AlbumResource.remove({
|
||||||
|
restConfig: session.getRestConfig(),
|
||||||
|
params: {
|
||||||
|
id: albumIdInt,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
onClose();
|
||||||
|
};
|
||||||
|
const initialRef = useRef(null);
|
||||||
|
const finalRef = useRef(null);
|
||||||
|
const form = useFormidable<Album>({
|
||||||
|
initialValues: dataAlbum,
|
||||||
|
});
|
||||||
|
const onSave = async () => {
|
||||||
|
if (isNullOrUndefined(albumIdInt)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const dataThatNeedToBeUpdated = form.getDeltaData({ omit: ['covers'] });
|
||||||
|
console.log(`onSave = ${JSON.stringify(dataThatNeedToBeUpdated, null, 2)}`);
|
||||||
|
store.update(
|
||||||
|
AlbumResource.patch({
|
||||||
|
restConfig: session.getRestConfig(),
|
||||||
|
data: dataThatNeedToBeUpdated,
|
||||||
|
params: {
|
||||||
|
id: albumIdInt,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
initialFocusRef={initialRef}
|
||||||
|
finalFocusRef={finalRef}
|
||||||
|
closeOnOverlayClick={false}
|
||||||
|
onClose={onClose}
|
||||||
|
isOpen={true}
|
||||||
|
>
|
||||||
|
<ModalOverlay />
|
||||||
|
<ModalContent>
|
||||||
|
<ModalHeader>Edit Album</ModalHeader>
|
||||||
|
<ModalCloseButton ref={finalRef} />
|
||||||
|
|
||||||
|
<ModalBody pb={6} gap="0px" paddingLeft="18px">
|
||||||
|
{admin && (
|
||||||
|
<>
|
||||||
|
<FormGroup isRequired label="Id">
|
||||||
|
<Text>{dataAlbum?.id}</Text>
|
||||||
|
</FormGroup>
|
||||||
|
{countTracksOfAnAlbum !== 0 && (
|
||||||
|
<Flex paddingLeft="14px">
|
||||||
|
<MdWarning color="red.600" />
|
||||||
|
<Text paddingLeft="6px" color="red.600" fontWeight="bold">
|
||||||
|
Can not remove album {countTracksOfAnAlbum} track(s) depend
|
||||||
|
on it.
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
<FormGroup label="Action(s):">
|
||||||
|
<Button
|
||||||
|
onClick={disclosure.onOpen}
|
||||||
|
marginRight="auto"
|
||||||
|
variant="@danger"
|
||||||
|
isDisabled={countTracksOfAnAlbum !== 0}
|
||||||
|
>
|
||||||
|
<MdDeleteForever /> Remove Media
|
||||||
|
</Button>
|
||||||
|
</FormGroup>
|
||||||
|
<ConfirmPopUp
|
||||||
|
disclosure={disclosure}
|
||||||
|
title="Remove album"
|
||||||
|
body={`Remove Album [${dataAlbum?.id}] ${dataAlbum?.name}`}
|
||||||
|
confirmTitle="Remove"
|
||||||
|
onConfirm={onRemove}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{!admin && (
|
||||||
|
<>
|
||||||
|
<FormInput
|
||||||
|
form={form}
|
||||||
|
variableName="name"
|
||||||
|
isRequired
|
||||||
|
label="Title"
|
||||||
|
ref={initialRef}
|
||||||
|
/>
|
||||||
|
<FormTextarea
|
||||||
|
form={form}
|
||||||
|
variableName="description"
|
||||||
|
label="Description"
|
||||||
|
/>
|
||||||
|
<FormInput
|
||||||
|
form={form}
|
||||||
|
variableName="publication"
|
||||||
|
label="Publication"
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</ModalBody>
|
||||||
|
<ModalFooter>
|
||||||
|
<Button
|
||||||
|
onClick={() => setAdmin((value) => !value)}
|
||||||
|
marginRight="auto"
|
||||||
|
>
|
||||||
|
{admin ? (
|
||||||
|
<>
|
||||||
|
<MdEdit />
|
||||||
|
Edit
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<MdAdminPanelSettings />
|
||||||
|
Admin
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
{!admin && form.isFormModified && (
|
||||||
|
<Button colorScheme="blue" mr={3} onClick={onSave}>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Button onClick={onClose}>Cancel</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
187
front2/src/components/popup/ArtistEditPopUp.tsx
Normal file
187
front2/src/components/popup/ArtistEditPopUp.tsx
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
import { useRef, useState } from 'react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Flex,
|
||||||
|
Modal,
|
||||||
|
ModalBody,
|
||||||
|
ModalCloseButton,
|
||||||
|
ModalContent,
|
||||||
|
ModalFooter,
|
||||||
|
ModalHeader,
|
||||||
|
ModalOverlay,
|
||||||
|
Text,
|
||||||
|
useDisclosure,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import {
|
||||||
|
MdAdminPanelSettings,
|
||||||
|
MdDeleteForever,
|
||||||
|
MdEdit,
|
||||||
|
MdWarning,
|
||||||
|
} from 'react-icons/md';
|
||||||
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { Artist, ArtistResource } from '@/back-api';
|
||||||
|
import { FormGroup } from '@/components/form/FormGroup';
|
||||||
|
import { FormInput } from '@/components/form/FormInput';
|
||||||
|
import { FormTextarea } from '@/components/form/FormTextarea';
|
||||||
|
import { useFormidable } from '@/components/form/Formidable';
|
||||||
|
import { ConfirmPopUp } from '@/components/popup/ConfirmPopUp';
|
||||||
|
import { useArtistService, useSpecificArtist } from '@/service/Artist';
|
||||||
|
import { useServiceContext } from '@/service/ServiceContext';
|
||||||
|
import { useCountTracksOfAnArtist } from '@/service/Track';
|
||||||
|
import { isNullOrUndefined } from '@/utils/validator';
|
||||||
|
|
||||||
|
export type ArtistEditPopUpProps = {};
|
||||||
|
|
||||||
|
export const ArtistEditPopUp = ({}: ArtistEditPopUpProps) => {
|
||||||
|
const { artistId } = useParams();
|
||||||
|
const artistIdInt = isNullOrUndefined(artistId)
|
||||||
|
? undefined
|
||||||
|
: parseInt(artistId, 10);
|
||||||
|
const { session } = useServiceContext();
|
||||||
|
const { countTracksOnAnArtist } = useCountTracksOfAnArtist(artistIdInt);
|
||||||
|
const { store } = useArtistService();
|
||||||
|
const { dataArtist } = useSpecificArtist(artistIdInt);
|
||||||
|
const [admin, setAdmin] = useState(false);
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const disclosure = useDisclosure();
|
||||||
|
const onClose = () => {
|
||||||
|
navigate('../../', { relative: 'path' });
|
||||||
|
};
|
||||||
|
const onRemove = () => {
|
||||||
|
if (isNullOrUndefined(artistIdInt)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
store.remove(
|
||||||
|
artistIdInt,
|
||||||
|
ArtistResource.remove({
|
||||||
|
restConfig: session.getRestConfig(),
|
||||||
|
params: {
|
||||||
|
id: artistIdInt,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
onClose();
|
||||||
|
};
|
||||||
|
const initialRef = useRef(null);
|
||||||
|
const finalRef = useRef(null);
|
||||||
|
const form = useFormidable<Artist>({
|
||||||
|
initialValues: dataArtist,
|
||||||
|
});
|
||||||
|
const onSave = async () => {
|
||||||
|
if (isNullOrUndefined(artistIdInt)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const dataThatNeedToBeUpdated = form.getDeltaData({ omit: ['covers'] });
|
||||||
|
console.log(`onSave = ${JSON.stringify(dataThatNeedToBeUpdated, null, 2)}`);
|
||||||
|
store.update(
|
||||||
|
ArtistResource.patch({
|
||||||
|
restConfig: session.getRestConfig(),
|
||||||
|
data: dataThatNeedToBeUpdated,
|
||||||
|
params: {
|
||||||
|
id: artistIdInt,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
initialFocusRef={initialRef}
|
||||||
|
finalFocusRef={finalRef}
|
||||||
|
closeOnOverlayClick={false}
|
||||||
|
onClose={onClose}
|
||||||
|
isOpen={true}
|
||||||
|
>
|
||||||
|
<ModalOverlay />
|
||||||
|
<ModalContent>
|
||||||
|
<ModalHeader>Edit Artist</ModalHeader>
|
||||||
|
<ModalCloseButton ref={finalRef} />
|
||||||
|
|
||||||
|
<ModalBody pb={6} gap="0px" paddingLeft="18px">
|
||||||
|
{admin && (
|
||||||
|
<>
|
||||||
|
<FormGroup isRequired label="Id">
|
||||||
|
<Text>{dataArtist?.id}</Text>
|
||||||
|
</FormGroup>
|
||||||
|
{countTracksOnAnArtist !== 0 && (
|
||||||
|
<Flex paddingLeft="14px">
|
||||||
|
<MdWarning color="red.600" />
|
||||||
|
<Text paddingLeft="6px" color="red.600" fontWeight="bold">
|
||||||
|
Can not remove artist {countTracksOnAnArtist} track(s)
|
||||||
|
depend on it.
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
<FormGroup label="Action(s):">
|
||||||
|
<Button
|
||||||
|
onClick={disclosure.onOpen}
|
||||||
|
marginRight="auto"
|
||||||
|
variant="@danger"
|
||||||
|
isDisabled={countTracksOnAnArtist !== 0}
|
||||||
|
>
|
||||||
|
<MdDeleteForever /> Remove Media
|
||||||
|
</Button>
|
||||||
|
</FormGroup>
|
||||||
|
<ConfirmPopUp
|
||||||
|
disclosure={disclosure}
|
||||||
|
title="Remove artist"
|
||||||
|
body={`Remove Artist [${dataArtist?.id}] ${dataArtist?.name}`}
|
||||||
|
confirmTitle="Remove"
|
||||||
|
onConfirm={onRemove}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{!admin && (
|
||||||
|
<>
|
||||||
|
<FormInput
|
||||||
|
form={form}
|
||||||
|
variableName="name"
|
||||||
|
isRequired
|
||||||
|
label="Artist name"
|
||||||
|
ref={initialRef}
|
||||||
|
/>
|
||||||
|
<FormTextarea
|
||||||
|
form={form}
|
||||||
|
variableName="description"
|
||||||
|
label="Description"
|
||||||
|
/>
|
||||||
|
<FormInput
|
||||||
|
form={form}
|
||||||
|
variableName="firstName"
|
||||||
|
label="First Name"
|
||||||
|
/>
|
||||||
|
<FormInput form={form} variableName="surname" label="SurName" />
|
||||||
|
<FormInput form={form} variableName="birth" label="Birth date" />
|
||||||
|
<FormInput form={form} variableName="death" label="Death date" />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</ModalBody>
|
||||||
|
<ModalFooter>
|
||||||
|
<Button
|
||||||
|
onClick={() => setAdmin((value) => !value)}
|
||||||
|
marginRight="auto"
|
||||||
|
>
|
||||||
|
{admin ? (
|
||||||
|
<>
|
||||||
|
<MdEdit />
|
||||||
|
Edit
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<MdAdminPanelSettings />
|
||||||
|
Admin
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
{!admin && form.isFormModified && (
|
||||||
|
<Button colorScheme="blue" mr={3} onClick={onSave}>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Button onClick={onClose}>Cancel</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
@ -1,9 +1,7 @@
|
|||||||
import { useEffect, useRef, useState } from 'react';
|
import { useRef, useState } from 'react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
IconButton,
|
|
||||||
Input,
|
|
||||||
Modal,
|
Modal,
|
||||||
ModalBody,
|
ModalBody,
|
||||||
ModalCloseButton,
|
ModalCloseButton,
|
||||||
@ -11,21 +9,10 @@ import {
|
|||||||
ModalFooter,
|
ModalFooter,
|
||||||
ModalHeader,
|
ModalHeader,
|
||||||
ModalOverlay,
|
ModalOverlay,
|
||||||
NumberDecrementStepper,
|
|
||||||
NumberIncrementStepper,
|
|
||||||
NumberInput,
|
|
||||||
NumberInputField,
|
|
||||||
NumberInputStepper,
|
|
||||||
Text,
|
Text,
|
||||||
Textarea,
|
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import {
|
import { MdAdminPanelSettings, MdDeleteForever, MdEdit } from 'react-icons/md';
|
||||||
MdAdminPanelSettings,
|
|
||||||
MdDeleteForever,
|
|
||||||
MdEdit,
|
|
||||||
MdRemove,
|
|
||||||
} from 'react-icons/md';
|
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
|
||||||
import { Track, TrackResource } from '@/back-api';
|
import { Track, TrackResource } from '@/back-api';
|
||||||
@ -37,8 +24,6 @@ import { FormSelectMultiple } from '@/components/form/FormSelectMultiple';
|
|||||||
import { FormTextarea } from '@/components/form/FormTextarea';
|
import { FormTextarea } from '@/components/form/FormTextarea';
|
||||||
import { useFormidable } from '@/components/form/Formidable';
|
import { useFormidable } from '@/components/form/Formidable';
|
||||||
import { ConfirmPopUp } from '@/components/popup/ConfirmPopUp';
|
import { ConfirmPopUp } from '@/components/popup/ConfirmPopUp';
|
||||||
import { SelectMultiple } from '@/components/select/SelectMultiple';
|
|
||||||
import { SelectSingle } from '@/components/select/SelectSingle';
|
|
||||||
import { useOrderedAlbums } from '@/service/Album';
|
import { useOrderedAlbums } from '@/service/Album';
|
||||||
import { useOrderedArtists } from '@/service/Artist';
|
import { useOrderedArtists } from '@/service/Artist';
|
||||||
import { useOrderedGenders } from '@/service/Gender';
|
import { useOrderedGenders } from '@/service/Gender';
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
import { Suspense } from 'react';
|
|
||||||
|
|
||||||
import { Flex, Text } from '@chakra-ui/react';
|
import { Flex, Text } from '@chakra-ui/react';
|
||||||
import { LuMusic2, LuPlay } from 'react-icons/lu';
|
import { LuMusic2, LuPlay } from 'react-icons/lu';
|
||||||
import { useNavigate } from 'react-router-dom';
|
|
||||||
|
|
||||||
import { Track } from '@/back-api';
|
import { Track } from '@/back-api';
|
||||||
import { Covers } from '@/components/Cover';
|
import { Covers } from '@/components/Cover';
|
||||||
import { ContextMenu, MenuElement } from '@/components/contextMenu/ContextMenu';
|
import { ContextMenu, MenuElement } from '@/components/contextMenu/ContextMenu';
|
||||||
import { DisplayTrackSkeleton } from '@/components/track/DisplayTrackSkeleton';
|
|
||||||
import { useActivePlaylistService } from '@/service/ActivePlaylist';
|
import { useActivePlaylistService } from '@/service/ActivePlaylist';
|
||||||
|
|
||||||
export type DisplayTrackProps = {
|
export type DisplayTrackProps = {
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
import { Box, Flex, Text } from '@chakra-ui/react';
|
import { Box, Button, Flex, Text } from '@chakra-ui/react';
|
||||||
import { LuDisc3 } from 'react-icons/lu';
|
import { LuDisc3 } from 'react-icons/lu';
|
||||||
|
import { MdEdit } from 'react-icons/md';
|
||||||
import { Route, Routes, useNavigate, useParams } from 'react-router-dom';
|
import { Route, Routes, useNavigate, useParams } from 'react-router-dom';
|
||||||
|
|
||||||
import { Covers } from '@/components/Cover';
|
import { Covers } from '@/components/Cover';
|
||||||
import { EmptyEnd } from '@/components/EmptyEnd';
|
import { EmptyEnd } from '@/components/EmptyEnd';
|
||||||
import { PageLayout } from '@/components/Layout/PageLayout';
|
import { PageLayout } from '@/components/Layout/PageLayout';
|
||||||
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
|
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
|
||||||
import { TopBar } from '@/components/TopBar/TopBar';
|
import { BUTTON_TOP_BAR_PROPERTY, TopBar } from '@/components/TopBar/TopBar';
|
||||||
|
import { AlbumEditPopUp } from '@/components/popup/AlbumEditPopUp';
|
||||||
import { TrackEditPopUp } from '@/components/popup/TrackEditPopUp';
|
import { TrackEditPopUp } from '@/components/popup/TrackEditPopUp';
|
||||||
import { DisplayTrack } from '@/components/track/DisplayTrack';
|
import { DisplayTrack } from '@/components/track/DisplayTrack';
|
||||||
import { DisplayTrackFull } from '@/components/track/DisplayTrackFull';
|
import { DisplayTrackFull } from '@/components/track/DisplayTrackFull';
|
||||||
@ -53,7 +55,16 @@ export const AlbumDetailPage = () => {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar title="Album detail" />
|
<TopBar title="Album detail">
|
||||||
|
<Button
|
||||||
|
{...BUTTON_TOP_BAR_PROPERTY}
|
||||||
|
onClick={() =>
|
||||||
|
navigate(`/album/${albumId}/edit-album/${dataAlbum.id}`)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<MdEdit />
|
||||||
|
</Button>
|
||||||
|
</TopBar>
|
||||||
<PageLayout>
|
<PageLayout>
|
||||||
<Flex
|
<Flex
|
||||||
direction="row"
|
direction="row"
|
||||||
@ -108,7 +119,7 @@ export const AlbumDetailPage = () => {
|
|||||||
{
|
{
|
||||||
name: 'Edit',
|
name: 'Edit',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
navigate(`/album/${albumId}/edit/${data.id}`);
|
navigate(`/album/${albumId}/edit-track/${data.id}`);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ name: 'Add Playlist', onClick: () => {} },
|
{ name: 'Add Playlist', onClick: () => {} },
|
||||||
@ -119,7 +130,8 @@ export const AlbumDetailPage = () => {
|
|||||||
<EmptyEnd />
|
<EmptyEnd />
|
||||||
</Flex>
|
</Flex>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="edit/:trackId" element={<TrackEditPopUp />} />
|
<Route path="edit-track/:trackId" element={<TrackEditPopUp />} />
|
||||||
|
<Route path="edit-album/:albumId" element={<AlbumEditPopUp />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</PageLayout>
|
</PageLayout>
|
||||||
</>
|
</>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Box, Button, Flex, Text } from '@chakra-ui/react';
|
import { Box, Button, Flex, Text } from '@chakra-ui/react';
|
||||||
import { LuDisc3, LuUser } from 'react-icons/lu';
|
import { LuDisc3, LuUser } from 'react-icons/lu';
|
||||||
import { MdPerson } from 'react-icons/md';
|
import { MdEdit, MdPerson } from 'react-icons/md';
|
||||||
import { Route, Routes, useNavigate, useParams } from 'react-router-dom';
|
import { Route, Routes, useNavigate, useParams } from 'react-router-dom';
|
||||||
|
|
||||||
import { Covers } from '@/components/Cover';
|
import { Covers } from '@/components/Cover';
|
||||||
@ -8,6 +8,7 @@ import { EmptyEnd } from '@/components/EmptyEnd';
|
|||||||
import { PageLayout } from '@/components/Layout/PageLayout';
|
import { PageLayout } from '@/components/Layout/PageLayout';
|
||||||
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
|
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
|
||||||
import { BUTTON_TOP_BAR_PROPERTY, TopBar } from '@/components/TopBar/TopBar';
|
import { BUTTON_TOP_BAR_PROPERTY, TopBar } from '@/components/TopBar/TopBar';
|
||||||
|
import { AlbumEditPopUp } from '@/components/popup/AlbumEditPopUp';
|
||||||
import { TrackEditPopUp } from '@/components/popup/TrackEditPopUp';
|
import { TrackEditPopUp } from '@/components/popup/TrackEditPopUp';
|
||||||
import { DisplayTrack } from '@/components/track/DisplayTrack';
|
import { DisplayTrack } from '@/components/track/DisplayTrack';
|
||||||
import { useActivePlaylistService } from '@/service/ActivePlaylist';
|
import { useActivePlaylistService } from '@/service/ActivePlaylist';
|
||||||
@ -57,21 +58,31 @@ export const ArtistAlbumDetailPage = () => {
|
|||||||
<>
|
<>
|
||||||
<TopBar title={dataArtist ? undefined : 'Album detail'}>
|
<TopBar title={dataArtist ? undefined : 'Album detail'}>
|
||||||
{dataArtist && (
|
{dataArtist && (
|
||||||
<Button
|
<>
|
||||||
{...BUTTON_TOP_BAR_PROPERTY}
|
<Button
|
||||||
marginRight="auto"
|
{...BUTTON_TOP_BAR_PROPERTY}
|
||||||
onClick={() => navigate(`/artist/${dataArtist.id}`)}
|
marginRight="auto"
|
||||||
>
|
onClick={() => navigate(`/artist/${dataArtist.id}`)}
|
||||||
<Covers
|
>
|
||||||
data={dataArtist?.covers}
|
<Covers
|
||||||
size="35px"
|
data={dataArtist?.covers}
|
||||||
borderRadius="full"
|
size="35px"
|
||||||
iconEmpty={<MdPerson height="full" />}
|
borderRadius="full"
|
||||||
/>
|
iconEmpty={<MdPerson height="full" />}
|
||||||
<Text fontSize="24px" fontWeight="bold">
|
/>
|
||||||
{dataArtist?.name}
|
<Text fontSize="24px" fontWeight="bold">
|
||||||
</Text>
|
{dataArtist?.name}
|
||||||
</Button>
|
</Text>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
{...BUTTON_TOP_BAR_PROPERTY}
|
||||||
|
onClick={() =>
|
||||||
|
navigate(`/album/${albumId}/edit-album/${dataAlbum.id}`)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<MdEdit />
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</TopBar>
|
</TopBar>
|
||||||
<PageLayout>
|
<PageLayout>
|
||||||
@ -129,7 +140,7 @@ export const ArtistAlbumDetailPage = () => {
|
|||||||
name: 'Edit',
|
name: 'Edit',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
navigate(
|
navigate(
|
||||||
`/artist/${artistIdInt}/album/${albumId}/edit/${data.id}`
|
`/artist/${artistIdInt}/album/${albumId}/edit-track/${data.id}`
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -141,7 +152,8 @@ export const ArtistAlbumDetailPage = () => {
|
|||||||
<EmptyEnd />
|
<EmptyEnd />
|
||||||
</Flex>
|
</Flex>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="edit/:trackId" element={<TrackEditPopUp />} />
|
<Route path="edit-track/:trackId" element={<TrackEditPopUp />} />
|
||||||
|
<Route path="edit-album/:albumId" element={<AlbumEditPopUp />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</PageLayout>
|
</PageLayout>
|
||||||
</>
|
</>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Button, Flex, Text, Wrap, WrapItem } from '@chakra-ui/react';
|
import { Button, Flex, Text, Wrap, WrapItem } from '@chakra-ui/react';
|
||||||
import { LuUser } from 'react-icons/lu';
|
import { LuUser } from 'react-icons/lu';
|
||||||
import { MdGroup } from 'react-icons/md';
|
import { MdEdit, MdGroup } from 'react-icons/md';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { Route, Routes, useNavigate, useParams } from 'react-router-dom';
|
||||||
|
|
||||||
import { Covers } from '@/components/Cover';
|
import { Covers } from '@/components/Cover';
|
||||||
import { EmptyEnd } from '@/components/EmptyEnd';
|
import { EmptyEnd } from '@/components/EmptyEnd';
|
||||||
@ -9,6 +9,7 @@ import { PageLayout } from '@/components/Layout/PageLayout';
|
|||||||
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
|
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
|
||||||
import { BUTTON_TOP_BAR_PROPERTY, TopBar } from '@/components/TopBar/TopBar';
|
import { BUTTON_TOP_BAR_PROPERTY, TopBar } from '@/components/TopBar/TopBar';
|
||||||
import { DisplayAlbumId } from '@/components/album/DisplayAlbumId';
|
import { DisplayAlbumId } from '@/components/album/DisplayAlbumId';
|
||||||
|
import { ArtistEditPopUp } from '@/components/popup/ArtistEditPopUp';
|
||||||
import { useSpecificArtist } from '@/service/Artist';
|
import { useSpecificArtist } from '@/service/Artist';
|
||||||
import { useAlbumIdsOfAnArtist } from '@/service/Track';
|
import { useAlbumIdsOfAnArtist } from '@/service/Track';
|
||||||
import { useThemeMode } from '@/utils/theme-tools';
|
import { useThemeMode } from '@/utils/theme-tools';
|
||||||
@ -37,16 +38,27 @@ export const ArtistDetailPage = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar>
|
<TopBar>
|
||||||
<Button
|
<>
|
||||||
{...BUTTON_TOP_BAR_PROPERTY}
|
<Button
|
||||||
marginRight="auto"
|
{...BUTTON_TOP_BAR_PROPERTY}
|
||||||
onClick={() => navigate(`/artist/all`)}
|
marginRight="auto"
|
||||||
>
|
onClick={() => navigate(`/artist/all`)}
|
||||||
<MdGroup height="full" />
|
>
|
||||||
<Text fontSize="24px" fontWeight="bold">
|
<MdGroup height="full" />
|
||||||
Artists
|
<Text fontSize="24px" fontWeight="bold">
|
||||||
</Text>
|
Artists
|
||||||
</Button>
|
</Text>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
{...BUTTON_TOP_BAR_PROPERTY}
|
||||||
|
onClick={() =>
|
||||||
|
navigate(`/artist/${artistId}/edit-artist/${artistId}`)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<MdEdit />
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
</TopBar>
|
</TopBar>
|
||||||
<PageLayout>
|
<PageLayout>
|
||||||
<Flex
|
<Flex
|
||||||
@ -97,6 +109,9 @@ export const ArtistDetailPage = () => {
|
|||||||
))}
|
))}
|
||||||
</Wrap>
|
</Wrap>
|
||||||
<EmptyEnd />
|
<EmptyEnd />
|
||||||
|
<Routes>
|
||||||
|
<Route path="edit-artist/:artistId" element={<ArtistEditPopUp />} />
|
||||||
|
</Routes>
|
||||||
</PageLayout>
|
</PageLayout>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -10,7 +10,7 @@ export const ArtistRoutes = () => {
|
|||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<Navigate to="all" replace />} />
|
<Route path="/" element={<Navigate to="all" replace />} />
|
||||||
<Route path="all" element={<ArtistsPage />} />
|
<Route path="all" element={<ArtistsPage />} />
|
||||||
<Route path=":artistId" element={<ArtistDetailPage />} />
|
<Route path=":artistId/*" element={<ArtistDetailPage />} />
|
||||||
<Route
|
<Route
|
||||||
path=":artistId/album/:albumId/*"
|
path=":artistId/album/:albumId/*"
|
||||||
element={<ArtistAlbumDetailPage />}
|
element={<ArtistAlbumDetailPage />}
|
||||||
|
@ -73,7 +73,7 @@ export const useTracksOfAnArtist = (idArtist?: number) => {
|
|||||||
* @param id - Id of the artist.
|
* @param id - Id of the artist.
|
||||||
* @returns The number of track present in this artist
|
* @returns The number of track present in this artist
|
||||||
*/
|
*/
|
||||||
export const useCountTracksOfAnArtist = (idArtist: number) => {
|
export const useCountTracksOfAnArtist = (idArtist?: number) => {
|
||||||
const { isLoading, tracksOnAnAlbum } = useTracksOfAnAlbum(idArtist);
|
const { isLoading, tracksOnAnAlbum } = useTracksOfAnAlbum(idArtist);
|
||||||
const countTracksOnAnArtist = useMemo(
|
const countTracksOnAnArtist = useMemo(
|
||||||
() => tracksOnAnAlbum?.length ?? 0,
|
() => tracksOnAnAlbum?.length ?? 0,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user