1import{c as R,r as y,n as Q,y as H,p as E,v as S,w as F,j as e,D as U,z as V,E as G,F as _,G as J,H as W,J as T,K as M,N as O,O as L,I as Y,Q as $,R as Z,B as p,T as X,U as ee,V as q,s as se,P as z,M as P,W as te,Y as ae,Z as ie,_ as re,$ as le,a0 as ne,o as oe,a as de,u as ce,b as me,q as I}from"./index-Dc78DrGS.js";import{S as ue}from"./ShareButton-IbZR3uUj.js";import{S as D}from"./skeleton-BetPZc7E.js";import{T as B,A as xe,a as he,b as pe,c as je,d as fe,e as ye,f as ge,g as ve,h as be}from"./alert-dialog-DyAr0trH.js";import{T as Ne}from"./textarea-iCUwUdTV.js";import{u as we,a as K,j as De,b as Ce,R as Pe,D as Se,c as ke,S as Ae,v as Ee,k as Fe,f as Te,m as Me,g as Oe,K as Le,P as $e,h as qe,C as Ie,G as Ke}from"./trackOrder-B8TJq3wl.js";import{C as Re,a as Qe}from"./card-CyBQusTt.js";import{A as ze}from"./arrow-left-AdIZqs25.js";/** 2 * @license lucide-react v0.453.0 - ISC 3 * 4 * This source code is licensed under the ISC license. 5 * See the LICENSE file in the root directory of this source tree. 6 */const Be=R("EllipsisVertical",[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"12",cy:"5",r:"1",key:"gxeob9"}],["circle",{cx:"12",cy:"19",r:"1",key:"lyex9k"}]]);/** 7 * @license lucide-react v0.453.0 - ISC 8 * 9 * This source code is licensed under the ISC license. 10 * See the LICENSE file in the root directory of this source tree. 11 */const He=R("Pen",[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}]]),Ue=ee({name:q().min(1,"Name is required").max(100,"Name is too long"),description:q().max(500,"Description is too long").optional()});function Ve({playlist:t,children:n}){const[r,u]=y.useState(!1),{toast:x}=Q(),a=H({resolver:X(Ue),defaultValues:{name:t.name,description:t.description||""}});y.useEffect(()=>{r&&a.reset({name:t.name,description:t.description||""})},[r,t,a]);const d=E({mutationFn:async l=>(await F("PATCH",`/api/playlists/${t.id}`,l)).json(),onSuccess:()=>{S.invalidateQueries({queryKey:["/api/playlists"]}),S.invalidateQueries({queryKey:["/api/playlists",t.id]}),x({title:"Playlist updated successfully"}),u(!1)},onError:()=>{x({title:"Failed to update playlist",variant:"destructive"})}}),h=l=>{d.mutate(l)};return e.jsxs(U,{open:r,onOpenChange:u,children:[e.jsx(V,{asChild:!0,children:n}),e.jsxs(G,{children:[e.jsx(_,{children:e.jsx(J,{children:"Edit Playlist"})}),e.jsx(W,{...a,children:e.jsxs("form",{onSubmit:a.handleSubmit(h),className:"space-y-4",children:[e.jsx(T,{control:a.control,name:"name",render:({field:l})=>e.jsxs(M,{children:[e.jsx(O,{children:"Name"}),e.jsx(L,{children:e.jsx(Y,{placeholder:"My Playlist","data-testid":"input-edit-playlist-name",...l})}),e.jsx($,{})]})}),e.jsx(T,{control:a.control,name:"description",render:({field:l})=>e.jsxs(M,{children:[e.jsx(O,{children:"Description (optional)"}),e.jsx(L,{children:e.jsx(Ne,{placeholder:"Add a description for your playlist","data-testid":"input-edit-playlist-description",className:"resize-none",...l})}),e.jsx($,{})]})}),e.jsxs(Z,{children:[e.jsx(p,{type:"button",variant:"outline",onClick:()=>u(!1),"data-testid":"button-cancel-edit",children:"Cancel"}),e.jsx(p,{type:"submit",disabled:d.isPending,"data-testid":"button-save-playlist",children:d.isPending?"Saving...":"Save"})]})]})})]})]})}function Ge({track:t,index:n,currentTrack:r,isPlaying:u,isOwner:x,onPlayTrack:a,onRemoveTrack:d}){const{attributes:h,listeners:l,setNodeRef:c,transform:f,transition:o,isDragging:s}=qe({id:t.id}),b={transform:Ie.Transform.toString(f),transition:o,opacity:s?.5:1};return e.jsx("div",{ref:c,style:b,children:e.jsx(Re,{className:`group hover-elevate active-elevate-2 overflow-visible ${(r==null?void 0:r.id)===t.id?"bg-muted":""}`,"data-testid":`card-track-${t.id}`,children:e.jsxs(Qe,{className:"flex items-center gap-4 p-3",children:[x&&e.jsx("button",{...h,...l,className:"h-8 w-8 rounded-md hover:bg-accent hover:text-accent-foreground flex items-center justify-center cursor-grab active:cursor-grabbing opacity-0 group-hover:opacity-100 transition-opacity",onClick:g=>{g.preventDefault(),g.stopPropagation()},"data-testid":`drag-handle-${t.id}`,children:e.jsx(Ke,{className:"h-4 w-4"})}),e.jsx("span",{className:"text-sm text-muted-foreground w-6 text-center",children:n+1}),e.jsx(p,{size:"icon",variant:"ghost",onClick:()=>a(t),"data-testid":`button-play-track-${t.id}`,children:(r==null?void 0:r.id)===t.id&&u?e.jsx(se,{className:"h-4 w-4"}):e.jsx(z,{className:"h-4 w-4"})}),e.jsx("div",{className:"w-10 h-10 rounded bg-muted flex items-center justify-center shrink-0",children:t.coverUrl?e.jsx("img",{src:t.coverUrl,alt:t.title,className:"w-full h-full object-cover rounded"}):e.jsx(P,{className:"h-5 w-5 text-muted-foreground"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("h4",{className:"font-medium truncate",children:t.title}),e.jsx("p",{className:"text-sm text-muted-foreground truncate",children:t.artist})]}),e.jsx("span",{className:"text-sm text-muted-foreground",children:te(t.duration)}),x&&e.jsxs(ae,{children:[e.jsx(ie,{asChild:!0,children:e.jsx(p,{size:"icon",variant:"ghost","data-testid":`button-track-menu-${t.id}`,children:e.jsx(Be,{className:"h-4 w-4"})})}),e.jsx(re,{align:"end",children:e.jsxs(le,{onClick:()=>d(t.id),"data-testid":`button-remove-track-${t.id}`,children:[e.jsx(B,{className:"h-4 w-4 mr-2"}),"Remove from playlist"]})})]})]})})})}function _e({playlistId:t,tracks:n,currentTrack:r,isPlaying:u,isOwner:x,onPlayTrack:a,onRemoveTrack:d,onTracksReordered:h}){const[l,c]=y.useState(n),[f,o]=y.useState(!1),s=we(K($e,{activationConstraint:{distance:8}}),K(Le,{coordinateGetter:Oe}));y.useEffect(()=>{const m=De(t);if(m){const j=Ce(n,m);c(j),o(!0)}else c(n),o(!1)},[n,t]);const b=m=>{const{active:j,over:N}=m;N&&j.id!==N.id&&c(v=>{const C=v.findIndex(i=>i.id===j.id),k=v.findIndex(i=>
11i.id===N.id),w=Te(v,C,k);return Me(t,w.map(i=>i.id)),o(!0),h==null||h(w),w})},g=()=>{Fe(t),c(n),o(!1)};return e.jsxs("div",{children:[f&&x&&e.jsxs("div",{className:"mb-4 flex items-center justify-between bg-card/75 backdrop-blur-sm border border-border rounded-lg px-4 py-2",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Custom order applied. Drag tracks with the grip handle to reorder."}),e.jsxs(p,{variant:"ghost",size:"sm",onClick:g,"data-testid":"button-reset-playlist-order",children:[e.jsx(Pe,{className:"h-4 w-4 mr-2"}),"Reset Order"]})]}),e.jsx(Se,{sensors:s,collisionDetection:ke,onDragEnd:b,children:e.jsx(Ae,{items:l.map(m=>m.id),strategy:Ee,children:e.jsx("div",{className:"space-y-1",children:l.map((m,j)=>e.jsx(Ge,{track:m,index:j,currentTrack:r,isPlaying:u,isOwner:x,onPlayTrack:a,onRemoveTrack:d},m.id))})})})]})}function as(){const[t,n]=ne("/playlist/:id"),[,r]=oe(),{user:u,isAuthenticated:x}=de(),{currentTrack:a,isPlaying:d,play:h,pause:l,setQueue:c}=ce(),{toast:f}=Q(),o=n==null?void 0:n.id,{data:s,isLoading:b}=me({queryKey:["/api/playlists",o],enabled:!!o}),g=E({mutationFn:async()=>{await F("DELETE",`/api/playlists/${o}`)},onSuccess:()=>{S.invalidateQueries({queryKey:["/api/playlists"]}),f({title:"Playlist deleted"}),r("/playlists")},onError:()=>{f({title:"Failed to delete playlist",variant:"destructive"})}}),m=E({mutationFn:async i=>{await F("DELETE",`/api/playlists/${o}/tracks/${i}`)},onSuccess:()=>{S.invalidateQueries({queryKey:["/api/playlists",o]}),f({title:"Track removed from playlist"})},onError:()=>{f({title:"Failed to remove track",variant:"destructive"})}}),j=x&&u&&s&&s.userId===u.id,N=()=>{s&&s.tracks.length>0&&(c(s.tracks),h(s.tracks[0]))},[v,C]=y.useState([]);y.useEffect(()=>{s!=null&&s.tracks&&C(s.tracks)},[s==null?void 0:s.tracks]);const k=i=>{if((a==null?void 0:a.id)===i.id&&d)l();else{const A=v.length>0?v:(s==null?void 0:s.tracks)||[];c(A),h(i)}},w=i=>{C(i),a&&d&&c(i)};return b?e.jsxs("div",{className:"p-6",children:[e.jsxs("div",{className:"flex items-center gap-4 mb-6",children:[e.jsx(D,{className:"h-48 w-48 rounded-md"}),e.jsxs("div",{className:"flex-1",children:[e.jsx(D,{className:"h-8 w-64 mb-2"}),e.jsx(D,{className:"h-4 w-32 mb-4"}),e.jsx(D,{className:"h-9 w-24"})]})]}),e.jsx("div",{className:"space-y-2",children:Array.from({length:5}).map((i,A)=>e.jsx(D,{className:"h-16 w-full rounded-md"},A))})]}):s?e.jsxs("div",{className:"p-6",children:[e.jsx(I,{href:"/playlists",children:e.jsxs(p,{variant:"ghost",size:"sm",className:"mb-4","data-testid":"button-back-playlists",children:[e.jsx(ze,{className:"h-4 w-4 mr-2"}),"Back to Playlists"]})}),e.jsxs("div",{className:"flex flex-col md:flex-row gap-6 mb-8",children:[e.jsx("div",{className:"w-48 h-48 rounded-md bg-muted flex items-center justify-center shrink-0",children:s.coverUrl?e.jsx("img",{src:s.coverUrl,alt:s.name,className:"w-full h-full object-cover rounded-md"}):e.jsx(P,{className:"h-16 w-16 text-muted-foreground"})}),e.jsxs("div",{className:"flex-1",children:[e.jsx("p",{className:"text-sm text-muted-foreground uppercase tracking-wide mb-1",children:"Playlist"}),e.jsx("h1",{className:"text-3xl font-bold mb-2","data-testid":"text-playlist-detail-name",children:s.name}),s.description&&e.jsx("p",{className:"text-muted-foreground mb-4",children:s.description}),e.jsxs("p",{className:"text-sm text-muted-foreground mb-4",children:[s.tracks.length," ",s.tracks.length===1?"track":"tracks"]}),e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[s.tracks.length>0&&e.jsxs(p,{onClick:N,"data-testid":"button-play-all",children:[e.jsx(z,{className:"h-4 w-4 mr-2"}),"Play All"]}),e.jsx(ue,{type:"playlist",id:s.id,title:s.name,variant:"default"}),j&&e.jsxs(e.Fragment,{children:[e.jsx(Ve,{playlist:s,children:e.jsxs(p,{variant:"outline","data-testid":"button-edit-playlist",children:[e.jsx(He,{className:"h-4 w-4 mr-2"}),"Edit"]})}),e.jsxs(xe,{children:[e.jsx(he,{asChild:!0,children:e.jsxs(p,{variant:"outline","data-testid":"button-delete-playlist",children:[e.jsx(B,{className:"h-4 w-4 mr-2"}),"Delete"]})}),e.jsxs(pe,{children:[e.jsxs(je,{children:[e.jsx(fe,{children:"Delete Playlist"}),e.jsxs(ye,{children:['Are you sure you want to delete "',s.name,'"? This action cannot be undone.']})]}),e.jsxs(ge,{children:[e.jsx(ve,{"data-testid":"button-cancel-delete",children:"Cancel"}),e.jsx(be,{onClick:()=>g.mutate(),"data-testid":"button-confirm-delete",children:"Delete"})]})]})]})]})]})]})]}),s.tracks.length===0?e.jsxs("div",{className:"text-center py-16",children:[e.jsx(P,{className:"h-12 w-12 text-muted-foreground mx-auto mb-4"}),e.jsx("h3",{className:"text-lg font-medium mb-2",children:"No tracks yet"}),e.jsx("p",{className:"text-muted-foreground",children:"Add tracks from the browse page to this playlist."})]}):e.jsx(_e,{playlistId:o||"",tracks:s.tracks,currentTrack:a,isPlaying:d,isOwner:j,onPlayTrack:k,onRemoveTrack:i=>m.mutate(i),onTracksReordered:w})]}):e.jsxs("div",{className:"flex flex-col items-center justify-center h-full p-6",children:[e.jsx(P,{className:"h-16 w-16 text-muted-foreground mb-4"}),e.jsx("h2",{className:"text-xl font-semibold mb-2",children:"Playlist not found"}),e.jsx(p,{asChild:!0,variant:"outline",children:e.jsx(I,{href:"/playlists",children:"Back to Playlists"})})]})}export{as as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.