PageSourceSearch

https://www.abbeytheatre.co.uk/assets/AdminProductionForm-CN0AHcg9.js

js abbeytheatre.co.uk collected 2026-10-02 21:28:01 UTC 93,969 bytes, 19 lines download raw bytes

1import{i as Cs,r as o,s as m,j as e,D as Me,w as Oe,x as Be,y as ze,z as Ve,v as N,I as M,bp as ks,B as T,q as f,bk as Et,bl as $t,bm as At,Z as ie,G as Ne,bo as Lt,P as le,C as Us,c as Ps,d as Ts,af as Vt,ah as Ht,e as Fs,a8 as ae,a as ce,a9 as Rs,a5 as Ds,l as Es,k as $s,p as As,A as Ls,bn as Is,N as ne,O as qs,bq as Ms,br as Os,an as Bs,bs as zs}from"./index-D6S94l3r.js";import{T as Gt}from"./textarea-zkxjn3Pk.js";import{R as tt}from"./RichTextEditor-CAuSqiXf.js";import{T as Vs,a as Hs,b as pe,c as ge}from"./tabs-BFGREGV3.js";import{C as It}from"./checkbox-BuBNczcV.js";import{S as J,a as Z,b as Q,c as ee,d as Y}from"./select-BkXyGY_9.js";import{A as Gs,b as Ws,c as Ys,d as Ks,e as Xs,f as Js,g as Zs}from"./alert-dialog-BuNtcri6.js";import{R as qt,a as xe}from"./radio-group-DO0CEx8l.js";import{S as Qs}from"./search-DRhsjgYy.js";import{I as ea}from"./info-DyWOcR4x.js";import{C as ta,a as sa}from"./CropEditor-B46xQaNm.js";import{g as Se,u as de,P as Wt,i as aa,I as Yt,c as it,a as rt,b as Mt,l as ia,r as ra}from"./storageUpload-D7YIHYjP.js";import{D as Kt}from"./download-CcVfMAvh.js";import{C as we}from"./copy-_brrhfoM.js";import{U as qe}from"./upload-DP2pymot.js";import{processImageForUpload as oa,IMAGE_PRESETS as na}from"./imageUtils-RoQh2GsP.js";import{C as la}from"./calendar-DLPb_Pgl.js";import{P as ca,a as da,b as ma}from"./popover-DtuDutnd.js";import{S as st}from"./square-pen-B5fbrOt9.js";import{P as je}from"./plus-BOxbBXe6.js";import"./index-DxKCTtkd.js";import"./index-DRYfENKC.js";import"./with-selector-DuwCZk0N.js";import"./list-WBYbipnp.js";import"./quote-DgGJCVmp.js";import"./minus-B45-gXHA.js";import"./image-C8tXgUOP.js";import"./index-BdQq_4o_.js";import"./chevron-down-0kA1qCjF.js";import"./chevron-up-D18T203o.js";import"./zoom-out-D5a-atx4.js";import"./save-t8jLgaQj.js";import"./isSameMonth-Bz5De9AU.js";import"./subDays-BSNKuTGW.js";const ua=Cs("CalendarPlus",[["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M16 2v4",key:"4m81vk"}],["path",{d:"M21 13V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h8",key:"3spt84"}],["path",{d:"M3 10h18",key:"8toen8"}],["path",{d:"M16 19h6",key:"xwg31i"}],["path",{d:"M19 16v6",key:"tddt3s"}]]),ha=({open:s,onOpenChange:i,showtimeId:u,seatRow:l,seatNumber:h,existingData:y,onSuccess:U})=>{const[S,n]=o.useState("reserved"),[R,D]=o.useState(""),[k,b]=o.useState(""),[C,E]=o.useState(""),[O,A]=o.useState("text"),[B,r]=o.useState([]),[G,K]=o.useState(""),[L,j]=o.useState(!1);o.useEffect(()=>{y?(n(y.unavailability_type),D(y.linked_user_id||""),b(y.free_text_name||""),E(y.comment||""),A(y.linked_user_id?"user":"text")):(n("reserved"),D(""),b(""),E(""),A("text"))},[y,s]),o.useEffect(()=>{G&&O==="user"&&d()},[G,O]);const d=async()=>{j(!0);try{const{data:x,error:P}=await m.from("user_profiles").select("id, first_name, last_name, email").or(`email.ilike.%${G}%,first_name.ilike.%${G}%,last_name.ilike.%${G}%`).limit(10);!P&&x&&r(x)}catch(x){console.error("Error searching customers:",x)}finally{j(!1)}},c=async()=>{if((S==="reserved"||S==="comp")&&!R&&!k.trim()){f.error("Please specify a customer or name for this reservation");return}try{const x={showtime_id:u,row_index:l,seat_index:h,unavailability_type:S,linked_user_id:O==="user"&&R?R:null,free_text_name:O==="text"&&k.trim()?k.trim():null,comment:C.trim()||null,requires_payment:S==="reserved",created_by_admin_id:null};await m.from("showtime_unavailable_seats").delete().eq("showtime_id",u).eq("row_index",l).eq("seat_index",h);const{error:P}=await m.from("showtime_unavailable_seats").insert(x);if(P)throw P;f.success("Seat marked as unavailable"),U(),i(!1)}catch(x){console.error("Error saving seat:",x),f.error("Failed to mark seat unavailable")}},w=async()=>{try{const{error:x}=await m.from("showtime_unavailable_seats").delete().eq("showtime_id",u).eq("row_index",l).eq("seat_index",h);if(x)throw x;f.success("Seat availability restored"),U(),i(!1)}catch(x){console.error("Error removing seat:",x),f.error("Failed to restore seat availability")}},g=String.fromCharCode(65+l);return e.jsx(Me,{open:s,onOpenChange:i,children:e.jsxs(Oe,{className:"max-w-md max-h-[90vh] overflow-y-auto",children:[e.jsxs(Be,{children:[e.jsxs(ze,{children:[y?"Edit":"Mark"," Seat Unavailable"]}),e.jsxs(Ve,{children:["Row ",g,", Seat ",h+1]})]}),e.jsxs("div",{className:"space-y-4 py-4",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsx(N,{children:"Unavailability Type"}),e.jsxs(qt,{value:S,onValueChange:x=>n(x),children:[e.jsxs("div",{className:"flex items-start space-x-2",children:[e.jsx(xe,{value:"reserved",id:"reserved"}),e.jsxs("div",{className:"flex-1",children:[e.jsx(N,{htmlFor:"reserved",className:"font-medium cursor-pointer",children:"Reserved (Box Office Hold)"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Still needs to be paid for at box office"})]})]}),e.jsxs("div",{className:"flex items-start space-x-2",children:[e.jsx(xe,{value:"comp",id:"comp"}),e.jsxs("div",{className:"flex-1",children:[e.jsx(N,{htmlFor:"comp",className:"font-medium cursor-pointer",children:"Comp (Complimentary)"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Free ticket, no payment required"})]})]}),e.jsxs("div",{className:"flex items-start space-x-2",children:[e.jsx(xe,{value:"access_issue",id:"access_issue"}),e.jsxs("div",{className:"flex-1",children:[e.jsx(N,{htmlFor:"access_issue",className:"font-medium cursor-pointer",children:"Access Issues"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Physical obstruction or viewing issues"})]})]}),e.jsxs("div",{className:"flex items-start space-x-2",children:[e.jsx(xe,{value:"other",id:"other"}),e.jsxs("div",{className:"flex-1",children:[e.jsx(N,{htmlFor:"other",className:"font-medium cursor-pointer",children:"Other"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Other reasons"})]})]})]})]}),(S==="reserved"||S==="comp")&&e.jsxs("div",{className:"space-y-3",children:[e.jsx(N,{children:S==="reserved"?"Reserved For":"Comp For"}),e.jsxs(qt,{value:O,onValueChange:x=>A(x),children:[e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(xe,{value:"text",id:"text"}),e.jsx(N,{htmlFor:"text",className:"cursor-pointer",children:"Free text name"})]}),e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(xe,{value:"user",id:"user"}),e.jsx(N,{htmlFor:"user",className:"cursor-pointer",children:"Link to customer"})]})]}),O==="text"?e.jsx(M,{placeholder:"Enter customer name",value:k,onChange:x=>b(x.target.value)}):e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"relative",children:[e.jsx(Qs,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),e.jsx(M,{placeholder:"Search by name or email...",value:G,onChange:x=>K(x.target.value),className:"pl-9"})]}),G&&B.length>0&&e.jsxs(J,{value:R,onValueChange:D,children:[e.jsx(Z,{children:e.jsx(Q,{placeholder:"Select customer"})}),e.jsx(ee,{children:B.map(x=>e.jsx(Y,{value:x.id,children:x.first_name&&x.last_name?`${x.first_name} ${x.last_name}`:x.email},x.id))})]}),G&&!L&&B.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"No customers found"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs(N,{htmlFor:"comment",children:["Comment ",S==="access_issue"||S==="other"?"":"(Optional)"]}),e.jsx(Gt,{id:"comment",placeholder:S==="access_issue"?"Describe the access issue...":S==="other"?"Provide reason...":"Additional notes...",value:C,onChange:x=>E(x.target.value),rows:3})]})]}),e.jsxs(ks,{className:"flex-col sm:flex-row gap-2",children:[y&&e.jsx(T,{type:"button",variant:"destructive",onClick:w,className:"sm:mr-auto",children:"Remove"}),e.jsx(T,{type:"button",variant:"outline",onClick:()=>i(!1),children:"Cancel"}),e.jsx(T,{type:"button",onClick:c,children:"Save"})]})]})})},pa=({showtimeId:s,seatingPlanId:i,soldSeats:u=[]})=>
1{const[l,h]=o.useState(null),[y,U]=o.useState(new Map),[S,n]=o.useState(new Map),[R,D]=o.useState({x:0,y:0,width:400,height:60}),[k,b]=o.useState(!1),[C,E]=o.useState(null);o.useEffect(()=>{i&&O()},[i]),o.useEffect(()=>{A()},[s]),o.useEffect(()=>{const g=new Map;u.forEach(x=>{const P=`${x.row_index}-${x.seat_index}`;g.set(P,x)}),n(g)},[u]);const O=async()=>{if(!i)return;const{data:g,error:x}=await m.from("seating_plan_templates").select("*").eq("id",i).single();!x&&g&&(h(g),D({x:g.stage_x||0,y:g.stage_y||0,width:g.stage_width||400,height:g.stage_height||60}))},A=async()=>{const{data:g,error:x}=await m.from("showtime_unavailable_seats").select("*").eq("showtime_id",s);if(!x&&g){const P=new Map;g.forEach(W=>{const F=`${W.row_index}-${W.seat_index}`;P.set(F,W)}),U(P)}},B=(g,x)=>{E({row:g,seat:x}),b(!0)},r=()=>{A()},G=async g=>{if(!l)return;const P=l.seats_data.filter(q=>q.row===g),F=P.map(q=>`${q.row}-${q.column}`).every(q=>y.has(q));try{if(F)await m.from("showtime_unavailable_seats").delete().eq("showtime_id",s).in("row_index",[g]),f.success("Row availability restored");else{const q=P.filter(I=>!y.has(`${I.row}-${I.column}`)).map(I=>({showtime_id:s,row_index:I.row,seat_index:I.column,unavailability_type:"other",requires_payment:!1,comment:"Bulk marked unavailable",created_by_admin_id:null}));q.length>0&&(await m.from("showtime_unavailable_seats").insert(q),f.success("Row marked as unavailable"))}A()}catch(q){console.error("Error toggling row:",q),f.error("Failed to update row")}},K=g=>{switch(g){case"sold":return"bg-blue-500 hover:bg-blue-600 border-blue-600";case"reserved":return"bg-amber-500 hover:bg-amber-600 border-amber-600";case"comp":return"bg-emerald-500 hover:bg-emerald-600 border-emerald-600";case"access_issue":return"bg-slate-400 hover:bg-slate-500 border-slate-500";case"other":return"bg-red-500 hover:bg-red-600 border-red-600";default:return"bg-destructive hover:bg-destructive/90 border-destructive"}},L=g=>{switch(g){case"sold":return"Sold";case"reserved":return"Reserved";case"comp":return"Comp";case"access_issue":return"Access Issue";case"other":return"Other";default:return"Unavailable"}},j=()=>{const g={reserved:0,comp:0,access_issue:0,other:0};return y.forEach(x=>{g[x.unavailability_type]++}),g};if(!i)return e.jsx("div",{className:"p-4 border rounded-lg bg-muted/50",children:e.jsx("p",{className:"text-sm text-muted-foreground",children:"No seating plan assigned to this showtime. Assign a seating plan to manage seat availability."})});if(!l)return e.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading seating plan..."});const d=l.seats_data,c=l.rows,w=j();return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between flex-wrap gap-2",children:[e.jsx(N,{children:"Mark Unavailable Seats"}),e.jsxs("div",{className:"flex gap-2 flex-wrap items-center text-xs",children:[w.reserved>0&&e.jsxs(le,{variant:"outline",className:"bg-amber-500/10 text-amber-700 border-amber-300",children:[w.reserved," Reserved"]}),w.comp>0&&e.jsxs(le,{variant:"outline",className:"bg-emerald-500/10 text-emerald-700 border-emerald-300",children:[w.comp," Comp"]}),w.access_issue>0&&e.jsxs(le,{variant:"outline",className:"bg-slate-400/10 text-slate-700 border-slate-300",children:[w.access_issue," Access Issues"]}),w.other>0&&e.jsxs(le,{variant:"outline",className:"bg-red-500/10 text-red-700 border-red-300",children:[w.other," Other"]}),y.size===0&&e.jsx("span",{className:"text-muted-foreground",children:"No seats marked unavailable"})]})]}),e.jsxs("div",{className:"p-4 border rounded-lg overflow-x-auto",children:[e.jsx("div",{className:"space-y-2",children:Array.from({length:c}).map((g,x)=>{const P=d.filter(F=>F.row===x);if(P.length===0)return null;P.sort((F,q)=>F.column-q.column);const W=String.fromCharCode(65+x);return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(T,{type:"button",variant:"outline",size:"sm",onClick:()=>G(x),className:"w-12 text-xs",children:W}),e.jsx("div",{className:"flex gap-1 flex-wrap",children:P.map(F=>{const q=`${F.row}-${F.column}`,I=y.get(q),z=S.get(q),_e=!!I;return z?e.jsx(Et,{children:e.jsxs($t,{children:[e.jsx(At,{asChild:!0,children:e.jsx(T,{type:"button",size:"sm",disabled:!0,className:Ne("w-8 h-8 p-0 text-xs text-white cursor-not-allowed",K("sold")),children:e.jsx(ie,{className:"h-3 w-3"})})}),e.jsx(Lt,{side:"top",className:"max-w-xs",children:e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"font-semibold",children:"Sold"}),z.customer_name&&e.jsxs("p",{className:"text-xs",children:["Customer: ",z.customer_name]}),z.customer_email&&e.jsx("p",{className:"text-xs",children:z.customer_email})]})})]})},F.column):_e?e.jsx(Et,{children:e.jsxs($t,{children:[e.jsx(At,{asChild:!0,children:e.jsx(T,{type:"button",size:"sm",onClick:()=>B(F.row,F.column),className:Ne("w-8 h-8 p-0 text-xs text-white",K(I.unavailability_type)),children:e.jsx(ie,{className:"h-3 w-3"})})}),e.jsx(Lt,{side:"top",className:"max-w-xs",children:e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"font-semibold",children:L(I.unavailability_type)}),I.free_text_name&&e.jsxs("p",{className:"text-xs",children:["For: ",I.free_text_name]}),I.comment&&e.jsx("p",{className:"text-xs",children:I.comment}),I.requires_payment&&e.jsx("p",{className:"text-xs italic",children:"Requires payment"})]})})]})},F.column):e.jsx(T,{type:"button",variant:"outline",size:"sm",onClick:()=>B(F.row,F.column),className:"w-8 h-8 p-0 text-xs",children:F.column+1},F.column)})})]},x)})}),e.jsx("div",{className:"mt-4 pt-4 border-t",children:e.jsx("div",{className:"text-sm font-medium text-center text-primary-foreground bg-primary py-2 rounded",style:{width:`${Math.min(R.width,300)}px`,margin:"0 auto"},children:"STAGE"})})]}),e.jsxs("div",{className:"flex items-start gap-2 p-3 bg-muted/50 rounded-lg",children:[e.jsx(ea,{className:"h-4 w-4 text-muted-foreground mt-0.5 flex-shrink-0"}),e.jsxs("div",{className:"text-xs text-muted-foreground space-y-1",children:[e.jsx("p",{children:"Click any seat to set unavailability details or edit existing ones."}),e.jsx("p",{children:'Click row letters to quickly mark/unmark entire rows (as "Other" type).'}),e.jsxs("div",{className:"flex gap-2 flex-wrap mt-2",children:[e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx("span",{className:"w-3 h-3 bg-blue-500 rounded"})," Sold"]}),e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx("span",{className:"w-3 h-3 bg-amber-500 rounded"})," Reserved"]}),e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx("span",{className:"w-3 h-3 bg-emerald-500 rounded"})," Comp"]}),e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx("span",{className:"w-3 h-3 bg-slate-400 rounded"})," Access Issues"]}),e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx("span",{className:"w-3 h-3 bg-red-500 rounded"})," Other"]}
1)]})]})]}),C&&e.jsx(ha,{open:k,onOpenChange:b,showtimeId:s,seatRow:C.row,seatNumber:C.seat,existingData:y.get(`${C.row}-${C.seat}`),onSuccess:r})]})},ga={"image/webp":"webp","image/jpeg":"jpg","image/jpg":"jpg","image/png":"png","image/gif":"gif","image/avif":"avif","image/svg+xml":"svg"};function xa(s){return s.toLowerCase().replace(/['’]/g,"").replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"image"}function _a(s,i){const u=i?ga[i.split(";")[0].trim().toLowerCase()]:void 0;if(u)return u;const h=s.split(/[?#]/)[0].match(/\.([a-z0-9]{3,4})$/i);return h?h[1].toLowerCase():"jpg"}async function Xt(s,i){let u;try{const y=await fetch(s);if(!y.ok)throw new Error(`Storage responded ${y.status}`);u=await y.blob()}catch{return window.open(s,"_blank","noopener,noreferrer"),"opened"}const l=URL.createObjectURL(u),h=document.createElement("a");return h.href=l,h.download=`${xa(i)}.${_a(s,u.type)}`,document.body.appendChild(h),h.click(),h.remove(),setTimeout(()=>URL.revokeObjectURL(l),1e4),"downloaded"}const fa=({open:s,onOpenChange:i,images:u,onPick:l})=>e.jsx(Me,{open:s,onOpenChange:i,children:e.jsxs(Oe,{className:"max-w-2xl",children:[e.jsxs(Be,{children:[e.jsx(ze,{children:"Use a different photo"}),e.jsx(Ve,{children:"Pick from the photos already on this production, then adjust the crop."})]}),u.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No other photos on this production yet."}):e.jsx("div",{className:"grid grid-cols-3 gap-3 max-h-[60vh] overflow-y-auto",children:u.map(h=>e.jsxs("button",{type:"button",className:"space-y-1 text-left",onClick:()=>l(h),children:[e.jsx("span",{className:"block aspect-square overflow-hidden rounded-lg border hover:ring-2 hover:ring-primary transition-shadow",children:e.jsx("img",{src:h.url,alt:"",className:"w-full h-full object-cover"})}),e.jsx("span",{className:"block text-xs text-muted-foreground truncate",children:h.label})]},h.url))})]})}),ba=({slotKey:s,state:i,productionTitle:u,canEdit:l,reusableImages:h,onUploadNe
1wSource:y,onSaveCrop:U,onAcceptReview:S})=>{const n=Se(s),R=o.useRef(null),[D,k]=o.useState(!1),[b,C]=o.useState(null),[E,O]=o.useState(!1),[A,B]=o.useState(!1),r=(j,d,c)=>C({id:j,url:d,matchesCurrent:c}),G=async j=>{O(!0);const d=await y(j);O(!1),d&&r(d.id,d.original_url,!1)},K=async()=>{if(i){B(!0);try{await Xt(i.imageUrl,`${u}-${s}-${n.exportWidth}x${n.exportHeight}`)==="opened"&&f.info("Opened the image in a new tab — save it from there.")}catch{f.error("Could not download this image")}finally{B(!1)}}},L=async j=>{b&&(await U({id:b.id},j),C(null))};return e.jsxs(Us,{children:[e.jsx(Ps,{children:e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{children:[e.jsx(Ts,{className:"text-base",children:n.label}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:n.description})]}),i?.needsReview&&e.jsxs("div",{className:"flex items-center gap-1 shrink-0",children:[e.jsxs(le,{variant:"outline",className:"gap-1 text-amber-600 border-amber-300 bg-amber-50 dark:bg-amber-950 dark:text-amber-300",children:[e.jsx(Vt,{className:"h-3 w-3"}),"Needs review"]}),l&&e.jsx(T,{type:"button",variant:"ghost",size:"icon",className:"h-6 w-6 text-green-600 hover:text-green-700 hover:bg-green-50 dark:hover:bg-green-950",title:"Looks good — accept this crop",onClick:S,children:e.jsx(Ht,{className:"h-4 w-4"})})]})]})}),e.jsxs(Fs,{className:"space-y-3",children:[e.jsx("div",{className:"rounded-lg border bg-muted/30 overflow-hidden flex items-center justify-center",style:{aspectRatio:`${n.aspectW} / ${n.aspectH}`},children:i?e.jsx("img",{src:i.imageUrl,alt:i.altText,className:"w-full h-full object-cover"}):e.jsx("span",{className:"text-xs text-muted-foreground px-4 text-center",children:"No image yet"})}),i&&e.jsxs(T,{type:"button",variant:"outline",size:"sm",disabled:A,onClick:K,children:[e.jsx(Kt,{className:"h-3.5 w-3.5 mr-1.5"}),A?"Downloading…":`Download ${n.exportWidth}×${n.exportHeight}`]}),l&&e.jsxs("div",{className:"flex flex-wrap gap-2",children:[!i&&h.length>0&&e.jsxs(T,{type:"button",variant:"default",size:"sm",onClick:()=>k(!0),children:[e.jsx(we,{className:"h-3.5 w-3.5 mr-1.5"}),"Use an existing photo"]}),e.jsxs(T,{type:"button",variant:!i&&h.length>0?"outline":"default",size:"sm",disabled:E,onClick:()=>R.current?.click(),children:[e.jsx(qe,{className:"h-3.5 w-3.5 mr-1.5"}),"Upload new photo"]}),e.jsx("input",{ref:R,type:"file",accept:"image/*",className:"hidden",onChange:j=>{const d=j.target.files?.[0];j.target.value="",d&&G(d)}}),i&&e.jsxs(T,{type:"button",variant:"outline",size:"sm",onClick:()=>r(i.sourceId,i.sourceUrl??i.imageUrl,!0),children:[e.jsx(ta,{className:"h-3.5 w-3.5 mr-1.5"}),"Recrop"]}),i&&h.length>0&&e.jsxs(T,{type:"button",variant:"outline",size:"sm",onClick:()=>k(!0),children:[e.jsx(we,{className:"h-3.5 w-3.5 mr-1.5"}),"Use a different photo"]})]})]}),e.jsx(fa,{open:D,onOpenChange:k,images:h,onPick:j=>{k(!1);const d=j.id?j.id===i?.sourceId:j.url===i?.imageUrl;r(j.id,j.url,d)}}),e.jsx(Me,{open:!!b,onOpenChange:j=>!j&&C(null),children:e.jsxs(Oe,{className:"max-w-2xl max-h-[90vh] overflow-y-auto",children:[e.jsxs(Be,{children:[e.jsxs(ze,{children:["Crop — ",n.label]}),e.jsxs(Ve,{children:["Drag to reposition, zoom to crop tighter. The export is a real cropped file at ",n.exportWidth,"×",n.exportHeight,"."]})]}),b&&e.jsx(sa,{imageUrl:b.url,slot:n,initialAltText:i?.altText,initialPositionX:b.matchesCurrent?i?.positionX:void 0,initialPositionY:b.matchesCurrent?i?.positionY:void 0,initialScale:b.matchesCurrent?i?.scale:void 0,onSave:L},b.url)]})})]})};function va(s,i){return!(s>0)||!(i>0)?"landscape":i>s?"portrait":"landscape"}function ya(s){return new Promise((i,u)=>{const l=document.createElement("video"),h=URL.createObjectURL(s),y=()=>{l.removeAttribute("src"),l.load(),URL.revokeObjectURL(h)};l.preload="metadata",l.muted=!0,l.onloadedmetadata=()=>{const U=l.videoWidth,S=l.videoHeight,n=Number.isFinite(l.duration)?l.duration:null;y(),i({width:U,height:S,durationSeconds:n,orientation:va(U,S)})},l.onerror=()=>{y(),u(new Error("Could not read this video file"))},l.src=h})}const at="production-signage-videos";
1function ja(s){const[i,u]=o.useState([]),[l,h]=o.useState(!0),[y,U]=o.useState(!1),S=o.useCallback(async()=>{if(!s){h(!1);return}h(!0);try{const{data:k,error:b}=await m.from("production_signage_videos").select("id, video_url, orientation, width, height, duration_seconds, size_bytes, order").eq("production_id",s).order("order").order("created_at");if(b)throw b;u((k??[]).map(C=>({id:C.id,videoUrl:ae(C.video_url),orientation:C.orientation==="portrait"?"portrait":"landscape",width:C.width,height:C.height,durationSeconds:C.duration_seconds,sizeBytes:C.size_bytes,order:C.order})))}catch(k){console.error(k),f.error("Failed to load signage videos")}finally{h(!1)}},[s]);o.useEffect(()=>{S()},[S]);const n=o.useCallback(async k=>{if(s){U(!0);try{let b=i.reduce((C,E)=>Math.max(C,E.order),-1)+1;for(const C of Array.from(k)){if(!C.type.startsWith("video/")){f.error(`${C.name} is not a video`);continue}const E=await ya(C),O=C.name.split(".").pop()||"mp4",A=`${s}/${crypto.randomUUID()}.${O}`,{publicUrl:B}=await de(at,A,C,{contentType:C.type}),{error:r}=await m.from("production_signage_videos").insert({production_id:s,storage_path:A,video_url:B,orientation:E.orientation,mime_type:C.type,duration_seconds:E.durationSeconds,width:E.width,height:E.height,size_bytes:C.size,order:b});if(r)throw r;b+=1}f.success("Video uploaded"),await S()}catch(b){console.error(b),f.error(b instanceof Error?b.message:"Failed to upload video")}finally{U(!1)}}},[s,i,S]),R=o.useCallback(async(k,b)=>{u(E=>E.map(O=>O.id===k?{...O,orientation:b}:O));const{error:C}=await m.from("production_signage_videos").update({orientation:b}).eq("id",k);C&&(f.error("Failed to update video orientation"),await S())},[S]),D=o.useCallback(async(k,b)=>{try{const C=b.split(`/${at}/`)[1];C&&await m.storage.from(at).remove([C]);const{error:E}=await m.from("production_signage_videos").delete().eq("id",k);if(E)throw E;u(O=>O.filter(A=>A.id!==k)),f.success("Video removed")}catch(C){console.error(C),f.error("Failed to remove video")}},[]);return{videos:i,loading:l,isUploading:y,uploadVideos:n,setOrientation:R,removeVideo:D,reload:S}}function Ot(s){if(s==null||!Number.isFinite(s))return null;const i=Math.round(s),u=Math.floor(i/60),l=i%60;return u>0?`${u}:${String(l).padStart(2,"0")}`:`${l}s`}const wa=({productionId:s,canEdit:i})=>{const{videos:u,loading:l,isUploading:h,uploadVideos:y,setOrientation:U,removeVideo:S}=ja(s);return e.jsxs("div",{className:"space-y-3 border-t pt-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold",children:"Signage videos"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Short clips for the foyer screens. Signage playlists prefer a video over the still image when one exists in the screen's shape — upload a 16:9 clip for landscape screens and a 9:16 clip for portrait ones. Clips play muted."})]}),l?e.jsxs("div",{className:"flex items-center text-sm text-muted-foreground",children:[e.jsx(ce,{className:"h-4 w-4 animate-spin mr-2"}),"Loading videos…"]}):e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3",children:[u.map(n=>e.jsxs("div",{className:"rounded-lg border bg-muted/30 overflow-hidden flex flex-col",children:[e.jsxs("div",{className:"relative group bg-black",style:{aspectRatio:n.orientation==="portrait"?"9 / 16":"16 / 9",maxHeight:220},children:[e.jsx("video",{src:n.videoUrl,className:"h-full w-full object-contain",muted:!0,playsInline:!0,preload:"metadata",controls:!0}),i&&e.jsx("button",{type:"button",onClick:()=>S(n.id,n.videoUrl),className:"absolute top-1 right-1 rounded-full bg-black/60 text-white p-1 opacity-0 group-hover:opacity-100 transition-opacity","aria-label":"Remove video",children:e.jsx(ie,{className:"h-3 w-3"})})]}),e.jsxs("div",{className:"p-2 space-y-1.5 text-xs",children:[e.jsxs("div",{className:"flex items-center gap-1.5 flex-wrap text-muted-foreground",children:[n.width&&n.height&&e.jsxs("span",{children:[n.width,"×",n.height]}),Ot(n.durationSeconds)&&e.jsxs("span",{children:["· ",Ot(n.durationSeconds)]})]}),i?e.jsxs(J,{value:n.orientation,onValueChange:R=>U(n.id,R),children:[e.jsx(Z,{className:"h-7 text-xs",children:e.jsx(Q,{})}),e.jsxs(ee,{children:[e.jsx(Y,{value:"landscape",children:"Landscape (16:9)"}),e.jsx(Y,{value:"portrait",children:"Portrait (9:16)"})]})]}):e.jsx(le,{variant:"outline",children:n.orientation==="portrait"?"Portrait (9:16)":"Landscape (16:9)"})]})]},n.id)),i&&e.jsxs("label",{className:Ne("flex flex-col items-center justify-center min-h-[120px] border-2 border-dashed rounded-lg cursor-pointer transition-colors",h?"opacity-50 cursor-not-allowed":"hover:bg-muted/50"),children:[h?e.jsx(ce,{className:"h-5 w-5 mb-1 text-muted-foreground animate-spin"}):e.jsx(qe,{className:"h-5 w-5 mb-1 text-muted-foreground"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:h?"Uploading…":"Add video"}),e.jsx("input",{type:"file",accept:"video/mp4,video/webm,video/quicktime,video/*",multiple:!0,className:"hidden",disabled:h,onChange:n=>{n.target.files?.length&&y(n.target.files),n.target.value=""}})]}),!i&&u.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground col-span-full",children:"No signage videos."})]})]})},ot=s=>s==="image/webp"?"webp":s==="image/png"?"png":"jpg";async function Jt(s){const[{data:i,error:u},{data:l,error:h}]=await Promise.all([m.from("production_images").select("image_type").eq("production_id",s),m.from("hero_carousel_slides").select("image_url, mobile_image_url").eq("production_id",s).maybeSingle()]);if(u)throw u;if(h)throw h;const y=new Set;for(const U of i??[])Wt.includes(U.image_type)&&y.add(U.image_type);return l?.image_url&&y.add("hero_desktop"),l?.mobile_image_url&&y.add("hero_mobile"),y}async function Zt(s,i,u,l){const h=Wt.filter(S=>!u.has(S));if(h.length===0)return;const y=h.filter(S=>S==="hero_desktop"||S==="hero_mobile"),U=h.filter(S=>S!=="hero_desktop"&&S!=="hero_mobile");for(const S of U)await nt(s,i,S);y.length>0&&await es(s,i,y,l.productionTitle)}const Qt=["thumbnail","banner","signage_landscape","signage_portrait"];async function Na(s){const{data:i,error:u}=await m.from("production_images").select("id, image_type, is_primary").eq("production_id",s).neq("image_type","carousel");if(u)throw u;const l={};for(const h of i??[]){const y=h.image_type;Qt.includes(y)&&(l[y]&&!h.is_primary||(l[y]=h.id))}return l}async function Sa(s,i,u){const[l,h]=await Promise.all([Na(s),Jt(s)]);for(const y of Qt)await nt(s,i,y,l[y]);h.has("carousel")||await nt(s,i,"carousel"),await es(s,i,["hero_desktop","hero_mobile"],u.productionTitle)}async function nt(s,i,u,l){const h=Yt[u];if(aa(h)){if(h.target.table!=="production_images")throw new Error(`Slot "${u}" does not target production_images`);const b=it(i.natural_width,i.natural_height,h.aspectW,h.aspectH),{blob:C}=await rt(i.original_url,b,h),E=`${s}/${crypto.randomUUID()}.${ot(C.type)}`,{publicUrl:O}=await de("production-images",E,C,{contentType:C.type}),A={image_url:O,source_id:i.id,crop_x:b.x,crop_y:b.y,crop_width:b.
1width,crop_height:b.height,crop_source_width:b.sourceWidth,crop_source_height:b.sourceHeight,target_aspect_ratio:`${h.aspectW}:${h.aspectH}`,is_auto_generated:!0,needs_review:!0};if(l){const{error:B}=await m.from("production_images").update(A).eq("id",l);if(B)throw B}else{const{error:B}=await m.from("production_images").insert({production_id:s,alt_text:"",image_type:h.target.imageType,is_primary:!0,order:0,...A});if(B)throw B}return}const U=await(await fetch(i.original_url)).blob(),S=new File([U],"carousel-source",{type:U.type||"image/jpeg"}),{file:n}=await oa(S,na.gallery),R=`${s}/${crypto.randomUUID()}.${n.name.split(".").pop()||"jpg"}`,{publicUrl:D}=await de("production-images",R,n,{contentType:n.type}),{error:k}=await m.from("production_images").insert({production_id:s,image_url:D,alt_text:"",image_type:"carousel",is_primary:!0,order:0,source_id:i.id,is_auto_generated:!0,needs_review:!0});if(k)throw k}async function es(s,i,u,l){const{data:h,error:y}=await m.from("hero_carousel_slides").select("id").eq("production_id",s).maybeSingle();if(y)throw y;const U=u.includes("hero_desktop")||!h,S=u.includes("hero_mobile"),n={};if(U){const D=Se("hero_desktop"),k=it(i.natural_width,i.natural_height,D.aspectW,D.aspectH),{blob:b}=await rt(i.original_url,k,D),C=`${s}/hero/${crypto.randomUUID()}.${ot(b.type)}`,{publicUrl:E}=await de("production-images",C,b,{contentType:b.type});Object.assign(n,Ca(E,i.id,k))}if(S){const D=Se("hero_mobile"),k=it(i.natural_width,i.natural_height,D.aspectW,D.aspectH),{blob:b}=await rt(i.original_url,k,D),C=`${s}/hero/mobile-${crypto.randomUUID()}.${ot(b.type)}`,{publicUrl:E}=await de("production-images",C,b,{contentType:b.type});Object.assign(n,ka(E,i.id,k))}if(h){const{error:D}=await m.from("hero_carousel_slides").update(n).eq("id",h.id);if(D)throw D;return}const{error:R}=await m.from("hero_carousel_slides").insert({page:"home",title:l,alt_text:l,is_active:!1,production_id:s,...n});if(R)throw R}const Ca=(s,i,u)=>({image_url:s,source_id:i,crop_x:u.x,crop_y:u.y,crop_width:u.width,crop_height:u.height,crop_source_width:u.sourceWidth,crop_source_height:u.sourceHeight,is_auto_generated:!0,needs_review:!0}),ka=(s,i,u)=>({mobile_image_url:s,mobile_source_id:i,mobile_crop_x:u.x,mobile_crop_y:u.y,mobile_crop_width:u.width,mobile_crop_height:u.height,mobile_crop_source_width:u.sourceWidth,mobile_crop_source_height:u.sourceHeight,mobile_is_auto_generated:!0,mobile_needs_review:!0}),Bt=["thumbnail","banner","signage_landscape","signage_portrait","hero_desktop","hero_mobile"];function Ua(s,i){const[u,l]=o.useState(!0),[h,y]=o.useState([]),[U,S]=o.useState({}),[n,R]=o.useState([]),[D,k]=o.useState(!1),b=o.useCallback(async()=>{if(!s){l(!1);return}l(!0);try{const[{data:j},{data:d},{data:c}]=await Promise.all([m.from("production_images").select("*").eq("production_id",s).order("order"),m.from("hero_carousel_slides").select("*").eq("production_id",s).maybeSingle(),m.from("production_image_sources").select("id, original_url, natural_width, natural_height, created_at").eq("production_id",s).order("created_at",{ascending:!1})]);y(c??[]);const w=new Map((c??[]).map(P=>[P.id,P])),g={},x=[];for(const P of j??[]){if(P.image_type==="carousel"){x.push({id:P.id,imageUrl:ae(P.image_url),altText:P.alt_text,isAutoGenerated:P.is_auto_generated,needsReview:P.needs_review});continue}const W=P.image_type;!Bt.includes(W)||g[W]&&!P.is_primary||(g[W]={rowId:P.id,imageUrl:ae(P.image_url),altText:P.alt_text,sourceId:P.source_id,sourceUrl:P.source_id?ae(w.get(P.source_id)?.original_url??P.image_url):null,positionX:P.image_position_x??50,positionY:P.image_position_y??50,scale:P.image_scale??100,isAutoGenerated:P.is_auto_generated,needsReview:P.needs_review})}d&&(d.image_url&&(g.hero_desktop={rowId:d.id,imageUrl:ae(d.image_url),altText:d.alt_text,sourceId:d.source_id,sourceUrl:d.source_id?ae(w.get(d.source_id)?.original_url??d.image_url):null,positionX:d.image_position_x??50,positionY:d.image_position_y??50,scale:d.image_scale??100,isAutoGenerated:d.is_auto_generated,needsReview:d.needs_review}),d.mobile_image_url&&(g.hero_mobile={rowId:d.id,imageUrl:ae(d.mobile_image_url),altText:d.alt_text,sourceId:d.mobile_source_id,sourceUrl:d.mobile_source_id?ae(w.get(d.mobile_source_id)?.original_url??d.mobile_image_url):null,positionX:d.mobile_position_x??50,positionY:d.mobile_position_y??50,scale:d.mobile_scale??100,isAutoGenerated:d.mobile_is_auto_generated,needsReview:d.mobile_needs_review})),S(g),R(x)}catch(j){console.error(j),f.error("Failed to load production media")}finally{l(!1)}},[s]);o.useEffect(()=>{b()},[b]);const C=o.useMemo(()=>{const j=new Set,d=[];for(const c of h){const w=ae(c.original_url);j.has(w)||(j.add(w),d.push({id:c.id,url:w,label:"Uploaded photo"}))}for(const c of Bt){const w=U[c];!w||w.sourceId||j.has(w.imageUrl)||(j.add(w.imageUrl),d.push({id:null,url:w.imageUrl,label:Yt[c].label}))}for(const c of n)j.has(c.imageUrl)||(j.add(c.imageUrl),d.push({id:null,url:c.imageUrl,label:"Gallery image"}));return d},[h,U,n]),E=o.useCallback(()=>{const j=new Set(Object.keys(U));return n.length>0&&j.add("carousel"),j},[U,n]),O=o.useCallback(async j=>{if(s){k(!0);try{const d=await Mt(s,j);await Zt(s,d,E(),{productionTitle:i}),f.success("Photo uploaded — every empty slot has been auto-cropped. Review recommended."),await b()}catch(d){console.error(d),f.error("Failed to process the photo")}finally{k(!1)}}},[s,i,E,b]),A=o.useCallback(async j=>{if(!s)return null;try{const d=await Mt(s,j);return y(c=>[d,...c]),d}catch(d){return console.error(d),f.error("Failed to upload photo"),null}},[s]),B=o.useCallback(async(j,d,c)=>{if(s){k(!0);try{const w=Se(j),g=c.blob.type==="image/webp"?"webp":c.blob.type==="image/png"?"png":"jpg",P=`${j.startsWith("hero")?`${s}
1/hero`:s}/${crypto.randomUUID()}.${g}`,{publicUrl:W}=await de("production-images",P,c.blob,{contentType:c.blob.type});if(w.target.table==="hero_carousel_slides"){const F=w.target.heroField,q=U.hero_desktop?.rowId??U.hero_mobile?.rowId??null,I=F==="desktop"?{image_url:W,source_id:d.id,crop_x:c.rect.x,crop_y:c.rect.y,crop_width:c.rect.width,crop_height:c.rect.height,crop_source_width:c.rect.sourceWidth,crop_source_height:c.rect.sourceHeight,image_position_x:c.positionX,image_position_y:c.positionY,image_scale:c.scale,alt_text:c.altText||i,is_auto_generated:!1,needs_review:!1}:{mobile_image_url:W,mobile_source_id:d.id,mobile_crop_x:c.rect.x,mobile_crop_y:c.rect.y,mobile_crop_width:c.rect.width,mobile_crop_height:c.rect.height,mobile_crop_source_width:c.rect.sourceWidth,mobile_crop_source_height:c.rect.sourceHeight,mobile_position_x:c.positionX,mobile_position_y:c.positionY,mobile_scale:c.scale,mobile_is_auto_generated:!1,mobile_needs_review:!1};if(q){const{error:z}=await m.from("hero_carousel_slides").update(I).eq("id",q);if(z)throw z}else{const{error:z}=await m.from("hero_carousel_slides").insert({page:"home",title:i,alt_text:c.altText||i,is_active:!1,production_id:s,image_url:F==="desktop"?W:"",...I});if(z)throw z}}else{const F=w.target.imageType,q=U[j]?.rowId,I={image_url:W,alt_text:c.altText||i,source_id:d.id,crop_x:c.rect.x,crop_y:c.rect.y,crop_width:c.rect.width,crop_height:c.rect.height,crop_source_width:c.rect.sourceWidth,crop_source_height:c.rect.sourceHeight,target_aspect_ratio:`${w.aspectW}:${w.aspectH}`,image_position_x:c.positionX,image_position_y:c.positionY,image_scale:c.scale,is_auto_generated:!1,needs_review:!1};if(q){const{error:z}=await m.from("production_images").update(I).eq("id",q);if(z)throw z}else{const{error:z}=await m.from("production_images").insert({production_id:s,image_type:F,is_primary:!0,order:0,...I});if(z)throw z}}f.success("Crop saved"),await b()}catch(w){console.error(w),f.error("Failed to save crop")}finally{k(!1)}}},[s,i,U,b]),r=o.useCallback(async j=>{const d=U[j];if(d)try{const c=Se(j);if(c.target.table==="hero_carousel_slides"){const w=c.target.heroField==="desktop"?{needs_review:!1}:{mobile_needs_review:!1},{error:g}=await m.from("hero_carousel_slides").update(w).eq("id",d.rowId);if(g)throw g}else{const{error:w}=await m.from("production_images").update({needs_review:!1}).eq("id",d.rowId);if(w)throw w}S(w=>{const g=w[j];return g?{...w,[j]:{...g,needsReview:!1}}:w})}catch(c){console.error(c),f.error("Failed to mark as reviewed")}},[U]),G=o.useCallback(async j=>{try{const{error:d}=await m.from("production_images").update({needs_review:!1}).eq("id",j);if(d)throw d;R(c=>c.map(w=>w.id===j?{...w,needsReview:!1}:w))}catch(d){console.error(d),f.error("Failed to mark as reviewed")}},[]),K=o.useCallback(async j=>{if(s){k(!0);try{const{processImageForUpload:d,IMAGE_PRESETS:c}=await Rs(async()=>{const{processImageForUpload:g,IMAGE_PRESETS:x}=await import("./imageUtils-RoQh2GsP.js");return{processImageForUpload:g,IMAGE_PRESETS:x}},[]);let w=n.length;for(const g of Array.from(j)){const{file:x}=await d(g,c.gallery),P=`${s}/${crypto.randomUUID()}.${x.name.split(".").pop()||"jpg"}`,{publicUrl:W}=await de("production-images",P,x,{contentType:x.type}),{error:F}=await m.from("production_images").insert({production_id:s,image_url:W,alt_text:i,image_type:"carousel",is_primary:w===0,order:w,is_auto_generated:!1,needs_review:!1});if(F)throw F;w+=1}f.success("Gallery images added"),await b()}catch(d){console.error(d),f.error("Failed to upload gallery images")}finally{k(!1)}}},[s,i,n.length,b]),L=o.useCallback(async(j,d)=>{try{const c=d.split("/production-images/")[1];c&&await m.storage.from("production-images").remove([c]);const{error:w}=await m.from("production_images").delete().eq("id",j);if(w)throw w;R(g=>g.filter(x=>x.id!==j)),f.success("Image removed")}catch(c){console.error(c),f.error("Failed to remove image")}},[]);return{loading:u,isMutating:D,sources:h,reusableImages:C,strictSlots:U,carouselImages:n,existingSlotKeys:E(),uploadFirstPhoto:O,uploadAdditionalSource:A,saveStrictSlotCrop:B,acceptStrictSlotReview:r,acceptCarouselImageReview:G,uploadCarou
1selImages:K,removeCarouselImage:L,reload:b}}const zt=["thumbnail","banner","signage_landscape","signage_portrait","hero_desktop","hero_mobile"],Pa=({productionId:s,productionTitle:i,canEdit:u})=>{const l=Ua(s,i),h=o.useRef(null),y=async(n,R)=>{try{await Xt(n,`${i}-gallery-${R+1}`)==="opened"&&f.info("Opened the image in a new tab — save it from there.")}catch{f.error("Could not download this image")}},U=async n=>{const R=Array.from(n.target.files??[]);if(n.target.value="",R.length===0)return;if(l.sources.length===0){const[k,...b]=R;await l.uploadFirstPhoto(k);for(const C of b)await l.uploadAdditionalSource(C)}else for(const k of R)await l.uploadAdditionalSource(k)};if(l.loading)return e.jsxs("div",{className:"flex items-center justify-center py-12 text-muted-foreground",children:[e.jsx(ce,{className:"h-5 w-5 animate-spin mr-2"}),"Loading media…"]});const S=[...zt.map(n=>l.strictSlots[n]),...l.carouselImages].filter(n=>n?.needsReview).length;return e.jsxs("div",{className:"space-y-6",children:[u&&e.jsxs("div",{className:"rounded-lg border-2 border-dashed p-6 text-center space-y-2",children:[e.jsx("p",{className:"text-sm font-medium",children:l.sources.length===0?"Upload one photo and every slot below will be auto-cropped — or upload several ready-made images and assign them yourself.":"Add more photos — upload one at a time and assign it to a slot, or drop several at once."}),e.jsxs(T,{type:"button",variant:"outline",disabled:l.isMutating,onClick:()=>h.current?.click(),children:[l.isMutating?e.jsx(ce,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(qe,{className:"h-4 w-4 mr-2"}),"Add photos"]}),e.jsx("input",{ref:h,type:"file",accept:"image/*",multiple:!0,className:"hidden",onChange:U})]}),S>0&&e.jsxs("div",{className:"flex items-center gap-2 text-sm text-amber-700 dark:text-amber-300",children:[e.jsx(Vt,{className:"h-4 w-4"}),S," auto-generated crop",S===1?"":"s"," could use a manual review."]}),e.jsx("div",{className:"grid md:grid-cols-2 lg:grid-cols-3 gap-4",children:zt.map(n=>e.jsx(ba,{slotKey:n,state:l.strictSlots[n],productionTitle:i,canEdit:u,reusableImages:l.reusableImages,onUploadNe
1wSource:l.uploadAdditionalSource,onSaveCrop:(R,D)=>l.saveStrictSlotCrop(n,R,D),onAcceptReview:()=>l.acceptStrictSlotReview(n)},n))}),e.jsxs("div",{className:"space-y-3 border-t pt-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold",children:"Lightbox gallery images"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Extra images shown uncropped in the production page lightbox — no fixed shape required."})]}),e.jsxs("div",{className:"grid grid-cols-3 sm:grid-cols-4 md:grid-cols-6 gap-3",children:[l.carouselImages.map((n,R)=>e.jsxs("div",{className:"relative group aspect-square rounded-lg overflow-hidden border bg-muted/30",children:[e.jsx("img",{src:n.imageUrl,alt:n.altText,className:"w-full h-full object-contain"}),n.needsReview&&e.jsxs("div",{className:"absolute top-1 left-1 flex items-center gap-1",children:[e.jsx(le,{variant:"outline",className:"text-[10px] px-1 py-0 border-amber-300 bg-amber-50 text-amber-700",children:"auto"}),u&&e.jsx("button",{type:"button",onClick:()=>l.acceptCarouselImageReview(n.id),className:"rounded-full bg-green-600 text-white p-0.5 hover:bg-green-700",title:"Looks good — accept this image","aria-label":"Accept this image",children:e.jsx(Ht,{className:"h-3 w-3"})})]}),e.jsxs("div",{className:"absolute top-1 right-1 flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity",children:[e.jsx("button",{type:"button",onClick:()=>y(n.imageUrl,R),className:"rounded-full bg-black/60 text-white p-1","aria-label":"Download image",title:"Download image",children:e.jsx(Kt,{className:"h-3 w-3"})}),u&&e.jsx("button",{type:"button",onClick:()=>l.removeCarouselImage(n.id,n.imageUrl),className:"rounded-full bg-black/60 text-white p-1","aria-label":"Remove image",children:e.jsx(ie,{className:"h-3 w-3"})})]})]},n.id)),u&&e.jsxs("label",{className:Ne("flex flex-col items-center justify-center aspect-square border-2 border-dashed rounded-lg cursor-pointer transition-colors",l.isMutating?"opacity-50 cursor-not-allowed":"hover:bg-muted/50"),children:[e.jsx(qe,{className:"h-5 w-5 mb-1 text-muted-foreground"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"Add images"}),e.jsx("input",{type:"file",accept:"image/*",multiple:!0,className:"hidden",disabled:l.isMutating,onChange:n=>{n.target.files?.length&&l.uploadCarouselImages(n.target.files),n.target.value=""}})]})]})]}),e.jsx(wa,{productionId:s,canEdit:u})]})};function di(){const{id:s}=Ds(),i=Es(),{user:u,isAdmin:l,isShowAdmin:h,isTrustee:y,isMarketing:U,canEditProduction:S,loading:n}=$s(),[R,D]=o.useState(!1),[k,b]=o.useState(!1),[C]=As(),[E,O]=o.useState(C.get("tab")||"basics"),[A,B]=o.useState(!0),[r,G]=o.useState({title:"",slug:"",company_id:"",description:"",synopsis:"",running_time:"",age_guidance:"",show_age_guidance:!1,seating_plan_id:"",type:"Theatre Production",category_id:"",genre_id:"",orphan_ticket_rule:!1,original_thumbnail_url:"",booking_visibility:"visible",booking_opens_at:"",external_production_id:"",theatre_commission_percent:"",box_office_phone:"",box_office_email:"",box_office_hours:""}),K=t=>t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""),L=o.useCallback(t=>{G(a=>({...a,...t})),te(!0)},[]),j=t=>{G(a=>({...a,title:t,...s?{}:{slug:K(t)}})),te(!0)},d=o.useCallback(t=>{w(t),te(!0)},[]),[c,w]=o.useState([]),[g,x]=o.useState({date:"",time:"19:30",seating_plan_id:"",pricing_ids:[],external_sales_type:"website",seating_type:"seat_selection",total_capacity:0}),[P,W]=o.useState(null),[F,q]=o.useState([]),[I,z]=o.useState({category_name:"",description:"",price:0,display_order:0}),[_e,He]=o.useState("0"),[ts,ss]=o.useState(0),[Ce,lt]=o.useState(null),[re,as]=o.useState([]),[is,rs]=o.useState([]),[os,ns]=o.use
1State([]),[ke,ls]=o.useState([]),[Ge,We]=o.useState(""),[me,Ue]=o.useState([]),[fe,ct]=o.useState(""),[dt,mt]=o.useState(""),[oe,cs]=o.useState([]),[ue,be]=o.useState([]),[he,Pe]=o.useState([]),[Te,ut]=o.useState(""),[Fe,Ye]=o.useState(""),[Re,ht]=o.useState(""),[pt,gt]=o.useState(""),[xt,_t]=o.useState(""),[ds,Ke]=o.useState(null),[De,ft]=o.useState(""),[Xe,bt]=o.useState(""),[ms,Je]=o.useState(null),[Ee,vt]=o.useState(""),[Ze,yt]=o.useState(""),[Qe,jt]=o.useState(""),[wt,Nt]=o.useState(!1),[$e,te]=o.useState(!1),[us,ve]=o.useState(!1),Ae=o.useRef(null);o.useEffect(()=>{const t=a=>{$e&&(a.preventDefault(),a.returnValue="")};return window.addEventListener("beforeunload",t),()=>window.removeEventListener("beforeunload",t)},[$e]);const hs=o.useCallback(t=>{$e?(Ae.current=t,ve(!0)):i(t)},[$e,i]);o.useEffect(()=>{!n&&(!u||!l&&!h&&!y&&!U)&&i("/admin/login")},[u,l,h,y,U,n,i]);const St=o.useRef(!1),Ct=o.useRef(!1);o.useEffect(()=>{u&&(l||h||y||U)&&!Ct.current&&(Ct.current=!0,ps(),gs(),xs(),_s(),fs())},[u,l,h,y,U]),o.useEffect(()=>{s&&u&&(l||h||y||U)&&!n&&!St.current&&(St.current=!0,bs(),B(l||y||S(s)))},[s,u,l,h,y,U,n,S]),o.useEffect(()=>{re.length>0&&!g.seating_plan_id&&x(t=>({...t,seating_plan_id:re[0].id}))},[re]);const ps=async()=>{const{data:t,error:a}=await m.from("seating_plan_templates").select("id, name").order("name");!a&&t&&as(t)},gs=async()=>{const{data:t,error:a}=await m.from("categories").select("id, name").order("display_order");!a&&t&&rs(t)},xs=async()=>{const{data:t,error:a}=await m.from("genres").select("id, name, category_id").order("display_order");!a&&t&&ns(t)},_s=async()=>{const{data:t,error:a}=await m.from("companies").select("id, name").order("name");!a&&t&&ls(t)},fs=async()=>{const{data:t,error:a}=await m.from("marketing_platforms").select("id, name").order("display_order");!a&&t&&cs(t)},bs=async()=>{if(!s)return;const{data:t,error:a}=await m.from("productions").select("*").eq("id",s).single();if(a){f.error("Failed to load production"),i("/admin");return}if(t){const p=Le=>typeof Le=="string"?Le:"",v=t,_=p(v.company).trim(),$=v.theatre_commission_percent;G({title:p(t.title),slug:p(t.slug),company_id:t.company_id||"",description:p(t.description),synopsis:p(t.synopsis),running_time:p(t.running_time),age_guidance:p(t.age_guidance),show_age_guidance:t.show_age_guidance||!1,seating_plan_id:t.seating_plan_id||"",type:p(t.type)||"Theatre Production",category_id:t.category_id||"",genre_id:t.genre_id||"",orphan_ticket_rule:t.orphan_ticket_rule||!1,original_thumbnail_url:p(t.original_thumbnail_url),booking_visibility:t.booking_visibility||"visible",booking_opens_at:p(t.booking_opens_at),external_production_id:p(t.external_production_id),theatre_commission_percent:$!=null?String($):"",box_office_phone:p(t.box_office_phone),box_office_email:p(t.box_office_email),box_office_hours:p(t.box_office_hours)}),We(t.company_id?"":_);const{data:V,error:se}=await m.from("showtimes").select(`
2          *,
3          showtime_pricing(pricing_id),
4          showtime_unavailable_seats(
5            row_index, 
6            seat_index, 
7            unavailability_type, 
8            linked_user_id, 
9            free_text_name, 
10            comment, 
11            requires_payment, 
12            created_by_admin_id
13          )
14        `).eq("production_id",s).order("date",{ascending:!0});if(!se&&V){const Le=V.map(H=>H.id),{data:Ss}=await m.from("order_tickets").select(`
15            seat_row,
16            seat_number,
17            showtime_id,
18            order:orders!inner(customer_name, customer_email)
19          `).in("showtime_id",Le),Ie=new Map;Ss?.forEach(H=>{Ie.has(H.showtime_id)||Ie.set(H.showtime_id,[]),Ie.get(H.showtime_id)?.push({row_index:H.seat_row,seat_index:H.seat_number,customer_name:H.order?.customer_name,customer_email:H.order?.customer_email})}),w(V.map(H=>{const Dt=(H.showtime_unavailable_seats||[]).map(X=>({row_index:X.row_index,seat_index:X.seat_index,unavailability_type:X.unavailability_type||"other",linked_user_id:X.linked_user_id,free_text_name:X.free_text_name,comment:X.comment,requires_payment:X.requires_payment||!1,created_by_admin_id:X.created_by_admin_id}));return{id:H.id,date:H.date,time:H.time,seating_plan_id:H.seating_plan_id||"",pricing_ids:(H.showtime_pricing||[]).map(X=>X.pricing_id),unavailable_seats:Dt,_originalUnavailableSeats:Dt,sold_seats:Ie.get(H.id)||[],external_sales_type:H.external_sales_type||"website",external_url:H.external_url||void 0,seating_type:H.seating_type||"seat_selection",total_capacity:H.total_capacity||0}}))}const{data:ye,error:et}=await m.from("production_pricing").select("*").eq("production_id",s).order("display_order");!et&&ye&&q(ye);const{data:Tt,error:Ns}=await m.from("production_videos").select("*").eq("production_id",s).order("display_order");!Ns&&Tt&&Ue(Tt);const{data:Ft}=await m.from("production_short_urls").select("*").eq("production_id",s).order("created_at");Ft&&be(Ft);const{data:Rt}=await m.from("production_blurbs").select("*").eq("production_id",s).order("display_order");Rt&&Pe(Rt)}};o.useEffect(()=>{if(!Ge||r.company_id||ke.length===0)return;const t=ke.find(a=>a.name.trim().toLowerCase()===Ge.toLowerCase());t&&(G(a=>({...a,company_id:t.id})),We(""))},[Ge,r.company_id,ke]);const kt=async t=>{t.preventDefault(),D(!0);try{if(s){const{error:a}=await m.from("productions").update({title:r.title,slug:r.slug,company_id:r.company_id||null,description:r.description,synopsis:r.synopsis,running_time:r.running_time,age_guidance:r.age_guidance,show_age_guidance:r.show_age_guidance,type:r.type,orphan_ticket_rule:r.orphan_ticket_rule,seating_plan_id:r.seating_plan_id||null,category_id:r.category_id||null,genre_id:r.genre_id||null,booking_visibility:r.booking_visibility,booking_opens_at:r.booking_visibility==="scheduled"&&r.booking_opens_at?new Date(r.booking_opens_at).toISOString():null,external_production_id:r.external_production_id||null,theatre_commission_percent:r.theatre_commission_percent!==""?parseFloat(r.theatre_commission_percent):null,box_office_phone:r.box_office_phone||null,box_office_email:r.box_office_email||null,box_office_hours:r.box_office_hours||null,updated_at:new Date().toISOString()}).eq("id",s);if(a)throw a;await m.from("production_categories").delete().eq("production_id",s).eq("is_primary",!0),r.category_id&&await m.from("production_categories").upsert({production_id:s,category_id:r.category_id,is_primary:!0},{onConflict:"production_id,category_id"}),await m.from("production_genres").delete().eq("production_id",s).eq("is_primary",!0),r.genre_id&&await m.from("production_genres").upsert({production_id:s,genre_id:r.genre_id,is_primary:!0},{onConflict:"production_id,genre_id"});const p=c.filter(_=>_.id).map(_=>_.id);p.length>0?await m.from("showtimes").delete().eq("production_id",s).not("id","in",`(${p.join(",")})`):await m.from("showtimes").delete().eq("production_id",s);for(const _ of c){let $=_.id;if(_.id)await m.from("showtimes").update({date:_.date,time:_.time,seating_plan_id:_.seating_plan_id||null,external_sales_type:_.external_sales_type||"website",external_url:_.external_url||null,seating_type:_.seating_type||"seat_selection",total_capacity:_.total_capacity||0}).eq("id",_.id);else{const{data:V}=await m.from("showtimes").insert([{production_id:s,date:_.date,time:_.time,seating_plan_id:_.seating_plan_id||null,external_sales_type:_.external_sales_type||"website",external_url:_.external_url||null,seating_type:_.seating_type||"seat_selection",total_capacity:_.total_capacity||0}]).select().single();if($=V?.id,V&&_.pricing_ids&&_.pricing_ids.length>0&&!_.external_sales_type)try{const{data:se,error:ye}=await m.functions.invoke("get-or-create-shopify-collection",{body:{productionId:s}});ye&&console.error("Failed to get/create collection:",ye);const et=se?.collectionId;await m.functions.invoke("get-or-create-shopify-products",{body:{showtimeId:V.id,categoryIds:_.pricing_ids,collectionId:et}}),console.log("Shopify products created for new showtime:",V.id)}catch(se){console.error("Failed to create Shopify products:",se)}}$&&(await m.from("showtime_pricing").delete().eq("showtime_id",$),_.pricing_ids&&_.pricing_ids.length>0&&await m.from("showtime_pricing").insert(_.pricing_ids.map(V=>({showtime_id:$,pricing_id:V}))))}const v=F.filter(_=>_.id).map(_=>_.id);v.length>0?await m.from("production_pricing").delete().eq("production_id",s).not("id","in",`(${v.join(",")})`):await m.from("production_pricing").delete().eq("production_id",s);for(const _ of F)_.id?await m.from("production_pricing").update({category_name:_.category_name,description:_.description,price:_.price,display_order:_.dis
19play_order}).eq("id",_.id):await m.from("production_pricing").insert([{production_id:s,category_name:_.category_name,description:_.description,price:_.price,display_order:_.display_order}]);te(!1),f.success("Production updated")}else{const{data:a,error:p}=await m.from("productions").insert([{title:r.title,slug:r.slug||K(r.title),company_id:r.company_id||null,description:r.description,synopsis:r.synopsis,running_time:r.running_time,age_guidance:r.age_guidance,show_age_guidance:r.show_age_guidance,type:r.type,orphan_ticket_rule:r.orphan_ticket_rule,seating_plan_id:r.seating_plan_id||null,category_id:r.category_id||null,genre_id:r.genre_id||null,external_production_id:r.external_production_id||null,theatre_commission_percent:r.theatre_commission_percent!==""?parseFloat(r.theatre_commission_percent):null,box_office_phone:r.box_office_phone||null,box_office_email:r.box_office_email||null,box_office_hours:r.box_office_hours||null}]).select().single();if(p)throw p;r.category_id&&await m.from("production_categories").insert({production_id:a.id,category_id:r.category_id,is_primary:!0}),r.genre_id&&await m.from("production_genres").insert({production_id:a.id,genre_id:r.genre_id,is_primary:!0});for(const v of c){const{data:_}=await m.from("showtimes").insert([{production_id:a.id,date:v.date,time:v.time,seating_plan_id:v.seating_plan_id||null,external_sales_type:v.external_sales_type||"website",external_url:v.external_url||null,seating_type:v.seating_type||"seat_selection",total_capacity:v.total_capacity||0}]).select().single();if(_&&v.pricing_ids&&v.pricing_ids.length>0&&(await m.from("showtime_pricing").insert(v.pricing_ids.map($=>({showtime_id:_.id,pricing_id:$}))),!v.external_sales_type))try{const{data:$,error:V}=await m.functions.invoke("get-or-create-shopify-collection",{body:{productionId:a.id}});V&&console.error("Failed to get/create collection:",V);const se=$?.collectionId;await m.functions.invoke("get-or-create-shopify-products",{body:{showtimeId:_.id,categoryIds:v.pricing_ids,collectionId:se}}),console.log("Shopify products created for showtime:",_.id)}catch($){console.error("Failed to create Shopify products:",$)}_&&v.unavailable_seats&&v.unavailable_seats.length>0&&await m.from("showtime_unavailable_seats").insert(v.unavailable_seats.map($=>({showtime_id:_.id,row_index:$.row_index,seat_index:$.seat_index,unavailability_type:$.unavailability_type,linked_user_id:$.linked_user_id||null,free_text_name:$.free_text_name||null,comment:$.comment||null,requires_payment:$.requires_payment,created_by_admin_id:u?.id||null})))}F.length>0&&await m.from("production_pricing").insert(F.map(v=>({production_id:a.id,category_name:v.category_name,description:v.description,price:v.price,display_order:v.display_order}))),te(!1),f.success("Production created")}k?i("/admin"):b(!1)}catch(a){console.error(a);const p=a?.message||a?.details||"Unknown error occurred";f.error(`Failed to save ${r.type==="Daytime Course"?"course":"production"}: ${p}`)}finally{D(!1)}},vs=()=>
19{if(!g.date||!g.time){f.error("Please fill in date and time");return}d([...c,{...g}]),x({date:"",time:"19:30",seating_plan_id:re.length>0?re[0].id:"",pricing_ids:F.map(t=>t.id).filter(Boolean),external_sales_type:"website"})},ys=t=>{d(c.filter((a,p)=>p!==t))},Ut=(t,a)=>{const p=c[t],v=new Date(p.date),_=new Date(v);_.setDate(_.getDate()+a);const $={...p,id:void 0,date:ne(_,"yyyy-MM-dd")};d([...c,$]),f.success(`Performance duplicated ${a} day${a>1?"s":""} later`)},js=()=>{const t=_e.trim()===""?NaN:Number(_e);if(!I.category_name||Number.isNaN(t)||t<0){f.error("Please fill in category name and price (can be £0 for free)");return}q([...F,{...I,price:t,display_order:F.length}]),z({category_name:"",description:"",price:0,display_order:0}),He("0"),te(!0)},ws=t=>{q(F.filter((a,p)=>p!==t)),te(!0)},Pt=async t=>{if(!(!s||!r.original_thumbnail_url)){lt(t),f.info("Fetching image from URL...");try{const{data:a,error:p}=await m.functions.invoke("process-thumbnail-url",{body:{production_id:s,original_thumbnail_url:r.original_thumbnail_url}});if(p)throw p;const v=zs("production-images",a.storage_path),_=await ia(v),$=await ra(s,{storagePath:a.storage_path,originalUrl:v,naturalWidth:_.naturalWidth,naturalHeight:_.naturalHeight});if(t==="all")await Sa(s,$,{productionTitle:r.title}),f.success("Image imported — every slot updated from this photo");else{const V=await Jt(s);await Zt(s,$,V,{productionTitle:r.title}),f.success("Image imported — filled in every empty slot")}ss(V=>V+1)}catch(a){console.error("Original Thumbnail URL processing failed:",a),f.error(a?.message||"Failed to process thumbnail — check the browser console for details")}finally{lt(null)}}};return n||!u||!l&&!h&&!y&&!U?null:e.jsxs("div",{className:"min-h-screen bg-background",children:[e.jsx("header",{className:"border-b border-border",children:e.jsxs("div",{className:"container mx-auto px-4 py-4",children:[e.jsxs(T,{variant:"ghost",onClick:()=>i("/admin"),className:"mb-2",children:[e.jsx(Ls,{className:"mr-2 h-4 w-4"}),"Back to Dashboard"]}),e.jsx("h1",{className:"text-2xl font-bold text-foreground",children:s?"Edit Production":"New Production"})]})}),e.jsxs("main",{className:"container mx-auto px-4 py-8 max-w-4xl",children:[!A&&s&&e.jsx("div",{className:"mb-6 p-4 border border-muted rounded-lg bg-muted/10",children:e.jsxs("div",{className:"flex items-center gap-2 text-muted-foreground",children:[e.jsx(Is,{className:"h-5 w-5"}),e.jsxs("div",{children:[e.jsx("p",{className:"font-semibold",children:"Read-Only Mode"}),e.jsx("p",{className:"text-sm",children:"You don't have permission to edit this production"})]})]})}),e.jsxs("form",{onSubmit:kt,className:"space-y-6",children:[e.jsxs(Vs,{value:E,onValueChange:O,children:[e.jsxs(Hs,{className:"grid w-full grid-cols-6",children:[e.jsx(pe,{value:"basics",children:"Basics"}),e.jsx(pe,{value:"pricing",children:"Pricing"}),e.jsx(pe,{value:"details",children:"Details"}),e.jsx(pe,{value:"images",children:"Images"}),e.jsx(pe,{value:"marketing",children:"Marketing"}),e.jsx(pe,{value:"external",children:"External Sales"})]}),e.jsxs(ge,{value:"basics",className:"space-y-6 mt-6",children:[e.jsxs("div",{children:[e.jsx(N,{htmlFor:"title",children:"Title"}),e.jsx(M,{id:"title",value:r.title,onChange:t=>j(t.target.value),required:!0,disabled:!A,placeholder:"The Lion King",className:"mt-1"})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"slug",children:"URL Slug"}),e.jsx(M,{id:"slug",value:r.slug,onChange:t=>L({slug:t.target.value.toLowerCase().replace(/[^a-z0-9-]+/g,"-").replace(/^-+|-+$/g,"")}),required:!0,disabled:!A,placeholder:"the-lion-king",className:"mt-1"}),e.jsxs("p",{className:"text-sm text-muted-foreground mt-1",children:["URL: /shows/",r.slug||"your-show-title"]})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"company_id",children:"Company"}),e.jsxs(J,{value:r.company_id||"none",onValueChange:t=>{We(""),L({company_id:t==="none"?"":t})},disabled:!A,children:[e.jsx(Z,{className:"mt-1",children:e.jsx(Q,{placeholder:"Select a company (optional)"})}),e.jsxs(ee,{children:[e.jsx(Y,{value:"none",children:"No company"}),ke.map(t=>e.jsx(Y,{value:t.id,children:t.name},t.id))]})]})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"description",children:"Short Description"}),e.jsx(Gt,{id:"description",value:r.description,onChange:t=>L({description:t.target.value}),required:!0,disabled:!A,placeholder:"A brief one-line description for cards",rows:2,className:"mt-1"})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"synopsis",children:"Full Synopsis"}),e.jsx("div",{className:"mt-1",children:e.jsx(tt,{value:r.synopsis,onChange:t=>L({synopsis:t}),placeholder:"Full production synopsis"})})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"type",children:"Production Type"}
19),e.jsxs("select",{id:"type",value:r.type,onChange:t=>L({type:t.target.value}),className:"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 mt-1",children:[e.jsx("option",{value:"Theatre Production",children:"Theatre Production"}),e.jsx("option",{value:"Daytime Course",children:"Daytime Course"})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx(N,{htmlFor:"running_time",children:"Running Time"}),e.jsx(M,{id:"running_time",value:r.running_time,onChange:t=>L({running_time:t.target.value}),required:!0,placeholder:"2 hours 30 minutes",className:"mt-1"})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"age_guidance",children:"Age Guidance"}),e.jsx(M,{id:"age_guidance",value:r.age_guidance,onChange:t=>L({age_guidance:t.target.value}),placeholder:"PG / 12+ / etc (optional)",className:"mt-1"}),e.jsxs("div",{className:"flex items-center space-x-2 mt-2",children:[e.jsx(It,{id:"show_age_guidance",checked:r.show_age_guidance,onCheckedChange:t=>L({show_age_guidance:!!t})}),e.jsx(N,{htmlFor:"show_age_guidance",className:"text-sm font-normal text-muted-foreground",children:"Show Age Guidance on listing pages"})]})]})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"seating_plan",children:"Seating Plan Template"}),e.jsxs("select",{id:"seating_plan",value:r.seating_plan_id,onChange:t=>L({seating_plan_id:t.target.value}),className:"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm r
19ing-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 mt-1",children:[e.jsx("option",{value:"",children:"No seating plan"}),re.map(t=>e.jsx("option",{value:t.id,children:t.name},t.id))]})]}),e.jsxs("div",{className:"border-t pt-6",children:[e.jsx("h2",{className:"text-xl font-semibold mb-4",children:"Performance Dates & Times"}),c.length>0&&e.jsx("div",{className:"space-y-2 mb-4",children:c.map((t,a)=>e.jsxs("div",{className:"flex items-center gap-2 p-3 border rounded-lg",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("span",{className:"font-medium",children:ne(new Date(t.date),"PPP")}),e.jsx("span",{className:"mx-2",children:"•"}),e.jsx("span",{children:qs(t.time)}),e.jsx("span",{className:"mx-2",children:"•"}),e.jsx("span",{className:"text-sm text-muted-foreground",children:t.seating_type==="general_seating"?`General Seating (${t.total_capacity||0} seats)`:"Seat Selection"}),t.seating_type==="seat_selection"&&t.seating_plan_id&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"mx-2",children:"•"}),e.jsx("span",{className:"text-sm text-muted-foreground",children:"Has seating plan"})]}),t.unavailable_seats&&t.unavailable_seats.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"mx-2",children:"•"}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[t.unavailable_seats.length," seat(s) unavailable"]})]}),t.pricing_ids&&t.pricing_ids.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"mx-2",children:"•"}),e.jsxs("span",{className:"text-sm text-muted-foreground",children:[t.pricing_ids.length," price categor",t.pricing_ids.length===1?"y":"ies"]})]})]}),e.jsxs(Me,{children:[e.jsx(Ms,{asChild:!0,children:e.jsx(T,{type:"button",variant:"outline",size:"sm",onClick:()=>W(a),children:e.jsx(st,{className:"h-4 w-4"})})}),e.jsxs(Oe,{className:"max-w-4xl max-h-[90vh] overflow-y-auto",children:[e.jsxs(Be,{children:[e.jsx(ze,{children:"Manage Performance"}),e.jsxs(Ve,{children:[ne(new Date(t.date),"PPP")," at ",t.time]})]}),e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold mb-3",children:"Seating Configuration"}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4",children:[e.jsxs("div",{children:[e.jsx(N,{htmlFor:`seating_type_${a}`,children:"Seating Type"}),e.jsxs("select",{id:`seating_type_${a}`,value:t.seating_type||"seat_selection",onChange:p=>{const v=[...c];v[a]={...v[a],seating_type:p.target.value,seating_plan_id:p.target.value==="general_seating"?"":v[a].seating_plan_id},d(v)},className:"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm r
19ing-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 mt-1",children:[e.jsx("option",{value:"seat_selection",children:"Seat Selection"}),e.jsx("option",{value:"general_seating",children:"General Seating"})]})]}),t.seating_type==="seat_selection"&&e.jsxs("div",{children:[e.jsx(N,{htmlFor:`edit_seating_plan_${a}`,children:"Seating Plan"}),e.jsxs("select",{id:`edit_seating_plan_${a}`,value:t.seating_plan_id||"",onChange:p=>{const v=[...c];v[a]={...v[a],seating_plan_id:p.target.value},d(v)},className:"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 mt-1",children:[e.jsx("option",{value:"",children:"Use default"}),re.map(p=>e.jsx("option",{value:p.id,children:p.name},p.id))]})]}),t.seating_type==="general_seating"&&e.jsxs("div",{children:[e.jsx(N,{htmlFor:`edit_capacity_${a}`,children:"Total Capacity"}),e.jsx(M,{id:`edit_capacity_${a}`,type:"number",min:"0",value:t.total_capacity||0,onChange:p=>{const v=[...c];v[a]={...v[a],total_capacity:parseInt(p.target.value)||0},d(v)},className:"mt-1"})]})]})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold mb-3",children:"Price Categories"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-3",children:"Select which price categories are available for this performance"}),F.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No pricing tiers defined yet. Add them in the Pricing tab."}):e.jsx("div",{className:"space-y-2",children:F.map(p=>e.jsxs("label",{className:"flex items-center gap-2 p-2 border rounded cursor-pointer hover:bg-muted/50",children:[e.jsx("input",{type:"checkbox",checked:t.pricing_ids?.includes(p.id||"")||!1,onChange:v=>{const _=[...c],$=_[a].pricing_ids||[];v.target.checked?_[a]={..._[a],pricing_ids:[...$,p.id||""]}:_[a]={..._[a],pricing_ids:$.filter(V=>V!==p.id)},d(_)},className:"rounded border-gray-300"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"font-medium",children:p.category_name}),e.jsxs("div",{className:"text-sm text-muted-foreground",children:["£",p.price.toFixed(2)]})]})]},p.id))})]}),t.seating_type==="seat_selection"&&t.seating_plan_id&&e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold mb-3",children:"Seat Availability"}),e.jsx(pa,{showtimeId:t.id||"",seatingPlanId:t.seating_plan_id,soldSeats:t.sold_seats||[]})]})]})]})]}),e.jsx(T,{type:"button",variant:"ghost",size:"sm",onClick:()=>Ut(a,1),title:"Duplicate +1 day",children:e.jsx(we,{className:"h-4 w-4"})}),e.jsx(T,{type:"button",variant:"ghost",size:"sm",onClick:()=>Ut(a,7),title:"Duplicate +7 days",children:e.jsx(ua,{className:"h-4 w-4"})}),e.jsx(T,{type:"button",variant:"ghost",size:"sm",onClick:()=>ys(a),children:e.jsx(ie,{className:"h-4 w-4"})})]},a))}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[e.jsxs("div",{children:[e.jsx(N,{children:"Date"}),e.jsxs(ca,{children:[e.jsx(da,{asChild:!0,children:e.jsx(T,{type:"button",variant:"outline",className:Ne("w-full justify-start text-left font-normal mt-1",!g.date&&"text-muted-foreground"),children:g.date?ne(new Date(g.date),"PPP"):e.jsx("span",{children:"Pick a date"})})}),e.jsx(ma,{className:"w-auto p-0",align:"start",children:e.jsx(la,{mode:"single",selected:g.date?new Date(g.date):void 0,onSelect:t=>x({...g,date:t?ne(t,"yyyy-MM-dd"):""}),initialFocus:!0,className:"pointer-events-auto"})})]})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"time",children:"Time"}),e.jsx(M,{id:"time",type:"time",value:g.time,onChange:t=>x({...g,time:t.target.value}),className:"mt-1"})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"seating_type",children:"Seating Type"}),e.jsxs("select",{id:"seating_type",value:g.seating_type||"seat_selection",onChange:t=>x({...g,seating_type:t.target.value,seating_plan_id:t.target.value==="general_seating"?"":g.seating_plan_id}),className:"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm r
19ing-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 mt-1",children:[e.jsx("option",{value:"seat_selection",children:"Seat Selection"}),e.jsx("option",{value:"general_seating",children:"General Seating"})]})]})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4 items-end",children:[g.seating_type==="seat_selection"&&e.jsxs("div",{children:[e.jsx(N,{htmlFor:"showtime_seating_plan",children:"Seating Plan"}),e.jsxs("select",{id:"showtime_seating_plan",value:g.seating_plan_id||"",onChange:t=>x({...g,seating_plan_id:t.target.value}),className:"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 mt-1",children:[e.jsx("option",{value:"",children:"Use default"}),re.map(t=>e.jsx("option",{value:t.id,children:t.name},t.id))]})]}),g.seating_type==="general_seating"&&e.jsxs("div",{children:[e.jsx(N,{htmlFor:"total_capacity",children:"Total Capacity"}),e.jsx(M,{id:"total_capacity",type:"number",min:"0",value:g.total_capacity||0,onChange:t=>x({...g,total_capacity:parseInt(t.target.value)||0}),className:"mt-1"})]}),e.jsxs(T,{type:"button",onClick:vs,className:"gap-2 md:col-start-3",children:[e.jsx(je,{className:"h-4 w-4"}),"Add Showtime"]})]})]})]})]}),e.jsxs(ge,{value:"pricing",className:"space-y-6 mt-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-semibold mb-2",children:"Ticket Price Categories"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:"Define different pricing tiers for tickets (e.g., Full Price, Concession, Child, Senior)"})]}),F.length>0&&e.jsx("div",{className:"space-y-2 mb-4",children:F.map((t,a)=>e.jsxs("div",{className:"flex items-center gap-2 p-4 border rounded-lg",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"font-medium",children:t.category_name}),t.description&&e.jsx("div",{className:"text-sm text-muted-foreground",children:t.description}),e.jsxs("div",{className:"text-sm font-semibold mt-1",children:["£",t.price.toFixed(2)]})]}),e.jsx(T,{type:"button",variant:"ghost",size:"sm",onClick:()=>ws(a),children:e.jsx(ie,{className:"h-4 w-4"})})]},a))}),e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{children:[e.jsx(N,{htmlFor:"category_name",children:"Category Name"}),e.jsx(M,{id:"category_name",value:I.category_name,onChange:t=>z({...I,category_name:t.target.value}),placeholder:"e.g., Full Price, Concession, Child",className:"mt-1"})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"tier_description",children:"Description (Optional)"}),e.jsx(M,{id:"tier_description",value:I.description,onChange:t=>z({...I,description:t.target.value}),placeholder:"e.g., Students and seniors with valid ID",className:"mt-1"})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"tier_price",children:"Price (£)"}),e.jsx(M,{id:"tier_price",type:"number",step:"0.01",min:"0",value:_e,onChange:t=>He(t.target.value),placeholder:"0.00",className:"mt-1"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Enter 0 for free tickets"})]}),e.jsxs(T,{type:"button",onClick:js,className:"gap-2",children:[e.jsx(je,{className:"h-4 w-4"}),"Add Pricing Tier"]})]})]}),e.jsxs(ge,{value:"details",className:"space-y-6 mt-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-semibold mb-2",children:"Production Details"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:"Categorize your production for better organization and filtering"})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx(N,{htmlFor:"category",children:"Category"}),e.jsxs(J,{value:r.category_id,onValueChange:t=>{L({category_id:t,genre_id:""})},children:[e.jsx(Z,{id:"category",className:"mt-1",children:e.jsx(Q,{placeholder:"Select category"})}),e.jsx(ee,{children:is.map(t=>e.jsx(Y,{value:t.id,children:t.name},t.id))})]})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"genre",children:"Genre"}),e.jsxs(J,{value:r.genre_id,onValueChange:t=>L({genre_id:t}),disabled:!r.category_id,children:[e.jsx(Z,{id:"genre",className:"mt-1",children:e.jsx(Q,{placeholder:r.category_id?"Select genre":"Select category first"})}),e.jsx(ee,{children:os.filter(t=>t.category_id===r.category_id).map(t=>e.jsx(Y,{value:t.id,children:t.name},t.id))})]})]})]}),e.jsxs("div",{className:"border-t pt-6",children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:"Booking Rules"}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(N,{htmlFor:"booking_visibility",className:"font-medium",children:"Booking Availability"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-2",children:"Control when customers can book tickets for this production"}),e.jsxs(J,{value:r.booking_visibility,onValueChange:t=>L({booking_visibility:t}),children:[e.jsx(Z,{className:"w-full md:w-80",children:e.jsx(Q,{})}),e.jsxs(ee,{children:[e.jsx(Y,{value:"visible",children:"Booking available now"}),e.jsx(Y,{value:"hidden",children:"Booking hidden completely"}),e.jsx(Y,{value:"scheduled",children:"Booking opens on a specific date"})]})]})]}),r.booking_visibility==="scheduled"&&e.jsxs("div",{children:[e.jsx(N,{htmlFor:"booking_opens_at",className:"font-medium",children:"Booking Opens"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-2",children:"Date and time when booking becomes available"}),e.jsx(M,{id:"booking_opens_at",type:"datetime-local",value:r.booking_opens_at?ne(new Date(r.booking_opens_at),"yyyy-MM-dd'T'HH:mm"):"",onCh
19ange:t=>L({booking_opens_at:t.target.value}),className:"w-full md:w-80"})]}),e.jsxs("div",{className:"flex items-center gap-3 pt-2",children:[e.jsx(It,{id:"orphan_ticket_rule",checked:r.orphan_ticket_rule,onCheckedChange:t=>L({orphan_ticket_rule:t})}),e.jsxs(N,{htmlFor:"orphan_ticket_rule",className:"cursor-pointer",children:[e.jsx("div",{className:"font-medium",children:"Orphan Ticket Rule"}),e.jsx("div",{className:"text-sm text-muted-foreground font-normal",children:"Prevent customers from leaving single isolated seats when booking"})]})]})]}),e.jsxs("div",{className:"border-t pt-6",children:[e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"Box Office Override"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:"Leave blank to use the default Abbey Theatre box office details."}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(N,{htmlFor:"box_office_phone",className:"font-medium",children:"Phone Number"}),e.jsx(M,{id:"box_office_phone",value:r.box_office_phone,onChange:t=>L({box_office_phone:t.target.value}),placeholder:"e.g. 02476 234567",className:"w-full md:w-80"})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"box_office_email",className:"font-medium",children:"Email"}),e.jsx(M,{id:"box_office_email",type:"email",value:r.box_office_email,onChange:t=>L({box_office_email:t.target.value}),placeholder:"e.g. [email protected]",className:"w-full md:w-80"})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"box_office_hours",className:"font-medium",children:"Opening Hours"}),e.jsx(M,{id:"box_office_hours",value:r.box_office_hours,onChange:t=>L({box_office_hours:t.target.value}),placeholder:"e.g. Mon-Fri 10am-4pm",className:"w-full md:w-80"})]})]})]})]}),e.jsxs("div",{className:"border-t pt-6",children:[e.jsx("h3",{className:"text-lg font-semibold mb-4",children:"Financial"}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"theatre_commission_percent",children:"Theatre Commission (%)"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-2",children:"Percentage commission the theatre takes from ticket revenue for this production"}),e.jsx(M,{id:"theatre_commission_percent",type:"number",min:"0",max:"100",step:"0.1",value:r.theatre_commission_percent,onChange:t=>L({theatre_commission_percent:t.target.value}),placeholder:"e.g. 20",className:"w-full md:w-40"})]})]})]}),e.jsxs(ge,{value:"images",className:"space-y-6 mt-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-semibold mb-2",children:"Production Media"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:"Upload, crop, and assign images for every place this production appears — What's On, the homepage hero, both signage orientations, the production page banner, and the lightbox gallery."})]}),!s&&e.jsx("div",{className:"p-4 border border-yellow-500 bg-yellow-50 dark:bg-yellow-950 rounded-lg",children:e.jsx("p",{className:"text-sm text-yellow-800 dark:text-yellow-200",children:"Please save the production first before uploading images."})}),e.jsx("div",{className:"space-y-6",children:s&&e.jsx(Pa,{productionId:s,productionTitle:r.title,canEdit:A},ts)}),e.jsxs("div",{className:"space-y-4 border-t pt-6",children:[e.jsx("h3",{className:"font-semibold",children:"Original Thumbnail URL"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Used for API imports. ",e.jsx("strong",{children:"Process"})," fetches the image and updates every slot from it — What's On thumbnail, production banner, both signage orientations, homepage hero, and the lightbox gallery.",e.jsx("strong",{children:" Process Missing"}
19)," only fills in slots that don't have a photo yet, leaving everything else untouched."]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(M,{value:r.original_thumbnail_url,onChange:t=>L({original_thumbnail_url:t.target.value}),placeholder:"https://example.com/image.jpg",className:"flex-1",disabled:!s}),e.jsx(T,{type:"button",disabled:!r.original_thumbnail_url||!s||Ce!==null,onClick:()=>Pt("all"),title:"Fetch this image and update every slot with it",children:Ce==="all"?e.jsx(ce,{className:"h-4 w-4 animate-spin"}):"Process"}),e.jsx(T,{type:"button",variant:"outline",disabled:!r.original_thumbnail_url||!s||Ce!==null,onClick:()=>Pt("missing"),title:"Only fill slots that don't have a photo yet",children:Ce==="missing"?e.jsx(ce,{className:"h-4 w-4 animate-spin"}):"Process Missing"})]}),r.original_thumbnail_url&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Current source: ",r.original_thumbnail_url]})]}),e.jsxs("div",{className:"space-y-4 border-t pt-6",children:[e.jsx("h3",{className:"font-semibold",children:"YouTube Videos"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Add YouTube video links to showcase trailers, behind-the-scenes, or promotional content."}),me.length>0&&e.jsx("div",{className:"space-y-2",children:me.map((t,a)=>e.jsxs("div",{className:"flex items-center gap-2 p-3 border rounded-lg bg-muted/30",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"font-medium text-sm",children:t.title||"Untitled Video"}),e.jsx("a",{href:t.youtube_url,target:"_blank",rel:"noopener noreferrer",className:"text-xs text-primary hover:underline truncate block",children:t.youtube_url})]}),e.jsx(T,{type:"button",variant:"ghost",size:"sm",onClick:async()=>{if(t.id){const{error:p}=await m.from("production_videos").delete().eq("id",t.id);p?f.error("Failed to delete video"):(Ue(me.filter(v=>v.id!==t.id)),f.success("Video deleted"))}else Ue(me.filter((p,v)=>v!==a))},children:e.jsx(ie,{className:"h-4 w-4"})})]},t.id||a))}),e.jsxs("div",{className:"grid gap-3",children:[e.jsxs("div",{children:[e.jsx(N,{htmlFor:"video_url",children:"YouTube URL"}),e.jsx(M,{id:"video_url",value:fe,onChange:t=>ct(t.target.value),placeholder:"https://www.youtube.com/watch?v=...",className:"mt-1",disabled:!s})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"video_title",children:"Video Title (optional)"}),e.jsx(M,{id:"video_title",value:dt,onChange:t=>mt(t.target.value),placeholder:"e.g., Official Trailer",className:"mt-1",disabled:!s})]}),e.jsxs(T,{type:"button",variant:"outline",className:"gap-2",disabled:!fe||!s,onClick:async()=>{if(!s||!fe)return;if(!/(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/|youtube\.com\/v\/)([a-zA-Z0-9_-]{11})/.test(fe)){f.error("Please enter a valid YouTube URL");return}const{data:a,error:p}=await m.from("production_videos").insert({production_id:s,youtube_url:fe,title:dt||null,display_order:me.length}).select().single();p?f.error("Failed to add video"):(Ue([...me,a]),ct(""),mt(""),f.success("Video added"),te(!0))},children:[e.jsx(je,{className:"h-4 w-4"}),"Add Video"]})]}),!s&&e.jsx("p",{className:"text-xs text-muted-foreground",children:"Save the production first to add videos."})]})]}),e.jsx(ge,{value:"marketing",className:"space-y-6 mt-6",children:e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-semibold mb-2",children:"Marketing"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-6",children:"Manage short URLs and blurbs for marketing this production across platforms."}),s?e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{className:"space-y-4",children:[e.jsx("h3",{className:"font-semibold",children:"Short URLs"}),ue.length>0&&e.jsx("div",{className:"space-y-2",children:ue.map(t=>e.jsx("div",{className:"p-3 border rounded-lg bg-muted/30 space-y-2",children:ds===t.id?e.jsxs("div",{className:"grid gap-3 sm:grid-cols-[1fr_auto_auto_auto] items-end",children:[e.jsxs("div",{children:[e.jsx(N,{children:"URL"}),e.jsx(M,{value:De,onChange:a=>ft(a.target.value),className:"mt-1"})]}),e.jsxs("div",{children:[e.jsx(N,{children:"Platform"}),e.jsxs(J,{value:Xe,onValueChange:bt,children:[e.jsx(Z,{className:"mt-1 w-[180px]",children:e.jsx(Q,{placeholder:"Select platform"})}),e.jsx(ee,{children:oe.map(a=>e.jsx(Y,{value:a.id,children:a.name},a.id))})]})]}),e.jsx(T,{type:"button",variant:"default",size:"sm",disabled:!De,onClick:async()=>{const{error:a}=await m.from("production_short_urls").update({url:De,platform_id:Xe||null}).eq("id",t.id);a?f.error("Failed to update short URL"):(be(ue.map(p=>p.id===t.id?{...p,url:De,platform_id:Xe||null}:p)),Ke(null),f.success("Short URL updated"))},children:"Save"}),e.jsx(T,{type:"button",variant:"ghost",size:"sm",onClick:()=>Ke(null),children:"Cancel"})]}):e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("a",{href:t.url,target:"_blank",rel:"noopener noreferrer",className:"text-sm text-primary hover:underline truncate block",children:t.url}),t.platform_id&&e.jsx("span",{className:"text-xs text-muted-foreground",children:oe.find(a=>a.id===t.platform_id)?.name||"Unknown"})]}),e.jsx(T,{type:"button",variant:"ghost",size:"sm",title:"Copy URL",onClick:()=>{navigator.clipboard.writeText(t.url),f.success("URL copied to clipboard")},children:e.jsx(we,{className:"h-4 w-4"})}),e.jsx(T,{type:"button",variant:"ghost",size:"sm",title:"Edit",onClick:()=>{Ke(t.id),ft(t.url),bt(t.platform_id||"")},children:e.jsx(st,{className:"h-4 w-4"})}),e.jsx(T,{type:"button",variant:"destructive",size:"sm",onClick:async()=>{const{error:a}=await m.from("production_short_urls").delete().eq("id",t.id);a?f.error("Failed to delete short URL"):(be(ue.filter(p=>p.id!==t.id)),f.success("Short URL deleted"))},children:e.jsx(ie,{className:"h-4 w-4"})})]})},t.id))}),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-[1fr_auto_auto] items-end",children:[e.jsxs("div",{children:[e.jsx(N,{htmlFor:"short_url",children:"URL"}),e.jsx(M,{id:"short_url",value:Te,onChange:t=>ut(t.target.value),placeholder:"https://bit.ly/...",className:"mt-1"})]}),e.jsxs("div",{children:[e.jsx(N,{children:"Platform"}),e.jsxs(J,{value:Fe,onValueChange:Ye,children:[e.jsx(Z,{className:"mt-1 w-[180px]",children:e.jsx(Q,{placeholder:"Select platform"})}),e.jsx(ee,{children:oe.map(t=>e.jsx(Y,{value:t.id,children:t.name},t.id))})]})]}),e.jsxs(T,{type:"button",variant:"outline",className:"gap-2",disabled:!Te,onClick:async()=>
19{if(!s||!Te)return;const{data:t,error:a}=await m.from("production_short_urls").insert({production_id:s,url:Te,platform_id:Fe||null}).select().single();a?f.error("Failed to add short URL"):(be([...ue,t]),ut(""),Ye(""),f.success("Short URL added"))},children:[e.jsx(je,{className:"h-4 w-4"}),"Add URL"]}),e.jsxs(T,{type:"button",variant:"outline",className:"gap-2",disabled:!s||!r.slug||wt,onClick:async()=>{if(!(!s||!r.slug)){Nt(!0);try{const t=`https://www.abbeytheatre.co.uk/shows/${r.slug}`,a=oe.find(se=>se.id===Fe),p=a?`${r.title} - ${a.name}`:r.title,{data:v,error:_}=await m.functions.invoke("generate-short-url",{body:{originalURL:t,title:p}});if(_||!v?.shortURL)throw new Error(v?.error||_?.message||"Failed to generate short URL");const{data:$,error:V}=await m.from("production_short_urls").insert({production_id:s,url:v.shortURL,platform_id:Fe||null}).select().single();V?f.error("Short URL generated but failed to save"):(be([...ue,$]),Ye(""),f.success("Short URL generated and saved"))}catch(t){f.error(t.message||"Failed to generate short URL")}finally{Nt(!1)}}},children:[wt?e.jsx(ce,{className:"h-4 w-4 animate-spin"}):e.jsx(Os,{className:"h-4 w-4"}),"Generate Short URL"]})]})]}),e.jsxs("div",{className:"space-y-4 border-t pt-6",children:[e.jsx("h3",{className:"font-semibold",children:"Blurbs"}),he.length>0&&e.jsx("div",{className:"space-y-3",children:he.map(t=>e.jsx("div",{className:"p-4 border rounded-lg bg-muted/30 space-y-2",children:ms===t.id?e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx(N,{children:"Platform"}),e.jsxs(J,{value:Qe,onValueChange:jt,children:[e.jsx(Z,{className:"mt-1",children:e.jsx(Q,{placeholder:"Select platform"})}),e.jsx(ee,{children:oe.map(a=>e.jsx(Y,{value:a.id,children:a.name},a.id))})]})]}),e.jsxs("div",{children:[e.jsx(N,{children:"Author"}),e.jsx(M,{value:Ze,onChange:a=>yt(a.target.value),placeholder:"e.g., Jane Smith",className:"mt-1"})]})]}),e.jsxs("div",{children:[e.jsx(N,{children:"Blurb"}),e.jsx("div",{className:"mt-1",children:e.jsx(tt,{value:Ee,onChange:vt})})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(T,{type:"button",variant:"default",size:"sm",disabled:!Ee.trim(),onClick:async()=>{const{error:a}=await m.from("production_blurbs").update({blurb:Ee,author:Ze||null,platform_id:Qe||null}).eq("id",t.id);a?f.error("Failed to update blurb"):(Pe(he.map(p=>p.id===t.id?{...p,blurb:Ee,author:Ze||null,platform_id:Qe||null}:p)),Je(null),f.success("Blurb updated"))},children:"Save"}),e.jsx(T,{type:"button",variant:"ghost",size:"sm",onClick:()=>Je(null),children:"Cancel"})]})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[t.platform_id&&e.jsx("span",{className:"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold bg-secondary text-secondary-foreground",children:oe.find(a=>a.id===t.platform_id)?.name||"Unknown"}),t.author&&e.jsxs("span",{className:"text-sm text-muted-foreground",children:["by ",t.author]})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(T,{type:"button",variant:"ghost",size:"sm",title:"Copy blurb text",onClick:()=>{const a=document.createElement("div");a.innerHTML=t.blurb,navigator.clipboard.writeText(a.textContent||a.innerText||""),f.success("Blurb copied to clipboard")},children:e.jsx(we,{className:"h-4 w-4"})}),e.jsx(T,{type:"button",variant:"ghost",size:"sm",title:"Edit",onClick:()=>{Je(t.id),vt(t.blurb),yt(t.author||""),jt(t.platform_id||"")},children:e.jsx(st,{className:"h-4 w-4"})}),e.jsx(T,{type:"button",variant:"destructive",size:"sm",onClick:async()=>{const{error:a}=await m.from("production_blurbs").delete().eq("id",t.id);a?f.error("Failed to delete blurb"):(Pe(he.filter(p=>p.id!==t.id)),f.success("Blurb deleted"))},children:e.jsx(ie,{className:"h-4 w-4"})})]})]}),e.jsx("div",{className:"prose prose-sm max-w-none text-foreground",dangerouslySetInnerHTML:{__html:Bs(t.blurb)}})]})},t.id))}),e.jsxs("div",{className:"grid gap-3",children:[e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx(N,{children:"Platform"}),e.jsxs(J,{value:xt,onValueChange:_t,children:[e.jsx(Z,{className:"mt-1",children:e.jsx(Q,{placeholder:"Select platform"})}),e.jsx(ee,{children:oe.map(t=>e.jsx(Y,{value:t.id,children:t.name},t.id))})]})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"blurb_author",children:"Author"}),e.jsx(M,{id:"blurb_author",value:pt,onChange:t=>gt(t.target.value),placeholder:"e.g., Jane Smith",className:"mt-1"})]})]}),e.jsxs("div",{children:[e.jsx(N,{children:"Blurb"}),e.jsx("div",{className:"mt-1",children:e.jsx(tt,{value:Re,onChange:ht})})]}),e.jsxs(T,{type:"button",variant:"outline",className:"gap-2 w-fit",disabled:!Re.trim(),onClick:async()=>
19{if(!s||!Re.trim())return;const{data:t,error:a}=await m.from("production_blurbs").insert({production_id:s,blurb:Re,author:pt||null,platform_id:xt||null,display_order:he.length}).select().single();a?f.error("Failed to add blurb"):(Pe([...he,t]),ht(""),gt(""),_t(""),f.success("Blurb added"))},children:[e.jsx(je,{className:"h-4 w-4"}),"Add Blurb"]})]})]})]}):e.jsx("p",{className:"text-sm text-muted-foreground italic",children:"Save the production first to add marketing content."})]})}),e.jsxs(ge,{value:"external",className:"space-y-6 mt-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-semibold mb-2",children:"External Ticket Sales"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-6",children:"Configure external ticketing platforms for individual performance dates."})]}),e.jsxs("div",{className:"p-4 border rounded-lg space-y-2",children:[e.jsx(N,{htmlFor:"external_production_id",children:"External Production ID"}),e.jsx(M,{id:"external_production_id",value:r.external_production_id,onChange:t=>L({external_production_id:t.target.value}),placeholder:"e.g. TicketSource Event ID"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"An identifier for this production on an external ticketing platform (e.g. TicketSource Event ID)."})]}),c.length===0?e.jsx("div",{className:"p-4 border rounded-lg bg-muted/50 text-center",children:e.jsx("p",{className:"text-sm text-muted-foreground",children:"Add performance dates in the Basics tab first."})}):e.jsx("div",{className:"space-y-6",children:c.map((t,a)=>e.jsxs("div",{className:"p-4 border rounded-lg space-y-4",children:[e.jsxs("div",{className:"font-medium",children:[ne(new Date(t.date),"PPP")," at ",t.time]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:`sales-type-${a}`,children:"Ticket Sales Platform"}),e.jsxs("select",{id:`sales-type-${a}`,value:t.external_sales_type||"website",onChange:p=>{const v=[...c];v[a]={...v[a],external_sales_type:p.target.value,external_url:p.target.value==="website"?void 0:v[a].external_url},d(v)},className:"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm r
19ing-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 mt-1",children:[e.jsx("option",{value:"website",children:"Website Sales"}),e.jsx("option",{value:"ticketsource",children:"Ticketsource"}),e.jsx("option",{value:"other",children:"Other"})]})]}),t.external_sales_type&&t.external_sales_type!=="website"&&e.jsxs("div",{children:[e.jsx(N,{htmlFor:`external-url-${a}`,children:"External Booking URL"}),e.jsx(M,{id:`external-url-${a}`,type:"url",value:t.external_url||"",onChange:p=>{const v=[...c];v[a]={...v[a],external_url:p.target.value},d(v)},placeholder:"https://example.com/tickets",className:"mt-1"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:'Users will be redirected to this URL when clicking "Buy Tickets" for this date.'})]})]},a))})]})]}),e.jsxs("div",{className:"flex gap-4 pt-6 border-t",children:[e.jsx(T,{type:"submit",disabled:R||!A,onClick:()=>b(!1),children:R&&!k?"Saving...":"Save"}),e.jsx(T,{type:"submit",disabled:R||!A,variant:"secondary",onClick:()=>b(!0),children:R&&k?"Saving...":"Save & Close"}),e.jsx(T,{type:"button",variant:"outline",onClick:()=>hs("/admin"),children:"Cancel"})]})]})]}),e.jsx(Gs,{open:us,onOpenChange:ve,children:e.jsxs(Ws,{children:[e.jsxs(Ys,{children:[e.jsx(Ks,{children:"Unsaved Changes"}),e.jsx(Xs,{children:"You have unsaved changes. Do you want to save before leaving?"})]}),e.jsxs(Js,{children:[e.jsx(Zs,{onClick:()=>ve(!1),children:"Cancel"}),e.jsx(T,{variant:"destructive",onClick:()=>{ve(!1),te(!1),Ae.current&&(i(Ae.current),Ae.current=null)},children:"Discard Changes"}),e.jsx(T,{onClick:async()=>{await kt({preventDefault:()=>{}}),ve(!1)},children:"Save Changes"})]})]})})]})}export{di 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.