|
|
@ -1,23 +1,12 @@ |
|
|
|
import React, { useState, useEffect } from 'react'; |
|
|
|
import React, { useState, useEffect } from 'react'; |
|
|
|
|
|
|
|
|
|
|
|
import { Button, Paper } from '@material-ui/core'; |
|
|
|
import { Paper } from '@material-ui/core'; |
|
|
|
|
|
|
|
|
|
|
|
import * as serverApi from './api'; |
|
|
|
import * as serverApi from './api'; |
|
|
|
import EditSongDialog, { SongProperties } from './components/EditSongDialog'; |
|
|
|
|
|
|
|
import EditArtistDialog, { ArtistProperties } from './components/EditArtistDialog'; |
|
|
|
|
|
|
|
import AppBar, { ActiveTab as AppBarActiveTab } from './components/AppBar'; |
|
|
|
import AppBar, { ActiveTab as AppBarActiveTab } from './components/AppBar'; |
|
|
|
import ItemList from './components/ItemList'; |
|
|
|
import ItemList from './components/ItemList'; |
|
|
|
import ItemListItem from './components/ItemListItem'; |
|
|
|
import ItemListItem from './components/ItemListItem'; |
|
|
|
import { SongDisplayItem, LoadingSongDisplayItem, DisplayItem } from './types/DisplayItem'; |
|
|
|
import { SongDisplayItem } from './types/DisplayItem'; |
|
|
|
|
|
|
|
|
|
|
|
interface SongEntry { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
interface ArtistEntry { |
|
|
|
|
|
|
|
name: String, |
|
|
|
|
|
|
|
id: Number, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
interface SongItemProps { |
|
|
|
interface SongItemProps { |
|
|
|
id: Number, |
|
|
|
id: Number, |
|
|
@ -82,147 +71,14 @@ function SongList() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function App() { |
|
|
|
function App() { |
|
|
|
const [songs, setSongs] = useState<SongEntry[]>([]); |
|
|
|
|
|
|
|
const [artists, setArtists] = useState<ArtistEntry[]>([]); |
|
|
|
|
|
|
|
const [editSongDialogOpen, setEditSongDialogOpen] = useState<boolean>(false); |
|
|
|
|
|
|
|
const [songDialogProperties, setSongDialogProperties] = useState<SongProperties>({ |
|
|
|
|
|
|
|
title: "", |
|
|
|
|
|
|
|
artistId: -1, |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
const [editArtistDialogOpen, setEditArtistDialogOpen] = useState<boolean>(false); |
|
|
|
|
|
|
|
const [artistDialogProperties, setArtistDialogProperties] = useState<ArtistProperties>({ |
|
|
|
|
|
|
|
name: "" |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const updateSongs = () => { |
|
|
|
|
|
|
|
return fetch(serverApi.QuerySongsEndpoint) |
|
|
|
|
|
|
|
// .then((response: any) => response.json())
|
|
|
|
|
|
|
|
// .then((result: serverApi.ListSongsResponse) => {
|
|
|
|
|
|
|
|
// setSongs(result.map((item: serverApi.ListSongsResponseItem) => {
|
|
|
|
|
|
|
|
// return {
|
|
|
|
|
|
|
|
// title: item.title,
|
|
|
|
|
|
|
|
// artistName: item.artistName
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
// }));
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const fetchArtists = () => { |
|
|
|
|
|
|
|
return fetch(serverApi.QueryArtistsEndpoint) |
|
|
|
|
|
|
|
// .then((response: any) => response.json())
|
|
|
|
|
|
|
|
// .then((result: serverApi.ListArtistsResponse) => {
|
|
|
|
|
|
|
|
// return result.map((item: serverApi.ListArtistsResponseItem) => {
|
|
|
|
|
|
|
|
// return {
|
|
|
|
|
|
|
|
// name: item.name,
|
|
|
|
|
|
|
|
// id: item.id,
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const updateArtists = () => { |
|
|
|
|
|
|
|
return fetchArtists() |
|
|
|
|
|
|
|
// .then((artists: any[]) => {
|
|
|
|
|
|
|
|
// setArtists(artists);
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const createSong = (p: SongProperties) => { |
|
|
|
|
|
|
|
if (!p.artistId) { |
|
|
|
|
|
|
|
throw "Undefined artist ID for song to be created."; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
const request: serverApi.CreateSongRequest = { |
|
|
|
|
|
|
|
title: p.title, |
|
|
|
|
|
|
|
artistIds: [p.artistId], |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
const requestOpts = { |
|
|
|
|
|
|
|
method: 'POST', |
|
|
|
|
|
|
|
headers: { 'Content-Type': 'application/json' }, |
|
|
|
|
|
|
|
body: JSON.stringify(request) |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
return fetch(serverApi.CreateSongEndpoint, requestOpts) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const createArtist = (p: ArtistProperties) => { |
|
|
|
|
|
|
|
const request: serverApi.CreateArtistRequest = { |
|
|
|
|
|
|
|
name: p.name, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
const requestOpts = { |
|
|
|
|
|
|
|
method: 'POST', |
|
|
|
|
|
|
|
headers: { 'Content-Type': 'application/json' }, |
|
|
|
|
|
|
|
body: JSON.stringify(request) |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
return fetch(serverApi.CreateArtistEndpoint, requestOpts) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const openCreateSongDialog = () => { |
|
|
|
|
|
|
|
setSongDialogProperties({ |
|
|
|
|
|
|
|
title: "", |
|
|
|
|
|
|
|
artistId: -1, |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
setEditSongDialogOpen(true); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const onSubmitCreateSongDialog = () => { |
|
|
|
|
|
|
|
createSong(songDialogProperties) |
|
|
|
|
|
|
|
.then(updateSongs) |
|
|
|
|
|
|
|
.then(() => { setEditSongDialogOpen(false); }) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const openCreateArtistDialog = () => { |
|
|
|
|
|
|
|
setArtistDialogProperties({ |
|
|
|
|
|
|
|
name: "", |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
setEditArtistDialogOpen(true); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const onSubmitCreateArtistDialog = () => { |
|
|
|
|
|
|
|
createArtist(artistDialogProperties) |
|
|
|
|
|
|
|
.then(updateArtists) |
|
|
|
|
|
|
|
.then(() => { setEditArtistDialogOpen(false); }) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { updateSongs(); }, []); |
|
|
|
|
|
|
|
useEffect(() => { updateArtists(); }, []); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const testSong: SongDisplayItem = { |
|
|
|
|
|
|
|
title: "My Song", |
|
|
|
|
|
|
|
artistNames: ["First dude", "Second dude"] |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const testLoadingSong: LoadingSongDisplayItem = { |
|
|
|
|
|
|
|
loadingSong: true |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const [appBarActiveTab, setAppBarActiveTab] = React.useState(AppBarActiveTab.Songs); |
|
|
|
const [appBarActiveTab, setAppBarActiveTab] = React.useState(AppBarActiveTab.Songs); |
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
return ( |
|
|
|
<div style={{ maxWidth: '100%' }}> |
|
|
|
<div style={{ maxWidth: '100%' }}> |
|
|
|
<AppBar activeTab={appBarActiveTab} onActiveTabChange={setAppBarActiveTab} /> |
|
|
|
<AppBar activeTab={appBarActiveTab} onActiveTabChange={setAppBarActiveTab} /> |
|
|
|
<Paper> |
|
|
|
<Paper> |
|
|
|
{/* <ItemList items={[testSong, testLoadingSong]}> |
|
|
|
|
|
|
|
<ItemListItem item={testSong} /> |
|
|
|
|
|
|
|
<ItemListItem item={testLoadingSong} /> |
|
|
|
|
|
|
|
</ItemList> */} |
|
|
|
|
|
|
|
{(appBarActiveTab === AppBarActiveTab.Songs) && <SongList />} |
|
|
|
{(appBarActiveTab === AppBarActiveTab.Songs) && <SongList />} |
|
|
|
</Paper> |
|
|
|
</Paper> |
|
|
|
<Button variant="contained" onClick={openCreateSongDialog}>Create Song</Button> |
|
|
|
|
|
|
|
<Button variant="contained" onClick={openCreateArtistDialog}>Create Artist</Button> |
|
|
|
|
|
|
|
<EditSongDialog |
|
|
|
|
|
|
|
dialogOpen={editSongDialogOpen} |
|
|
|
|
|
|
|
onClose={() => { setEditSongDialogOpen(false); }} |
|
|
|
|
|
|
|
onChangeSongProperties={(props: SongProperties) => setSongDialogProperties(props)} |
|
|
|
|
|
|
|
songProperties={songDialogProperties} |
|
|
|
|
|
|
|
onSubmit={onSubmitCreateSongDialog} |
|
|
|
|
|
|
|
artists={artists} |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
<EditArtistDialog |
|
|
|
|
|
|
|
dialogOpen={editArtistDialogOpen} |
|
|
|
|
|
|
|
onClose={() => { setEditArtistDialogOpen(false); }} |
|
|
|
|
|
|
|
onChangeArtistProperties={(props: ArtistProperties) => setArtistDialogProperties(props)} |
|
|
|
|
|
|
|
artistProperties={artistDialogProperties} |
|
|
|
|
|
|
|
onSubmit={onSubmitCreateArtistDialog} |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|