PageSourceSearch

https://zafiri.com/assets/Collection-BcwxuBYr.js

js zafiri.com collected 2026-09-25 09:51:34 UTC 12,428 bytes, 2 lines download raw bytes

1import{j as e}from"./vendor-query-Cd1K-a1f.js";import{r as c,L as U}from"./vendor-react-BrtDVGEF.js";import{u as ie,a as ce,d as de,s as h,S as me,H as ue,B as r,C as R,i as E,I as d,aa as z,F as ge,E as xe,V as he,U as pe}from"./index-T3jWWUEU.js";import{B as fe}from"./badge-BfoWilCF.js";import{u as je}from"./usePages-DtoxT6iV.js";import{I as ve}from"./ImageGalleryPicker-DRCgpibb.js";import{P as Ne,U as F,_ as G,X as w,K as B,T as be,aW as we,x as _e,a4 as ye,L as M,g as Ce}from"./vendor-icons-BKHJKxwD.js";import"./vendor-radix-C_0uraVY.js";import"./vendor-supabase-Bvq1Btpc.js";import"./vendor-charts-BfMOMpwd.js";const Z=["USA","UK","Europe","Asia Pacific","Africa","Other"],He=()=>{const{user:q,isAdmin:_}=ie(),{isActive:J}=ce(),j=_||J,{data:f}=je("collection"),{toast:g}=de(),[p,A]=c.useState([]),[K,V]=c.useState({}),[W,I]=c.useState(!0),[X,P]=c.useState(null),[y,L]=c.useState(null),[n,m]=c.useState({}),[Q,C]=c.useState(!1),[t,u]=c.useState({region:"USA"}),[H,O]=c.useState(null),[k,v]=c.useState(null),Y=s=>{k&&(k.target==="draft"?m(l=>({...l,image_url:s})):u(l=>({...l,image_url:s})),v(null))},$=async(s,l)=>{try{const a=await xe(s),i=he(a.name),o=pe({folder:"collection/",name:l||s.name,ext:i}),{error:x}=await h.storage.from("location-images").upload(o,a,{cacheControl:"3600",upsert:!1,contentType:a.type});if(x)throw x;const{data:b}=h.storage.from("location-images").getPublicUrl(o);return b.publicUrl}catch(a){return g({title:"Upload failed",description:a.message,variant:"destructive"}),null}},T=async(s,l,a,i)=>{var b;const o=(b=s.target.files)==null?void 0:b[0];if(s.target.value="",!o)return;O(a);const x=await $(o,i);O(null),x&&(l==="draft"?m(S=>({...S,image_url:x})):u(S=>({...S,image_url:x})))},N=async()=>{if(I(!0),j){const{data:s,error:l}=await h.from("hotel_collection_codes").select("*").order("sort_order",{ascending:!0});!l&&s&&A(s)}else{const{data:s,error:l}=await h.rpc("get_public_hotel_collection");!l&&s&&A(s)}I(!1)};c.useEffect(()=>{const s=p.map(l=>l.hotel_name).filter(Boolean);s.length!==0&&(async()=>{const{data:l}=await h.from("map_locations").select("name,image_url").in("name",s).not("image_url","is",null);if(l){const a={};l.forEach(i=>{i.image_url&&(a[i.name.toLowerCase()]=i.image_url)}),V(a)}})()},[p]),c.useEffect(()=>{N()},[j]);const ee=c.useMemo(()=>{const s=new Map;return p.forEach(a=>{const i=s.get(a.region)||[];i.push(a),s.set(a.region,i)}),Array.from(s.keys()).sort((a,i)=>{const o=Z.indexOf(a),x=Z.indexOf(i);return(o===-1?99:o)-(x===-1?99:x)}).map(a=>({region:a,items:s.get(a)}))},[p]),se=async(s,l)=>{try{await navigator.clipboard.writeText(l),P(s),setTimeout(()=>P(null),1500)}catch{g({title:"Couldn't copy",variant:"destructive"})}},ae=s=>{L(s.id),m({hotel_name:s.hotel_name,location:s.location||"",region:s.region,code:s.code||"",discount_label:s.discount_label||"",url:s.url||"",image_url:s.image_url||""})},D=()=>{L(null),m({})},te=async()=>{if(!y)return;const{error:s}=await h.from("hotel_collection_codes").update(n).eq("id",y);if(s){g({title:"Save failed",description:s.message,variant:"destructive"});return}g({title:"Saved"}),D(),N()},le=async s=>{if(!confirm("Remove this hotel from the collection?"))return;const{error:l}=await h.from("hotel_collection_codes").delete().eq("id",s);if(l){g({title:"Delete failed",description:l.message,variant:"destructive"});return}g({title:"Removed"}),N()},oe=async()=>{if(!t.hotel_name||!t.region){g({title:"Hotel name and region required",variant:"destructive"});return}const{error:s}=await h.from("hotel_collection_codes").insert({hotel_name:t.hotel_name,location:t.location||null,region:t.region,code:t.code||null,discount_label:t.discount_label||"15% off",url:t.url||null,image_url:t.image_url||null,sort_order:p.length*10+10});if(s){g({title:"Add failed",description:s.message,variant:"destructive"});return}g({title:"Hotel added"}),u({region:"USA"}),C(!1),N()},ne=(f==null?void 0:f.meta_title)||"The Collection — Discounted Hotels for Zafiri Members",re=(f==null?void 0:f.meta_description)||"A curated collection of athlete-friendly hotels worldwide offering exclusive discounts for Zafiri Plus and PRO members.";return e.jsxs("div",{className:"min-h-screen bg-background",children:[e.jsx(me,{title:ne,description:re}),e.jsx(ue,{}),e.jsxs("main",{className:"container px-2 sm:px-4 py-12",children:[e.jsxs("div",{className:"mb-10 text-center max-w-2xl mx-auto",children:[e.jsx("h1",{className:"mb-3 text-4xl font-bold text-foreground",children:"The Collection"}),e.jsx("p",{className:"text-lg text-muted-foreground",children:"A curated set of athlete-friendly hotels worldwide. Plus and PRO members unlock exclusive discount codes — typically 15% off — at every property."}),!j&&e.jsx("div",{className:"mt-6",children:e.jsx(U,{to:"/premium",children:e.jsx(r,{className:"bg-accent text-accent-foreground hover:bg-accent/90",children:"Unlock codes — Join Plus"})})})]}),_&&e.jsx("div",{className:"mb-8 max-w-5xl mx-auto flex justify-end",children:Q?e.jsx(R,{className:"w-full border-accent/40",children:e.jsxs(E,{className:"p-4 grid gap-3 sm:grid-cols-2 lg:grid-cols-6",children:[e.jsx(d,{placeholder:"Hotel name",value:t.hotel_name||"",onChange:s=>u({...t,hotel_name:s.target.value})}),e.jsx(d,{placeholder:"Location",value:t.location||"",onChange:s=>u({...t,location:s.target.value})}),e.jsx(d,{placeholder:"Region",value:t.region||"",onChange:s=>u({...t,region:s.target.value})}),e.jsx(d,{placeholder:"Code",value:t.code||"",onChange:s=>u({...t,code:s.target.value})}),e.jsx(d,{placeholder:"Discount label",value:t.discount_label||"",onChange:s=>u({...t,discount_label:s.target.value})}),e.jsx(d,{placeholder:"URL (https://…)",value:t.url||"",onChange:s=>u({...t,url:s.target.value})}),e.jsxs("div",{className:"flex items-center gap-2",children:[t.image_url?e.jsx("img",{src:z(t.image_url,{width:120}
1),alt:"",className:"h-10 w-14 rounded object-cover bg-muted"}):null,e.jsxs("label",{className:"inline-flex",children:[e.jsx("input",{type:"file",accept:"image/*",className:"hidden",onChange:s=>T(s,"new","new",t.hotel_name)}),e.jsx(r,{size:"sm",variant:"outline",asChild:!0,className:"gap-1 cursor-pointer",children:e.jsxs("span",{children:[e.jsx(F,{className:"h-4 w-4"}),H==="new"?"Uploading…":t.image_url?"Replace":"Image"]})})]}),e.jsxs(r,{size:"sm",variant:"outline",type:"button",className:"gap-1",onClick:()=>v({target:"new"}),children:[e.jsx(G,{className:"h-4 w-4"})," Gallery"]}),t.image_url&&e.jsx(r,{size:"sm",variant:"ghost",onClick:()=>u({...t,image_url:""}),children:e.jsx(w,{className:"h-4 w-4"})})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(r,{size:"sm",onClick:oe,className:"gap-1",children:[e.jsx(B,{className:"h-4 w-4"})," Save"]}),e.jsx(r,{size:"sm",variant:"ghost",onClick:()=>C(!1),children:e.jsx(w,{className:"h-4 w-4"})})]})]})}):e.jsxs(r,{size:"sm",variant:"outline",onClick:()=>C(!0),className:"gap-1",children:[e.jsx(Ne,{className:"h-4 w-4"})," Add hotel"]})}),W?e.jsx("div",{className:"max-w-5xl mx-auto grid gap-4",children:Array.from({length:4}).map((s,l)=>e.jsx("div",{className:"h-20 animate-pulse rounded-lg bg-muted"},l))}):e.jsxs("div",{className:"max-w-5xl mx-auto space-y-10",children:[ee.map(({region:s,items:l})=>e.jsxs("section",{children:[e.jsx("h2",{className:"mb-4 text-xs font-semibold uppercase tracking-widest text-accent",children:s}),e.jsx("div",{className:"space-y-3",children:l.map(a=>{const i=y===a.id;return e.jsx(R,{className:"border-border",children:e.jsx(E,{className:"p-4 sm:p-5",children:i?e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2 lg:grid-cols-6 items-center",children:[e.jsx(d,{placeholder:"Hotel",value:n.hotel_name||"",onChange:o=>m({...n,hotel_name:o.target.value})}),e.jsx(d,{placeholder:"Location",value:n.location||"",onChange:o=>m({...n,location:o.target.value})}),e.jsx(d,{placeholder:"Region",value:n.region||"",onChange:o=>m({...n,region:o.target.value})}),e.jsx(d,{placeholder:"Code",value:n.code||"",onChange:o=>m({...n,code:o.target.value.toUpperCase()})}),e.jsx(d,{placeholder:"Discount label",value:n.discount_label||"",onChange:o=>m({...n,discount_label:o.target.value})}),e.jsx(d,{placeholder:"URL (https://…)",value:n.url||"",onChange:o=>m({...n,url:o.target.value})}),e.jsxs("div",{className:"flex items-center gap-2 sm:col-span-2 lg:col-span-3",children:[n.image_url?e.jsx("img",{src:z(n.image_url,{width:120}),alt:"",className:"h-10 w-14 rounded object-cover bg-muted"}):null,e.jsxs("label",{className:"inline-flex",children:[e.jsx("input",{type:"file",accept:"image/*",className:"hidden",onChange:o=>T(o,"draft",a.id,n.hotel_name||a.hotel_name)}),e.jsx(r,{size:"sm",variant:"outline",asChild:!0,className:"gap-1 cursor-pointer",children:e.jsxs("span",{children:[e.jsx(F,{className:"h-4 w-4"}),H===a.id?"Uploading…":n.image_url?"Replace image":"Upload image"]})})]}),e.jsxs(r,{size:"sm",variant:"outline",type:"button",className:"gap-1",onClick:()=>v({target:"draft"}),children:[e.jsx(G,{className:"h-4 w-4"})," Gallery"]}),n.image_url&&e.jsx(r,{size:"sm",variant:"ghost",onClick:()=>m({...n,image_url:""}),children:e.jsx(w,{className:"h-4 w-4"})})]}),e.jsxs("div",{className:"flex gap-2 justify-end sm:col-span-2 lg:col-span-3",children:[e.jsxs(r,{size:"sm",onClick:te,className:"gap-1",children:[e.jsx(B,{className:"h-4 w-4"})," Save"]}),e.jsx(r,{size:"sm",variant:"ghost",onClick:D,children:e.jsx(w,{className:"h-4 w-4"})}),e.jsx(r,{size:"sm",variant:"ghost",onClick:()=>le(a.id),className:"text-destructive",children:e.jsx(be,{className:"h-4 w-4"})})]})]}):e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3",children:[e.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[(()=>{const o=a.image_url||K[a.hotel_name.toLowerCase()];return o?e.jsx("img",{src:z(o,{width:160}),alt:a.hotel_name,loading:"lazy",className:"h-14 w-20 sm:h-16 sm:w-24 rounded-md object-cover shrink-0 bg-muted"}):e.jsx("div",{className:"h-14 w-20 sm:h-16 sm:w-24 rounded-md bg-muted flex items-center justify-center shrink-0",children:e.jsx(we,{className:"h-5 w-5 text-muted-foreground
1/60"})})})(),e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("h3",{className:"font-semibold text-foreground whitespace-pre-line",children:a.hotel_name.replace(/\\n/g,`
2`)}),a.discount_label&&e.jsx(fe,{variant:"secondary",className:"text-xs",children:a.discount_label})]}),a.location&&e.jsx("p",{className:"text-sm text-muted-foreground mt-0.5",children:a.location})]})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[j?a.code?e.jsxs("button",{onClick:()=>se(a.id,a.code),className:"group flex items-center gap-2 rounded-md border border-accent/40 bg-accent/5 px-3 py-1.5 font-mono text-sm font-semibold text-foreground hover:bg-accent/10 transition",title:"Copy code",children:[e.jsx("span",{children:a.code}),X===a.id?e.jsx(_e,{className:"h-4 w-4 text-accent"}):e.jsx(ye,{className:"h-4 w-4 text-muted-foreground group-hover:text-accent"})]}):e.jsx("span",{className:"text-xs text-muted-foreground italic",children:"Code coming soon"}):e.jsxs(U,{to:q?"/premium":"/auth",className:"flex items-center gap-2 rounded-md border border-dashed border-border px-3 py-1.5 text-xs text-muted-foreground hover:text-foreground hover:border-accent transition",children:[e.jsx(M,{className:"h-3.5 w-3.5"}),"Members only"]}),_&&e.jsx(r,{size:"sm",variant:"ghost",onClick:()=>ae(a),className:"h-8 w-8 p-0",children:e.jsx(Ce,{className:"h-4 w-4"})})]})]})})},a.id)})})]},s)),p.length===0&&e.jsx("p",{className:"text-center text-muted-foreground py-12",children:"No hotels in the collection yet."})]}),!j&&p.length>0&&e.jsx("div",{className:"mt-12 text-center max-w-xl mx-auto",children:e.jsx(R,{className:"border-accent/30 bg-accent/5",children:e.jsxs(E,{className:"p-6",children:[e.jsx(M,{className:"mx-auto mb-3 h-6 w-6 text-accent"}),e.jsx("h3",{className:"mb-2 text-lg font-semibold text-foreground",children:"Unlock every code in The Collection"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:"Plus and PRO members get instant access to discount codes at every hotel above — plus all the other benefits of a Zafiri membership."}),e.jsx(U,{to:"/premium",children:e.jsx(r,{className:"bg-accent text-accent-foreground hover:bg-accent/90",children:"Join Zafiri Plus"})})]})})})]}),e.jsx(ge,{}),e.jsx(ve,{open:!!k,onClose:()=>v(null),onSelect:Y})]})};export{He 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.