1import{f as D,r as n,u as R,b as p,a as H,j as s,L as g,B as d,d as l,I as h,S as A,T as O,s as c,t as o}from"./index-CfrGix-z.js";import{I as L}from"./ImageSlotCard-CYEx7BG8.js";import{T as $}from"./trash-2-Dz4xwwxZ.js";import{P}from"./plus-Bqz2idYm.js";import"./image-compress-Cmy7BWq4.js";function X({siteImages:F}){const{data:N,isLoading:K}=D(),u=n.useMemo(()=>N??[],[N]),m=R(),[Q,v]=n.useState(!1),[i,x]=n.useState({name:"",key:"",state:"",description:""}),w=(e,a)=>F.find(t=>t.section===e&&t.slot===a),y=p({mutationFn:async e=>{const a=u.length>0?Math.max(...u.map(r=>r.display_order??0)):0,{error:t}=await c.from("cities").insert({...e,display_order:a+1});if(t)throw t},onSuccess:()=>{m.invalidateQueries({queryKey:["cities"]}),o({title:"City added!"}),x({name:"",key:"",state:"",description:""}),v(!1)},onError:e=>{o({title:"Failed to add city",description:e.message,variant:"destructive"})}}),S=p({mutationFn:async e=>{const{error:a}=await c.from("cities").delete().eq("id",e);if(a)throw a},onSuccess:()=>{m.invalidateQueries({queryKey:["cities"]}),o({title:"City removed"})},onError:e=>{o({title:"Delete failed",description:e.message,variant:"destructive"})}}),[_,z]=n.useState({}),[f,q]=n.useState({}),{data:M}=H({queryKey:["site-content","city_tour_button"],queryFn:async()=>{const{data:e,error:a}=await c.from("site_content").select("*").eq("section","city_tour_button");if(a)throw a;return e}}),j=n.useMemo(()=>M??[],[M]),[E,I]=n.useState({}),[b,B]=n.useState({});n.useEffect(()=>{z(e=>{const a={...e};return u.forEach(t=>{f[t.id]||(a[t.id]=t.caption??"")}),a})},[u,f]),n.useEffect(()=>{I(e=>{const a={...e};return j.forEach(t=>{b[t.key]||(a[t.key]=t.value??"")}),a})},[j,b]);const k=p({mutationFn:async({id:e,caption:a})=>{const{error:t}=await c.from("cities").update({caption:a||null}).eq("id",e);if(t)throw t},onSuccess:(e,a)=>{m.invalidateQueries({queryKey:["cities"]}),o({title:"Caption saved"}),q(t=>({...t,[a.id]:!1}))},onError:e=>{o({title:"Save failed",description:e.message,variant:"destructive"})}}),C=p({mutationFn:async({cityKey:e,label:a})=>{const t=j.find(r=>r.key===e);if(t){const{error:r}=await c.from("site_content").update({value:a}).eq("id",t.id);if(r)throw r}else{const{error:r}=await c.from("site_content").insert({section:"city_tour_button",key:e,value:a});if(r)throw r}},onSuccess:(e,a)=>{m.invalidateQueries({queryKey:["site-content","city_tour_button"]}),m.invalidateQueries({queryKey:["site-content"]}),o({title:"Button label saved"}),B(t=>({...t,[a.cityKey]:!1}))},onError:e=>{o({title:"Save failed",description:e.message,variant:"destructive"})}}),T=()=>{if(!i.name||!i.state){o({title:"Name and state are required",variant:"destructive"});return}const e=i.key||i.name.toLowerCase().replace(/[^a-z0-9]/g,"");y.mutate({...i,key:e})};return K?s.jsx("div",{className:"flex items-center justify-center py-10",children:s.jsx(g,{className:"animate-spin text-muted-foreground",size:24})}):s.jsxs("div",{className:"space-y-8",children:[s.jsxs("p",{className:"text-sm text-muted-foreground",children:["Each city has a ",s.jsx("strong",{children:"card image"})," (shown in the carousel card), a"," ",s.jsx("strong",{children:"background image"})," (shown behind the section when that city is active), and an optional ",s.jsx("strong",{children:"hero caption"}),' (the small label on the home page hero card, e.g. "Adire Maker, Itoku Market").']}),u.map(e=>s.jsxs("div",{className:"border border-border rounded-lg p-5 bg-card/50",children:[s.jsxs("div",{className:"flex items-center justify-between mb-4",children:[s.jsxs("div",{children:[s.jsx("h3",{className:"font-display text-base font-semibold text-gold",children:e.name}),s.jsx("p",{className:"text-xs text-muted-foreground",children:e.state})]}),s.jsx(d,{variant:"ghost",size:"sm",onClick:()=>S.mutate(e.id),disabled:S.isPending,className:"text-destructive hover:text-destructive",children:s.jsx($,{size:14})})]}),s.jsxs("div",{className:"mb-4 max-w-2xl",children:[s.jsx(l,{className:"text-xs",children:"Home Hero Caption (optional)"}),s.jsxs("div",{className:"flex gap-2 mt-1",children:[s.jsx(h,{value:_[e.id]??"",onChange:a=>{z(t=>
1({...t,[e.id]:a.target.value})),q(t=>({...t,[e.id]:!0}))},placeholder:"e.g. Adire Maker, Itoku Market"}),s.jsxs(d,{size:"sm",variant:"outline",disabled:!f[e.id]||k.isPending,onClick:()=>k.mutate({id:e.id,caption:_[e.id]??""}),className:"gap-1.5 shrink-0",children:[k.isPending?s.jsx(g,{size:14,className:"animate-spin"}):s.jsx(A,{size:14}),"Save"]})]})]}),s.jsxs("div",{className:"mb-4 max-w-2xl",children:[s.jsx(l,{className:"text-xs",children:"Tour Button Label (optional)"}),s.jsxs("p",{className:"text-[11px] text-muted-foreground mt-0.5 mb-1",children:['Defaults to "Tour ',e.name,'" if left empty.']}),s.jsxs("div",{className:"flex gap-2 mt-1",children:[s.jsx(h,{value:E[e.key]??"",onChange:a=>{I(t=>({...t,[e.key]:a.target.value})),B(t=>({...t,[e.key]:!0}))},placeholder:`Tour ${e.name}`}),s.jsxs(d,{size:"sm",variant:"outline",disabled:!b[e.key]||C.isPending,onClick:()=>C.mutate({cityKey:e.key,label:E[e.key]??""}),className:"gap-1.5 shrink-0",children:[C.isPending?s.jsx(g,{size:14,className:"animate-spin"}):s.jsx(A,{size:14}),"Save"]})]})]}),s.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4 max-w-2xl",children:[s.jsx(L,{label:"Card Image",section:"city_card",slot:e.key,currentImage:w("city_card",e.key)}),s.jsx(L,{label:"Background Image",section:"city_bg",slot:e.key,currentImage:w("city_bg",e.key)})]})]},e.id)),Q?s.jsxs("div",{className:"border border-dashed border-gold/40 rounded-lg p-5 space-y-4 max-w-2xl",children:[s.jsx("h3",{className:"font-display text-sm font-semibold",children:"Add New City"}),s.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[s.jsxs("div",{className:"space-y-2",children:[s.jsx(l,{children:"City Name"}),s.jsx(h,{value:i.name,onChange:e=>x({...i,name:e.target.value}),placeholder:"e.g. Calabar"})]}),s.jsxs("div",{className:"space-y-2",children:[s.jsx(l,{children:"State"}),s.jsx(h,{value:i.state,onChange:e=>x({...i,state:e.target.value}),placeholder:"e.g. Cross River State"})]})]}),s.jsxs("div",{className:"space-y-2",children:[s.jsx(l,{children:"Key (auto-generated if empty)"}),s.jsx(h,{value:i.key,onChange:e=>x({...i,key:e.target.value}),placeholder:"e.g. calabar"})]}),s.jsxs("div",{className:"space-y-2",children:[s.jsx(l,{children:"Description"}),s.jsx(O,{value:i.description,onChange:e=>x({...i,description:e.target.value}),placeholder:"A brief description of the city...",rows:3})]}),s.jsxs("div",{className:"flex gap-2",children:[s.jsxs(d,{onClick:T,disabled:y.isPending,size:"sm",className:"gap-1.5",children:[y.isPending?s.jsx(g,{size:14,className:"animate-spin"}):s.jsx(P,{size:14}),"Add City"]}),s.jsx(d,{variant:"ghost",size:"sm",onClick:()=>v(!1),children:"Cancel"})]})]}):s.jsxs(d,{variant:"outline",onClick:()=>v(!0),className:"gap-1.5",children:[s.jsx(P,{size:14}),"Add City"]})]})}export{X as CityManager};
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.