PageSourceSearch

https://www.studioe.ai/assets/AdminHeadshotDownload-CsaJukxh.js

js studioe.ai collected 2026-10-05 14:29:17 UTC 7,813 bytes, 1 lines download raw bytes

1import{j as t}from"./jsx-runtime-CqrCmrYQ.js";import{r as c,L as M}from"./vendor-react-DWiRq_5Q.js";import{x as O,U as N,V as R,h as T}from"./index-COyPRzeT.js";import{thumbUrl as _,FEMALE_HEADSHOTS as z,MALE_HEADSHOTS as P}from"./tryOnCdnAssets-B97xlmHA.js";const C={lite:"bg-blue-500/20 text-blue-400 border-blue-500/30",pro:"bg-purple-500/20 text-purple-400 border-purple-500/30",elite:"bg-amber-500/20 text-amber-400 border-amber-500/30"};function S(l,o,n){try{const i=new URL(l).pathname.split("/"),m=i[i.length-1];return`${o}_${m}`}catch{return`${o}_headshot_${n+1}.webp`}}function B(l){if(!l||typeof l!="string")return l;const o="/image/upload/",n=l.indexOf(o);if(n===-1)return l;const i=l.slice(0,n+o.length),m=l.slice(n+o.length);if(/^v\d+\//.test(m))return l;const d=m.match(/(v\d+\/.*)$/);return d?i+d[1]:l}async function $(l,o){const n=B(l),i=await fetch(n);if(!i.ok)throw new Error(`Download failed: ${i.status}`);const m=await i.blob(),d=document.createElement("a");d.href=URL.createObjectURL(m),d.download=o,document.body.appendChild(d),d.click(),d.remove(),URL.revokeObjectURL(d.href)}function G(l){const o=[];for(const n of["lite","pro","elite"])if(Array.isArray(l[n]))for(const i of l[n])o.push({...i,tier:n});return o}function I({label:l,active:o,color:n,onClick:i}){return t.jsx("button",{onClick:i,className:`text-xs px-2.5 py-1 rounded-full border transition-all ${o?`${n} border-current font-medium`:"bg-white/5 text-gray-400 border-white/10 hover:text-white hover:border-white/20"}`,children:l})}function K(){const[l,o]=c.useState("female"),[n,i]=c.useState({}),[m,d]=c.useState(!1),[u,b]=c.useState(new Set),[g,y]=c.useState("all"),f=c.useMemo(()=>G(l==="female"?z:P),[l]),w=l==="female"?"female":"male",h=c.useMemo(()=>g==="all"?f:f.filter(e=>e.tier===g),[f,g]),D=c.useMemo(()=>{const e=new Set(f.map(r=>r.tier));return["all",...["lite","pro","elite"].filter(r=>e.has(r))]},[f]),A=c.useMemo(()=>{const e={lite:[],pro:[],elite:[]};for(const r of h){const s=r.tier||"lite";e[s]||(e[s]=[]),e[s].push(r)}return e},[h]),F=c.useCallback(e=>{b(r=>{const s=new Set(r);return s.has(e)?s.delete(e):s.add(e),s})},[]),L=c.useCallback(()=>{b(new Set(h.map(e=>e.url)))},[h]),U=c.useCallback(()=>b(new Set),[]),E=c.useCallback(async(e,r)=>{const s=e.url;if(s){i(a=>({...a,[s]:!0}));try{const a=S(s,`${w}_${e.tier}`,r);await $(s,a)}catch(a){console.error("Download failed:",a),alert(`Download failed: ${a.message}`)}finally{i(a=>({...a,[s]:!1}))}}},[w]),j=c.useCallback(async e=>{const r=e||h;d(!0);let s=0;for(let a=0;a<r.length;a++){const x=r[a];if(x.url)try{const p=S(x.url,`${w}_${x.tier}`,a);await $(x.url,p),a<r.length-1&&await new Promise(v=>setTimeout(v,350))}catch(p){console.error(`Failed to download headshot ${a}:`,p),s++}}d(!1),s>0&&alert(`${s} download(s) failed. Check console for details.`)},[h,w]),H=c.useCallback(()=>{const e=h.filter(r=>u.has(r.url));e.length&&j(e)},[h,u,j]),k=g!=="all";return t.jsxs("div",{className:"min-h-screen bg-[#101215] text-white pb-20",children:[t.jsx("div",{className:"sticky top-0 z-30 bg-[#101215]/95 backdrop-blur border-b border-white/10 px-4 py-3",children:t.jsxs("div",{className:"max-w-7xl mx-auto flex items-center gap-4",children:[t.jsxs(M,{to:"/admin",className:"flex items-center gap-1 text-sm text-gray-400 hover:text-white transition-colors",children:[t.jsx(O,{className:"w-4 h-4"}),"Admin"]}),t.jsx("h1",{className:"text-lg font-bold",children:"Model Headshot Downloads"}),t.jsxs("div",{className:"ml-auto text-xs text-gray-500",children:[h.length," of ",f.length," headshots"]})]})}),t.jsxs("div",{className:"max-w-7xl mx-auto px-4 pt-6 space-y-5",children:[t.jsxs("div",{className:"space-y-3",children:[t.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[t.jsx("div",{className:"flex rounded-lg bg-white/5 border border-white/10 p-0.5",children:["female","male"].map(e=>t.jsx("button",{onClick:()=>{o(e),b(new Set),y("all")},className:`px-4 py-1.5 rounded-md text-sm font-medium transition-colors ${l===e?"bg-white/10 text-white":"text-gray-400 hover:text-white"}`,children:e.charAt(0).toUpperCase()+e.slice(1)},e))}),t.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[t.jsxs("button",{onClick:L,className:"text-xs px-3 py-1.5 rounded-lg bg-white/5 hover:bg-white/10 border border-white/10 text-gray-300 hover:text-white transition-colors",children:["Select All (",h.length,")"]}),t.jsx("button",{onClick:U,disabled:u.size===0,className:"text-xs px-3 py-1.5 rounded-lg bg-white/5 hover:bg-white/10 border border-white/10 text-gray-300 hover:text-white transition-colors disabled:opacity-30",children:"Deselect"}),t.jsxs("button",{onClick:H,disabled:m||u.size===0,className:"flex items-center gap-1.5 text-sm px-4 py-1.5 rounded-lg bg-blue-600 hover:bg-blue-500 text-white font-medium transition-colors disabled:opacity-40",children:[t.jsx(N,{className:"w-3.5 h-3.5"}),m?"Downloading…":`Download Selected (${u.size})`]}),t.jsxs("button",{onClick:()=>j(null),disabled:m,className:"flex items-center gap-1.5 text-sm px-4 py-1.5 rounded-lg bg-emerald-600 hover:bg-emerald-500 text-white font-medium transition-colors disabled:opacity-40",children:[t.jsx(N,{className:"w-3.5 h-3.5"}),m?"Downloading…":`Download All (${h.length})`]})]})]}),t.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[t.jsx(R,{className:"w-3.5 h-3.5 text-gray-500"}),t.jsx("span",{className:"text-xs text-gray-500 mr-1",children:"Tier:"}),D.map(e=>t.jsx(I,{label:e==="all"?"All":e.charAt(0).toUpperCase()+e.slice(1),active:g===e,color:e==="all"?"bg-white/10 text-white":C[e]||"bg-white/10 text-white",onClick:()=>{y(e),b(new Set)}},`tier-${e}`)),k&&t.jsx("button",{onClick:()=>{y("all"),b(new Set)},className:"text-xs px-2 py-0.5 rounded bg-red-500/10 text-red-400 border border-red-500/20 hover:bg-red-500/20 transition-colors ml-2",children:"Clear filter"})]})]}),["lite","pro","elite"].map(e=>{const r=A[e]||[];return r.length?t.jsxs("div",{children:[t.jsxs("h2",{className:"text-sm font-semibold text-gray-400 uppercase tracking-wider mb-3 flex items-center gap-2",children:[t.jsx("span",{className:`px-2 py-0.5 rounded text-xs border ${C[e]}`,children:e}),t.jsxs("span",{className:"text-gray-500",children:[r.length," headshot",r.length!==1?"s":""]})]}),t.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-3",children:r.map((s,a)=>{const x=u.has(s.url),p=n[s.url];return t.jsxs("div",{className:`relative group rounded-xl border overflow-hidden transition-all cursor-pointer ${x?"border-blue-500 bg-blue-500/10 ring-1 ring-blue-500/40":"border-white/10 bg-white/[0.03] hover:border-white/20"}`,onClick:()=>F(s.url),children:[t.jsx("div",{className:`absolute top-2 left-2 z-10 w-5 h-5 rounded border flex items-center justify-center transition-colors ${x?"bg-blue-500 border-blue-500":"bg-black/40 border-white/30 group-hover:border-white/50"}`,children:x&&t.jsx(T,{className:"w-3 h-3 text-white"})}),t.jsx("div",{className:"aspect-[3/4] bg-black/20",children:t.jsx("img",{src:_(s.url,300),alt:s.name,className:"w-full h-full object-cover",loading:"lazy"})}),t.jsxs("div",{className:"p-2 space-y-1.5",children:[t.jsx("div",{className:"text-xs text-gray-300 font-medium truncate",children:s.name}),t.jsxs("button",{onClick:v=>{v.stopPropagation(),E(s,a)},disabled:p,className:"w-full flex items-center justify-center gap-1.5 text-xs py-1.5 rounded-lg bg-white/5 hover:bg-white/10 border border-white/10 text-gray-300 hover:text-white transition-colors disabled:opacity-40",children:[t.jsx(N,{className:"w-3 h-3"}),p?"…":"Download"]})]})]},s.url||a)})})]},e):null}),h.length===0&&t.jsx("div",{className:"text-center text-gray-500 py-20",children:k?"No headshots match the current filter.":`No headshots found for ${l} models.`})]})]})}export{K 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.