feat: implement favorites toggle functionality in PlaylistEditHeader and PlaylistEditPage
This commit is contained in:
@@ -1,17 +1,21 @@
|
|||||||
import { Badge } from '@/components/ui/badge'
|
import { Badge } from '@/components/ui/badge'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import type { Playlist } from '@/lib/api/services/playlists'
|
import type { Playlist } from '@/lib/api/services/playlists'
|
||||||
|
import { Heart } from 'lucide-react'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
interface PlaylistEditHeaderProps {
|
interface PlaylistEditHeaderProps {
|
||||||
playlist: Playlist
|
playlist: Playlist
|
||||||
isEditMode: boolean
|
isEditMode: boolean
|
||||||
onSetCurrent: () => void
|
onSetCurrent: () => void
|
||||||
|
onFavoriteToggle?: (playlistId: number, shouldFavorite: boolean) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PlaylistEditHeader({
|
export function PlaylistEditHeader({
|
||||||
playlist,
|
playlist,
|
||||||
isEditMode,
|
isEditMode,
|
||||||
onSetCurrent,
|
onSetCurrent,
|
||||||
|
onFavoriteToggle,
|
||||||
}: PlaylistEditHeaderProps) {
|
}: PlaylistEditHeaderProps) {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-between mb-6">
|
<div className="flex items-center justify-between mb-6">
|
||||||
@@ -25,6 +29,24 @@ export function PlaylistEditHeader({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
|
{onFavoriteToggle && (
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => onFavoriteToggle(playlist.id, !playlist.is_favorited)}
|
||||||
|
className="h-8 w-8 p-0"
|
||||||
|
title={playlist.is_favorited ? "Remove from favorites" : "Add to favorites"}
|
||||||
|
>
|
||||||
|
<Heart
|
||||||
|
className={cn(
|
||||||
|
'h-4 w-4 transition-all duration-200',
|
||||||
|
playlist.is_favorited
|
||||||
|
? 'fill-current text-red-500 hover:text-red-600'
|
||||||
|
: 'text-muted-foreground hover:text-foreground'
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
{!playlist.is_current && !isEditMode && (
|
{!playlist.is_current && !isEditMode && (
|
||||||
<Button variant="outline" onClick={onSetCurrent}>
|
<Button variant="outline" onClick={onSetCurrent}>
|
||||||
Set as Current
|
Set as Current
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import {
|
|||||||
playlistsService,
|
playlistsService,
|
||||||
} from '@/lib/api/services/playlists'
|
} from '@/lib/api/services/playlists'
|
||||||
import { type Sound, soundsService } from '@/lib/api/services/sounds'
|
import { type Sound, soundsService } from '@/lib/api/services/sounds'
|
||||||
|
import { favoritesService } from '@/lib/api/services/favorites'
|
||||||
import {
|
import {
|
||||||
DndContext,
|
DndContext,
|
||||||
type DragEndEvent,
|
type DragEndEvent,
|
||||||
@@ -235,6 +236,37 @@ export function PlaylistEditPage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleFavoriteToggle = async (playlistId: number, shouldFavorite: boolean) => {
|
||||||
|
try {
|
||||||
|
if (shouldFavorite) {
|
||||||
|
await favoritesService.addPlaylistFavorite(playlistId)
|
||||||
|
toast.success('Added to favorites')
|
||||||
|
} else {
|
||||||
|
await favoritesService.removePlaylistFavorite(playlistId)
|
||||||
|
toast.success('Removed from favorites')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the playlist in the local state
|
||||||
|
setPlaylist(prevPlaylist =>
|
||||||
|
prevPlaylist
|
||||||
|
? {
|
||||||
|
...prevPlaylist,
|
||||||
|
is_favorited: shouldFavorite,
|
||||||
|
favorite_count: shouldFavorite
|
||||||
|
? prevPlaylist.favorite_count + 1
|
||||||
|
: Math.max(0, prevPlaylist.favorite_count - 1),
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
)
|
||||||
|
} catch (error) {
|
||||||
|
toast.error(
|
||||||
|
`Failed to ${shouldFavorite ? 'add to' : 'remove from'} favorites: ${
|
||||||
|
error instanceof Error ? error.message : 'Unknown error'
|
||||||
|
}`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleMoveSoundUp = async (index: number) => {
|
const handleMoveSoundUp = async (index: number) => {
|
||||||
if (index === 0 || sounds.length < 2) return
|
if (index === 0 || sounds.length < 2) return
|
||||||
|
|
||||||
@@ -574,6 +606,7 @@ export function PlaylistEditPage() {
|
|||||||
playlist={playlist}
|
playlist={playlist}
|
||||||
isEditMode={isEditMode}
|
isEditMode={isEditMode}
|
||||||
onSetCurrent={handleSetCurrent}
|
onSetCurrent={handleSetCurrent}
|
||||||
|
onFavoriteToggle={handleFavoriteToggle}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||||
|
|||||||
Reference in New Issue
Block a user