PageSourceSearch

https://joggle.it/assets/SignageManager-DVAZ3pyD.js

js joggle.it collected 2026-10-09 22:55:53 UTC 73,536 bytes, 1 lines download raw bytes

1import{r as i,j as e}from"./react-vendor-6-uVh9lA.js";import{i as Ns}from"./isImageFile-CG2Sj1yp.js";import{b as Ae,u as xe,c as A}from"./query-vendor-B4HfZuV6.js";import{B as u,f as ge,D as ye,g as be,h as Ne,i as we,T as ws,j as Se,C as ss,a as ts,L as j,I as Q,aa as ve,S as is,x as Te,y as Le,z as Ue,A as Pe,E as se,V as $e}from"./ui-primitives-lzo5gGe9.js";import{u as Qe}from"./ui-root-DBDUP2Wa.js";import{f as T}from"./index-Dj8rAq6V.js";import{R as De,I as ke,N as Os,aE as us,b1 as hs,az as Ke,r as os,a$ as Ss,b7 as Vs,s as as,t as ps,M as ks,g as Cs,aY as We,e as Oe,d as Ve,a8 as ze,a2 as Ws,aG as gs,dU as fs,a7 as Fs,bU as Ts,bg as zs,$ as As,_ as Me,dV as rs,dd as qe,b as ns,a5 as Qs,n as Ks,dW as js,X as vs,d2 as ys,W as Bs}from"./icons-vendor-CNaJirIZ.js";import"./ui-vendor-CcmWsAw-.js";import"./form-vendor-DNXU13ZK.js";import"./ui-vendor-root-CmPLdN-9.js";const Ls=[{id:"events",label:"Events (Upcoming)",description:"Rotating event cards",rotationInterval:1e4},{id:"tonight",label:"Tonight",description:"Tonight's events or next upcoming",rotationInterval:6e3},{id:"photos",label:"Photos (Curated)",description:"Crossfading photo gallery",rotationInterval:1e4},{id:"menu",label:"Menu (Food)",description:"Food menu by category",rotationInterval:12e3},{id:"drinks",label:"Drinks",description:"Drinks menu by category",rotationInterval:12e3},{id:"history",label:"History",description:"Venue story slides",rotationInterval:1e4},{id:"team",label:"Team",description:"Team member cards",rotationInterval:1e4},{id:"wall",label:"Wall Mode (Live Photos)",description:"Live photo wall — guests post via Joggle chat",rotationInterval:0},{id:"specials",label:"Specials",description:"Featured special with full-screen image overlay",rotationInterval:0}];function Hs(d){return Ls.find(f=>f.id===d)}function Js(d){return Hs(d)?.label||d}function ls(d){const f=new Date(d),p=(Date.now()-f.getTime())/1e3;return p<60?`${Math.floor(p)}s ago`:p<3600?`${Math.floor(p/60)}m ago`:p<86400?`${Math.floor(p/3600)}h ago`:f.toLocaleDateString()}function _s({signId:d,assistantId:f}){const{toast:p}=Qe(),g=Ae(),[K,w]=i.useState(null),[v,V]=i.useState(""),{data:te,isLoading:W,refetch:_}=xe({queryKey:[`/api/wall/posts/${d}`],queryFn:async()=>{const r=await fetch(`/api/wall/posts/${d}`,{headers:{"Content-Type":"application/json"}});if(!r.ok)throw new Error("Failed to load posts");return r.json()},refetchInterval:1e4}),$=A({mutationFn:async r=>{if(!(await T(`/api/wall/posts/${r}/approve`,{method:"POST"})).ok)throw new Error("Failed to approve")},onSuccess:()=>{g.invalidateQueries({queryKey:[`/api/wall/posts/${d}`]}),p({title:"Post approved and live on the sign"})},onError:()=>p({title:"Failed to approve post",variant:"destructive"})}),G=A({mutationFn:async({postId:r,reason:c})=>{if(!(await T(`/api/wall/posts/${r}/reject`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({reason:c})})).ok)throw new Error("Failed to reject")},onSuccess:()=>{g.invalidateQueries({queryKey:[`/api/wall/posts/${d}`]}),w(null),V(""),p({title:"Post rejected"})},onError:()=>p({title:"Failed to reject post",variant:"destructive"})}),Y=A({mutationFn:async r=>{if(!(await T(`/api/wall/posts/${r}`,{method:"DELETE"})).ok)throw new Error("Failed to remove")},onSuccess:()=>{g.invalidateQueries({queryKey:[`/api/wall/posts/${d}`]}),p({title:"Post removed from wall"})},onError:()=>p({title:"Failed to remove post",variant:"destructive"})}),h=te||[],L=h.filter(r=>r.moderationStatus==="pending"||r.moderationStatus==="processing"),x=h.filter(r=>r.moderationStatus==="approved"),M=h.filter(r=>r.moderationStatus==="rejected"||r.moderationStatus==="failed");if(W)return e.jsxs("div",{className:"flex items-center justify-center py-8 text-sm text-muted-foreground gap-2",children:[e.jsx(De,{className:"w-3 h-3 animate-spin"}),"Loading posts…"]});if(h.length===0)return e.jsxs("div",{className:"text-center py-8 text-sm text-muted-foreground",children:[e.jsx(ke,{className:"w-6 h-6 mx-auto mb-2 opacity-40"}),"No posts yet. Share the Wall code with guests."]});function b({post:r}){return e.jsx("div",{className:"w-16 h-16 flex-shrink-0 rounded-lg overflow-hidden bg-muted",children:r.thumbnailUrl||r.imageUrl?e.jsx("img",{src:r.thumbnailUrl||r.imageUrl,alt:"Post",className:"w-full h-full object-cover"}):e.jsx("div",{className:"w-full h-full flex items-center justify-center",children:e.jsx(ke,{className:"w-5 h-5 text-muted-foreground"})})})}return e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"Auto-refreshes every 10 seconds"}),e.jsxs(u,{variant:"ghost",size:"sm",onClick:()=>_(),className:"h-7 text-xs gap-1",children:[e.jsx(De,{className:"w-3 h-3"})," Refresh"]})]}),L.length>0&&e.jsxs("section",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h4",{className:"text-sm font-semibold",children:"Pending"}),e.jsx(ge,{variant:"secondary",className:"text-xs",children:L.length})]}),e.jsx("div",{className:"space-y-2",children:L.map(r=>e.jsxs("div",{className:"flex items-center gap-3 rounded-xl border p-3 bg-amber-50/50",children:[e.jsx(b,{post:r}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"flex items-center gap-1.5 mb-1",children:r.moderationStatus==="processing"?e.jsxs(ge,{variant:"outline",className:"text-xs gap-1",children:[e.jsx("span",{className:"animate-spin inline-block w-2 h-2 border border-current border-t-transparent roun
1ded-full"}),"Processing"]}):e.jsxs(ge,{variant:"outline",className:"text-xs gap-1 border-amber-300 text-amber-700 bg-amber-50",children:[e.jsx(Os,{className:"w-2.5 h-2.5"}),"Pending"]})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:ls(r.createdAt)})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(u,{size:"sm",className:"h-8 px-3 bg-green-600 hover:bg-green-700 text-white",onClick:()=>$.mutate(r.id),disabled:$.isPending||r.moderationStatus==="processing",children:[e.jsx(us,{className:"w-3.5 h-3.5 mr-1"}),"Approve"]}),e.jsxs(u,{size:"sm",variant:"outline",className:"h-8 px-3 text-red-600 border-red-200 hover:bg-red-50",onClick:()=>{w(r.id),V("")},disabled:G.isPending||r.moderationStatus==="processing",children:[e.jsx(hs,{className:"w-3.5 h-3.5 mr-1"}),"Reject"]})]})]},r.id))})]}),x.length>0&&e.jsxs("section",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h4",{className:"text-sm font-semibold",children:"Live on Wall"}),e.jsx(ge,{className:"text-xs bg-green-600",children:x.length})]}),e.jsx("div",{className:"space-y-2",children:x.map(r=>e.jsxs("div",{className:"flex items-center gap-3 rounded-xl border p-3 bg-green-50/40",children:[e.jsx(b,{post:r}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs(ge,{variant:"outline",className:"text-xs gap-1 border-green-300 text-green-700 bg-green-50 mb-1",children:[e.jsx(us,{className:"w-2.5 h-2.5"}),"Live"]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:r.publishedAt?ls(r.publishedAt):ls(r.createdAt)})]}),e.jsxs(u,{size:"sm",variant:"outline",className:"h-8 px-3 text-red-600 border-red-200 hover:bg-red-50",onClick:()=>Y.mutate(r.id),disabled:Y.isPending,children:[e.jsx(Ke,{className:"w-3.5 h-3.5 mr-1"}),"Remove"]})]},r.id))})]}),M.length>0&&e.jsxs("section",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h4",{className:"text-sm font-semibold text-muted-foreground",children:"Rejected / Failed"}),e.jsx(ge,{variant:"secondary",className:"text-xs",children:M.length})]}),e.jsx("div",{className:"space-y-2",children:M.map(r=>e.jsxs("div",{className:"flex items-center gap-3 rounded-xl border p-3 bg-muted/30 opacity-60",children:[e.jsx(b,{post:r}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs(ge,{variant:"outline",className:"text-xs gap-1 border-red-200 text-red-600 bg-red-50 mb-1",children:[e.jsx(hs,{className:"w-2.5 h-2.5"}),r.moderationStatus==="failed"?"Failed":"Rejected"]}),r.moderationReason&&e.jsx("p",{className:"text-xs text-muted-foreground truncate",children:r.moderationReason})]})]},r.id))})]}),e.jsx(ye,{open:K!==null,onOpenChange:r=>{r||w(null)},children:e.jsxs(be,{children:[e.jsx(Ne,{children:e.jsx(we,{children:"Reject post"})}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Optionally provide a reason (not shown to guest)."}),e.jsx(ws,{placeholder:"Reason (optional)",value:v,onChange:r=>V(r.target.value),rows:3})]}),e.jsxs(Se,{children:[e.jsx(u,{variant:"outline",onClick:()=>w(null),children:"Cancel"}),e.jsx(u,{variant:"destructive",onClick:()=>K!==null&&G.mutate({postId:K,reason:v||void 0}),disabled:G.isPending,children:G.isPending?"Rejecting…":"Reject post"})]})]})})]})}function it({assistantId:d,username:f}){const{toast:p}=Qe(),g=Ae(),[K,w]=i.useState(!1),[v,V]=i.useState(null),[te,W]=i.useState(null),[_,$]=i.useState(null),[G,Y]=i.useState(!1),[h,L]=i.useState(""),[x,M]=i.useState("events"),[b,r]=i.useState("landscape"),[c,C]=i.useState("light"),[ae,re]=i.useState(""),[ne,X]=i.useState({type:"random"}),[le,Z]=i.useState({type:"all"}),[k,ie]=i.useState({type:"all"}),[D,U]=i.useState({}),[q,z]=i.useState(15),[oe,O]=i.useState(""),[B,P]=i.useState(""),[ue,I]=i.useState({});function pe(t){const o={...ue,[x]:{welcomeText:oe.trim(),introText:B.trim()}};I(o);const F=o[t]||{};O(F.welcomeText||""),P(F.introText||""),M(t)}const[de,me]=i.useState(""),[he,a]=i.useState("live_reveal"),[m,n]=i.useState("auto"),[N,E]=i.useState(90),[ee,R]=i.useState(24),[Ce,fe]=i.useState("active"),[ds,Fe]=i.useState(null),[Re,Be]=i.useState(null),[Ie,s]=i.useState(null),[l,y]=i.useState(null),[S,H]=i.useState(null),[ce,je]=i.useState(""),[He,cs]=i.useState(!1),{data:Je}=xe({queryKey:["/api/owner/signage-settings"],queryFn:async()=>{const t=await fetch("/api/owner/signage-settings");if(!t.ok)throw new Error("Failed to load signage settings");return t.json()}});i.useEffect(()=>{Je&&!He&&je(Je.signageQrLabel||"")},[Je,He]);const _e=A({mutationFn:async t=>{const o=await T("/api/owner/signage-settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({assistantId:d,signageQrLabel:t})});if(!o.ok)throw new Error("Failed to save");return o.json()},onSuccess:()=>{g.invalidateQueries({queryKey:["/api/owner/signage-settings"]}),cs(!1),p({title:"QR label saved"})},onError:()=>{p({title:"Failed to save QR label",variant:"destructive"})}}),{data:Ps=[],isLoading:Ms}=xe({queryKey:["/api/owner/signs"],queryFn:async()=>{const t=await fetch("/api/owner/signs");if(!t.ok)throw new Error("Failed to load signs");return t.json()}}),ms=Ps.filter(t=>t.assistantId===d),Ge=A({mutationFn:async t=>{const o=await T("/api/owner/signs",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!o.ok)throw new Error("Failed to create sign");return o.json()},onSuccess:()=>{g.invalidateQueries({queryKey:["/api/owner/signs"]}),w(!1),Ee(),p({title:"Sign created"})}}),Ye=A({mutationFn:async({id:t,...o})=>{const F=await T(`/api/owner/signs/${t}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)});if(!F.ok)throw new Error("Failed to update sign");return F.json()},onSuccess:()=>{g.invalidateQueries({queryKey:["/api/owner/signs"]}),V(null),Ee(),p({title:"Sign updated"})}}),Xe=A({mutationFn:async t=>{if(!(await T(`/api/owner/signs/${t}`,{method:"DELETE"})).ok)throw new Error("Failed to delete sign")},onSuccess:()=>{g.invalidateQueries({queryKey:["/api/owner/signs"]}),W(null),p({title:"Sign deleted"})}}),Ze=A({mutationFn:async t=>{const o=await T(`/api/owner/signs/${t}/rotate-token`,{method:"POST"});if(!o.ok)throw new Error("Failed to rotate token");return o.json()},onSuccess:()=>{g.invalidateQueries({queryKey:["/api/owner/signs"]}
1),$(null),p({title:"Token rotated. Old URL is now invalid."})}}),Ds=A({mutationFn:async({signId:t,specialId:o})=>{const F=await T(`/api/owner/signs/${t}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({activeSpecialId:o})});if(!F.ok)throw new Error("Failed to update sign");return F.json()},onSuccess:(t,o)=>{g.invalidateQueries({queryKey:["/api/owner/signs"]}),H(o.specialId),p({title:"Special selected — sign updated"})},onError:()=>p({title:"Failed to update sign",variant:"destructive"})}),es=A({mutationFn:async t=>{const o=await T(`/api/owner/signs/${t}/refresh`,{method:"POST"});if(!o.ok)throw new Error("Failed to refresh sign");return o.json()},onSuccess:()=>{p({title:"Sign refreshed",description:"The screen will reload momentarily."})},onError:()=>{p({title:"Refresh failed",variant:"destructive"})}});function Ee(){L(""),M("events"),r("landscape"),C("light"),re(""),X({type:"random"}),Z({type:"all"}),ie({type:"all"}),U({}),z(15),O(""),P(""),I({}),me(""),a("live_reveal"),n("auto"),E(90),R(24),fe("active"),Fe(null)}async function Rs(t){if(V(t),H(t.activeSpecialId??null),L(t.name),M(t.mode),r(t.orientation),C(t.theme==="dark"?"dark":"light"),re(t.qrTargetUrl||""),t.photoSelection)try{X(JSON.parse(t.photoSelection))}catch{X({type:"random"})}else X({type:"random"});if(t.menuSelection)try{Z(JSON.parse(t.menuSelection))}catch{Z({type:"all"})}else Z({type:"all"});if(t.drinksSelection)try{ie(JSON.parse(t.drinksSelection))}catch{ie({type:"all"})}else ie({type:"all"});if(t.tonightConfig)try{U(JSON.parse(t.tonightConfig))}catch{U({})}else U({});if(z(t.slideDelay??15),t.modeConfig)try{const o=JSON.parse(t.modeConfig);if(o&&typeof o=="object")if("welcomeText"in o||"introText"in o){const J={[t.mode]:{welcomeText:o.welcomeText||"",introText:o.introText||""}};I(J),O(o.welcomeText||""),P(o.introText||"")}else{I(o);const J=o[t.mode]||{};O(J.welcomeText||""),P(J.introText||"")}else I({}),O(""),P("")}catch{I({}),O(""),P("")}else I({}),O(""),P("");if(t.mode==="wall")try{const o=await fetch(`/api/wall/config/${t.id}`);if(o.ok){const F=await o.json();if(F.config){const J=F.config;Fe(J.id),me(J.wallCode||""),a(J.layoutPreset||"live_reveal"),n(J.moderationMode||"auto"),E(J.rateLimitSeconds||90),R(J.retentionHours||24),fe(J.status||"active")}else Fe(null),me(""),a("live_reveal"),n("auto"),E(90),R(24),fe("active")}}catch{}}function Is(){h.trim()&&Ge.mutate({assistantId:d,name:h.trim(),mode:x,orientation:b,theme:c,qrTargetUrl:ae.trim()||null,photoSelection:x==="photos"?ne:null,menuSelection:x==="menu"?le:null,drinksSelection:x==="drinks"?k:null,tonightConfig:x==="tonight"?D:null,slideDelay:q,modeConfig:(()=>{const t={...ue,[x]:{welcomeText:oe.trim(),introText:B.trim()}};return Object.values(t).some(F=>F.welcomeText||F.introText)?t:null})()})}async function Es(){if(!(!v||!h.trim())){if(x==="wall"&&de.trim())try{await T("/api/wall/config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({assistantId:d,signId:v.id,wallCode:de.trim(),layoutPreset:he,moderationMode:m,rateLimitSeconds:N,retentionHours:ee,status:Ce})})}catch{}Ye.mutate({id:v.id,name:h.trim(),mode:x,orientation:b,theme:c,qrTargetUrl:ae.trim()||null,photoSelection:x==="photos"?ne:null,menuSelection:x==="menu"?le:null,drinksSelection:x==="drinks"?k:null,tonightConfig:x==="tonight"?D:null,slideDelay:q,modeConfig:(()=>{const t={...ue,[x]:{welcomeText:oe.trim(),introText:B.trim()}};return Object.values(t).some(F=>F.welcomeText||F.introText)?t:null})()})}}function $s(t){return`${window.location.origin}/${t.username||f}/signage/${t.token}`}function qs(t){navigator.clipboard.writeText($s(t)),p({title:"URL copied to clipboard"})}function xs(t,o){const F=`/${t.username||f}/signage/${t.token}?preview=1&orientation=${o}`;window.open(F,"_blank")}return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-bold",children:"Signage"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage digital signs for your screens and TVs"})]}),e.jsxs(u,{onClick:()=>{Ee(),w(!0)},children:[e.jsx(os,{className:"w-4 h-4 mr-2"})," Create Sign"]})]}),e.jsx(ss,{children:e.jsx(ts,{className:"py-4",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(Ss,{className:"w-5 h-5 text-muted-foreground mt-0.5 flex-shrink-0"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx(j,{className:"text-sm font-semibold",children:"QR Code Label"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5 mb-3",children:"Text shown beneath the QR code on every sign. Leave blank to use each mode's default."}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Q,{value:ce,onChange:t=>{je(t.target.value.slice(0,120)),cs(!0)},placeholder:"e.g. Learn more about us",className:"flex-1",maxLength:120}),e.jsxs(u,{size:"sm",disabled:!He||_e.isPending,onClick:()=>_e.mutate(ce),children:[e.jsx(Vs,{className:"w-3 h-3 mr-1"}),_e.isPending?"Saving…":"Save"]})]})]})]})})}
1),Ms?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"Loading signs..."}):ms.length===0?e.jsx(ss,{children:e.jsxs(ts,{className:"py-12 text-center",children:[e.jsx(as,{className:"w-12 h-12 mx-auto mb-4 text-muted-foreground"}),e.jsx("h3",{className:"text-lg font-semibold mb-2",children:"No Signs Yet"}),e.jsx("p",{className:"text-muted-foreground mb-4",children:"Create your first digital sign to display content on screens and TVs."}),e.jsxs(u,{onClick:()=>{Ee(),w(!0)},children:[e.jsx(os,{className:"w-4 h-4 mr-2"})," Create Your First Sign"]})]})}):e.jsx("div",{className:"grid gap-4",children:ms.map(t=>e.jsx(ss,{children:e.jsxs(ts,{className:"py-4",children:[e.jsxs("div",{className:"flex flex-col gap-3",children:[e.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[e.jsx("h3",{className:"font-semibold text-lg",children:t.name}),e.jsx("span",{className:"px-2 py-0.5 bg-primary/10 rounded text-primary text-sm font-medium",children:Js(t.mode)}),e.jsxs("span",{className:"flex items-center gap-1 text-sm text-muted-foreground",children:[t.orientation==="landscape"?e.jsx(as,{className:"w-3 h-3"}):e.jsx(ps,{className:"w-3 h-3"}),t.orientation]}),e.jsxs("span",{className:"flex items-center gap-1 text-sm text-muted-foreground",children:[t.theme==="dark"?e.jsx(ks,{className:"w-3 h-3"}):e.jsx(Cs,{className:"w-3 h-3"}),t.theme==="dark"?"Dark":"Light"]})]}),e.jsx("div",{className:"flex flex-col gap-2",children:e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[t.mode==="wall"&&e.jsxs(u,{variant:"outline",size:"sm",onClick:()=>Be(o=>o===t.id?null:t.id),className:"gap-1",children:[e.jsx(We,{className:"w-3 h-3 mr-1"}),"Moderation",Re===t.id?e.jsx(Oe,{className:"w-3 h-3"}):e.jsx(Ve,{className:"w-3 h-3"})]}),t.mode==="specials"&&e.jsxs(u,{variant:"outline",size:"sm",onClick:()=>y(o=>o===t.id?null:t.id),className:"gap-1",children:[e.jsx(ze,{className:"w-3 h-3 mr-1"}),"Specials",l===t.id?e.jsx(Oe,{className:"w-3 h-3"}):e.jsx(Ve,{className:"w-3 h-3"})]}),e.jsxs(u,{variant:"outline",size:"sm",onClick:()=>qs(t),title:"Copy URL",children:[e.jsx(Ws,{className:"w-3 h-3 sm:mr-1"}),e.jsx("span",{className:"hidden sm:inline",children:"Copy URL"})]}),e.jsxs(u,{variant:"outline",size:"sm",title:"Force refresh the sign screen",disabled:es.isPending,onClick:()=>es.mutate(t.id),children:[e.jsx(De,{className:`w-3 h-3 sm:mr-1 ${es.isPending?"animate-spin":""}`}),e.jsx("span",{className:"hidden sm:inline",children:"Refresh"})]}),e.jsxs(u,{variant:"outline",size:"sm",onClick:()=>xs(t,"landscape"),title:"Preview landscape",children:[e.jsx(gs,{className:"w-3 h-3 mr-1"})," ",e.jsx(as,{className:"w-3 h-3"})]}),e.jsxs(u,{variant:"outline",size:"sm",onClick:()=>xs(t,"portrait"),title:"Preview portrait",children:[e.jsx(gs,{className:"w-3 h-3 mr-1"})," ",e.jsx(ps,{className:"w-3 h-3"})]}),e.jsxs(u,{variant:"outline",size:"sm",onClick:()=>s(o=>o===t.id?null:t.id),title:"QR scan stats",children:[e.jsx(fs,{className:"w-3 h-3 sm:mr-1"}),e.jsx("span",{className:"hidden sm:inline",children:"Stats"}),Ie===t.id?e.jsx(Oe,{className:"w-3 h-3 ml-1"}):e.jsx(Ve,{className:"w-3 h-3 ml-1"})]}),e.jsx(u,{variant:"outline",size:"sm",onClick:()=>Rs(t),title:"Edit sign",children:e.jsx(Fs,{className:"w-3 h-3"})}),e.jsx(u,{variant:"outline",size:"sm",onClick:()=>$(t.id),title:"Regenerate URL",children:e.jsx(Ts,{className:"w-3 h-3"})}),e.jsx(u,{variant:"outline",size:"sm",className:"text-destructive hover:text-destructive",onClick:()=>W(t.id),title:"Delete sign",children:e.jsx(Ke,{className:"w-3 h-3"})})]})})]}),t.mode==="wall"&&Re===t.id&&e.jsxs("div",{className:"mt-4 pt-4 border-t",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx(We,{className:"w-4 h-4 text-orange-600"}),e.jsx("h4",{className:"font-semibold text-sm",children:"Wall Posts"})]}),e.jsx(_s,{signId:t.id,assistantId:t.assistantId})]}),t.mode==="specials"&&l===t.id&&e.jsxs("div",{className:"mt-4 pt-4 border-t",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx(ze,{className:"w-4 h-4 text-orange-500"}),e.jsx("h4",{className:"font-semibold text-sm",children:"Specials Library"})]}
1),e.jsx(Us,{signId:t.id,assistantId:t.assistantId})]}),Ie===t.id&&e.jsxs("div",{className:"mt-4 pt-4 border-t",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx(fs,{className:"w-4 h-4 text-[#DE6D2F]"}),e.jsx("h4",{className:"font-semibold text-sm",children:"QR Scan Stats"})]}),e.jsx(Gs,{signId:t.id})]})]})},t.id))}),e.jsx(ye,{open:K,onOpenChange:w,children:e.jsxs(be,{className:"max-w-2xl max-h-[90vh] flex flex-col overflow-hidden",children:[e.jsx(Ne,{children:e.jsx(we,{children:"Create Sign"})}),e.jsx("div",{className:"overflow-y-auto flex-1 min-h-0 overflow-x-hidden",children:e.jsx(bs,{assistantId:d,name:h,setName:L,mode:x,setMode:pe,orientation:b,setOrientation:r,theme:c,setTheme:C,qrUrl:ae,setQrUrl:re,photoSelection:ne,setPhotoSelection:X,menuSelection:le,setMenuSelection:Z,drinksSelection:k,setDrinksSelection:ie,tonightConfig:D,setTonightConfig:U,slideDelay:q,setSlideDelay:z,welcomeText:oe,setWelcomeText:O,introText:B,setIntroText:P})}),e.jsxs(Se,{children:[e.jsx(u,{variant:"outline",onClick:()=>w(!1),children:"Cancel"}),e.jsx(u,{onClick:Is,disabled:!h.trim()||Ge.isPending,children:Ge.isPending?"Creating...":"Create Sign"})]})]})}),e.jsx(ye,{open:!!v,onOpenChange:t=>{t||V(null)},children:e.jsxs(be,{className:"max-w-2xl max-h-[90vh] flex flex-col overflow-hidden",children:[e.jsx(Ne,{children:e.jsx(we,{children:"Edit Sign"})}),e.jsx("div",{className:"overflow-y-auto flex-1 min-h-0 overflow-x-hidden",children:e.jsx(bs,{assistantId:d,signId:v?.id,activeSpecialId:S,onDisplaySpecial:t=>{v&&Ds.mutate({signId:v.id,specialId:t})},name:h,setName:L,mode:x,setMode:pe,orientation:b,setOrientation:r,theme:c,setTheme:C,qrUrl:ae,setQrUrl:re,photoSelection:ne,setPhotoSelection:X,menuSelection:le,setMenuSelection:Z,drinksSelection:k,setDrinksSelection:ie,tonightConfig:D,setTonightConfig:U,slideDelay:q,setSlideDelay:z,welcomeText:oe,setWelcomeText:O,introText:B,setIntroText:P,wallConfig:{wallCode:de,setWallCode:me,wallLayout:he,setWallLayout:a,wallModeration:m,setWallModeration:n,wallRateLimit:N,setWallRateLimit:E,wallRetention:ee,setWallRetention:R,wallStatus:Ce,setWallStatus:fe}})}),e.jsxs(Se,{children:[e.jsx(u,{variant:"outline",onClick:()=>V(null),children:"Cancel"}),e.jsx(u,{onClick:Es,disabled:!h.trim()||Ye.isPending,children:Ye.isPending?"Saving...":"Save Changes"})]})]})}),e.jsx(ye,{open:te!==null,onOpenChange:t=>{t||W(null)},children:e.jsxs(be,{children:[e.jsx(Ne,{children:e.jsx(we,{children:"Delete Sign"})}),e.jsx("p",{children:"Are you sure you want to delete this sign? The URL will stop working immediately."}),e.jsxs(Se,{children:[e.jsx(u,{variant:"outline",onClick:()=>W(null),children:"Cancel"}),e.jsx(u,{variant:"destructive",onClick:()=>te&&Xe.mutate(te),disabled:Xe.isPending,children:Xe.isPending?"Deleting...":"Delete"})]})]})}),e.jsx(ye,{open:_!==null,onOpenChange:t=>{t||($(null),Y(!1))},children:e.jsxs(be,{children:[e.jsx(Ne,{children:e.jsx(we,{children:"Regenerate Sign URL"})}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"This will generate a new URL for this sign. The old URL will stop working immediately and you will need to update any screens or devices currently using it."}),e.jsxs("div",{className:"flex items-start gap-3 rounded-md border p-3 mt-1",children:[e.jsx(ve,{id:"rotate-confirm-check",checked:G,onCheckedChange:t=>Y(!!t)}),e.jsx("label",{htmlFor:"rotate-confirm-check",className:"text-sm leading-snug cursor-pointer select-none",children:"I understand the old URL will stop working and I want to generate a new one"})]}),e.jsxs(Se,{children:[e.jsx(u,{variant:"outline",onClick:()=>{$(null),Y(!1)},children:"Cancel"}),e.jsx(u,{onClick:()=>_&&Ze.mutate(_),disabled:Ze.isPending||!G,children:Ze.isPending?"Regenerating...":"Regenerate URL"})]})]})})]})}function bs({assistantId:d,signId:f,activeSpecialId:p,onDisplaySpecial:g,name:K,setName:w,mode:v,setMode:V,orientation:te,setOrientation:W,theme:_,setTheme:$,qrUrl:G,setQrUrl:Y,photoSelection:h,setPhotoSelection:L,menuSelection:x,setMenuSelection:M,drinksSelection:b,setDrinksSelection:r,tonightConfig:c,setTonightConfig:C,slideDelay:ae,setSlideDelay:re,welcomeText:ne,setWelcomeText:X,introText:le,setIntroText:Z,wallConfig:k}){const ie=Ae(),{toast:D}=Qe(),[U,q]=i.useState(!1),[z,oe]=i.useState(!1),[O,B]=i.useState(!1),[P,ue]=i.useState([]),[I,pe]=i.useState(!1);async function de(){pe(!0);try{const s=await fetch("/api/owner/signs/video-library",{credentials:"include"});if(s.ok){const l=await s.json();ue(l.videos||[])}}catch{}finally{pe(!1)}}function me(){B(!0),P.length===0&&de()}function he(s){C({...c,backgroundVideoUrl:s.videoUrl,backgroundVideoFilename:s.fileName,backgroundVideoSize:s.size}),B(!1)}async function a(s){const l=s.target.files?.[0];if(!(!l||!f)){if(!["video/mp4","video/webm","video/quicktime"].includes(l.type)){D({title:"Invalid file type",description:"Please upload an MP4 or WebM video.",variant:"destructive"}),s.target.value="";return}if(l.size>50*1024*1024){D({title:"File too large",description:"Video must be 50MB or smaller.",variant:"destructive"}),s.target.value="";return}oe(!0);try{const y=new FormData;y.append("video",l);const S=await T(`/api/owner/signs/${f}/tonight-bg-video`,{method:"POST",body:y}
1);if(!S.ok){const ce=await S.json().catch(()=>({}));throw new Error(ce.error||"Upload failed")}const H=await S.json();C({...c,backgroundVideoUrl:H.videoUrl,backgroundVideoFilename:H.filename,backgroundVideoSize:H.size}),D({title:"Video uploaded",description:"Background video added successfully."})}catch(y){D({title:"Upload failed",description:y.message||"Something went wrong.",variant:"destructive"})}finally{oe(!1),s.target.value=""}}}async function m(s){const l=s.target.files?.[0];if(l&&!((c.photoUrls||[]).length>=3)){if(!Ns(l)){D({title:"Invalid file type",description:"Please select an image file.",variant:"destructive"});return}if(l.size>10*1024*1024){D({title:"File too large",description:"Please select an image smaller than 10MB.",variant:"destructive"});return}q(!0);try{const y=new FormData;y.append("photo",l),y.append("category","tonight");const S=await T(`/api/pub-gallery-photos/${d}/upload`,{method:"POST",body:y});if(!S.ok){const je=await S.json().catch(()=>({}));throw new Error(je.message||"Upload failed")}const ce=(await S.json()).photoUrl;C({...c,photoUrls:[...c.photoUrls||[],ce]}),ie.invalidateQueries({queryKey:[`/api/owner/signs/photos-for-picker?assistantId=${d}`]}),D({title:"Photo uploaded",description:"Background photo added successfully."})}catch(y){D({title:"Upload failed",description:y.message||"Something went wrong.",variant:"destructive"})}finally{q(!1),s.target.value=""}}}const{data:n,isLoading:N}=xe({queryKey:[`/api/owner/signs/photos-for-picker?assistantId=${d}`],queryFn:async()=>{const s=await fetch(`/api/owner/signs/photos-for-picker?assistantId=${d}`);if(!s.ok)throw new Error("Failed to load photos");return s.json()},enabled:v==="photos"||v==="tonight"}),{data:E,isLoading:ee}=xe({queryKey:[`/api/owner/signs/menu-for-picker?assistantId=${d}`],queryFn:async()=>{const s=await fetch(`/api/owner/signs/menu-for-picker?assistantId=${d}`);if(!s.ok)throw new Error("Failed to load menu");return s.json()},enabled:v==="menu"}),{data:R,isLoading:Ce}=xe({queryKey:[`/api/owner/signs/drinks-for-picker?assistantId=${d}`],queryFn:async()=>{const s=await fetch(`/api/owner/signs/drinks-for-picker?assistantId=${d}`);if(!s.ok)throw new Error("Failed to load drinks");return s.json()},enabled:v==="drinks"});function fe(s){const l=h.collectionIds||[],y=l.includes(s)?l.filter(S=>S!==s):[...l,s];L({...h,collectionIds:y})}function ds(s){const l=h.photoIds||[],y=l.includes(s)?l.filter(S=>S!==s):[...l,s];L({...h,photoIds:y})}function Fe(s){const l=x.categories||[],y=l.includes(s)?l.filter(S=>S!==s):[...l,s];M({...x,categories:y})}function Re(s){const l=x.itemIds||[],y=l.includes(s)?l.filter(S=>S!==s):[...l,s];M({...x,itemIds:y})}function Be(s){const l=b.categoryIds||[],y=l.includes(s)?l.filter(S=>S!==s):[...l,s];r({...b,categoryIds:y})}function Ie(s){const l=b.itemIds||[],y=l.includes(s)?l.filter(S=>S!==s):[...l,s];r({...b,itemIds:y})}return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(j,{htmlFor:"sign-name",children:"Name"}),e.jsx(Q,{id:"sign-name",value:K,onChange:s=>w(s.target.value),placeholder:"e.g. Bar TV, Front Window"})]}),e.jsxs("div",{children:[e.jsx(j,{children:"Mode"}),e.jsxs(Te,{value:v,onValueChange:V,children:[e.jsx(Le,{children:e.jsx(Ue,{})}),e.jsx(Pe,{children:Ls.map(s=>e.jsx(se,{value:s.id,children:s.label},s.id))})]})]}),v==="photos"&&e.jsxs("div",{className:"space-y-3 border rounded-lg p-4 bg-muted/30",children:[e.jsxs(j,{className:"text-sm font-semibold flex items-center gap-1.5",children:[e.jsx(We,{className:"w-4 h-4"})," Photo Selection"]}),e.jsx("div",{className:"grid grid-cols-3 gap-2",children:[{type:"random",icon:e.jsx(rs,{className:"w-4 h-4"}),label:"All Photos",sub:"Random order"},{type:"collection",icon:e.jsx(qe,{className:"w-4 h-4"}),label:"By Collection",sub:"Pick collections"},{type:"curated",icon:e.jsx(We,{className:"w-4 h-4"}),label:"Specific Photos",sub:"Choose images"}].map(s=>e.jsxs("button",{type:"button",onClick:()=>L({...h,type:s.type}),className:"flex flex-col items-center gap-1 p-3 rounded-lg border text-center transition-all",style:h.type===s.type?{borderColor:"#f97316",backgroundColor:"#fff7ed",color:"#c2410c"}:{borderColor:"#e5e7eb",backgroundColor:"#fff",color:"#6b7280"},children:[s.icon,e.jsx("span",{className:"text-xs font-semibold",children:s.label}),e.jsx("span",{className:"text-xs opacity-70",children:s.sub})]},s.type))}),h.type==="collection"&&e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Select one or more collections to show photos from:"}),N?e.jsx("p",{className:"text-xs text-muted-foreground",children:"Loading collections..."}):n?.collections.length?e.jsx("div",{className:"space-y-1.5 max-h-48 overflow-y-auto pr-1",children:n.collections.map(s=>e.jsxs("label",{className:"flex items-center gap-2.5 p-2 rounded-md hover:bg-muted cursor-pointer",children:[e.jsx(ve,{checked:(h.collectionIds||[]).includes(s.id
1),onCheckedChange:()=>fe(s.id)}),e.jsx("span",{className:"text-sm flex-1",children:s.name}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[s.photoCount," photos"]})]},s.id))}):e.jsx("p",{className:"text-xs text-muted-foreground",children:"No collections found. Create collections in your Gallery first."})]}),h.type==="curated"&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Click photos to select them for the slideshow:"}),(h.photoIds||[]).length>0&&e.jsxs("span",{className:"text-xs font-medium text-primary",children:[(h.photoIds||[]).length," selected"]})]}),N?e.jsx("p",{className:"text-xs text-muted-foreground",children:"Loading photos..."}):n?.photos.length?e.jsx($e,{className:"h-56",children:e.jsx("div",{className:"grid grid-cols-4 gap-1.5 pr-2",children:n.photos.map(s=>{const l=(h.photoIds||[]).includes(s.id);return e.jsxs("button",{type:"button",onClick:()=>ds(s.id),className:"relative aspect-square rounded-md overflow-hidden border-2 transition-all",style:{borderColor:l?"#f97316":"transparent"},title:s.altText||"",children:[e.jsx("img",{src:s.thumbUrl,alt:s.altText||"",className:"w-full h-full object-cover"}),l&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center",style:{backgroundColor:"rgba(249,115,22,0.35)"},children:e.jsx("div",{className:"w-5 h-5 rounded-full bg-orange-500 flex items-center justify-center",children:e.jsx(ns,{className:"w-3 h-3 text-white"})})})]},s.id)})})}):e.jsx("p",{className:"text-xs text-muted-foreground",children:"No photos found in your gallery."})]}),e.jsxs("div",{className:"border-t pt-3 space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx(j,{htmlFor:"photos-fullscreen",className:"text-sm font-medium",children:"Fullscreen"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Show the photo edge to edge, with no header or footer."})]}),e.jsx(is,{id:"photos-fullscreen",checked:h.fullscreen===!0,onCheckedChange:s=>L({...h,fullscreen:s})})]}),h.fullscreen&&e.jsxs("div",{className:"space-y-1",children:[e.jsx(j,{htmlFor:"photos-overlay-text",className:"text-xs",children:"Text over the photo (optional)"}),e.jsx(ws,{id:"photos-overlay-text",value:h.overlayText||"",onChange:s=>L({...h,overlayText:s.target.value}),placeholder:"e.g. Sunday roast served 12–6",maxLength:200,rows:2}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Shown top left over every photo. Leave blank for none."})]})]})]}),v==="menu"&&e.jsxs("div",{className:"space-y-3 border rounded-lg p-4 bg-muted/30",children:[e.jsxs(j,{className:"text-sm font-semibold flex items-center gap-1.5",children:[e.jsx(Qs,{className:"w-4 h-4"})," Menu Items to Show"]}),e.jsx("div",{className:"grid grid-cols-3 gap-2",children:[{type:"all",icon:e.jsx(qe,{className:"w-4 h-4"}),label:"All Items",sub:"Show everything"},{type:"categories",icon:e.jsx(rs,{className:"w-4 h-4"}),label:"By Category",sub:"Pick categories"},{type:"items",icon:e.jsx(ns,{className:"w-4 h-4"}),label:"Specific Items",sub:"Choose items"}].map(s=>e.jsxs("button",{type:"button",onClick:()=>M({...x,type:s.type}),className:"flex flex-col items-center gap-1 p-3 rounded-lg border text-center transition-all",style:x.type===s.type?{borderColor:"#f97316",backgroundColor:"#fff7ed",color:"#c2410c"}:{borderColor:"#e5e7eb",backgroundColor:"#fff",color:"#6b7280"},children:[s.icon,e.jsx("span",{className:"text-xs font-semibold",children:s.label}),e.jsx("span",{className:"text-xs opacity-70",children:s.sub})]},s.type))}),x.type==="categories"&&e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Select which categories to display on the sign:"}),ee?e.jsx("p",{className:"text-xs text-muted-foreground",children:"Loading categories..."}):E?.categories.length?e.jsx("div",{className:"space-y-1.5 max-h-48 overflow-y-auto pr-1",children:E.categories.map(s=>e.jsxs("label",{className:"flex items-center gap-2.5 p-2 rounded-md hover:bg-muted cursor-pointer",children:[e.jsx(ve,{checked:(x.categories||[]).includes(s),onCheckedChange:()=>Fe(s)}),e.jsx("span",{className:"text-sm flex-1",children:s})]},s))}):e.jsx("p",{className:"text-xs text-muted-foreground",children:"No menu categories found. Add menu items first."})]}),x.type==="items"&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Select specific menu items to show on the sign:"}),(x.itemIds||[]).length>0&&e.jsxs("span",{className:"text-xs font-medium text-primary",children:[(x.itemIds||[]).length," selected"]})]}),ee?e.jsx("p",{className:"text-xs text-muted-foreground",children:"Loading menu items..."}):E?.items.length?e.jsx($e,{className:"h-56",children:e.jsx("div",{className:"space-y-1 pr-2",children:E.items.map(s=>
1{const l=(x.itemIds||[]).includes(s.id);return e.jsxs("label",{className:"flex items-center gap-2.5 p-2 rounded-md hover:bg-muted cursor-pointer transition-colors",style:l?{backgroundColor:"#fff7ed"}:{},children:[e.jsx(ve,{checked:l,onCheckedChange:()=>Re(s.id)}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-sm font-medium truncate",children:s.name}),e.jsx("div",{className:"text-xs text-muted-foreground",children:s.category})]}),s.price&&e.jsx("span",{className:"text-xs font-medium text-muted-foreground flex-shrink-0",children:s.price})]},s.id)})})}):e.jsx("p",{className:"text-xs text-muted-foreground",children:"No menu items found."})]})]}),v==="drinks"&&e.jsxs("div",{className:"space-y-3 border rounded-lg p-4 bg-muted/30",children:[e.jsxs(j,{className:"text-sm font-semibold flex items-center gap-1.5",children:[e.jsx(qe,{className:"w-4 h-4"})," Drinks to Show"]}),e.jsx("div",{className:"grid grid-cols-3 gap-2",children:[{type:"all",icon:e.jsx(rs,{className:"w-4 h-4"}),label:"All Drinks",sub:"Show everything"},{type:"categories",icon:e.jsx(qe,{className:"w-4 h-4"}),label:"By Category",sub:"Pick categories"},{type:"items",icon:e.jsx(ns,{className:"w-4 h-4"}),label:"Specific Drinks",sub:"Choose items"}].map(s=>e.jsxs("button",{type:"button",onClick:()=>r({...b,type:s.type}),className:"flex flex-col items-center gap-1 p-3 rounded-lg border text-center transition-all",style:b.type===s.type?{borderColor:"#f97316",backgroundColor:"#fff7ed",color:"#c2410c"}:{borderColor:"#e5e7eb",backgroundColor:"#fff",color:"#6b7280"},children:[s.icon,e.jsx("span",{className:"text-xs font-semibold",children:s.label}),e.jsx("span",{className:"text-xs opacity-70",children:s.sub})]},s.type))}),b.type==="categories"&&e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Select which drink categories to display on the sign:"}),Ce?e.jsx("p",{className:"text-xs text-muted-foreground",children:"Loading categories..."}):R?.categories.length?e.jsx("div",{className:"space-y-1.5 max-h-48 overflow-y-auto pr-1",children:R.categories.map(s=>e.jsxs("label",{className:"flex items-center gap-2.5 p-2 rounded-md hover:bg-muted cursor-pointer",children:[e.jsx(ve,{checked:(b.categoryIds||[]).includes(s.id),onCheckedChange:()=>Be(s.id)}),e.jsx("span",{className:"text-sm flex-1",children:s.name})]},s.id))}):e.jsx("p",{className:"text-xs text-muted-foreground",children:"No drink categories found. Add drinks first."})]}),b.type==="items"&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Select specific drinks to show on the sign:"}),(b.itemIds||[]).length>0&&e.jsxs("span",{className:"text-xs font-medium text-primary",children:[(b.itemIds||[]).length," selected"]})]}),Ce?e.jsx("p",{className:"text-xs text-muted-foreground",children:"Loading drinks..."}):R?.items.length?e.jsx($e,{className:"h-56",children:e.jsx("div",{className:"space-y-1 pr-2",children:R.items.map(s=>{const l=(b.itemIds||[]).includes(s.id);return e.jsxs("label",{className:"flex items-center gap-2.5 p-2 rounded-md hover:bg-muted cursor-pointer transition-colors",style:l?{backgroundColor:"#fff7ed"}:{},children:[e.jsx(ve,{checked:l,onCheckedChange:()=>Ie(s.id)}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("div",{className:"text-sm font-medium truncate",children:s.name}),e.jsx("div",{className:"text-xs text-muted-foreground",children:s.category})]}),s.price&&e.jsx("span",{className:"text-xs font-medium text-muted-foreground flex-shrink-0",children:s.price})]},s.id)})})}):e.jsx("p",{className:"text-xs text-muted-foreground",children:"No drinks found."})]})]}),v==="tonight"&&e.jsxs("div",{className:"space-y-4 border rounded-lg p-4 bg-muted/30",children:[e.jsxs(j,{className:"text-sm font-semibold flex items-center gap-1.5",children:[e.jsx(Ks,{className:"w-4 h-4"})," Tonight Setup"]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Set a custom heading, sub-heading, and optional photo for your sign. Leave blank to show tonight's events instead."}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(j,{className:"text-xs",children:"Heading"}),e.jsx(Q,{value:c.heading||"",onChange:s=>C({...c,heading:s.target.value}),placeholder:"e.g. Live Music Tonight"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(j,{className:"text-xs",children:"Sub-heading"}),e.jsx(Q,{value:c.subheading||"",onChange:s=>C({...c,subheading:s.target.value}),placeholder:"e.g. Doors open at 7pm"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(j,{className:"text-xs",children:"Backgroun
1d Type"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{type:"button",onClick:()=>C({...c,backgroundType:"image"}),className:`flex items-center gap-1.5 text-xs px-3 py-1.5 rounded-md border transition-colors ${!c.backgroundType||c.backgroundType==="image"?"bg-orange-500 text-white border-orange-500":"hover:bg-muted"}`,children:[e.jsx(ke,{className:"w-3 h-3"})," Image"]}),e.jsxs("button",{type:"button",onClick:()=>C({...c,backgroundType:"video"}),className:`flex items-center gap-1.5 text-xs px-3 py-1.5 rounded-md border transition-colors ${c.backgroundType==="video"?"bg-orange-500 text-white border-orange-500":"hover:bg-muted"}`,children:[e.jsx(Me,{className:"w-3 h-3"})," Video"]})]})]}),c.backgroundType==="video"?e.jsxs("div",{className:"space-y-2",children:[e.jsx(j,{className:"text-xs",children:"Background Video"}),c.backgroundVideoUrl?e.jsxs("div",{className:"flex items-start gap-3 p-3 rounded-md border bg-background",children:[e.jsx("video",{src:c.backgroundVideoUrl,className:"w-24 h-16 object-cover rounded-md flex-shrink-0 bg-black",muted:!0,preload:"metadata"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-xs font-medium truncate",children:c.backgroundVideoFilename||"Background video"}),c.backgroundVideoSize?e.jsxs("p",{className:"text-xs text-muted-foreground",children:[(c.backgroundVideoSize/(1024*1024)).toFixed(1)," MB"]}):null,e.jsxs("div",{className:"flex flex-wrap gap-2 mt-2",children:[e.jsxs("label",{className:`flex items-center gap-1 text-xs px-2 py-1 rounded border cursor-pointer transition-colors ${z?"opacity-50 pointer-events-none":"hover:bg-muted"}`,children:[e.jsx(Ts,{className:"w-3 h-3"}),z?"Uploading…":"Replace",e.jsx("input",{type:"file",accept:"video/mp4,video/webm,video/quicktime",className:"hidden",disabled:z||!f,onChange:a})]}),e.jsxs("button",{type:"button",onClick:me,className:"flex items-center gap-1 text-xs px-2 py-1 rounded border hover:bg-muted transition-colors",children:[e.jsx(js,{className:"w-3 h-3"})," From library"]}),e.jsxs("button",{type:"button",onClick:()=>C({...c,backgroundVideoUrl:void 0,backgroundVideoFilename:void 0,backgroundVideoSize:void 0}),className:"flex items-center gap-1 text-xs px-2 py-1 rounded border text-destructive hover:bg-destructive/10 transition-colors",children:[e.jsx(Ke,{className:"w-3 h-3"})," Remove"]})]}),O&&e.jsxs("div",{className:"mt-2 border rounded-lg bg-background overflow-hidden",children:[e.jsxs("div",{className:"flex items-center justify-between px-3 py-2 border-b bg-muted/30",children:[e.jsx("span",{className:"text-xs font-medium",children:"Previously uploaded videos"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{type:"button",onClick:de,className:"p-1 hover:bg-muted rounded transition-colors",title:"Refresh",children:e.jsx(De,{className:`w-3 h-3 text-muted-foreground ${I?"animate-spin":""}`})}),e.jsx("button",{type:"button",onClick:()=>B(!1),className:"p-1 hover:bg-muted rounded transition-colors",children:e.jsx(vs,{className:"w-3 h-3 text-muted-foreground"})})]})]}),I?e.jsx("div",{className:"px-3 py-4 text-center text-xs text-muted-foreground",children:"Loading…"}):P.length===0?e.jsx("div",{className:"px-3 py-4 text-center text-xs text-muted-foreground",children:"No previously uploaded videos found."}):e.jsx("div",{className:"divide-y max-h-48 overflow-y-auto",children:P.map(s=>e.jsxs("button",{type:"button",onClick:()=>he(s),className:"w-full flex items-center gap-3 px-3 py-2 hover:bg-muted/50 transition-colors text-left",children:[e.jsx("div",{className:"w-8 h-8 rounded bg-gray-800 flex items-center justify-center flex-shrink-0",children:e.jsx(ys,{className:"w-4 h-4 text-white"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-xs font-medium truncate",children:s.fileName}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[s.size?`${(s.size/(1024*1024)).toFixed(1)} MB · `:"",new Date(s.uploadedAt).toLocaleDateString()]})]})]},s.fileKey))})]})]})]}):e.jsxs("div",{className:"space-y-1.5",children:[!f&&e.jsx("p",{className:"text-xs text-muted-foreground",children:"Save the sign first to enable video upload."}),f&&e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs("label",{className:`flex items-center gap-1.5 text-xs px-3 py-1.5 rounded-md border cursor-pointer transition-colors w-fit ${z?"opacity-50 pointer-events-none":"hover:bg-muted"}`,children:[e.jsx(Me,{className:"w-3 h-3"}),z?"Uploading…":"Upload video",e.jsx("input",{type:"file",accept:"video/mp4,video/webm,video/quicktime",className:"hidden",disabled:z,onChange:a})]}),e.jsxs("button",{type:"button",onClick:me,className:"flex items-center gap-1.5 text-xs px-3 py-1.5 rounded-md border hover:bg-muted transition-colors w-fit",children:[e.jsx(js,{className:"w-3 h-3"}),"Choose from library"]})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"MP4 preferred · Max 50MB · 30–60s recommended"}),O&&e.jsxs("div",{className:"mt-2 border rounded-lg bg-background overflow-hidden",children:[e.jsxs("div",{className:"flex items-center justify-between px-3 py-2 border-b bg-muted/30",children:[e.jsx("span",{className:"text-xs font-medium",children:"Previously uploaded videos"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{type:"button",onClick:de,className:"p-1 hover:bg-muted rounded transition-colors",title:"Refresh",children:e.jsx(De,{className:`w-3 h-3 text-muted-foreground ${I?"animate-spin":""}`})}),e.jsx("button",{type:"button",onClick:()=>B(!1),className:"p-1 hover:bg-muted rounded transition-colors",children:e.jsx(vs,{className:"w-3 h-3 text-muted-foreground"})})]})]}),I?e.jsx("div",{className:"px-3 py-4 text-center text-xs text-muted-foreground",children:"Loading…"}):P.length===0?e.jsx("div",{className:"px-3 py-4 text-center text-xs text-muted-foreground",children:"No previously uploaded videos found."}):e.jsx("div",{className:"divide-y max-h-48 overflow-y-auto",children:P.map(s=>e.jsxs("button",{type:"button",onClick:()=>he(s),className:"w-full flex items-center gap-3 px-3 py-2 hover:bg-muted/50 transition-colors text-left",children:[e.jsx("div",{className:"w-8 h-8 rounded bg-gray-800 flex items-center justify-center flex-shrink-0",children:e.jsx(ys,{className:"w-4 h-4 text-white"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-xs font-medium truncate",children:s.fileName}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[s.size?`${(s.size/(1024*1024)).toFixed(1)} MB · `:"",new Date(s.uploadedAt).toLocaleDateString()]})]})]},s.fileKey))})]})]})]}):e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(j,{className:"text-xs",children:"Backgroun
1d Photos"}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[(c.photoUrls||[]).length,"/3 selected — rotated automatically"]})]}),(c.photoUrls||[]).length>0&&e.jsx("div",{className:"flex gap-2 flex-wrap",children:(c.photoUrls||[]).map((s,l)=>e.jsxs("div",{className:"relative w-20 h-20 rounded-md overflow-hidden border flex-shrink-0",children:[e.jsx("img",{src:s,alt:"",className:"w-full h-full object-cover"}),e.jsx("div",{className:"absolute top-1 left-1 w-5 h-5 rounded-full bg-orange-500 text-white text-xs flex items-center justify-center font-bold",children:l+1}),e.jsx("button",{type:"button",onClick:()=>{const y=(c.photoUrls||[]).filter((S,H)=>H!==l);C({...c,photoUrls:y})},className:"absolute top-1 right-1 w-5 h-5 rounded-full bg-black/60 text-white text-xs flex items-center justify-center hover:bg-black/80",children:"×"})]},l))}),(c.photoUrls||[]).length<3&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("label",{className:`flex items-center gap-1.5 text-xs px-3 py-1.5 rounded-md border cursor-pointer transition-colors ${U?"opacity-50 pointer-events-none":"hover:bg-muted"}`,children:[e.jsx(Me,{className:"w-3 h-3"}),U?"Uploading…":"Upload photo",e.jsx("input",{type:"file",accept:"image/*",className:"hidden",disabled:U,onChange:m})]}),n?.photos?.length?e.jsx("span",{className:"text-xs text-muted-foreground",children:"or pick from gallery below"}):null]}),N?e.jsx("p",{className:"text-xs text-muted-foreground",children:"Loading gallery photos…"}):n?.photos?.length?e.jsx($e,{className:"h-48",children:e.jsx("div",{className:"grid grid-cols-4 gap-2 pr-2",children:n.photos.map(s=>{const y=(c.photoUrls||[]).indexOf(s.url||s.thumbUrl),S=y!==-1;return e.jsxs("button",{type:"button",onClick:()=>{const H=s.url||s.thumbUrl,ce=c.photoUrls||[];S?C({...c,photoUrls:ce.filter(je=>je!==H)}):ce.length<3&&C({...c,photoUrls:[...ce,H]})},className:"relative aspect-square rounded-md overflow-hidden border-2 transition-all",style:{borderColor:S?"#f97316":"transparent"},children:[e.jsx("img",{src:s.thumbUrl,alt:"",className:"w-full h-full object-cover"}),S&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center",style:{backgroundColor:"rgba(249,115,22,0.35)"},children:e.jsx("div",{className:"w-5 h-5 rounded-full bg-orange-500 flex items-center justify-center text-white text-xs font-bold",children:y+1})})]},s.id)})})}):null]})]})]}),v==="wall"&&k&&e.jsxs("div",{className:"space-y-4 border rounded-lg p-4 bg-orange-50/60",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ss,{className:"w-4 h-4 text-orange-600"}),e.jsx("span",{className:"text-sm font-semibold text-orange-800",children:"Wall Mode Settings"})]}),e.jsxs("div",{children:[e.jsx(j,{className:"text-xs text-muted-foreground",children:"Wall Code"}),e.jsxs("div",{className:"flex gap-2 mt-1",children:[e.jsx(Q,{value:k.wallCode,onChange:s=>k.setWallCode(s.target.value.replace(/\D/g,"").slice(0,8)),placeholder:"e.g. 1234",className:"font-mono text-lg font-bold tracking-widest",maxLength:8}),e.jsxs(u,{type:"button",variant:"outline",size:"sm",className:"flex-shrink-0 gap-1",onClick:()=>k.setWallCode(String(Math.floor(1e3+Math.random()*9e3))),children:[e.jsx(Bs,{className:"w-3 h-3"}),"Generate"]})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Guests enter this code in your Joggle chat to post a photo."})]}),e.jsxs("div",{children:[e.jsx(j,{className:"text-xs text-muted-foreground",children:"Layout"}),e.jsx("div",{className:"grid grid-cols-3 gap-2 mt-1",children:[{value:"live_reveal",label:"Live Reveal",sub:"Full-screen flash"},{value:"slideshow",label:"Slideshow",sub:"Rotating photos"},{value:"mosaic",label:"Mosaic",sub:"Photo grid"}].map(s=>e.jsxs("button",{type:"button",onClick:()=>k.setWallLayout(s.value),className:"flex flex-col items-center gap-0.5 p-2 rounded-lg border text-center transition-all",style:k.wallLayout===s.value?{borderColor:"#f97316",backgroundColor:"#fff7ed",color:"#c2410c"}:{borderColor:"#e5e7eb",backgroundColor:"#fff",color:"#6b7280"},children:[e.jsx("span",{className:"text-xs font-semibold",children:s.label}),e.jsx("span",{className:"text-xs opacity-70",children:s.sub})]},s.value))})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx(j,{className:"text-xs text-muted-foreground",children:"Moderation"}),e.jsxs(Te,{value:k.wallModeration,onValueChange:k.setWallModeration,children:[e.jsx(Le,{className:"mt-1",children:e.jsx(Ue,{})}),e.jsxs(Pe,{children:[e.jsx(se,{value:"auto",children:"Auto (Gemini AI)"}),e.jsx(se,{value:"manual",children:"Manual approval"})]})]})]}),e.jsxs("div",{children:[e.jsx(j,{className:"text-xs text-muted-foreground",children:"Rate limit"}),e.jsxs(Te,{value:String(k.wallRateLimit),onValueChange:s=>k.setWallRateLimit(Number(s)),children:[e.jsx(Le,{className:"mt-1",children:e.jsx(Ue,{})}),e.jsxs(Pe,{children:[e.jsx(se,{value:"30",children:"Relaxed (30s)"}),e.jsx(se,{value:"90",children:"Standard (90s)"}),e.jsx(se,{value:"300",children:"Strict (5 min)"})]})]})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx(j,{className:"text-xs text-muted-foreground",children:"Retention"}),e.jsxs(Te,{value:String(k.wallRetention),onValueChange:s=>k.setWallRetention(Number(s)),children:[e.jsx(Le,{className:"mt-1",children:e.jsx(Ue,{})}),e.jsxs(Pe,{children:[e.jsx(se,{value:"24",children:"24 hours"}),e.jsx(se,{value:"48",children:"48 hours"}),e.jsx(se,{value:"168",children:"7 days"})]})]})]}),e.jsxs("div",{children:[e.jsx(j,{className:"text-xs text-muted-foreground",children:"Status"}),e.jsxs("div",{className:"flex items-center gap-2 mt-2",children:[e.jsx(is,{checked:k.wallStatus==="active",onCheckedChange:s=>k.setWallStatus(s?"active":"paused")}),e.jsx("span",{className:"text-sm",children:k.wallStatus==="active"?"Active":"Paused"})]})]})]})]}),e.jsxs("div",{children:[e.jsx(j,{children:"Orientation"}),e.jsxs(Te,{value:te,onValueChange:W,children:[e.jsx(Le,{children:e.jsx(Ue,{})}),e.jsxs(Pe,{children:[e.jsx(se,{value:"landscape",children:"Landscape"}),e.jsx(se,{value:"portrait",children:"Portrait"})]})]})]}),e.jsxs("div",{children:[e.jsx(j,{children:"Theme"}),e.jsxs("div",{className:"flex gap-2 mt-1",children:[e.jsxs("button",{type:"button",onClick:()=>$("light"),className:"flex-1 flex items-center justify-center gap-2 py-2 px-3 rounded-lg border text-sm font-medium transition-all",style:_==="light"?{borderColor:"#f97316",backgroundColor:"#fff7ed",color:"#c2410c"}:{borderColor:"#e5e7eb",backgroundColor:"#ffffff",color:"#6b7280"},children:[e.jsx(Cs,{className:"w-4 h-4"})," Light"]}),e.jsxs("button",{type:"button",onClick:()=>$("dark"),className:"flex-1 flex items-center justify-center gap-2 py-2 px-3 rounded-lg border text-sm font-medium transition-all",style:_==="dark"?{borderColor:"#6366f1",backgroundColor:"#eef2ff",color:"#4338ca"}:{borderColor:"#e5e7eb",backgroundColor:"#ffffff",color:"#6b7280"},children:[e.jsx(ks,{className:"w-4 h-4"})," Dark"]})]})]}),e.jsxs("div",{children:[e.jsx(j,{htmlFor:"sign-slide-delay",children:"Slide Delay (seconds)"}),e.jsx("p",{className:"text-xs text-muted-foreground mb-1",children:"How long each item shows before rotating to the next"}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("input",{id:"sign-slide-delay",type:"range",min:5,max:60,step:5,value:ae,onChange:s=>re(parseInt(s.target.value)),className:"flex-1"}),e.jsxs("span",{className:"text-sm font-medium w-12 text-right",children:[ae,"s"]})]}),e.jsxs("div",{className:"flex justify-between text-xs text-muted-foreground mt-0.5",children:[e.jsx("span",{children:"5s"}),e.jsx("span",{children:"60s"})]})]}),v!=="tonight"&&e.jsxs("div",{className:"space-y-3 rounded-lg border p-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-semibold mb-0.5",children:"Sign Header Text"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Customise the two lines shown at the top of this sign. Leave blank to use the defaults."})]}),e.jsxs("div",{children:[e.jsx(j,{htmlFor:"sign-welcome-text",children:"Welcome Message"}),e.jsx("p",{className:"text-xs text-muted-foreground mb-1",children:'Default: "Welcome to [Venue Name]"'}),e.jsx(Q,{id:"sign-welcome-text",value:ne,onChange:s=>X(s.target.value),placeholder:"Welcome to [Venue Name]"})]}),e.jsxs("div",{children:[e.jsx(j,{htmlFor:"sign-intro-text",children:"Intro Text"}),e.jsx("p",{className:"text-xs text-muted-foreground mb-1",children:'Default: the mode name (e.g. "History", "Events")'}),e.jsx(Q,{id:"sign-intro-text",value:le,onChange:s=>Z(s.target.value),placeholder:"e.g. Check out our menu"})]})]}),e.jsxs("div",{children:[e.jsx(j,{htmlFor:"sign-qr",children:"QR Destination URL (optional)"}),e.jsx(Q,{id:"sign-qr",value:G,onChange:s=>Y(s.target.value),placeholder:"Defaults to your Joggle page"})]}),v==="specials"&&f&&e.jsxs("div",{className:"space-y-3 rounded-lg border p-4",children:[e.jsxs("div",{children:[e.jsxs("p",{className:"text-sm font-semibold mb-0.5 flex items-center gap-2",children:[e.jsx(ze,{className:"w-4 h-4 text-orange-500"}
1),"Specials Library"]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Create and manage Specials for this sign. Toggle up to 6 active at a time — they cycle automatically on the screen."})]}),e.jsx(Us,{signId:f,assistantId:d})]})]})}function Gs({signId:d}){const{data:f,isLoading:p,error:g}=xe({queryKey:[`/api/owner/signs/${d}/qr-stats`],queryFn:async()=>{const w=await fetch(`/api/owner/signs/${d}/qr-stats`);if(!w.ok)throw new Error("Failed to load stats");return w.json()},staleTime:3e4});if(p)return e.jsx("div",{className:"text-sm text-muted-foreground py-2",children:"Loading stats…"});if(g||!f)return e.jsx("div",{className:"text-sm text-destructive py-2",children:"Could not load stats."});const K=f.lastScan?new Date(f.lastScan).toLocaleString(void 0,{dateStyle:"medium",timeStyle:"short"}):"Never";return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-3",children:[e.jsxs("div",{className:"rounded-lg border bg-muted/40 px-3 py-2 text-center",children:[e.jsx("div",{className:"text-2xl font-bold",children:f.totalScans}),e.jsx("div",{className:"text-xs text-muted-foreground mt-0.5",children:"All time"})]}),e.jsxs("div",{className:"rounded-lg border bg-muted/40 px-3 py-2 text-center",children:[e.jsx("div",{className:"text-2xl font-bold",children:f.last7Days}),e.jsx("div",{className:"text-xs text-muted-foreground mt-0.5",children:"Last 7 days"})]}),e.jsxs("div",{className:"rounded-lg border bg-muted/40 px-3 py-2 text-center",children:[e.jsx("div",{className:"text-2xl font-bold",children:f.last30Days}),e.jsx("div",{className:"text-xs text-muted-foreground mt-0.5",children:"Last 30 days"})]}),e.jsxs("div",{className:"rounded-lg border bg-muted/40 px-3 py-2 text-center",children:[e.jsx("div",{className:"text-xs font-medium truncate",children:K}),e.jsx("div",{className:"text-xs text-muted-foreground mt-0.5",children:"Last scan"})]})]}),f.byMode.length>0&&e.jsxs("div",{children:[e.jsx("p",{className:"text-xs font-semibold text-muted-foreground uppercase tracking-wide mb-2",children:"By Mode"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:f.byMode.map(({mode:w,total:v})=>e.jsxs("span",{className:"inline-flex items-center gap-1.5 rounded-full bg-primary/10 px-3 py-1 text-sm font-medium text-primary",children:[w.charAt(0).toUpperCase()+w.slice(1),e.jsx("span",{className:"font-bold",children:v})]},w))})]}),f.totalScans===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"No scans recorded yet. Stats will appear here once someone scans this sign's QR code."})]})}function Us({signId:d,assistantId:f}){const p=Ae(),{toast:g}=Qe(),[K,w]=i.useState(!1),[v,V]=i.useState(null),[te,W]=i.useState(!1),[_,$]=i.useState(""),[G,Y]=i.useState(null),[h,L]=i.useState(""),[x,M]=i.useState(""),[b,r]=i.useState(""),[c,C]=i.useState(""),[ae,re]=i.useState(""),[ne,X]=i.useState(!1),[le,Z]=i.useState(!1),{data:k=[],isLoading:ie}=xe({queryKey:[`/api/owner/signs/${d}/specials`],queryFn:async()=>{const a=await fetch(`/api/owner/signs/${d}/specials`);if(!a.ok)throw new Error("Failed to load specials");return a.json()}}),{data:D}=xe({queryKey:[`/api/owner/signs/photos-for-picker?assistantId=${f}`],queryFn:async()=>{const a=await fetch(`/api/owner/signs/photos-for-picker?assistantId=${f}`);if(!a.ok)throw new Error("Failed to load photos");return a.json()},enabled:K}),U=k.filter(a=>a.isActive).sort((a,m)=>a.sortOrder-m.sortOrder),q=U.length;function z(){V(null),L(""),M(""),r(""),C(""),re(""),w(!0)}function oe(a){V(a),L(a.name),M(a.imageUrl||""),r(a.videoUrl||""),C(a.overlayHeading||""),re(a.overlaySubheading||""),w(!0)}async function O(a){const m=a.target.files?.[0];if(a.target.value="",!!m){if(!Ns(m)){g({title:"Invalid file type",description:"Please select an image file.",variant:"destructive"});return}if(m.size>10*1024*1024){g({title:"File too large",description:"Please select an image smaller than 10MB.",variant:"destructive"});return}X(!0);try{const n=new FormData;n.append("photo",m);const N=await T(`/api/pub-gallery-photos/${f}/upload`,{method:"POST",body:n});if(!N.ok){const R=await N.json().catch(()=>({}));throw new Error(R.message||"Upload failed")}const ee=(await N.json()).photoUrl;M(ee),W(!1),p.invalidateQueries({queryKey:[`/api/owner/signs/photos-for-picker?assistantId=${f}`]}),g({title:"Photo uploaded",description:"Photo added to your library and selected."})}catch(n){g({title:"Upload failed",description:n.message||"Something went wrong.",variant:"destructive"})}finally{X(!1)}}}async function B(a){const m=a.target.files?.[0];if(a.target.value="",!!m){if(!m.type.startsWith("video/")){g({title:"Invalid file type",description:"Please select a video file.",variant:"destructive"});return}if(m.size>200*1024*1024){g({title:"File too large",description:"Please select a video smaller than 200MB.",variant:"destructive"});return}Z(!0);try{const n=new FormData;n.append("video",m);const N=await T(`/api/owner/signs/${d}/specials/upload-video`,{method:"POST",body:n});if(!N.ok){const ee=await N.json().catch(()=>({}));throw new Error(ee.error||"Upload failed")}const E=await N.json();r(E.videoUrl),g({title:"Video uploaded",description:"Video ready to use with your special."})}catch(n){g({title:"Upload failed",description:n.message||"Something went wrong.",variant:"destructive"})}finally{Z(!1)}}}const P=A({mutationFn:async a=>{const m=await T(`/api/owner/signs/${d}/specials`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)});if(!m.ok)throw new Error("Failed to create special");return m.json()},onSuccess:()=>{p.invalidateQueries({queryKey:[`/api/owner/signs/${d}/specials`]}),w(!1),g({title:"Special saved"})},onError:()=>g({title:"Failed to save special",variant:"destructive"})}),ue=A({mutationFn:async({id:a,...m})=>{const n=await T(`/api/owner/specials/${a}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(m)});if(!n.ok)throw new Error("Failed to update special");return n.json()},onSuccess:()=>{p.invalidateQueries({queryKey:[`/api/owner/signs/${d}/specials`]}),w(!1),g({title:"Special updated"})},onError:()=>g({title:"Failed to update special",variant:"destructive"})}),I=A({mutationFn:async a=>{if(!(await T(`/api/owner/specials/${a}`,{method:"DELETE"})).ok)throw new Error("Failed to archive special")},onSuccess:()=>{p.invalidateQueries({queryKey:[`/api/owner/signs/${d}/specials`]}),g({title:"Special removed"})},onError:()=>g({title:"Failed to remove special",variant:"destructive"})});async function pe(a){const m=!a.isActive;if(m&&q>=6){g({title:"Maximum reached",description:"You can have at most 6 active specials. Deactivate one before activating another.",variant:"destructive"});return}Y(a.id);try{const n=await T(`/api/owner/specials/${a.id}/toggle`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({isActive:m})});if(!n.ok){const N=await n.json().catch(()=>({}));throw new Error(N.error||"Failed to toggle special")}p.invalidateQueries({queryKey:[`/api/owner/signs/${d}/specials`]}),g({title:m?"Special activated":"Special deactivated"})}catch(n){g({title:n.message||"Failed to toggle special",variant:"destructive"})}finally{Y(null)}}async function de(a,m){const n=U.findIndex(R=>R.id===m.id);if(n<0)return;const N=[...U];if(a==="up"&&n===0||a==="down"&&n===N.length-1)return;const E=a==="up"?n-1:n+1;[N[n],N[E]]=[N[E],N[n]];const ee=N.map(R=>R.id);try{if(!(await T(`/api/owner/signs/${d}/specials/reorder`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({orderedIds:ee})})).ok)throw new Error("Failed to reorder");p.invalidateQueries({queryKey:[`/api/owner/signs/${d}/specials`]})}catch{g({title:"Failed to reorder specials",variant:"destructive"})}}function me(){if(!h.trim())return;const a={name:h.trim(),imageUrl:x.trim()||null,videoUrl:b.trim()||null,overlayHeading:c.trim()||null,overlaySubheading:ae.trim()||null};v?ue.mutate({id:v.id,...a}
1):P.mutate(a)}const he=P.isPending||ue.isPending;return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-semibold ${q>=6?"bg-orange-100 text-orange-700":"bg-muted text-muted-foreground"}`,children:[q,"/6 active"]}),q>1&&e.jsxs("span",{className:"text-xs text-muted-foreground",children:["cycling every ",8,"s"]})]}),e.jsxs(u,{size:"sm",onClick:z,children:[e.jsx(os,{className:"w-3 h-3 mr-1"})," New Special"]})]}),ie?e.jsx("p",{className:"text-sm text-muted-foreground py-2",children:"Loading specials…"}):k.length===0?e.jsxs("div",{className:"rounded-lg border border-dashed p-6 text-center text-muted-foreground",children:[e.jsx(ke,{className:"w-8 h-8 mx-auto mb-2 opacity-40"}),e.jsx("p",{className:"text-sm",children:"No specials yet. Create your first one."})]}):e.jsx("div",{className:"grid gap-3",children:k.map(a=>{const m=U.findIndex(N=>N.id===a.id),n=a.isActive;return e.jsxs("div",{className:`rounded-lg border p-3 flex gap-3 items-start ${n?"border-primary bg-primary/5":"bg-muted/30"}`,children:[a.videoUrl?e.jsxs("div",{className:"w-16 h-16 rounded bg-black flex-shrink-0 overflow-hidden relative",children:[e.jsx("video",{src:a.videoUrl,muted:!0,playsInline:!0,className:"w-full h-full object-cover opacity-80"}),e.jsx("div",{className:"absolute inset-0 flex items-center justify-center",children:e.jsx(zs,{className:"w-5 h-5 text-white drop-shadow"})})]}):a.imageUrl?e.jsx("img",{src:a.imageUrl,alt:a.name,className:"w-16 h-16 rounded object-cover flex-shrink-0 bg-muted",onError:N=>{N.target.style.display="none"}}):e.jsx("div",{className:"w-16 h-16 rounded bg-muted flex items-center justify-center flex-shrink-0",children:e.jsx(ke,{className:"w-6 h-6 opacity-30"})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("span",{className:"font-semibold text-sm truncate",children:a.name}),n&&e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-primary text-primary-foreground px-2 py-0.5 text-xs font-medium",children:[e.jsx(ze,{className:"w-3 h-3"})," Active ",U.length>1?`· slot ${m+1}`:""]})]}),a.overlayHeading&&e.jsx("p",{className:"text-xs text-muted-foreground truncate mt-0.5",children:a.overlayHeading}),a.overlaySubheading&&e.jsx("p",{className:"text-xs text-muted-foreground truncate",children:a.overlaySubheading}),e.jsxs("div",{className:"flex gap-2 mt-2 flex-wrap items-center",children:[e.jsx(is,{checked:n,onCheckedChange:()=>pe(a),disabled:G===a.id||!n&&q>=6,"aria-label":n?"Deactivate special":"Activate special"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:n?"On screen":"Off"}),n&&U.length>1&&e.jsxs(e.Fragment,{children:[e.jsx(u,{size:"sm",variant:"ghost",className:"h-7 w-7 p-0",disabled:m===0,onClick:()=>de("up",a),title:"Move earlier in cycle",children:e.jsx(Oe,{className:"w-3 h-3"})}),e.jsx(u,{size:"sm",variant:"ghost",className:"h-7 w-7 p-0",disabled:m===U.length-1,onClick:()=>de("down",a),title:"Move later in cycle",children:e.jsx(Ve,{className:"w-3 h-3"})})]}),e.jsxs(u,{size:"sm",variant:"outline",onClick:()=>oe(a),className:"h-7 text-xs px-2",title:"Edit",children:[e.jsx(Fs,{className:"w-3 h-3 sm:mr-1"}),e.jsx("span",{className:"hidden sm:inline",children:"Edit"})]}),e.jsxs(u,{size:"sm",variant:"outline",className:"h-7 text-xs px-2 text-destructive hover:text-destructive",onClick:()=>I.mutate(a.id),disabled:I.isPending,title:"Remove",children:[e.jsx(Ke,{className:"w-3 h-3 sm:mr-1"}),e.jsx("span",{className:"hidden sm:inline",children:"Remove"})]})]})]})]},a.id)})}),q>=6&&e.jsxs("p",{className:"text-xs text-orange-600 font-medium flex items-center gap-1",children:[e.jsx(As,{className:"w-3 h-3"})," Maximum 6 active specials reached. Deactivate one to add another."]}),e.jsx(ye,{open:K,onOpenChange:a=>{a||w(!1)},children:e.jsxs(be,{className:"max-w-lg max-h-[90vh] flex flex-col",children:[e.jsx(Ne,{children:e.jsx(we,{children:v?"Edit Special":"New Special"})}),e.jsxs("div",{className:"space-y-4 py-2 overflow-y-auto flex-1 min-h-0",children:[e.jsxs("div",{children:[e.jsx(j,{htmlFor:"sp-name",children:"Name (internal label)"}),e.jsx(Q,{id:"sp-name",value:h,onChange:a=>L(a.target.value),placeholder:"e.g. Monday Lunch Deal"})]}),e.jsxs("div",{children:[e.jsx(j,{htmlFor:"sp-image",children:"Photo"}),e.jsx("p",{className:"text-xs text-muted-foreground mb-1",children:"Upload a photo, pick from your library, or paste a direct image URL"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Q,{id:"sp-image",value:x,onChange:a=>{M(a.target.value),W(!1)},placeholder:"https://example.com/photo.jpg",className:"flex-1"}),e.jsxs(u,{type:"button",size:"sm",variant:"outline",onClick:()=>{W(a=>!a),$("")},className:"shrink-0",children:[e.jsx(ke,{className:"w-4 h-4 mr-1"}),"Library"]}),e.jsxs("label",{className:"shrink-0",children:[e.jsx("input",{type:"file",accept:"image/*",className:"hidden",onChange:O,disabled:ne}),e.jsx(u,{type:"button",size:"sm",variant:"outline",className:"shrink-0 pointer-events-none",disabled:ne,asChild:!0,children:e.jsxs("span",{children:[e.jsx(Me,{className:"w-4 h-4 mr-1"}),ne?"Uploading…":"Upload"]})})]})]}),te&&e.jsxs("div",{className:"mt-2 rounded-lg border bg-muted/30 p-2",children:[e.jsx("div",{className:"mb-2",children:e.jsx(Q,{autoFocus:!0,placeholder:"Search photos…",value:_,onCh
1ange:a=>$(a.target.value),className:"h-8 text-sm"})}),D?.photos?.length?(()=>{const a=D.photos.filter(m=>{const n=_.trim().toLowerCase();return n?(m.caption||"").toLowerCase().includes(n)||m.url.toLowerCase().includes(n):!0});return a.length===0?e.jsx("p",{className:"text-xs text-muted-foreground text-center py-3",children:"No photos match your search"}):e.jsx("div",{className:"grid grid-cols-4 gap-1.5 max-h-40 overflow-y-auto",children:a.map(m=>e.jsx("button",{type:"button",onClick:()=>{M(m.url),W(!1),$("")},className:`rounded overflow-hidden aspect-square focus:outline-none focus:ring-2 focus:ring-primary ${x===m.url?"ring-2 ring-primary":"hover:opacity-90"}`,title:m.caption||void 0,children:e.jsx("img",{src:m.url,alt:m.caption||"",className:"w-full h-full object-cover",onError:n=>{n.target.style.display="none"}})},m.id))})})():e.jsx("p",{className:"text-xs text-muted-foreground text-center py-3",children:"No photos in your library yet"})]}),x&&!te&&e.jsx("div",{className:"mt-2 rounded overflow-hidden h-28 bg-muted",children:e.jsx("img",{src:x,alt:"Preview",className:"w-full h-full object-cover",onError:a=>{a.target.style.display="none"}})})]}),e.jsxs("div",{children:[e.jsx(j,{children:"Video"}),e.jsx("p",{className:"text-xs text-muted-foreground mb-1",children:"Upload a video to play on screen — the headline text will be overlaid on top"}),e.jsxs("div",{className:"flex gap-2 items-center",children:[b?e.jsxs("div",{className:"flex-1 flex items-center gap-2 rounded border px-3 py-1.5 bg-muted/30 text-sm text-muted-foreground truncate",children:[e.jsx("span",{className:"truncate",children:b.split("/").pop()}),e.jsx(u,{type:"button",size:"sm",variant:"ghost",className:"h-6 px-1.5 text-xs shrink-0",onClick:()=>r(""),children:"Remove"})]}):e.jsx("span",{className:"flex-1 text-xs text-muted-foreground",children:"No video selected"}),e.jsxs("label",{className:"shrink-0",children:[e.jsx("input",{type:"file",accept:"video/*",className:"hidden",onChange:B,disabled:le}),e.jsx(u,{type:"button",size:"sm",variant:"outline",className:"shrink-0 pointer-events-none",disabled:le,asChild:!0,children:e.jsxs("span",{children:[e.jsx(Me,{className:"w-4 h-4 mr-1"}),le?"Uploading…":"Upload video"]})})]})]}),b&&e.jsx("div",{className:"mt-2 rounded overflow-hidden bg-black aspect-video max-h-32",children:e.jsx("video",{src:b,muted:!0,loop:!0,autoPlay:!0,playsInline:!0,className:"w-full h-full object-cover"})})]}),e.jsxs("div",{children:[e.jsx(j,{htmlFor:"sp-heading",children:"Overlay Heading"}),e.jsx(Q,{id:"sp-heading",value:c,onChange:a=>C(a.target.value),placeholder:"e.g. 2 for 1 Burgers"})]}),e.jsxs("div",{children:[e.jsx(j,{htmlFor:"sp-subheading",children:"Overlay Subheading"}),e.jsx(Q,{id:"sp-subheading",value:ae,onChange:a=>re(a.target.value),placeholder:"e.g. Every Monday 12–3pm"})]})]}),e.jsxs(Se,{className:"gap-2 flex-wrap",children:[e.jsx(u,{variant:"outline",onClick:()=>w(!1),children:"Cancel"}),e.jsx(u,{onClick:me,disabled:!h.trim()||he,children:he?"Saving…":"Save"})]})]})})]})}export{it as SignageManager};

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.