You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
4.3 KiB
146 lines
4.3 KiB
import React, { useState, useEffect } from 'react'; |
|
|
|
import { Box, Button } from '@material-ui/core'; |
|
|
|
import * as serverApi from './api'; |
|
import SongTable, { Entry as SongEntry } from './components/SongTable'; |
|
import ArtistTable, { Entry as ArtistEntry } from './components/ArtistTable'; |
|
import EditSongDialog, { SongProperties } from './components/EditSongDialog'; |
|
import EditArtistDialog, { ArtistProperties } from './components/EditArtistDialog'; |
|
|
|
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.ListSongsEndpoint) |
|
.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.ListArtistsEndpoint) |
|
.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, |
|
artistId: 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(); }, []); |
|
|
|
return ( |
|
<div style={{ maxWidth: '100%' }}> |
|
<Button variant="contained" onClick={openCreateSongDialog}>Create Song</Button> |
|
<Button variant="contained" onClick={openCreateArtistDialog}>Create Artist</Button> |
|
<Box> |
|
<SongTable |
|
songs={songs} |
|
/> |
|
<ArtistTable |
|
artists={artists} |
|
/> |
|
</Box> |
|
<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> |
|
); |
|
} |
|
|
|
export default App; |