Skip to content

Commit

Permalink
Fix playlist list page
Browse files Browse the repository at this point in the history
  • Loading branch information
espidev committed Jul 26, 2023
1 parent c19a0ff commit b12c2ba
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 60 deletions.
40 changes: 40 additions & 0 deletions website/app/api/playlist/[playlistId]/thumbnail/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { getDB } from "@/util/db";
import { NextResponse } from "next/server";

// GET /api/playlist/[playlistId]/thumbnail
// get a playlist's thumbnail

export async function GET(request: Request, { params }: { params: { playlistId: string } }) {
const playlistId = params.playlistId;

// check if valid id
if (isNaN(+playlistId)) {
return NextResponse.json({ error: "invalid playlist id" }, { status: 400 });
}

const conn = await getDB();

let tracks: any;
try {
tracks = await conn.query(`
SELECT track.id FROM playlist
INNER JOIN playlist_tracks ON playlist_tracks.playlist_id = $1
INNER JOIN track ON playlist_tracks.track_id = track.id
LIMIT 1`,
[playlistId]);

if (tracks.rowCount < 1) {
// if there are no songs, just use a default image
return await fetch(`https://github.com/google/material-design-icons/blob/master/png/av/library_music/materialiconsoutlined/48dp/2x/outline_library_music_black_48dp.png?raw=true`);
}
} catch (e) {
await conn.end();
return NextResponse.json({ error: "invalid playlist id" }, { status: 400 });
}

await conn.end();

const trackId = tracks.rows[0].id;

return await fetch(`http://${process.env.FILESTORE_HOST}:${process.env.FILESTORE_PORT}/track-thumbnail/${trackId}`);
}
2 changes: 1 addition & 1 deletion website/app/api/playlist/[playlistId]/tracks/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { getAPITrack } from "@/util/models/track";
import { NextResponse } from "next/server";

// GET /api/playlist/[playlistId]/tracks
// get an playlist's track list
// get a playlist's track list

export async function GET(request: Request, { params }: { params: { albumId: string } }) {
const albumId = params.albumId;
Expand Down
54 changes: 0 additions & 54 deletions website/app/collection/playlists/[playlistId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,9 @@ export default function CollectionPlaylistPage({params} : {params: {playlistId:

const playlistId = params.playlistId;

const [playlists, setPlaylists] = useState<APIPlaylist[]>([]);
const [playlist, setPlaylist] = useState<APIPlaylist>();
const [tracks, setTracks] = useState([] as APITrack[]);
const [alerts, setAlerts] = useState([] as AlertEntry[]);
const [showCreateModal, setShowCreateModal] = useState(false);
const [newPlaylistName, setNewPlaylistName] = useState('');
const [newPlaylistDescription, setNewPlaylistDescription] = useState('');

useEffect(() => {
// wait for credentials to be loaded
Expand Down Expand Up @@ -82,29 +78,6 @@ export default function CollectionPlaylistPage({params} : {params: {playlistId:

const totalTime = tracks.reduce((acc, track) => acc + track.audio_length, 0);

const handleCreatePlaylist = () => {
setShowCreateModal(true);
};

const handleCloseModal = () => {
setShowCreateModal(false);
setNewPlaylistName('');
setNewPlaylistDescription('');
};

const handleCreateButtonClick = async () => {
try {
const data = { name: newPlaylistName, description: newPlaylistDescription };
const response = await apiPostCreatePlaylist(playlistId, data);
const newPlaylist = response.data;
setPlaylists([...playlists, newPlaylist]);
handleCloseModal();
} catch (error) {
console.error('Error creating playlist:', error);
// Handle error and show error message
}
};

return (
<div>
<Box>
Expand All @@ -122,37 +95,10 @@ export default function CollectionPlaylistPage({params} : {params: {playlistId:
{tracks.length} songs • Total duration: {formatDuration(totalTime)}
</Typography>
</div>
<Button variant="contained" onClick={handleCreatePlaylist}>
Create Playlist
</Button>
</div>

<TrackTable tracks={tracks} handleTrackClick={handleTrackClick} />
</Box>

{/* Create Playlist Modal */}
<Modal open={showCreateModal} onClose={handleCloseModal}>
<div style={{ padding: '1rem', background: 'white' }}>
<Typography variant="h6">Create New Playlist</Typography>
<TextField
label="Playlist Name"
value={newPlaylistName}
onChange={(e) => setNewPlaylistName(e.target.value)}
fullWidth
margin="normal"
/>
<TextField
label="Playlist Description"
value={newPlaylistDescription}
onChange={(e) => setNewPlaylistDescription(e.target.value)}
fullWidth
margin="normal"
/>
<Button variant="contained" color="primary" onClick={handleCreateButtonClick}>
Create
</Button>
</div>
</Modal>
</div>
);
}
61 changes: 58 additions & 3 deletions website/app/collection/playlists/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
'use client'

import { useEffect, useState } from "react";
import { apiGetCollectionPlaylists } from "@/components/apiclient";
import { apiGetCollectionPlaylists, apiPostCreatePlaylist } from "@/components/apiclient";
import { useLoginStateContext } from "@/components/loginstateprovider";
import { useRouter } from "next/navigation";
import { APIPlaylist } from "@/util/models/playlist";
import AlertComponent, { AlertEntry } from "@/components/alerts";
import { Typography, Grid } from "@mui/material";
import { Typography, Grid, Modal, TextField, Button } from "@mui/material";
import PlaylistCard from "@/components/playlistCard";

export default function CollectionPlaylistsPage() {
Expand All @@ -16,6 +16,33 @@ export default function CollectionPlaylistsPage() {
const [playlists, setPlaylists] = useState([] as APIPlaylist[]);
const [alerts, setAlerts] = useState([] as AlertEntry[]);

const [showCreateModal, setShowCreateModal] = useState(false);
const [newPlaylistName, setNewPlaylistName] = useState('');
const [newPlaylistDescription, setNewPlaylistDescription] = useState('');

const handleCreatePlaylist = () => {
setShowCreateModal(true);
};

const handleCloseModal = () => {
setShowCreateModal(false);
setNewPlaylistName('');
setNewPlaylistDescription('');
};

const handleCreateButtonClick = async () => {
try {
const data = { name: newPlaylistName, description: newPlaylistDescription };
const response = await apiPostCreatePlaylist(loginState.loggedInUserUuid, data);
const newPlaylist = response.data;
setPlaylists([...playlists, newPlaylist]);
handleCloseModal();
} catch (error) {
console.error('Error creating playlist:', error);
// Handle error and show error message
}
};

useEffect(() => {
// wait for credentials to be loaded
if (!loginState.loggedInStateValid) {
Expand Down Expand Up @@ -46,9 +73,37 @@ export default function CollectionPlaylistsPage() {
return (
<Grid sx={{ position: 'absolute', width: 0.83 }}>
<AlertComponent alerts={alerts} setAlerts={setAlerts} />


{/* Create Playlist Modal */}
<Modal open={showCreateModal} onClose={handleCloseModal}>
<div style={{ padding: '1rem', background: 'white' }}>
<Typography variant="h6">Create New Playlist</Typography>
<TextField
label="Playlist Name"
value={newPlaylistName}
onChange={(e) => setNewPlaylistName(e.target.value)}
fullWidth
margin="normal"
/>
<TextField
label="Playlist Description"
value={newPlaylistDescription}
onChange={(e) => setNewPlaylistDescription(e.target.value)}
fullWidth
margin="normal"
/>
<Button variant="contained" color="primary" onClick={handleCreateButtonClick}>
Create
</Button>
</div>
</Modal>

<Grid sx={{ padding: 2 }} container direction="row" justifyContent="space-between">
<Typography variant="h6">Playlists</Typography>

<Button variant="contained" onClick={handleCreatePlaylist}>
Create Playlist
</Button>
</Grid>

{playlists.map((playlist) => {
Expand Down
4 changes: 2 additions & 2 deletions website/components/apiclient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ export function apiGetPlaylistTracks(playlistId: string) {
});
}

export function apiPostCreatePlaylist(playlistId: string, data: { name: string, description: string }) {
return axios.post(`/api/collection/${playlistId}/playlists`, data);
export function apiPostCreatePlaylist(accountUuid: string, data: { name: string, description: string }) {
return axios.post(`/api/collection/${accountUuid}/playlists`, data);
}

export function apiGetCollectionGenres(accountUuid: string) {
Expand Down

0 comments on commit b12c2ba

Please sign in to comment.