1import{g as w,y as N,h as C,aV as Ks,i as Qs,r as i,j as e,L as Gs,B as o,t as h,C as ms,X as Te,M as rs,s as ns,aQ as Hs,aW as Ws,aX as Ms}from"./index-CFv9XKiB.js";import{u as m}from"./useServerFn-DJOSWF3u.js";import{u as is}from"./useQuery-DQfTiywB.js";import{u as q}from"./useMutation-Ou9Q83JG.js";import{C as ke,a as Ae,b as De,d as Ee}from"./card-DdomOa6A.js";import{B as Vs}from"./badge-sq-DRzk8.js";import{S as ie,a as le,b as oe,c as de,d as M}from"./select-t0bn6R_5.js";import{T as ze}from"./textarea-Bh5HNQqU.js";import{I as Oe}from"./input-CcozFbXh.js";import{L as z}from"./label-DGWP3VjG.js";import{D as ce,a as me,b as ue,c as he,e as $e,f as xe}from"./dialog-CITrCC0q.js";import{A as us,a as hs,b as xs,c as ps,d as gs,e as fs,f as js,g as bs}from"./alert-dialog-CyVAX-nD.js";import{S as Xs,o as Ys}from"./optimize.functions-CCOf8XDZ.js";import{I as Zs}from"./ImageLightbox-B4gpK_30.js";import{getMe as Js}from"./auth.functions-Bc9U0q8J.js";import{n as et,I as st}from"./image-normalize-CYxSZAO1.js";import{S as ls,a as tt,A as os}from"./constants-D2NZddPn.js";import{C as at}from"./color-picker-input-CZondvrD.js";import{d as rt}from"./normalize-VuR-t9s5.js";import{r as nt,d as it}from"./watermark-BbsoOQkH.js";import{D as ys,f as vs}from"./drop-zone-DbvwfCFH.js";import{A as lt}from"./arrow-left-naH5FbVx.js";import{S as pe}from"./sparkles-xCKySoSc.js";import{P as ot}from"./pencil-DGU49Mdv.js";import{U as ws}
1from"./upload-BxbMyw0_.js";import{T as Ns}from"./trash-2-BjT2FBeF.js";import{L as Cs}from"./loader-circle-B0cqi-8G.js";import{W as _s}from"./wand-sparkles-zkV8ML3F.js";import{D as dt}from"./download-DiWPzXW5.js";import"./index-Bf2Jiyvi.js";import"./index-J0TyYv5_.js";import"./chevron-down-CHCp_ATj.js";import"./plus-B20Kg9lT.js";const ct=w({method:"POST"}).middleware([N]).handler(C("8803ea069fe79a8fe98c8f5c352ab1b947a5684a10ece7f08ddb4a7a5454fc32")),mt=w({method:"POST"}).middleware([N]).handler(C("942306752c730d4a43d3404afb33a76bf28ab3203858897570735274b117bb47")),ut=w({method:"POST"}).middleware([N]).handler(C("8c25d3901282313849d547b241e59c892eb064466de94d15d6000f89f0590e19")),ht=w({method:"POST"}).middleware([N]).handler(C("8168fa07212336881c192acaa8b9ec27d7efde03782fcbdd87365e8d0d3f6b63")),xt=w({method:"POST"}).middleware([N]).handler(C("8f252ddc2e11c9b022041019005870d7484f6499ce00e17ef5fe87b32c1cb064")),pt=w({method:"POST"}).middleware([N]).handler(C("052caf88717392430320202484620982d7d05fc34b9995371c0f1ac872eaa2de")),gt=w({method:"POST"}).middleware([N]).handler(C("d74d3eeeca4fa79ba7c2d2ba2a55f6177818270605c8f7bee9f3e10790812f50")),ft=w({method:"POST"}).middleware([N]).handler(C("093eb9c4e6c4675c2989fb434866620c6b4a4e9bac4a16a0a73eb785ec43d4e7")),jt=w({method:"POST"}).middleware([N]).handler(C("4c7a301d57f3042074d0663e972cc36118affccf29d1f27260cf86bf6b7ecc35")),bt=w({method:"POST"}).middleware([N]).handler(C("006a95a471b1eb95e5ac22175fd9f33cd897c5253a4b978396a620771428be36")),yt=w({method:"POST"}).middleware([N]).handler(C("ccd6bd2700c1e13a5b279d29f30efb4b665d5b46d000748e8fba73266b0d2ec8")),vt=w({method:"POST"}).middleware([N]).handler(C("bbb30a4e28c9974906427e7eed30734fc49b16c4b810dbb624dd94084666bb19")),wt=w({method:"POST"}).middleware([N]).handler(C("b3f78b81b5810dfc866fda659b047cbf40a3034af0f938039621599584c66e7b"));function ds(t,n){if(!t)return n;if(typeof t=="string")return t.trim()||n;const l=t,_=[l?.message,l?.error?.message,l?.data?.message,l?.body?.message,typeof l?.cause=="string"?l.cause:l?.cause?.message,l?.statusText];for(const x of _)if(typeof x=="string"&&x.trim())return x.trim();return l?.name==="AbortError"||l?.name==="TypeError"?"Network interrupted before the server finished. The concept may still appear shortly â check the Generated concepts list.":n}function na(){const{id:t}=Ks.useParams(),n=Qs(),l=m(Ms),_=m(ct),x=m(pt),D=m(mt),O=m(ut),p=m(gt),$=m(ft),b=m(yt),S=m(jt),E=m(bt),g=m(vt),y=m(wt),T=m(ht),L=m(xt),f=m(Js),P=!!is({queryKey:["me"],queryFn:()=>f()}).data?.isAdmin,{data:R,isLoading:u}=is({queryKey:["project",t],queryFn:()=>l({data:{id:t}}),refetchInterval:s=>s.state.data?.concepts?.some(r=>r.status==="generating")?4e3:!1}),[k,K]=i.useState({}),[Q,V]=i.useState({}),[X,Ss]=i.useState({}),[Pe,ks]=i.useState({}),[Y,Re]=i.useState(null);i.useEffect(()=>{b({data:{project_id:t}}).then(s=>{s?.reconciled&&n.invalidateQueries({queryKey:["project",t]})}).catch(()=>{})},[t,b,n]),i.useEffect(()=>{const s=R;if(!s)return;const a=(s.assets??[]).map(d=>d.storage_path).filter(Boolean);a.length&&p({data:{paths:a,bucket:"assets",thumbs:!0,thumb_width:320}}).then(d=>{K(d.urls),V(d.thumbs??{})});const r=(s.concepts??[]).map(d=>d.storage_path).filter(Boolean);r.length&&p({data:{paths:r,bucket:"concepts",thumbs:!0}}).then(d=>{Ss(d.urls),ks(d.thumbs??{})})},[R,p]);const Z=i.useRef(null),[J,Ie]=i.useState(!1),[qe,As]=i.useState("reference"),Ue=async(s,a)=>{if(s.length===0)return{uploaded:0,failed:0};Ie(!0);let r=0;const d=[];try{const{data:v,error:I}=await ns.auth.getUser();if(I)throw new Error(`Auth check failed: ${I.message}`);const ne=v.user?.id;if(!ne)throw new Error("Not signed in â please reload and sign in again.");for(const B of s)try{let j=B;if(B.type.startsWith("image/"))try{j=await et(B)}catch(Se){throw Se instanceof st?Se:new Error(`Could not process ${B.name}: ${Se?.message??"unknown error"}`)}const Bs=j.name.replace(/[^a-zA-Z0-9._-]/g,"_"),ts=`${ne}/${t}/${Date.now()}-${Bs}`,{error:as}=await ns.storage.from("assets").upload(ts,j,{contentType:j.type,upsert:!1});if(as)throw new Error(`Storage: ${as.message}`);await _({data:{project_id:t,storage_path:ts,filename:j.name,mime_type:j.type,asset_type:a}}),r+=1}catch(j){console.error("[upload] failed",B.name,j),d.push(`${B.name}: ${j.message??"unknown error"}`)}return await n.invalidateQueries({queryKey:["project",t]}),await n.refetchQueries({queryKey:["project",t]}),{uploaded:r,failed:d.length,firstError:d[0]}}catch(v){throw console.error("[upload] fatal",v),v}finally{Ie(!1)}},Le=async s=>{const a=Array.from(s.target.files??[]);if(a.length!==0)try{const r=await Ue(a,qe);r.uploaded>0&&r.failed===0?h.success(`Uploaded ${r.uploaded} file${r.uploaded===1?"":"s"}`):r.uploaded>0?h.warning(`${r.uploaded} uploaded, ${r.failed} failed: ${r.firstError}`):h.error(`Upload failed: ${r.firstError??"no files processed"}`)}catch(r){h.error(r.message??"Upload failed")}finally{Z.current&&(Z.current.value="")}},Ds=m(Ws),G=q({mutationFn:s=>$({data:{project_id:t,...s}}),onSuccess:()=>{h.success("Concept ready"),n.invalidateQueries({queryKey:["project",t]})},onError:s=>{console.error("[generateConcept] mutation error",s),h.error(ds(s,"Generation failed â please try again.")),n.invalidateQueries({queryKey:["project",t]})},onSettled:()=>{b({data:{project_id:t}}
1).then(s=>{s?.reconciled&&n.invalidateQueries({queryKey:["project",t]})}).catch(()=>{})}}),[Es,ee]=i.useState(!1),[A,F]=i.useState({title:"",description:"",focus_notes:"",incorporate_notes:"",avoid_notes:"",exact_text:"",shirt_color:"black",design_colors:[],style_tags:[]}),Fs=()=>{const s=R?.project??{};F({title:s.title??"",description:s.description??"",focus_notes:s.focus_notes??"",incorporate_notes:s.incorporate_notes??"",avoid_notes:s.avoid_notes??"",exact_text:s.exact_text??"",shirt_color:s.shirt_color??"black",design_colors:rt(s.design_colors??[]).slice(0,4),style_tags:(s.style_tags??[]).slice(0,4)}),ee(!0),fe(null),W(null)},[ge,fe]=i.useState(null),[H,W]=i.useState(null),[se,Be]=i.useState(null),[je,te]=i.useState({incorporate:[],avoid:[]}),Os=m(Ys),Ts=m(Hs),Ke=async s=>{Be(s);try{const a=je[s].join(", "),r=await Ts({data:{project_id:t,kind:s,avoid_text:a}});te(d=>({...d,[s]:r.suggestions}))}catch(a){h.error(ds(a,"Could not generate suggestions."))}finally{Be(null)}},Qe=(s,a)=>{const r=s==="incorporate"?"incorporate_notes":"avoid_notes";F(d=>{const v=d[r].split(/[,\n]/).map(I=>I.trim()).filter(Boolean);return v.some(I=>I.toLowerCase()===a.toLowerCase())||v.push(a),{...d,[r]:v.join(", ")}}),te(d=>({...d,[s]:d[s].filter(v=>v!==a)}))},be=async s=>{const a=(A[s]??"").trim();if(!a){h.error("Add some text first, then optimize.");return}fe(s);try{const r=await Os({data:{project_id:t,field:s,text:a}});W({field:s,text:r.optimized})}catch(r){h.error(r?.message??"Optimize failed")}finally{fe(null)}},ye=()=>{H&&(F(s=>({...s,[H.field]:H.text})),W(null))},ve=q({mutationFn:()=>Ds({data:{id:t,...A}}),onSuccess:()=>{h.success("Project updated"),ee(!1),n.invalidateQueries({queryKey:["project",t]})},onError:s=>h.error(s.message??"Update failed")}),zs=s=>{F(a=>a.style_tags.includes(s)?{...a,style_tags:a.style_tags.filter(r=>r!==s)}:a.style_tags.length>=4?a:{...a,style_tags:[...a.style_tags,s]})},Ge=q({mutationFn:s=>S({data:s}),onSuccess:()=>n.invalidateQueries({queryKey:["project",t]})}),$s=q({mutationFn:s=>E({data:{id:s}}),onSuccess:()=>n.invalidateQueries({queryKey:["project",t]})}),Ps=q({mutationFn:s=>x({data:{id:s}}),onSuccess:()=>n.invalidateQueries({queryKey:["project",t]})}),Rs=q({mutationFn:s=>D({data:s}),onSuccess:()=>n.invalidateQueries({queryKey:["project",t]})}),Is=q({mutationFn:s=>O({data:s}),onSuccess:()=>n.invalidateQueries({queryKey:["project",t]})}),qs=q({mutationFn:s=>s.current?L({data:{project_id:t}}):T({data:{id:s.id,project_id:t}}),onSuccess:()=>n.invalidateQueries({queryKey:["project",t]})}),[we,Ne]=i.useState(null),[ae,Ce]=i.useState(null),_e=q({mutationFn:s=>g({data:s}),onSuccess:s=>{h.success(`Sent to ${s.to}`),Ce(null),n.invalidateQueries({queryKey:["project",t]})},onError:s=>h.error(s.message??"Email failed")});if(u)return e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loadingâ¦"});if(!R)return e.jsx("p",{children:"Not found."});const{project:c,assets:He,concepts:re,dailyCounts:We}=R,Me=6,Ve=4,Xe=We?.rough??0,Ye=We?.refined??0,Ze=!P&&Xe>=Me,Je=!P&&Ye>=Ve,Us=re.filter(s=>s.stage==="refined"&&s.status!=="failed").length,es=re.some(s=>s.status==="generating"),Ls=ls.find(s=>s.value===c.shirt_color)?.hex??"#0a0a0a";return e.jsxs("div",{className:"mx-auto max-w-6xl space-y-6",children:[e.jsxs(Gs,{to:"/prospects/$id",params:{id:c.prospect_id},className:"inline-flex items-center text-sm text-muted-foreground hover:text-foreground",children:[e.jsx(lt,{className:"mr-1 h-4 w-4"})," ",c.prospects?.company_name]}),e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"font-display text-3xl font-bold tracking-tight",children:c.title}),e.jsxs("div",{className:"mt-2 flex flex-wrap items-center gap-2",children:[e.jsxs("span",{className:"inline-flex items-center gap-1.5 rounded-full border bg-background px-2 py-0.5 text-xs",children:[e.jsx("span",{className:"h-3 w-3 rounded-sm border",style:{background:Ls}}),c.shirt_color," shirt"]}),(c.design_colors??[]).map(s=>e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full border bg-background px-2 py-0.5 text-xs",children:[e.jsx("span",{className:"h-3 w-3 rounded-sm border",style:{background:s}}),s]},s)),c.style_tags?.map(s=>e.jsx(Vs,{variant:"secondary",children:s},s))]})]}),e.jsxs("div",{className:"flex flex-col items-end gap-2",children:[e.jsx("div",{className:"flex items-center gap-2",children:e.jsxs(o,{onClick:()=>G.mutate({stage:"rough"}),disabled:G.isPending||es||Ze,size:"lg",children:[e.jsx(pe,{className:"mr-2 h-4 w-4"}),G.isPending?"Generatingâ¦":"Generate rough concept"]})}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:["Today: Rough ",Xe,"/",Me," · Refined ",Ye,"/",Ve,P&&e.jsx("span",{className:"ml-1 text-[10px] uppercase tracking-wide",children:"(admin · no cap)"})]}),(Ze||Je)&&e.jsx("div",{className:"text-[11px] text-amber-700",children:"Daily limit reached â resets at 6:00 AM EST."})]})]}),e.jsx("div",{className:"rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-900",children:"Internal preview only â every concept must be reviewed and refined by Excel's artists before going to a customer."}),e.jsxs(ke,{children:[e.jsxs(Ae,{className:"flex flex-row items-center justify-between",children:[e.jsx(De,{className:"text-sm",children:"Brief"}),e.jsxs(o,{variant:"ghost",size:"sm",onClick:Fs,children:[e.jsx(ot,{className:"mr-1 h-3.5 w-3.5"})," Edit"]})]}),e.jsxs(Ee,{className:"space-y-3 text-sm",children:[c.incorporate_notes?e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-medium text-foreground",children:"Design elements to incorporate"}),e.jsx("p",{className:"mt-1 whitespace-pre-wrap text-muted-foreground",children:c.incorporate_notes})]}):null,c.avoid_notes?e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-medium text-foreground",children:"Avoid"}),e.jsx("p",{className:"mt-1 whitespace-pre-wrap text-muted-foreground",children:c.avoid_notes})]}):null,c.description?e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-medium text-foreground",children:"Notes"}),e.jsx("p",{className:"mt-1 whitespace-pre-wrap text-muted-foreground",children:c.description})]}):null,!(c.incorporate_notes||c.avoid_notes||c.description)&&e.jsx("p",{className:"text-muted-foreground",children:"No brief yet. Click Edit to add design elements, exclusions, and notes."})]})]}),e.jsx(ce,{open:Es,onOpenChange:ee,children:e.jsxs(me,{className:"max-w-xl max-h-[90vh] overflow-y-auto",children:[e.jsxs(ue,{children:[e.jsx(he,{children:"Edit project"}),e.jsx($e,{children:"Update the brief, design direction, and apparel details."})]}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"text-xs font-semibold uppercase tracking-wider text-muted-foreground",children:"Project"}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(z,{children:"Title"}),e.jsx(Oe,{value:A.title,onChange:s=>F(a=>({...a,title:s.target.value}))})]})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"text-xs font-semibold uppercase tracking-wider text-muted-foreground",children:"Design"}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(z,{children:"Shirt color"}),e.jsxs(ie,{value:A.shirt_color,onValueChange:s=>F(a=>({...a,shirt_color:s})),children:[e.jsx(le,{children:e.jsx(oe,{})}),e.jsx(de,{children:ls.map(s=>e.jsx(M,{value:s.value,children:e.jsxs("span",{className:"inline-flex items-center gap-2",children:[e.jsx("span",{className:"h-3 w-3 rounded-sm border",style:{background:s.hex}}),s.value]})},s.value))})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(z,{children:"Design ink colors"}),e.jsx(at,{value:A.design_colors,onChange:s=>F(a=>({...a,design_colors:s})),max:4})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs(z,{children:["Art style tags (",A.style_tags.length,"/4)"]}),e.jsx("div",{className:"flex flex-wrap gap-1.5",children:tt.map(s=>{const a=A.style_tags.includes(s),r=!a&&A.style_tags.length>=4;return e.jsx("button",{type:"button",onClick:()=>zs(s),disabled:r,className:`rounded-full border px-3 py-1 text-xs transition ${a?"border-primary bg-primary text-primary-foreground":r?"opacity-40 cursor-not-allowed":"hover:bg-muted"}`,children:s},s)})})]})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"text-xs font-semibold uppercase tracking-wider text-muted-foreground",children:"Brief"}),e.jsx(Fe,{label:"Design elements to incorporate",field:"incorporate_notes",rows:3,placeholder:"Supporting design elements, e.g. flames, dirt texture, trees, badge shapes",value:A.incorporate_notes,onChange:s=>F(a=>({...a,incorporate_notes:s})),optimizing:ge,suggestion:H,onOptimize:be,onAccept:ye,onDiscard:()=>W(null)}),e.jsx(cs,{kind:"incorporate",loading:se==="incorporate",disabled:se!==null,ideas:je.incorporate,onGenerate:Ke,onAdd:Qe,onClear:()=>te(s=>({...s,incorporate:[]}))}),e.jsx(Fe,{label:"Avoid",field:"avoid_notes",rows:2,placeholder:"e.g. No skulls, no competitor colors",value:A.avoid_notes,onChange:s=>F(a=>({...a,avoid_notes:s})),optimizing:ge,suggestion:H,onOptimize:be,onAccept:ye,onDiscard:()=>W(null)}),e.jsx(cs,{kind:"avoid",loading:se==="avoid",disabled:se!==null,ideas:je.avoid,onGenerate:Ke,onAdd:Qe,onClear:()=>te(s=>({...s,avoid:[]}))}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(z,{children:"Exact text to include"}),e.jsx(Oe,{value:A.exact_text,onChange:s=>F(a=>({...a,exact_text:s.target.value})),placeholder:'e.g. "EXCEL RACING · EST. 1982"',maxLength:500})]}),e.jsx(Fe,{label:"Additional notes",field:"description",rows:2,value:A.description,onChange:s=>F(a=>({...a,description:s})),optimizing:ge,suggestion:H,onOptimize:be,onAccept:ye,onDiscard:()=>W(null)})]})]}),e.jsxs(xe,{children:[e.jsx(o,{variant:"ghost",onClick:()=>ee(!1),children:"Cancel"}),e.jsx(o,{onClick:()=>ve.mutate(),disabled:ve.isPending,children:ve.isPending?"Savingâ¦":"Save changes"})]})]})}),e.jsx(ys,{accept:"image/*",multiple:!0,disabled:J,onFiles:s=>Le(vs(s)),overlayLabel:"Drop images to add as references",children:e.jsxs(ke,{children:[e.jsxs(Ae,{className:"flex flex-row items-center justify-between",children:[e.jsx(De,{children:"Brand assets"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(ie,{value:qe,onValueChange:As,children:[e.jsx(le,{className:"h-9 w-44",children:e.jsx(oe,{})}),e.jsx(de,{children:os.map(s=>e.jsx(M,{value:s.value,children:s.label},s.value))})]}),e.jsx("input",{ref:Z,type:"file",accept:"image/*",multiple:!0,className:"hidden",onChange:Le}),e.jsxs(o,{variant:"outline",size:"sm",onClick:()=>Z.current?.click(),disabled:J,children:[e.jsx(ws,{className:"mr-2 h-4 w-4"})," ",J?"Uploadingâ¦":"Upload"]})]})]}),e.jsx(Ee,{children:He.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Upload logos, mascots, vehicle/building/equipment photos, and references. Tap the star to mark the ONE hero subject the design must center on (e.g. their truck)."}):e.jsx("div",{className:"grid grid-cols-2 gap-3 sm:grid-cols-4 md:grid-cols-6",children:He.map(s=>e.jsxs("div",{className:"group relative space-y-1",children:[e.jsxs("div",{className:`relative aspect-square overflow-hidden rounded-md border bg-muted ${s.is_hero?"ring-2 ring-amber-400":""}`,children:[k[s.storage_path]?e.jsx("img",{src:Q[s.storage_path]??k[s.storage_path],alt:`Reference upload â ${s.filename??"project asset"}`,loading:"lazy",decoding:"async",className:"h-full w-full object-cover"}):e.jsx("div",{className:"flex h-full w-full items-center justify-center bg-muted p-2 text-center text-[10px] text-muted-foreground",children:s.filename??"(no preview)"}),e.jsx("button",{onClick:()=>qs.mutate({id:s.id,current:!!s.is_hero}
1),title:s.is_hero?"Unmark hero subject":"Mark as hero subject",className:`absolute left-1 top-1 rounded p-1 ${s.is_hero?"bg-amber-400 text-amber-950":"hidden bg-background/90 text-muted-foreground group-hover:block"}`,children:e.jsx(Xs,{className:`h-3 w-3 ${s.is_hero?"fill-current":""}`})}),e.jsxs("button",{onClick:()=>{confirm(`Remove ${s.filename??"this reference"}?`)&&Ps.mutate(s.id)},title:"Remove reference","aria-label":`Remove reference ${s.filename??"asset"}`,className:"absolute right-1 top-1 hidden rounded bg-background/90 p-1 text-destructive group-hover:block",children:[e.jsx(Ns,{className:"h-3 w-3"}),e.jsx("span",{className:"sr-only",children:"Remove reference"})]})]}),e.jsxs(ie,{value:s.asset_type,onValueChange:a=>Rs.mutate({id:s.id,asset_type:a}),children:[e.jsx(le,{className:"h-7 text-xs",children:e.jsx(oe,{})}),e.jsx(de,{children:os.map(a=>e.jsx(M,{value:a.value,children:a.label},a.value))})]}),e.jsxs(ie,{value:s.reference_role??"exact",onValueChange:a=>Is.mutate({id:s.id,reference_role:a}),children:[e.jsx(le,{className:"h-7 text-[11px]",title:"How the AI should treat this reference",children:e.jsx(oe,{})}),e.jsxs(de,{children:[e.jsx(M,{value:"exact",children:"Reproduce exactly"}),e.jsx(M,{value:"style",children:"Style inspiration"}),e.jsx(M,{value:"context",children:"Context only"})]})]})]},s.id))})})]})}),e.jsxs(ke,{children:[e.jsx(Ae,{children:e.jsx(De,{children:"Generated concepts"})}),e.jsx(Ee,{children:re.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:'No concepts yet. Click "Generate rough concept" to begin.'}):e.jsx("div",{className:"grid gap-6 md:grid-cols-2",children:re.map(s=>e.jsx(Nt,{concept:s,projectTitle:c.title,ownerId:c.owner_id,projectId:t,url:s.storage_path?X[s.storage_path]:void 0,thumbUrl:s.storage_path?Pe[s.storage_path]:void 0,onExpand:()=>{const a=s.storage_path?X[s.storage_path]:void 0;a&&Re({url:a,thumb:s.storage_path?Pe[s.storage_path]:void 0,title:`${c.title} â v${s.version} (${s.stage})`})},refinedCount:Us,refinedCapped:Je,onApprove:()=>Ge.mutate({id:s.id,status:"approved"}),onReject:()=>Ge.mutate({id:s.id,status:"rejected"}),onDelete:()=>$s.mutate(s.id),onRefine:()=>Ne(s),onEmailSelf:async()=>{let a;try{a=await ss(s)}catch(r){h.error(`Could not watermark image: ${r.message??r}`);return}_e.mutate({concept_id:s.id,audience:"self",watermarked_path:a})},onEmailCustomer:()=>Ce(s),disabled:es||G.isPending,isAdmin:P},s.id))})})]}),e.jsx(Ct,{concept:we,onClose:()=>Ne(null),onUploadFiles:s=>Ue(s,"reference"),uploading:J,onSubmit:s=>{we&&(G.mutate({stage:"refined",parent_concept_id:we.id,refinement_note:s}),Ne(null))},loading:G.isPending}),e.jsx(_t,{concept:ae,defaultCustomerEmail:c.prospects?.contact_email,onClose:()=>Ce(null),onSubmit:async s=>{if(!ae)return;let a;try{a=await ss(ae)}catch(r){h.error(`Could not watermark image: ${r.message??r}`);return}_e.mutate({concept_id:ae.id,audience:"customer",...s,watermarked_path:a})},loading:_e.isPending}),e.jsx(Zs,{open:!!Y,onOpenChange:s=>!s&&Re(null),url:Y?.url??null,thumbUrl:Y?.thumb??null,title:Y?.title??null})]});async function ss(s){const a=s?.storage_path?X[s.storage_path]:void 0;if(!a||!s?.storage_path)return;const r=await nt(a,{watermark:!0}),d=new Uint8Array(await r.arrayBuffer());let v="";const I=32768;for(let j=0;j<d.length;j+=I)v+=String.fromCharCode.apply(null,Array.from(d.subarray(j,j+I)));const ne=btoa(v);return(await y({data:{concept_id:s.id,image_base64:ne}})).watermarked_path}}function Nt({concept:t,projectTitle:n,url:l,thumbUrl:_,onExpand:x,refinedCount:D,refinedCapped:O,onApprove:p,onReject:$,onDelete:b,onRefine:S,onEmailSelf:E,onEmailCustomer:g,disabled:y,isAdmin:T}){const[L,f]=i.useState(!1),[U,P]=i.useState(!1),R={generating:"bg-blue-100 text-blue-700",completed:"bg-emerald-100 text-emerald-700",approved:"bg-emerald-200 text-emerald-800",rejected:"bg-rose-100 text-rose-700",failed:"bg-destructive/10 text-destructive"},u={rough:"bg-slate-100 text-slate-700",refined:"bg-indigo-100 text-indigo-700",polished:"bg-amber-100 text-amber-800"},k=(n??"concept").replace(/[^a-z0-9-_]+/gi,"-").toLowerCase(),K=(t.download_filename||`${k}-${t.stage}-v${t.version}.png`).replace(/\.png$/i,"");async function Q(V){if(l){P(!0);try{await it(l,{watermark:V,filename:K}),f(!1)}catch(X){h.error(X.message??"Download failed")}finally{P(!1)}}}return e.jsxs("div",{className:"overflow-hidden rounded-lg border bg-card",children:[e.jsxs("div",{className:"relative aspect-square bg-muted",children:[t.status==="generating"&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center",children:e.jsxs("div",{className:"text-center",children:[e.jsx(pe,{className:"mx-auto h-8 w-8 animate-pulse text-primary"}),e.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:"Generatingâ¦"})]})}),t.status==="failed"&&e.jsx("div",{className:"flex h-full items-center justify-center p-4",children:e.jsx("p",{className:"text-center text-sm text-destructive",children:t.error_message||"Generation failed"})}),l&&e.jsx("button",{type:"button",onClick:x,title:"Click to view full resolution",className:"block h-full w-full cursor-zoom-in",children:e.jsx("img",{src:_??l,alt:`AI-generated apparel concept v${t.version} (${t.stage}) for ${t.company_name_snapshot??"this project"}`,loading:"lazy",decoding:"async",className:"h-full w-full object-contain"})}),l&&e.jsx("span",{className:"pointer-events-none absolute bottom-2 right-2 roun
1ded-full px-2.5 py-1 text-[10px] font-bold uppercase tracking-wider text-white shadow-lg ring-1 ring-white/25",style:{backgroundColor:"#8A2432",letterSpacing:"0.08em"},children:"AI Concept Only · Artist Revision Required"})]}),e.jsxs("div",{className:"space-y-3 p-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:`rounded-full px-2 py-0.5 text-xs font-medium ${u[t.stage]??"bg-muted"}`,children:t.stage}),e.jsxs("span",{className:"font-display text-sm font-semibold",children:["v",t.version]}),e.jsx("span",{className:`rounded-full px-2 py-0.5 text-xs font-medium ${R[t.status]??"bg-muted"}`,children:t.status}),t.qa_score!=null&&e.jsxs("span",{className:"text-xs text-muted-foreground",children:["QA ",Math.round(t.qa_score),"/100"]})]}),e.jsxs("button",{onClick:()=>{confirm("Delete this concept? This can't be undone.")&&b()},title:"Delete concept","aria-label":`Delete concept v${t.version}`,className:"text-muted-foreground hover:text-destructive",children:[e.jsx(Ns,{className:"h-4 w-4"}),e.jsx("span",{className:"sr-only",children:"Delete concept"})]})]}),e.jsx("div",{className:"rounded-md border bg-muted/40 px-2.5 py-1.5 text-[11px] leading-relaxed text-muted-foreground",children:e.jsxs("div",{className:"flex flex-wrap gap-x-3 gap-y-0.5",children:[t.company_name_snapshot&&e.jsxs("span",{children:[e.jsx("span",{className:"font-medium text-foreground/80",children:"Company:"})," ",t.company_name_snapshot]}),t.industry_snapshot&&e.jsxs("span",{children:[e.jsx("span",{className:"font-medium text-foreground/80",children:"Industry:"})," ",t.industry_snapshot]}),t.created_by_email&&e.jsxs("span",{children:[e.jsx("span",{className:"font-medium text-foreground/80",children:"By:"})," ",t.created_by_email]}),e.jsxs("span",{children:[e.jsx("span",{className:"font-medium text-foreground/80",children:"Created:"})," ",new Date(t.created_at).toLocaleDateString()]}),t.model&&e.jsxs("span",{children:[e.jsx("span",{className:"font-medium text-foreground/80",children:"Model:"})," ",t.model]}),T&&t.cost_estimate_usd!=null&&Number(t.cost_estimate_usd)>0&&e.jsxs("span",{children:[e.jsx("span",{className:"font-medium text-foreground/80",children:"Cost:"})," $",Number(t.cost_estimate_usd).toFixed(3)]}),t.download_filename&&e.jsx("span",{className:"w-full truncate font-mono text-[10px] text-foreground/60",children:t.download_filename})]})}),t.customer_brief&&e.jsx("p",{className:"text-sm text-muted-foreground line-clamp-3",children:t.customer_brief}),t.status==="completed"||t.status==="approved"||t.status==="rejected"?e.jsx("div",{className:"space-y-2",children:e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(o,{size:"sm",variant:"outline",onClick:p,children:[e.jsx(ms,{className:"mr-1 h-4 w-4"})," Approve"]}),e.jsxs(o,{size:"sm",variant:"outline",onClick:$,children:[e.jsx(Te,{className:"mr-1 h-4 w-4"})," Reject"]}),e.jsxs(o,{size:"sm",variant:"outline",onClick:S,disabled:y||O,children:[e.jsx(_s,{className:"mr-1 h-4 w-4"})," Refine"]}),e.jsxs(o,{size:"sm",variant:"outline",onClick:()=>f(!0),disabled:!l,children:[e.jsx(dt,{className:"mr-1 h-4 w-4"})," Download"]}),e.jsxs(o,{size:"sm",variant:"outline",onClick:E,disabled:!l,children:[e.jsx(rs,{className:"mr-1 h-4 w-4"})," Email self"]}),e.jsxs(o,{size:"sm",onClick:g,disabled:!l,children:[e.jsx(rs,{className:"mr-1 h-4 w-4"})," Email customer"]})]})}):null]}),e.jsx(ce,{open:L,onOpenChange:V=>!V&&f(!1),children:e.jsxs(me,{children:[e.jsxs(ue,{children:[e.jsx(he,{children:"Download concept"}),e.jsx($e,{children:'The "AI Concept Only · Artist Revision Required" tag is always baked in. Choose whether to also stamp the repeating "Excel Sportswear - Property" watermark across the image.'})]}),e.jsxs(xe,{className:"flex-col gap-2 sm:flex-row",children:[e.jsx(o,{variant:"outline",onClick:()=>f(!1),disabled:U,children:"Cancel"}),e.jsx(o,{variant:"outline",onClick:()=>Q(!1),disabled:U,children:"Plain (badge only)"}),e.jsx(o,{onClick:()=>Q(!0),disabled:U,children:U?"Renderingâ¦":"With watermark"})]})]})})]})}function Ct({concept:t,onClose:n,onSubmit:l,loading:_,onUploadFiles:x,uploading:D}){const[O,p]=i.useState(""),[$,b]=i.useState(!1),[S,E]=i.useState(!1),[g,y]=i.useState([]),T=i.useRef(null);i.useEffect(()=>{t||(p(""),b(!1),y([]))},[t]);const L=u=>{if(!u&&$){E(!0);return}u||(p(""),b(!1),y([]),n())},f=()=>{if($){E(!0);return}p(""),b(!1),y([]),n()},U=u=>{const k=Array.from(u.target.files??[]);k.length!==0&&(y(K=>[...K,...k]),b(!0),T.current&&(T.current.value=""))},P=u=>{y(k=>k.filter((K,Q)=>Q!==u))},R=async()=>{g.length>0&&x&&await x(g),l(O)};return e.jsxs(e.Fragment,{children:[e.jsx(ce,{open:!!t,onOpenChange:L,children:e.jsxs(me,{className:"max-w-lg",children:[e.jsx(ue,{children:e.jsxs(he,{children:["Refine concept v",t?.version]})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(z,{className:"text-xs",children:"What should change?"}),e.jsx(ze,{rows:4,value:O,onChange:u=>{p(u.target.value),b(!0)},placeholder:"e.g. push the truck bigger, swap palette to red/white, add a halftone backgroundâ¦"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(z,{className:"text-xs",children:"Add reference images (optional)"}),e.jsxs(ys,{accept:"image/*",multiple:!0,disabled:D,onFiles:u=>U(vs(u)),overlayLabel:"Drop reference images",children:[e.jsx("input",{ref:T,type:"file",accept:"image/*",multiple:!0,className:"hidden",onChange:U}),e.jsxs(o,{variant:"outline",size:"sm",type:"button",onClick:()=>T.current?.click(),disabled:D,children:[e.jsx(ws,{className:"mr-2 h-4 w-4"})," ",D?"Uploadingâ¦":"Upload references"]}),g.length>0&&e.jsx("div",{className:"mt-2 flex flex-wrap gap-2",children:g.map((u,k)=>e.jsxs("div",{className:"inline-flex items-center gap-1 rounded-md border bg-muted px-2 py-1 text-xs",children:[e.jsx("span",{className:"max-w-[180px] truncate",children:u.name}),e.jsx("button",{onClick:()=>P(k),className:"text-muted-foreground hover:text-destructive",children:e.jsx(Te,{className:"h-3 w-3"})})]},k))})]})]})]}),e.jsxs(xe,{children:[e.jsx(o,{variant:"outline",onClick:f,children:"Cancel"}),e.jsx(o,{onClick:R,disabled:_||!O.trim()&&g.length===0,children:_?"Refiningâ¦":"Generate refinement"})]})]})}),e.jsx(us,{open:S,onOpenChange:E,children:e.jsxs(hs,{children:[e.jsxs(xs,{children:[e.jsx(ps,{children:"Discard changes?"}),e.jsx(gs,{children:"Any incomplete data will not be saved."})]}),e.jsxs(fs,{children:[e.jsx(js,{onClick:()=>E(!1),children:"Keep editing"}),e.jsx(bs,{onClick:()=>{E(!1),p(""),b(!1),y([]),n()},children:"Discard"})]})]})})]})}function _t({concept:t,defaultCustomerEmail:n,onClose:l,onSubmit:_,loading:x}){const[D,O]=i.useState(""),[p,$]=i.useState(""),[b,S]=i.useState(!1),[E,g]=i.useState(!1);i.useEffect(()=>{t&&(O(n??""),$(""),S(!1))},[t,n]);const y=()=>D!==(n??"")||p.trim().length>0,T=f=>
1{if(!f&&y()){g(!0);return}f||(S(!1),l())},L=()=>{if(y()){g(!0);return}S(!1),l()};return e.jsxs(e.Fragment,{children:[e.jsx(ce,{open:!!t,onOpenChange:T,children:e.jsxs(me,{children:[e.jsxs(ue,{children:[e.jsx(he,{children:"Email concept to customer"}),e.jsx($e,{children:"Sends the watermarked concept. You'll be CC'd as the assigned salesperson."})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(z,{className:"text-xs",children:"Customer email"}),e.jsx(Oe,{type:"email",value:D,onChange:f=>{O(f.target.value),S(!0)},placeholder:"[email protected]"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(z,{className:"text-xs",children:"Optional message"}),e.jsx(ze,{rows:3,value:p,onChange:f=>{$(f.target.value),S(!0)}})]}),e.jsx("p",{className:"rounded border border-amber-200 bg-amber-50 p-2 text-xs text-amber-900",children:"Customer-bound emails include a disclaimer that this is an early concept and final artwork will be refined by Excel's artists."})]}),e.jsxs(xe,{children:[e.jsx(o,{variant:"outline",onClick:L,children:"Cancel"}),e.jsx(o,{onClick:()=>_({to:D,message:p}),disabled:x||!D.trim(),children:x?"Sendingâ¦":"Send"})]})]})}),e.jsx(us,{open:E,onOpenChange:g,children:e.jsxs(hs,{children:[e.jsxs(xs,{children:[e.jsx(ps,{children:"Discard changes?"}),e.jsx(gs,{children:"Any incomplete data will not be saved."})]}),e.jsxs(fs,{children:[e.jsx(js,{onClick:()=>g(!1),children:"Keep editing"}),e.jsx(bs,{onClick:()=>{g(!1),S(!1),l()},children:"Discard"})]})]})})]})}function cs(t){return e.jsxs("div",{className:"-mt-1 space-y-2",children:[e.jsxs(o,{type:"button",variant:"outline",size:"sm",className:"h-8 text-xs",disabled:t.disabled,onClick:()=>t.onGenerate(t.kind),children:[t.loading?e.jsx(Cs,{className:"mr-1.5 h-3.5 w-3.5 animate-spin"}):e.jsx(pe,{className:"mr-1.5 h-3.5 w-3.5"}),t.loading?"Thinkingâ¦":t.ideas.length?"Suggest fresh ideas":"Suggest ideas"]}),t.ideas.length>0?e.jsxs("div",{className:"rounded-md border border-primary/20 bg-primary/5 p-3",children:[e.jsxs("div",{className:"mb-2 flex items-center justify-between gap-3",children:[e.jsx("span",{className:"text-xs font-medium",children:"Click an idea to add it"}),e.jsx(o,{type:"button",variant:"ghost",size:"sm",className:"h-6 px-2 text-xs",onClick:t.onClear,children:"Clear"})]}),e.jsx("div",{className:"flex flex-wrap gap-2",children:t.ideas.map(n=>e.jsx(o,{type:"button",variant:"outline",size:"sm",className:"h-auto rounded-full px-3 py-1 text-xs",onClick:()=>t.onAdd(t.kind,n),children:n},n))})]}):null]})}function Fe(t){const n=t.optimizing===t.field,l=t.optimizing!==null,_=t.suggestion?.field===t.field;return e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx(z,{children:t.label}),e.jsxs(o,{type:"button",variant:"ghost",size:"sm",className:"h-7 px-2 text-xs",disabled:l||!t.value.trim(),onClick:()=>t.onOptimize(t.field),children:[n?e.jsx(Cs,{className:"mr-1 h-3.5 w-3.5 animate-spin"}):e.jsx(pe,{className:"mr-1 h-3.5 w-3.5"}),n?"Optimizingâ¦":"Optimize"]})]}),e.jsx(ze,{rows:t.rows,placeholder:t.placeholder,value:t.value,onChange:x=>t.onChange(x.target.value)}),_&&t.suggestion?e.jsxs("div",{className:"rounded-md border border-primary/30 bg-primary/5 p-3 space-y-2",children:[e.jsx("div",{className:"text-xs font-medium text-foreground",children:"AI suggestion"}),e.jsx("p",{className:"whitespace-pre-wrap text-sm text-muted-foreground",children:t.suggestion.text}),e.jsxs("div",{className:"flex flex-wrap gap-2 pt-1",children:[e.jsxs(o,{type:"button",size:"sm",onClick:t.onAccept,children:[e.jsx(ms,{className:"mr-1 h-3.5 w-3.5"})," Accept"]}),e.jsxs(o,{type:"button",size:"sm",variant:"outline",disabled:l,onClick:()=>t.onOptimize(t.field),children:[e.jsx(_s,{className:"mr-1 h-3.5 w-3.5"})," Regenerate"]}),e.jsxs(o,{type:"button",size:"sm",variant:"ghost",onClick:t.onDiscard,children:[e.jsx(Te,{className:"mr-1 h-3.5 w-3.5"})," Discard"]})]})]}):null]})}export{na 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.