feat: add delete functionality for playlists with confirmation and error handling
This commit is contained in:
@@ -5,16 +5,17 @@ import type { Playlist } from '@/lib/api/services/playlists'
|
||||
import { formatDateDistanceToNow } from '@/utils/format-date'
|
||||
import { formatDuration } from '@/utils/format-duration'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { Calendar, Clock, Edit, Heart, Music, Play, User } from 'lucide-react'
|
||||
import { Calendar, Clock, Edit, Heart, Music, Play, Trash2, User } from 'lucide-react'
|
||||
|
||||
interface PlaylistRowProps {
|
||||
playlist: Playlist
|
||||
onEdit: (playlist: Playlist) => void
|
||||
onSetCurrent: (playlist: Playlist) => void
|
||||
onFavoriteToggle?: (playlistId: number, isFavorited: boolean) => void
|
||||
onDelete?: (playlist: Playlist) => void
|
||||
}
|
||||
|
||||
export function PlaylistRow({ playlist, onEdit, onSetCurrent, onFavoriteToggle }: PlaylistRowProps) {
|
||||
export function PlaylistRow({ playlist, onEdit, onSetCurrent, onFavoriteToggle, onDelete }: PlaylistRowProps) {
|
||||
const handleFavoriteToggle = () => {
|
||||
if (onFavoriteToggle) {
|
||||
onFavoriteToggle(playlist.id, !playlist.is_favorited)
|
||||
@@ -121,6 +122,17 @@ export function PlaylistRow({ playlist, onEdit, onSetCurrent, onFavoriteToggle }
|
||||
<Play className="h-4 w-4" />
|
||||
</Button>
|
||||
)}
|
||||
{onDelete && !playlist.is_main && playlist.is_deletable && (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
onClick={() => onDelete(playlist)}
|
||||
className="h-8 w-8 p-0 text-destructive hover:text-destructive"
|
||||
title={`Delete "${playlist.name}"`}
|
||||
>
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
@@ -13,9 +13,10 @@ interface PlaylistTableProps {
|
||||
onEdit: (playlist: Playlist) => void
|
||||
onSetCurrent: (playlist: Playlist) => void
|
||||
onFavoriteToggle?: (playlistId: number, isFavorited: boolean) => void
|
||||
onDelete?: (playlist: Playlist) => void
|
||||
}
|
||||
|
||||
export function PlaylistTable({ playlists, onEdit, onSetCurrent, onFavoriteToggle }: PlaylistTableProps) {
|
||||
export function PlaylistTable({ playlists, onEdit, onSetCurrent, onFavoriteToggle, onDelete }: PlaylistTableProps) {
|
||||
return (
|
||||
<div className="rounded-md border">
|
||||
<Table>
|
||||
@@ -39,6 +40,7 @@ export function PlaylistTable({ playlists, onEdit, onSetCurrent, onFavoriteToggl
|
||||
onEdit={onEdit}
|
||||
onSetCurrent={onSetCurrent}
|
||||
onFavoriteToggle={onFavoriteToggle}
|
||||
onDelete={onDelete}
|
||||
/>
|
||||
))}
|
||||
</TableBody>
|
||||
|
||||
@@ -189,6 +189,53 @@ export function PlaylistsPage() {
|
||||
}
|
||||
}
|
||||
|
||||
const handleDeletePlaylist = async (playlist: Playlist) => {
|
||||
// Protect main playlist from deletion
|
||||
if (playlist.is_main) {
|
||||
toast.error('The main playlist cannot be deleted')
|
||||
return
|
||||
}
|
||||
|
||||
// Check if playlist is deletable
|
||||
if (!playlist.is_deletable) {
|
||||
toast.error('This playlist cannot be deleted')
|
||||
return
|
||||
}
|
||||
|
||||
// Confirm deletion
|
||||
const confirmMessage = `Are you sure you want to delete the playlist "${playlist.name}"?${
|
||||
playlist.sound_count > 0
|
||||
? `\n\nThis playlist contains ${playlist.sound_count} sound${playlist.sound_count !== 1 ? 's' : ''}. The sounds will not be deleted, only removed from this playlist.`
|
||||
: ''
|
||||
}\n\nThis action cannot be undone.`
|
||||
|
||||
if (!confirm(confirmMessage)) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await playlistsService.deletePlaylist(playlist.id)
|
||||
toast.success(`Playlist "${playlist.name}" deleted successfully`)
|
||||
|
||||
// Remove the deleted playlist from the local state
|
||||
setPlaylists(prevPlaylists =>
|
||||
prevPlaylists.filter(p => p.id !== playlist.id)
|
||||
)
|
||||
|
||||
// Update total count
|
||||
setTotalCount(prev => prev - 1)
|
||||
|
||||
// If current page is now empty and not the first page, go to previous page
|
||||
const remainingOnCurrentPage = playlists.length - 1
|
||||
if (remainingOnCurrentPage === 0 && currentPage > 1) {
|
||||
setCurrentPage(currentPage - 1)
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : 'Failed to delete playlist'
|
||||
toast.error(errorMessage)
|
||||
}
|
||||
}
|
||||
|
||||
const renderContent = () => {
|
||||
if (loading) {
|
||||
return <PlaylistsLoading />
|
||||
@@ -209,6 +256,7 @@ export function PlaylistsPage() {
|
||||
onEdit={handleEditPlaylist}
|
||||
onSetCurrent={handleSetCurrent}
|
||||
onFavoriteToggle={handleFavoriteToggle}
|
||||
onDelete={handleDeletePlaylist}
|
||||
/>
|
||||
<AppPagination
|
||||
currentPage={currentPage}
|
||||
|
||||
Reference in New Issue
Block a user