|
|
@ -1,14 +1,14 @@ |
|
|
|
import React, { useState, useEffect } from 'react'; |
|
|
|
import React, { useState, useEffect } from 'react'; |
|
|
|
|
|
|
|
|
|
|
|
import { Box, Button, Paper } from '@material-ui/core'; |
|
|
|
import { Button, Paper } from '@material-ui/core'; |
|
|
|
|
|
|
|
|
|
|
|
import * as serverApi from './api'; |
|
|
|
import * as serverApi from './api'; |
|
|
|
import EditSongDialog, { SongProperties } from './components/EditSongDialog'; |
|
|
|
import EditSongDialog, { SongProperties } from './components/EditSongDialog'; |
|
|
|
import EditArtistDialog, { ArtistProperties } from './components/EditArtistDialog'; |
|
|
|
import EditArtistDialog, { ArtistProperties } from './components/EditArtistDialog'; |
|
|
|
import AppBar 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 } from './types/DisplayItem'; |
|
|
|
import { SongDisplayItem, LoadingSongDisplayItem, DisplayItem } from './types/DisplayItem'; |
|
|
|
|
|
|
|
|
|
|
|
interface SongEntry { |
|
|
|
interface SongEntry { |
|
|
|
|
|
|
|
|
|
|
@ -19,6 +19,68 @@ interface ArtistEntry { |
|
|
|
id: Number, |
|
|
|
id: Number, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
interface SongItemProps { |
|
|
|
|
|
|
|
id: Number, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function SongItem(props: SongItemProps) { |
|
|
|
|
|
|
|
const [songDisplayItem, setSongDisplayItem] = React.useState<SongDisplayItem | undefined>(undefined); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const updateSong = async () => { |
|
|
|
|
|
|
|
const response:any = await fetch(serverApi.SongDetailsEndpoint.replace(':id', props.id.toString())); |
|
|
|
|
|
|
|
const json:any = await response.json(); |
|
|
|
|
|
|
|
const title:String|undefined = json.title; |
|
|
|
|
|
|
|
const artistIds:Number[]|undefined = json.artistIds; |
|
|
|
|
|
|
|
const artistNamesPromises:Promise<String>[]|undefined = artistIds && artistIds.map((id:Number) => { |
|
|
|
|
|
|
|
return fetch(serverApi.ArtistDetailsEndpoint.replace(':id', id.toString())) |
|
|
|
|
|
|
|
.then((response:any) => response.json()) |
|
|
|
|
|
|
|
.then((json:any) => json.name); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
const artistNames:String[]|undefined = artistNamesPromises && await Promise.all(artistNamesPromises); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return { |
|
|
|
|
|
|
|
title: title ? title : "Unknown", |
|
|
|
|
|
|
|
artistNames: artistNames ? artistNames : [] |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
|
|
|
updateSong().then((song:SongDisplayItem) => { setSongDisplayItem(song); }); |
|
|
|
|
|
|
|
}, []); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return <ItemListItem item={songDisplayItem ? songDisplayItem : { |
|
|
|
|
|
|
|
loadingSong: true |
|
|
|
|
|
|
|
}} />; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function SongList() { |
|
|
|
|
|
|
|
const [songs, setSongs] = useState<Number[]>([]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
React.useEffect(() => { |
|
|
|
|
|
|
|
const request: serverApi.QuerySongsRequest = { |
|
|
|
|
|
|
|
query: {} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
const requestOpts = { |
|
|
|
|
|
|
|
method: 'POST', |
|
|
|
|
|
|
|
headers: { 'Content-Type': 'application/json' }, |
|
|
|
|
|
|
|
body: JSON.stringify(request) |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
fetch(serverApi.QuerySongsEndpoint, requestOpts) |
|
|
|
|
|
|
|
.then((response: any) => response.json()) |
|
|
|
|
|
|
|
.then((json: any) => { |
|
|
|
|
|
|
|
'ids' in json && setSongs(json.ids); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
}, []); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return <Paper> |
|
|
|
|
|
|
|
<ItemList> |
|
|
|
|
|
|
|
{songs.map((song: any) => { |
|
|
|
|
|
|
|
return <SongItem id={song} />; |
|
|
|
|
|
|
|
})} |
|
|
|
|
|
|
|
</ItemList> |
|
|
|
|
|
|
|
</Paper>; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function App() { |
|
|
|
function App() { |
|
|
|
const [songs, setSongs] = useState<SongEntry[]>([]); |
|
|
|
const [songs, setSongs] = useState<SongEntry[]>([]); |
|
|
|
const [artists, setArtists] = useState<ArtistEntry[]>([]); |
|
|
|
const [artists, setArtists] = useState<ArtistEntry[]>([]); |
|
|
@ -132,14 +194,17 @@ function App() { |
|
|
|
loadingSong: true |
|
|
|
loadingSong: true |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const [appBarActiveTab, setAppBarActiveTab] = React.useState(AppBarActiveTab.Songs); |
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
return ( |
|
|
|
<div style={{ maxWidth: '100%' }}> |
|
|
|
<div style={{ maxWidth: '100%' }}> |
|
|
|
<AppBar /> |
|
|
|
<AppBar activeTab={appBarActiveTab} onActiveTabChange={setAppBarActiveTab} /> |
|
|
|
<Paper> |
|
|
|
<Paper> |
|
|
|
<ItemList items={[testSong, testLoadingSong]}> |
|
|
|
{/* <ItemList items={[testSong, testLoadingSong]}> |
|
|
|
<ItemListItem item={testSong}/> |
|
|
|
<ItemListItem item={testSong} /> |
|
|
|
<ItemListItem item={testLoadingSong}/> |
|
|
|
<ItemListItem item={testLoadingSong} /> |
|
|
|
</ItemList> |
|
|
|
</ItemList> */} |
|
|
|
|
|
|
|
{(appBarActiveTab === AppBarActiveTab.Songs) && <SongList />} |
|
|
|
</Paper> |
|
|
|
</Paper> |
|
|
|
<Button variant="contained" onClick={openCreateSongDialog}>Create Song</Button> |
|
|
|
<Button variant="contained" onClick={openCreateSongDialog}>Create Song</Button> |
|
|
|
<Button variant="contained" onClick={openCreateArtistDialog}>Create Artist</Button> |
|
|
|
<Button variant="contained" onClick={openCreateArtistDialog}>Create Artist</Button> |
|
|
|