253 lines
6.8 KiB
TypeScript
253 lines
6.8 KiB
TypeScript
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 { FormCovers } from '@/components/form/FormCovers';
|
|
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,
|
|
},
|
|
})
|
|
);
|
|
};
|
|
|
|
const onUriSelected = (uri: string) => {
|
|
if (isNullOrUndefined(albumIdInt)) {
|
|
return;
|
|
}
|
|
// no real need the wrapper must be able to set optional the uri our file ...
|
|
const plop = new File([], 'emptyFile.txt', {
|
|
type: 'text/plain',
|
|
});
|
|
store.update(
|
|
AlbumResource.uploadCover({
|
|
restConfig: session.getRestConfig(),
|
|
data: {
|
|
file: plop,
|
|
uri: uri,
|
|
},
|
|
params: {
|
|
id: albumIdInt,
|
|
},
|
|
})
|
|
);
|
|
};
|
|
|
|
const onFilesSelected = (files: File[]) => {
|
|
files.forEach((element) => {
|
|
console.log(`Select file: '${element.name}'`);
|
|
});
|
|
if (isNullOrUndefined(albumIdInt)) {
|
|
return;
|
|
}
|
|
store.update(
|
|
AlbumResource.uploadCover({
|
|
restConfig: session.getRestConfig(),
|
|
data: {
|
|
file: files[0],
|
|
uri: null,
|
|
},
|
|
params: {
|
|
id: albumIdInt,
|
|
},
|
|
})
|
|
);
|
|
};
|
|
const onRemoveCover = (index: number) => {
|
|
if (isNullOrUndefined(dataAlbum?.covers)) {
|
|
return;
|
|
}
|
|
if (isNullOrUndefined(albumIdInt)) {
|
|
return;
|
|
}
|
|
store.update(
|
|
AlbumResource.removeCover({
|
|
restConfig: session.getRestConfig(),
|
|
params: {
|
|
id: albumIdInt,
|
|
coverId: dataAlbum.covers[index],
|
|
},
|
|
})
|
|
);
|
|
};
|
|
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"
|
|
/>
|
|
<FormCovers
|
|
form={form}
|
|
variableName="covers"
|
|
onFilesSelected={onFilesSelected}
|
|
onUriSelected={onUriSelected}
|
|
onRemove={onRemoveCover}
|
|
/>
|
|
</>
|
|
)}
|
|
</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>
|
|
);
|
|
};
|