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

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;