1import{u as F,d as D,r as p,b as i,j as e}from"./index-CfEgT0g9.js";import{u as I}from"./useQuery-AUGL08jU.js";import{P as b,a as C}from"./PageShell-CFju-0a6.js";import{u as O}from"./useAuth-CxP84Wvx.js";import"./useSiteContent-B8yfFcgI.js";const y=[{key:"about",label:"About â Collage",description:"Masonry grid on the About page."},{key:"about_feature",label:"About â Feature",description:"Full-width photo below the collage. First photo is used."},{key:"home_gallery",label:"Home â In Frame",description:"Two-up editorial gallery on the homepage."},{key:"tour_hero",label:"Tour â Hero",description:"Banner atop the Tour page. First photo is used."},{key:"contact_feature",label:"Contact â Portrait",description:"Portrait beside the booking info. First photo is used."}],R=3600*24*365*10;function L(){const{user:d,isAdmin:E,loading:x}=O(),m=F(),h=D(),[s,A]=p.useState(y[0].key),[j,c]=p.useState(null),[v,n]=p.useState(null);p.useEffect(()=>{!x&&!d&&m({to:"/auth"})},[x,d,m]);const{data:a=[],refetch:g,isFetching:U}=I({queryKey:["admin-photos",s],queryFn:async()=>{const{data:t,error:r}=await i.from("photos").select("*").eq("category",s).order("sort_order",{ascending:!0});if(r)throw r;return t??[]},enabled:!!d});async function S(t){c("Uploadingâ¦"),n(null);try{const r=t.name.split(".").pop()||"jpg",o=`${s}/${Date.now()}-${crypto.randomUUID()}.${r}`,{error:l}=await i.storage.from("photos").upload(o,t,{cacheControl:"31536000",upsert:!1});if(l)throw l;const{data:u,error:k}=await i.storage.from("photos").createSignedUrl(o,R);if(k||!u)throw k??new Error("Failed to sign URL");const q=(a[a.length-1]?.sort_order??0)+10,{error:_}=await i.from("photos").insert({category:s,url:u.signedUrl,alt:t.name.replace(/\.[^/.]+$/,""),sort_order:q,storage_path:o});if(_)throw _;c("Uploaded."),h.invalidateQueries({queryKey:["photos",s]}),g()}catch(r){n(r instanceof Error?r.message:"Upload failed"),c(null)}}async function P(t){if(confirm("Delete this photo?")){n(null);try{t.storage_path&&await i.storage.from("photos").remove([t.storage_path]);const{error:r}=await i.from("photos").delete().eq("id",t.id);if(r)throw r;h.invalidateQueries({queryKey:["photos",t.category]}),g()}catch(r){n(r instanceof Error?r.message:"Delete failed")}}}async function f(t,r){const{error:o}=await i.from("photos").update(r).eq("id",t);if(o){n(o.message);return}h.invalidateQueries({queryKey:["photos",s]}),g()}async function N(t,r){const o=a.findIndex(u=>u.id===t.id),l=a[o+r];l&&await Promise.all([f(t.id,{sort_order:l.sort_order}),f(l.id,{sort_order:t.sort_order})])}async function w(){await i.auth.signOut(),m({to:"/auth"})}return x?e.jsx(b,{children:e.jsx("div",{className:"px-6 py-32 text-center text-foreground/60",children:"Loadingâ¦"})}):E?e.jsxs(b,{children:[e.jsx(C,{eyebrow:"Admin",title:"Photo Management"}),e.jsx("section",{className:"px-6 pb-32",children:e.jsxs("div",{className:"mx-auto max-w-6xl space-y-8",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-4",children:[e.jsxs("div",{className:"text-mono text-[11px] uppercase tracking-[0.3em] text-foreground/70",children:["Signed in as ",d?.email]}),e.jsx("button",{onClick:w,className:"text-mono text-[10px] uppercase tracking-[0.3em] text-foreground/60 hover:text-primary",children:"Sign Out"})]}),e.jsx("div",{className:"flex flex-wrap gap-2",children:y.map(t=>e.jsx("button",{onClick:()=>{A(t.key),c(null),n(null)},className:`px-4 py-2 rounded-full text-mono text-[10px] uppercase tracking-[0.3em] border transition-colors ${s===t.key?"border-primary/60 text-primary bg-primary/5":"border-border/60 text-foreground/70 hover:text-primary"}`,children:t.label},t.key))}),e.jsx("p",{className:"text-sm text-foreground/60",children:y.find(t=>t.key===s)?.description}),e.jsxs("div",{className:"glass rounded-2xl border border-border/60 p-6 space-y-3",children:[e.jsx("label",{className:"block text-mono text-[10px] uppercase tracking-[0.3em] text-foreground/70",children:"Upload photo"}),e.jsx("input",{type:"file",accept:"image/*",onChange:t=>{const r=t.target.files?.[0];r&&S(r),t.target.value=""}
1,className:"block text-sm text-foreground/80 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:bg-primary/20 file:text-primary hover:file:bg-primary/30 file:cursor-pointer file:text-mono file:text-[10px] file:uppercase file:tracking-[0.2em]"}),j&&e.jsx("p",{className:"text-xs text-primary",children:j}),v&&e.jsx("p",{className:"text-xs text-red-400",children:v})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("h3",{className:"text-mono text-[11px] uppercase tracking-[0.3em] text-foreground/70",children:[a.length," photo",a.length===1?"":"s"]}),U&&e.jsx("span",{className:"text-xs text-foreground/40",children:"Refreshingâ¦"})]}),a.length===0&&e.jsx("div",{className:"rounded-2xl border border-dashed border-border/60 p-8 text-center text-sm text-foreground/50",children:"No photos uploaded yet â the site will fall back to the built-in defaults."}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:a.map((t,r)=>e.jsxs("div",{className:"glass rounded-xl border border-border/60 overflow-hidden flex flex-col",children:[e.jsx("div",{className:"aspect-[4/3] bg-background/60",children:e.jsx("img",{src:t.url,alt:t.alt??"",className:"w-full h-full object-cover"})}),e.jsxs("div",{className:"p-4 space-y-3",children:[e.jsx("input",{defaultValue:t.alt??"",onBlur:o=>o.target.value!==(t.alt??"")&&f(t.id,{alt:o.target.value}),placeholder:"Alt text (for accessibility)",className:"w-full bg-background/40 border border-border/60 rounded-md px-3 py-2 text-sm"}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("button",{disabled:r===0,onClick:()=>N(t,-1),className:"text-mono text-[10px] uppercase tracking-[0.3em] text-foreground/70 hover:text-primary disabled:opacity-30 px-2 py-1 border border-border/60 rounded",children:"â Up"}),e.jsx("button",{disabled:r===a.length-1,onClick:()=>N(t,1),className:"text-mono text-[10px] uppercase tracking-[0.3em] text-foreground/70 hover:text-primary disabled:opacity-30 px-2 py-1 border border-border/60 rounded",children:"â Down"}),e.jsx("button",{onClick:()=>P(t),className:"ml-auto text-mono text-[10px] uppercase tracking-[0.3em] text-red-400 hover:text-red-300 px-2 py-1 border border-red-500/40 rounded",children:"Delete"})]})]})]},t.id))})]})]})})]}):e.jsxs(b,{children:[e.jsx(C,{eyebrow:"Access denied",title:"Not Authorized"}),e.jsxs("div",{className:"px-6 pb-32 max-w-xl mx-auto space-y-4 text-foreground/80",children:[e.jsxs("p",{children:["You're signed in as ",e.jsx("strong",{children:d?.email}),", but this account isn't an admin."]}),e.jsx("p",{className:"text-sm text-foreground/60",children:"The first user to sign up is granted admin. If you already have an admin account, sign out and sign in with it."}),e.jsx("button",{onClick:w,className:"glass-cta hover:glass-cta-hover px-5 py-2.5 text-mono text-[11px] uppercase tracking-[0.3em]",children:"Sign Out"})]})]})}export{L as component};
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.