Skip to content

Commit

Permalink
Add new playlist creation from track menu playlist selection
Browse files Browse the repository at this point in the history
  • Loading branch information
espidev committed Jul 26, 2023
1 parent ba1a76e commit 767132b
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export async function POST(request: Request, { params }: { params: { accountUuid

// Validate
if (!name || name.trim() === "") {
await conn.end();
return NextResponse.json({ error: "Playlist name must not be empty." }, { status: 400 });
}

Expand Down
2 changes: 2 additions & 0 deletions website/app/api/playlist/[playlistId]/tracks/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ export async function GET(request: Request, { params }: { params: { playlistId:

const playlistRes = await conn.query(`SELECT * FROM playlist WHERE playlist.id = $1 LIMIT 1`, [albumId]);
if (playlistRes.rowCount < 1) {
await conn.end();
return NextResponse.json({ error: "playlist not found" }, { status: 404 });
}

const dbPlaylist = playlistRes.rows[0] as DBPlaylist;

if (tokenUuid !== dbPlaylist.account_uuid) {
await conn.end();
return NextResponse.json({ error: "not authorized" }, { status: 401 });
}

Expand Down
43 changes: 8 additions & 35 deletions website/app/collection/playlists/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { APIPlaylist } from "@/util/models/playlist";
import AlertComponent, { AlertEntry } from "@/components/alerts";
import { Typography, Grid, Modal, TextField, Button, Dialog, DialogTitle, DialogContent, DialogActions } from "@mui/material";
import PlaylistCard from "@/components/playlistCard";
import CreatePlaylistDialog from "@/components/createPlaylistDialog";

export default function CollectionPlaylistsPage() {
const loginState = useLoginStateContext();
Expand All @@ -17,7 +18,6 @@ export default function CollectionPlaylistsPage() {
const [alerts, setAlerts] = useState([] as AlertEntry[]);

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

const loadPlaylists = () => {
apiGetCollectionPlaylists(loginState.loggedInUserUuid)
Expand Down Expand Up @@ -57,46 +57,19 @@ export default function CollectionPlaylistsPage() {

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

const handleCreateButtonClick = async () => {
try {
await apiPostCreatePlaylist(loginState.loggedInUserUuid, newPlaylistName);
loadPlaylists();
handleCloseModal();
} catch (error) {
setAlerts([...alerts, { severity: "error", message: "Error creating playlist, see console for details." }]);
console.error('Error creating playlist:', error);
}
};

// create playlist dialog
const createPlaylistDialog = (
<Dialog open={showCreateModal} onClose={handleCloseModal}>
<DialogTitle>Create New Playlist</DialogTitle>
<DialogContent>
<TextField
label="Playlist Name"
value={newPlaylistName}
onChange={(e) => setNewPlaylistName(e.target.value)}
fullWidth
autoFocus
margin="normal"
/>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseModal}>Cancel</Button>
<Button onClick={handleCreateButtonClick}>Create</Button>
</DialogActions>
</Dialog>
);

return (
<Grid sx={{ position: 'absolute', width: 0.83 }}>
<AlertComponent alerts={alerts} setAlerts={setAlerts} />

{createPlaylistDialog}
<CreatePlaylistDialog
isOpen={showCreateModal}
handleClose={handleCloseModal}
alerts={alerts}
setAlerts={setAlerts}
refreshPlaylists={loadPlaylists}
/>

<Grid sx={{ padding: 2 }} container direction="row" justifyContent="space-between">
<Typography variant="h6">Playlists</Typography>
Expand Down
41 changes: 41 additions & 0 deletions website/components/createPlaylistDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, TextField } from "@mui/material";
import { useState } from "react";
import { useLoginStateContext } from "./loginstateprovider";
import { apiPostCreatePlaylist } from "./apiclient";

export default function CreatePlaylistDialog(props: { isOpen: boolean, handleClose: any, alerts: any, setAlerts: any, refreshPlaylists: any }) {
const loginState = useLoginStateContext();

const [newPlaylistName, setNewPlaylistName] = useState('');

const handleCreateButtonClick = async () => {
try {
await apiPostCreatePlaylist(loginState.loggedInUserUuid, newPlaylistName);
props.refreshPlaylists();
props.handleClose();
} catch (error) {
props.setAlerts([...props.alerts, { severity: "error", message: "Error creating playlist, see console for details." }]);
console.error('Error creating playlist:', error);
}
};

return (
<Dialog open={props.isOpen} onClose={props.handleClose}>
<DialogTitle>Create New Playlist</DialogTitle>
<DialogContent>
<TextField
label="Playlist Name"
value={newPlaylistName}
onChange={(e) => setNewPlaylistName(e.target.value)}
fullWidth
autoFocus
margin="normal"
/>
</DialogContent>
<DialogActions>
<Button onClick={() => { setNewPlaylistName(''); props.handleClose(); }}>Cancel</Button>
<Button onClick={handleCreateButtonClick}>Create</Button>
</DialogActions>
</Dialog>
);
}
20 changes: 18 additions & 2 deletions website/components/trackmenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AddOutlined, FavoriteBorderOutlined, FavoriteOutlined, PlaylistAddCheck
import { Avatar, Dialog, DialogTitle, List, ListItem, ListItemAvatar, ListItemButton, ListItemIcon, ListItemText, Menu, MenuItem, Typography } from "@mui/material";
import { useState } from "react";
import { useAppStateContext } from "./appstateprovider";
import CreatePlaylistDialog from "./createPlaylistDialog";

export default function TrackMenu(props: { track: APITrack, anchorEl: any, requestClose: any }) {
const appState = useAppStateContext();
Expand All @@ -12,9 +13,11 @@ export default function TrackMenu(props: { track: APITrack, anchorEl: any, reque
const addedToPlaylist = useState(false);

const track = props.track;
const trackPlaylists = track.playlists;

const [isPlaylistDialogOpen, setIsPlaylistDialogOpen] = useState(false);

const [isCreatePlaylistDialogOpen, setIsCreatePlaylistDialogOpen] = useState(false);

const handlePlaylistDialogClose = () => {
setIsPlaylistDialogOpen(false);
};
Expand All @@ -23,7 +26,12 @@ export default function TrackMenu(props: { track: APITrack, anchorEl: any, reque
<Dialog onClose={handlePlaylistDialogClose} open={isPlaylistDialogOpen}>
<DialogTitle>Select playlists for {track.name}</DialogTitle>
<List sx={{ pt: 0 }}>
<ListItem disableGutters>

{

}

<ListItem disableGutters onClick={() => setIsCreatePlaylistDialogOpen(true)}>
<ListItemButton>
<ListItemAvatar>
<Avatar>
Expand Down Expand Up @@ -85,6 +93,14 @@ export default function TrackMenu(props: { track: APITrack, anchorEl: any, reque

{playlistDialog}

<CreatePlaylistDialog
isOpen={isCreatePlaylistDialogOpen}
handleClose={() => setIsCreatePlaylistDialogOpen(false)}
alerts={[]}
setAlerts={(alerts: any) => {}}
refreshPlaylists={() => {}}
/>

</Menu>
);
}

0 comments on commit 767132b

Please sign in to comment.