PageSourceSearch

https://www.algofuse.ai/assets/TikTokShop-Dl-EaMZ6.js

js algofuse.ai collected 2026-10-05 12:35:00 UTC 40,300 bytes, 1 lines download raw bytes

1import{z as ss,a as as,Y as is,_ as rs,r as n,J as l,j as e,B as h,P as gt,S as pt,N as ht,$ as ft,C as xt}from"./index-r0VDtvoP.js";import{B as Ge}from"./badge-DKTIdHSU.js";import{I as bt}from"./input-CjKBdGKk.js";import{D as jt,a as vt,E as yt,b as _t,c as ue}from"./dropdown-menu-CBwCl370.js";import{F as Oe,S as ns,a as os,b as ls,c as cs,d as wt}from"./select-whVwggvg.js";import{L as ds}from"./label-oB9fb1ZN.js";import{C as ms,I as us,B as gs,M as ps,S as hs,E as fs,a as xs}from"./BrandStyleGuide-qDuFAUT_.js";import{F as K}from"./folder-open-DzFLCjAk.js";import{T as Nt,S as bs}from"./trash-2-Gk3W2-HM.js";import{D as kt}from"./download-BktoiKck.js";import{T as It}from"./type-PqizLoJT.js";import"./chevron-right-ConBaMX7.js";import"./collapsible-B4I91MhA.js";import"./switch-BkD-CZ-P.js";import"./upload-DrIs72JA.js";import"./star-D_cOm5GK.js";import"./list-BUGQeuBP.js";import"./dialog-Dm6NFqzV.js";import"./zoom-in-CS9cHPLl.js";import"./square-EWJ37Me6.js";const St=[{id:"tt_hook",name:"Why should I care?",icon:"zap"},{id:"tt_proof",name:"Does this actually work?",icon:"shield"},{id:"tt_fit",name:"How do I use it?",icon:"user"},{id:"tt_kit",name:"What do I get?",icon:"package"},{id:"tt_worth",name:"Is it worth it?",icon:"dollar-sign"},{id:"tt_end",name:"Life with this",icon:"smile"}],js={main:"tiktok_hero_images",tt_hook:"tiktok_hook_images",tt_proof:"tiktok_proof_images",tt_fit:"tiktok_fit_images",tt_kit:"tiktok_kit_images",tt_worth:"tiktok_worth_images",tt_end:"tiktok_end_images"},S=M=>js[M]||`${M}_images`,vs=M=>{if(!M||typeof M!="string")return!1;const _=M.trim();return/^[A-Z0-9]{10}$/i.test(_)};function Js(){var mt;const{user:M,tokenBalance:_,refreshBalance:T}=ss(),{settings:Ct,isAdmin:Et}=as(),[Mt,z]=is(),{toast:r}=rs(),[q,Ee]=n.useState([]),[Je,ge]=n.useState([]),[c,pe]=n.useState(null),[i,p]=n.useState(null),[Tt,G]=n.useState(!0),[Ft,Me]=n.useState(!1),[Pt,he]=n.useState(null),[V,W]=n.useState(""),[C,Te]=n.useState("New Project"),[w,H]=n.useState(null),[N,fe]=n.useState(""),[b,Z]=n.useState(""),[F,Q]=n.useState(""),[xe,X]=n.useState(""),[f,ee]=n.useState(""),[P,te]=n.useState(""),[U,se]=n.useState(""),[O,be]=n.useState(""),[j,je]=n.useState(!1),[I,ae]=n.useState(""),[D,ve]=n.useState("us"),[E,ie]=n.useState([]),[ye,Fe]=n.useState("nano-banana-pro"),[Ye,Ke]=n.useState(!1),[Ut,_e]=n.useState(!1),[J,re]=n.useState(null),[Pe,ne]=n.useState(null),[Ue,Dt]=n.useState([]),[Lt,ze]=n.useState([]),[At,ys]=n.useState(""),[De,qe]=n.useState(null),[we,Le]=n.useState(null),[Ve,L]=n.useState(!1),[Rt,We]=n.useState(!1),[A,R]=n.useState(null),[_s,oe]=n.useState(null),[He,$t]=n.useState(!0),[Ze,Ne]=n.useState({}),[Bt,le]=n.useState(!1),[x,Qe]=n.useState(null),[$,Ae]=n.useState({}),[Xe,et]=n.useState(!1),[y,ce]=n.useState(0),[Gt,tt]=n.useState(0),[Re,st]=n.useState({}),$e=()=>i?C!==(i.product_title||"Untitled Project")||w!==(i.product_image_url||null)||b!==(i.brand_name||"")||F!==(i.category||"")||N!==(i.listing_url||"")||f!==(i.features||"")||P!==(i.brand_identity||"")||U!==(i.target_audience||"")||O!==(i.competitors||"")||j!==(i.is_new_listing||!1)||I!==(i.product_description||"")||D!==(i.marketplace||"us")||JSON.stringify(E)!==JSON.stringify(i.reference_images||[])||JSON.stringify(A)!==JSON.stringify(i.brand_style_guide||null):!1,at=async()=>{if(!(!i||!$e()))try{const t={name:C,product_title:xe,product_image_url:w,brand_name:b,category:F,listing_url:j?null:N,features:f,brand_identity:P,target_audience:U,competitors:O,folder_id:(c==null?void 0:c.id)||null,is_new_listing:j,product_description:I,marketplace:D,reference_images:E,image_model:ye,brand_style_guide:A};await l.projects.update(i.id,t),console.log("[Projects] Auto-saved project:",i.id)}catch(t){console.error("[Projects] Auto-save failed:",t)}};n.useEffect(()=>{const t=s=>{i&&$e()&&(at(),s.preventDefault(),s.returnValue="")};return window.addEventListener("beforeunload",t),()=>window.removeEventListener("beforeunload",t)},[i,C,w,b,F,N,f,P,U,O,j,I,D,E,A]),n.useEffect(()=>{Ot()},[]),n.useEffect(()=>{He||k(y,c)},[y]),n.useEffect(()=>{R((i==null?void 0:i.brand_style_guide)||null)},[i==null?void 0:i.id]),n.useEffect(()=>{const t=Mt.get("project_id");if(t&&q.length>0&&!i){const s=q.find(a=>a.id===t);s?(p(s),G(!1)):Be(t).then(()=>{G(!1)}).catch(()=>{z({})})}},[q]),n.useEffect(()=>
1{i&&(ke(i),z({project_id:i.id}))},[i]),n.useEffect(()=>{if((i==null?void 0:i.tiktok_status)==="processing"&&!Ve){const t=setInterval(()=>{Be(i.id)},15e3);return()=>clearInterval(t)}},[i==null?void 0:i.status,Ve]),n.useEffect(()=>{const t=async s=>{var d,m,u;console.log("[Projects] Job completed event received:",s.detail),L(!1),oe(null);const a=(d=s.detail)==null?void 0:d.job,o=a==null?void 0:a.type;if(i!=null&&i.id)try{const g=await l.projects.get(i.id);if(p(g),ke(g),(m=a==null?void 0:a.input)!=null&&m.fontMatch){const v=(((u=a==null?void 0:a.input)==null?void 0:u.targets)||[]).map(B=>B.imageType);Ne(B=>{const Y={...B};for(const me of v){const Se=S(me),Ce=(g==null?void 0:g[Se])||[];Ce.length>0&&(Y[me]=Ce.length-1)}return Y}),r({title:"Font Match Complete!",description:"Your images have been updated with the matched font style.",duration:6e3})}else r(o==="edit_image"?{title:"Edit Complete!",description:"Click Edit on the same image to see it in Edit History at the bottom.",duration:6e3}:o==="create_more"?{title:"Complete!",description:"New image added to your listing!"}:{title:"Complete!",description:"All images have been generated successfully!"})}catch(g){console.error("[Projects] Failed to reload project:",g)}await k(y,c),T()};return window.addEventListener("algofuse_job_completed",t),()=>window.removeEventListener("algofuse_job_completed",t)},[i==null?void 0:i.id]);const k=async(t=0,s=null)=>{const a=await l.projects.list({projectType:"tiktok",limit:20,offset:t*20,folderId:(s==null?void 0:s.id)||null});return Ee(a.projects||[]),tt(a.total||0),st(a.folder_counts||{}),a},Ot=async()=>{try{const[t,s,a]=await Promise.all([l.projects.list({projectType:"tiktok",limit:20,offset:0,folderId:null}),l.folders.list(),l.projects.list({projectType:"listing",limit:500})]);Ee(t.projects||[]),tt(t.total||0),st(t.folder_counts||{}),ge(s.folders||[]),Dt(a.projects||[])}catch(t){console.error("Error loading data:",t),r({title:"Error",description:"Failed to load projects",variant:"destructive"})}finally{$t(!1)}},Jt=async t=>{var a;if(!t){if(re(null),ne(null),ze([]),Z(""),ee(""),H(null),X(""),ae(""),te(""),se(""),Q(""),R(null),ie([]),i!=null&&i.id)try{await l.projects.update(i.id,{reference_project_id:null})}catch{}return}const s=Ue.find(o=>o.id===t);if(s){if(re(t),ne(s),ze([]),s.brand_name&&Z(s.brand_name),s.features&&ee(s.features),s.product_image_url&&H(s.product_image_url),s.product_title&&X(s.product_title),s.product_description&&ae(s.product_description),s.brand_identity&&te(s.brand_identity),s.target_audience&&se(s.target_audience),s.category&&Q(s.category),s.brand_style_guide&&R(s.brand_style_guide),(a=s.reference_images)!=null&&a.length&&ie(s.reference_images),s.listing_url&&(fe(s.listing_url),je(!1)),s.marketplace&&ve(s.marketplace),s.competitors&&be(s.competitors),i!=null&&i.id)try{await l.projects.update(i.id,{reference_project_id:t})}catch{}r({title:"Imported",description:`Pulled brand, product, and style guide from "${s.product_title||s.brand_name}".`})}},Be=async t=>{try{const s=await l.projects.get(t);p(s),ke(s),Ee(a=>a.map(o=>o.id===t?s:o))}catch(s){console.error("Error loading project:",s)}},ke=t=>{if(Te(t.product_title||"Untitled Project"),X(""),H(t.product_image_url||null),Z(t.brand_name||""),Q(t.category||""),fe(t.listing_url||""),ee(t.features||""),te(t.brand_identity||""),se(t.target_audience||""),be(t.competitors||""),je(t.is_new_listing||!1),ae(t.product_description||""),ve(t.marketplace||"us"),ie(t.reference_images||[]),Fe(t.image_model||"nano-banana-pro"),R(t.brand_style_guide||null),t.reference_project_id){re(t.reference_project_id);const s=Ue.find(a=>a.id===t.reference_project_id);ne(s||null)}else re(null),ne(null)},it=()=>{p(null),z({}),G(!1),Te("New Project"),X(""),H(null),Z(""),Q(""),fe(""),ee(""),te(""),se(""),be(""),je(!1),ae(""),ve("us"),ie([]),Fe("nano-banana-pro"),re(null),ne(null),R(null)},Yt=async t=>{try{await l.folders.create(t.name,t.description),r({title:"Success",description:"Folder created successfully"});const s=await l.folders.list();ge(s.folders||[]),Me(!1)}catch(s){r({title:"Error",description:s.message,variant:"destructive"})}},rt=async(t,s)=>{if(!s||!s.trim()){r({title:"Error",description:"Folder name cannot be empty",variant:"destructive"});return}
1try{await l.folders.update(t,s.trim()),r({title:"Success",description:"Folder renamed successfully"});const a=await l.folders.list();ge(a.folders||[]),(c==null?void 0:c.id)===t&&pe(o=>({...o,name:s.trim()})),he(null),W("")}catch(a){r({title:"Error",description:a.message,variant:"destructive"})}},Kt=async t=>{const s=Re[t.id]||0,a=s>0?`Delete "${t.name}"? ${s} project(s) will be moved to All Projects. This action cannot be undone.`:`Delete "${t.name}"? This action cannot be undone.`;if(confirm(a))try{await l.folders.delete(t.id),r({title:"Success",description:"Folder deleted successfully"});const o=await l.folders.list();ge(o.folders||[]),(c==null?void 0:c.id)===t.id?(pe(null),ce(0),await k(0,null)):await k(y,c)}catch(o){r({title:"Error",description:o.message,variant:"destructive"})}},nt=async(t,s)=>{try{await l.projects.move(t.id,s),r({title:"Success",description:"Project moved successfully"}),await k(y,c)}catch(a){r({title:"Error",description:a.message,variant:"destructive"})}},zt=async t=>{if(confirm(`Delete "${t.product_title||"Untitled"}"? This action cannot be undone.`))try{await l.projects.delete(t.id),r({title:"Success",description:"Project deleted successfully"}),await k(y,c),(i==null?void 0:i.id)===t.id&&(p(null),z({}),G(!0))}catch(s){r({title:"Error",description:s.message,variant:"destructive"})}},qt=t=>{G(!1),p(t),ke(t),Be(t.id).catch(s=>console.error("[TikTok] Refresh project failed:",s))},Ie=async(t={})=>{Ke(!0);try{const s={name:C,project_type:"tiktok",product_title:xe,product_image_url:w,brand_name:b,category:F,listing_url:j?null:N,features:f,brand_identity:P,target_audience:U,competitors:O,folder_id:(c==null?void 0:c.id)||null,is_new_listing:j,product_description:I,marketplace:D,image_model:ye,reference_images:E,reference_project_id:J||null,brand_style_guide:A,...t};let a;i?a=await l.projects.update(i.id,s):a=await l.projects.create(s),p(a),r({title:"Saved",description:"Project saved successfully"}),await k(y,c)}catch(s){r({title:"Error",description:s.message,variant:"destructive"})}finally{Ke(!1)}},Vt=async()=>{i&&$e()&&(await at(),r({title:"Saved",description:"Project auto-saved"})),p(null),G(!0),z({})},Wt=async()=>{if(console.log("[Frontend] Generate All clicked"),console.log("[Frontend] productImage:",w?"present":"MISSING"),console.log("[Frontend] brandName:",b||"MISSING"),console.log("[Frontend] features:",f||"MISSING"),console.log("[Frontend] isNewListing:",j),console.log("[Frontend] listingUrl:",N||"MISSING"),console.log("[Frontend] productDescription:",I||"MISSING"),!b||!f){r({title:"Error",description:"Brand name and keywords are required.",variant:"destructive"});return}if(!f){r({title:"Error",description:"Please provide key product features.",variant:"destructive"});return}if(_<90){r({title:"Insufficient Tokens",description:"You need at least 90 tokens to generate all images.",variant:"destructive"});return}L(!0),We(!0),setTimeout(()=>We(!1),1e4);try{let t;const s={name:C,project_type:"tiktok",product_title:xe||C,product_image_url:w,brand_name:b,category:F,listing_url:j?null:N,features:f,brand_identity:P,target_audience:U,competitors:O,folder_id:(c==null?void 0:c.id)||null,is_new_listing:j,product_description:I,image_model:ye,marketplace:D,reference_images:E,reference_project_id:J||null,brand_style_guide:A};console.log("[Frontend] Saving project first..."),i?t=await l.projects.update(i.id,s):t=await l.projects.create(s),console.log("[Frontend] Project saved:",t.id),p(t),console.log("[Frontend] Calling tiktok.generate...");const a=await l.tiktok.generate({project_id:t.id,productImage:w,brandName:b,features:f,category:F,productDescription:I,brandIdentity:P,targetAudience:U,referenceImages:E,referenceProjectId:J||null,selectedListingImages:Lt||[],promoText:At||null,listingUrl:j?null:N||null,marketplace:D||"us"});console.log("[Frontend] Generate result:",a),a.jobId?(oe(a.jobId),window.dispatchEvent(new CustomEvent("algofuse_job_started",{detail:{jobId:a.jobId,type:"generate_all"}})),r({title:"Generation Started",description:"Your images are being generated. This may take 2-5 minutes."})):r({title:"Processing",description:"Image generation started. Results will appear when ready."}),T(),await k(y,c)}catch(t){console.error("[Frontend] Generate error:",t),r({title:"Error",description:t.message,variant:"destructive"}),L(!1)}},Ht=async()=>
1{if(!i)return;const t=["main","lifestyle","infographic","scale","howto","package","social"],s=[];if(t.forEach(a=>{(i[S(a)]||[]).forEach((d,m)=>{s.push({url:d,name:`${a}-${m+1}.png`})})}),s.length===0){r({title:"No Images",description:"No images to download yet.",variant:"destructive"});return}r({title:"Downloading",description:`Downloading ${s.length} images...`});for(let a=0;a<s.length;a++){const{url:o,name:d}=s[a];try{const u=await(await fetch(o)).blob(),g=window.URL.createObjectURL(u),v=document.createElement("a");v.href=g,v.download=d,document.body.appendChild(v),v.click(),document.body.removeChild(v),window.URL.revokeObjectURL(g),await new Promise(B=>setTimeout(B,300))}catch(m){console.error(`Failed to download ${d}:`,m)}}r({title:"Complete",description:`Downloaded ${s.length} images`})},ot=async(t,s)=>{if(console.log("handleImageUpload called:",{imageType:s,hasProject:!!i,projectId:i==null?void 0:i.id}),!i||!i.id){r({title:"Error",description:"Please save the project first using the Save button",variant:"destructive"});return}try{r({title:"Uploading",description:"Uploading image..."}),console.log("Starting file upload...");const a=await l.upload.file(t);console.log("Upload result:",a);const o=a.url||a.file_url;if(!o)throw new Error("Upload failed - no URL returned");const d=S(s),m=i[d]||[];console.log("Updating project:",i.id,d,"with URL:",o);const u=await l.projects.update(i.id,{[d]:[...m,o]});console.log("Project updated:",u),p(u),r({title:"Success",description:"Image uploaded successfully"})}catch(a){console.error("Image upload error:",a),r({title:"Error",description:a.message||"Upload failed",variant:"destructive"})}},lt=async(t,s)=>{if(i)try{const a=S(s),d=(i[a]||[]).filter(u=>u!==t),m=await l.projects.update(i.id,{[a]:d});p(m),r({title:"Success",description:"Image deleted successfully"})}catch(a){r({title:"Error",description:a.message,variant:"destructive"})}},ct=(t,s)=>{var o;const a=((o=i==null?void 0:i.image_prompts)==null?void 0:o[s])||null;qe({url:t,type:s,prompt:a})},dt=(t,s)=>{Le({imageType:t,existingImages:s})},Zt=async t=>{var s;if(!i||!i.id){r({title:"Error",description:"Please save the project first using the Save button",variant:"destructive"});return}if(_<15){r({title:"Insufficient Tokens",description:"You need at least 15 tokens.",variant:"destructive"});return}try{if(((s=t.createMoreReferenceImages)==null?void 0:s.length)>0){const o={...i.create_more_reference_images||{},[t.imageType]:t.createMoreReferenceImages};await l.projects.update(i.id,{create_more_reference_images:o}),p(d=>({...d,create_more_reference_images:o}))}L(!0);const a=await l.generate.more(i.id,t.imageType,{prompt:t.prompt,referenceImage:t.referenceImage,brandName:b,features:f,styleGuide:A,referenceImages:t.createMoreReferenceImages||[]});a.jobId?(console.log("[CreateMore] Job started:",a.jobId),oe(a.jobId),window.dispatchEvent(new CustomEvent("algofuse_job_started",{detail:{jobId:a.jobId,type:"create_more"}})),console.log("[CreateMore] Dispatched algofuse_job_started event"),r({title:"Creating Image",description:"Your image is being generated. This may take 1-2 minutes."})):(console.warn("[CreateMore] No jobId in response:",a),r({title:"Processing",description:"Creating more images. Results will update shortly."})),T()}catch(a){throw console.error("[CreateMore] Error:",a),r({title:"Failed",description:a.message||"Failed to create more images",variant:"destructive"}),L(!1),a}},Qt=async t=>{if(!i||!i.id){r({title:"Error",description:"Please save the project first using the Save button",variant:"destructive"});return}const s=t.editMode==="both"?10:5;if(_<s){r({title:"Insufficient Tokens",description:`You need at least ${s} tokens.`,variant:"destructive"});return}try{L(!0);const a=await l.generate.edit(i.id,t.imageUrl,t.imageType,t.instructions,{editMode:t.editMode||"image",textPrompt:t.textPrompt,quickEdits:t.quickEdits,styleStrength:t.styleStrength,referenceImages:t.referenceImages||[],originalImageUrl:t.originalImageUrl,maskImage:t.maskImage||void 0});a.jobId?(console.log("[Edit] Job started:",a.jobId),oe(a.jobId),window.dispatchEvent(new CustomEvent("algofuse_job_started",{detail:{jobId:a.jobId,type:"edit_image"}})),console.log("[Edit] Dispatched algofuse_job_started event"),r({title:"Edit Started",description:"Check the Edit button on this image when complete to see results."})):(console.warn("[Edit] No jobId in response:",a),r({title:"Processing",description:"Image edit started. Results will update shortly."})),T()}catch(a){throw console.error("[Edit] Error:",a),r({title:"Edit Failed",description:a.message,variant:"destructive"}),L(!1),a}},de=()=>{if(!i)return[];const t=[],s=i.tiktok_hero_images||[];if(s.length>0){const a=Math.min(Ze.main||0,s.length-1);t.push({url:s[a],type:"main",name:"Main Image"})}for(const a of St){const o=i[S(a.id)]||[];
1if(o.length>0){const d=Math.min(Ze[a.id]||0,o.length-1);t.push({url:o[d],type:a.id,name:a.name})}}return t},Xt=()=>{if(de().length<2){r({title:"Not enough images",description:"You need at least 2 generated images to use font match.",variant:"destructive"});return}Qe(null),Ae({}),le(!0)},es=async()=>{if(!x){r({title:"Select reference",description:"Pick an image whose font style you want to match.",variant:"destructive"});return}const t=de().filter(a=>a.type!==x.type&&$[a.type]).map(a=>({imageUrl:a.url,imageType:a.type}));if(t.length===0){r({title:"No targets selected",description:"Select at least one image to apply the font to.",variant:"destructive"});return}const s=t.length*5;if(_<s){r({title:"Insufficient Tokens",description:`You need ${s} tokens (${t.length} × 5).`,variant:"destructive"});return}try{et(!0);const a=await l.generate.fontMatch(i.id,x.url,x.type,t);if(a.jobId){oe(a.jobId),window.dispatchEvent(new CustomEvent("algofuse_job_started",{detail:{jobId:a.jobId,type:"edit_image"}})),r({title:"Font Match Started",description:`Matching fonts on ${t.length} image${t.length>1?"s":""}...`});const o=i.id;(async()=>{for(let m=0;m<240;m++){await new Promise(u=>setTimeout(u,5e3));try{const u=await l.generate.getJob(a.jobId),g=u.job||u;if(g.status==="completed"||g.status==="complete"){const v=await l.projects.get(o);p(v);const B=(t||[]).map(Y=>Y.imageType);Ne(Y=>{const me={...Y};for(const Se of B){const Ce=S(Se),ut=(v==null?void 0:v[Ce])||[];ut.length>0&&(me[Se]=ut.length-1)}return me}),r({title:"Font Match Complete!",description:"Your images have been updated.",duration:6e3}),T();return}if(g.status==="failed"||g.status==="cancelled"){r({title:"Font Match Failed",description:g.error||"Something went wrong.",variant:"destructive"}),T();return}}catch(u){console.error("[FontMatch] Poll error:",u)}}})()}le(!1),T()}catch(a){console.error("[FontMatch] Error:",a),r({title:"Font Match Failed",description:a.message,variant:"destructive"})}finally{et(!1)}},ts=async t=>{R(t),await Ie({brand_style_guide:t})};if(Tt){const t=Math.ceil(Gt/20);return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(K,{className:"w-8 h-8 text-blue-500"}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold text-white",children:"TikTok Shop Projects"}),e.jsx("p",{className:"text-slate-400 text-sm",children:"Generate stunning product images for your listings"})]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(h,{onClick:()=>Me(!0),variant:"outline",className:"border-slate-700 hover:bg-slate-800",children:[e.jsx(Oe,{className:"w-4 h-4 mr-2"}),"New Folder"]}),e.jsxs(h,{onClick:it,className:"bg-gradient-to-r from-blue-500 to-purple-600 hover:from-blue-600 hover:to-purple-700","data-tour":"new-project",children:[e.jsx(gt,{className:"w-4 h-4 mr-2"}),"New Project"]})]})]}),e.jsx("div",{className:"p-4 bg-gradient-to-br from-pink-500/10 to-cyan-500/5 border border-pink-500/30 rounded-xl overflow-hidden",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(pt,{className:"w-5 h-5 text-pink-400 flex-shrink-0 mt-0.5"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("p",{className:"text-pink-300 font-semibold",children:"Win the TikTok Shop Scroll"}),e.jsxs("p",{className:"text-slate-300 text-sm leading-snug",children:["7 images that walk a TikTok buyer through their decision — one image per buyer question, in order: ",e.jsx("span",{className:"text-pink-300/90",children:"Is this it?"})," → ",e.jsx("span",{className:"text-pink-300/90",children:"Why should I care?"})," → ",e.jsx("span",{className:"text-pink-300/90",children:"Does this actually work?"})," → ",e.jsx("span",{className:"text-pink-300/90",children:"How do I use it?"})," → ",e.jsx("span",{className:"text-pink-300/90",children:"What do I get?"})," → ",e.jsx("span",{className:"text-pink-300/90",children:"Is it worth it?"})," → ",e.jsx("span",{className:"text-pink-300/90",children:"Life with this."})]}),e.jsxs("div",{className:"flex items-center gap-2 mt-3 pt-2 border-t border-pink-500/20",children:[e.jsx(ht,{className:"w-4 h-4 text-pink-400"}),e.jsxs("span",{className:"text-pink-400 text-sm",children:[e.jsx("strong",{children:_})," tokens available"]}),e.jsx("span",{className:"text-slate-500 text-xs",children:"(90 tokens per full generation)"})]})]})]})}),e.jsxs("div",{className:"flex gap-6",children:[e.jsx("div",{className:"w-64 flex-shrink-0",children:e.jsxs("div",{className:"bg-slate-800/50 border border-slate-700/50 rounded-xl p-4 space-y-2",children:[e.jsx("h3",{className:"font-semibold text-white mb-3",children:"Folders"}),e.jsx("div",{onClick:()=>{pe(null),ce(0),k(0,null)},className:`p-3 rounded-lg cursor-pointer transition-all ${c?"hover:bg-slate-700/50 text-slate-300":"bg-blue-500 text-white"}`,children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(K,{className:"w-4 h-4 flex-shrink-0"}),e.jsx("span",{className:"text-sm font-medium truncate flex-1",children:"All Projects"}),e.jsx("span",{className:"text-xs opacity-70 flex-shrink-0",children:Re.unfiled||0}),e.jsx("div",{className:"w-6 h-6 flex-shrink-0"})]})}),Je.map(s=>e.jsx("div",{className:`p-3 rounded-lg transition-all group relative ${(c==null?void 0:c.id)===s.id?"bg-blue-500 text-white":"hover:bg-slate-700/50 text-slate-300"}`,children:Pt===s.id?e.jsx("div",{className:"flex items-center gap-2",children:e.jsx(bt,{value:V,onChange:a=>W(a.target.value),className:"h-7 text-sm bg-slate-900 border-slate-600 text-white",autoFocus:!0,onKeyDown:a=>{a.key==="Enter"&&rt(s.id,V),a.key==="Escape"&&(he(null),W(""))},onBlur:()=>{V.trim()&&V.trim()!==s.name?rt(s.id,V):(he(null),W(""))},onClick:a=>a.stopPropagation()})}):e.jsxs("div",{onClick:()=>{pe(s),ce(0),k(0,s)},className:"flex items-center gap-2 cursor-pointer",children:[e.jsx(Oe,{className:"w-4 h-4 flex-shrink-0"}),e.jsx("span",{className:"text-sm font-medium truncate flex-1",children:s.name}),e.jsx("span",{className:"text-xs opacity-70 flex-shrink-0",children:Re[s.id]||0}),e.jsxs(jt,{children:[e.jsx(vt,{asChild:!0,onClick:a=>a.stopPropagation(),children:e.jsx(h,{variant:"ghost",size:"icon",className:`h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0 ${(c==null?void 0:c.id)===s.id?"text-white hover:bg-blue-600":"text-slate-400 hover:text-white hover:bg-slate-600"}`,children:e.jsx(yt,{className:"w-3 h-3"})})}),e.jsxs(_t,{align:"end",className:"bg-slate-800 border-slate-700",children:[e.jsxs(ue,{onClick:a=>{a.stopPropagation(),he(s.id),W(s.name)},className:"text-slate-300 focus:text-white focus:bg-slate-700",children:[e.jsx(ft,{className:"w-4 h-4 mr-2"}),"Rename"]}),e.jsxs(ue,{onClick:a=>{a.stopPropagation(),Kt(s)},className:"text-red-400 focus:text-red-400 focus:bg-red-500/10",children:[e.jsx(Nt,{className:"w-4 h-4 mr-2"}),"Delete"]})]})]})]})},s.id))]})}),e.jsxs("div",{className:"flex-1",children:[He?e.jsx("div",{className:"flex items-center justify-center h-64",children:e.jsx("div",{className:"animate-spin w-8 h-8 border-2 border-blue-500 border-t-transparent roun
1ded-full"})}):q.length>0?e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:q.map(s=>e.jsxs("div",{className:"bg-slate-800/50 border border-slate-700/50 rounded-xl p-4 hover:border-blue-500/50 transition-all relative group",children:[e.jsxs("div",{onClick:()=>qt(s),className:"space-y-3 cursor-pointer",children:[s.product_image_url?e.jsx("img",{src:s.product_image_url,alt:"",className:"w-full h-32 object-contain rounded-lg bg-slate-900"}):e.jsx("div",{className:"w-full h-32 rounded-lg bg-slate-900 flex items-center justify-center",children:e.jsx(K,{className:"w-8 h-8 text-slate-600"})}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold text-white truncate",children:s.product_title||"Untitled"}),e.jsx("p",{className:"text-sm text-slate-400 truncate",children:s.brand_name||"No brand"})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(Ge,{className:s.tiktok_status==="complete"?"bg-green-500/20 text-green-400 border-green-500/30":s.tiktok_status==="processing"?"bg-amber-500/20 text-amber-400 border-amber-500/30":s.tiktok_status==="failed"?"bg-red-500/20 text-red-400 border-red-500/30":"bg-slate-500/20 text-slate-400 border-slate-500/30",children:s.tiktok_status||"draft"}),e.jsx("span",{className:"text-xs text-slate-500",children:new Date(s.created_at).toLocaleDateString()})]})]}),e.jsxs(jt,{children:[e.jsx(vt,{asChild:!0,onClick:a=>a.stopPropagation(),children:e.jsx(h,{variant:"ghost",size:"icon",className:"absolute top-2 right-2 h-8 w-8 opacity-0 group-hover:opacity-100 transition-opacity text-slate-400 hover:text-white",children:e.jsx(yt,{className:"w-4 h-4"})})}),e.jsxs(_t,{align:"end",className:"bg-slate-800 border-slate-700",children:[e.jsxs(ue,{onClick:a=>{a.stopPropagation(),nt(s,null)},className:"text-slate-300 focus:text-white focus:bg-slate-700",children:[e.jsx(K,{className:"w-4 h-4 mr-2"}),"Move to All Projects"]}),Je.map(a=>e.jsxs(ue,{onClick:o=>{o.stopPropagation(),nt(s,a.id)},className:"text-slate-300 focus:text-white focus:bg-slate-700",children:[e.jsx(Oe,{className:"w-4 h-4 mr-2"}),"Move to ",a.name]},a.id)),e.jsxs(ue,{onClick:a=>{a.stopPropagation(),zt(s)},className:"text-red-400 focus:text-red-400 focus:bg-red-500/10",children:[e.jsx(Nt,{className:"w-4 h-4 mr-2"}),"Delete Project"]})]})]})]},s.id))}):e.jsxs("div",{className:"flex flex-col items-center justify-center h-64 text-center",children:[e.jsx("div",{className:"w-16 h-16 rounded-full bg-slate-700/50 flex items-center justify-center mb-4",children:e.jsx(K,{className:"w-8 h-8 text-slate-500"})}),e.jsx("p",{className:"text-slate-400 mb-4",children:"No projects in this folder"}),e.jsxs(h,{onClick:it,className:"bg-blue-500 hover:bg-blue-600",children:[e.jsx(gt,{className:"w-4 h-4 mr-2"}),"Create your first project"]})]}),t>1&&e.jsxs("div",{className:"flex items-center justify-center gap-4 mt-6 pt-4 border-t border-slate-700/50",children:[e.jsx(h,{variant:"outline",size:"sm",onClick:()=>ce(s=>Math.max(0,s-1)),disabled:y===0,className:"border-slate-600 hover:bg-slate-700 disabled:opacity-40",children:"← Previous"}),e.jsxs("span",{className:"text-sm text-slate-400",children:["Page ",y+1," of ",t]}),e.jsx(h,{variant:"outline",size:"sm",onClick:()=>ce(s=>Math.min(t-1,s+1)),disabled:y>=t-1,className:"border-slate-600 hover:bg-slate-700 disabled:opacity-40",children:"Next →"})]})]})]}),Ft&&e.jsx(ms,{onClose:()=>Me(!1),onCreate:Yt})]})}return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs(h,{variant:"ghost",onClick:Vt,className:"text-slate-400 hover:text-white",children:[e.jsx(K,{className:"w-4 h-4 mr-2"}),"Back to Projects"]}),e.jsx("div",{className:"h-6 w-px bg-slate-700"}),Ut?e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(bt,{value:C,onChange:t=>Te(t.target.value),className:"w-64 bg-slate-800 border-slate-600 text-white text-xl font-bold",autoFocus:!0,onKeyDown:t=>{t.key==="Enter"&&(_e(!1),Ie()),t.key==="Escape"&&_e(!1)}}),e.jsx(h,{size:"icon",variant:"ghost",onClick:()=>{_e(!1),Ie()},className:"text-green-400 hover:text-green-300",children:e.jsx(xt,{className:"w-4 h-4"})})]}):e.jsxs("div",{className:"flex items-center gap-2 group cursor-pointer",onClick:()=>_e(!0),"data-tour":"project-name",children:[e.jsx("span",{className:"text-xl font-bold text-white",children:C}),e.jsx(ft,{className:"w-4 h-4 text-slate-500 opacity-0 group-hover:opacity-100 transition-opacity"})]}),i&&e.jsx(Ge,{className:i.tiktok_status==="complete"?"bg-green-500/20 text-green-400":i.tiktok_status==="processing"?"bg-amber-500/20 text-amber-400":"bg-slate-500/20 text-slate-400",children:i.tiktok_status||"draft"})]}),e.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[e.jsxs("div",{className:"flex items-center gap-2 px-3 py-1.5 bg-amber-500/10 border border-amber-500/20 rounded-lg","data-tour":"token-balance",children:[e.jsx(ht,{className:"w-4 h-4 text-amber-400"}),e.jsx("span",{className:"text-amber-400 font-medium",children:_})]}),e.jsxs(h,{onClick:()=>Ie(),disabled:Ye,variant:"outline",className:"border-slate-700 hover:bg-slate-800","data-tour":"save-button",children:[e.jsx(bs,{className:"w-4 h-4 mr-2"}),Ye?"Saving...":"Save Project"]}),i&&e.jsxs(h,{onClick:Ht,variant:"outline",className:"border-slate-700 hover:bg-slate-800","data-tour":"download-all",children:[e.jsx(kt,{className:"w-4 h-4 mr-2"}),"Download"]}),(i==null?void 0:i.tiktok_status)==="complete"&&e.jsxs(h,{onClick:Xt,variant:"outline",className:"border-purple-700 hover:bg-purple-900/30 text-purple-400",children:[e.jsx(It,{className:"w-4 h-4 mr-2"}),"Match Fonts"]}),e.jsxs(h,{onClick:Wt,disabled:Rt||Ct.maintenance_mode&&!Et||!w||!b||!f||_<90,className:"bg-gradient-to-r from-pink-500 to-purple-600 hover:from-pink-600 hover:to-purple-700","data-tour":"generate-all",children:[e.jsx(pt,{className:"w-4 h-4 mr-2"}),((mt=i==null?void 0:i.tiktok_hero_images)==null?void 0:mt.length)>0?"Regenerate All (90 tokens)":"Generate All (90 tokens)"]})]})]}),e.jsx("div",{className:"px-3 py-2 bg-amber-500/10 border border-amber-500/30 rounded-lg",children:e.jsxs("p",{className:"text-xs text-amber-300",children:[e.jsx("span",{className:"font-medium",children:"AI Disclaimer:"})," Generated images may contain inaccurate packaging, labels, text, or product details. Always review and verify images before using in your listings. Use at your own risk. As AI models improve, we will update."," ",e.jsx("a",{href:"/disclaimer",target:"_blank",className:"text-amber-400 hover:text-amber-300 underline font-medium",children:"Learn more"})]})}),(()=>{const t=[];return b||t.push("Brand Name"),f||t.push("Keywords"),_<90&&t.push("90+ Tokens"),j?I||t.push("Product Description"):(!N||!vs(N))&&t.pu
1sh("Valid ASIN"),t.length>0?e.jsxs("p",{className:"text-xs text-amber-400",children:["Missing: ",t.join(", ")]}):null})(),e.jsxs("div",{className:"flex gap-6 flex-col lg:flex-row",children:[e.jsxs("div",{className:"lg:w-80 flex-shrink-0 space-y-4",children:[e.jsx(us,{afterProductImage:e.jsxs("div",{className:"space-y-2",children:[e.jsxs(ds,{className:"flex items-center gap-2",children:[e.jsx(kt,{className:"w-4 h-4 text-blue-400"}),"Reference Listing Images Project ",e.jsx("span",{className:"text-slate-500 text-xs",children:"(optional)"})]}),e.jsxs(ns,{value:J||"none",onValueChange:t=>Jt(t==="none"?null:t),children:[e.jsx(os,{className:J?"border-blue-500/50":"border-slate-700",children:e.jsx(ls,{placeholder:"Select a listing images project..."})}),e.jsxs(cs,{children:[e.jsx(wt,{value:"none",children:"— Select a project —"}),Ue.map(t=>e.jsx(wt,{value:t.id,children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"truncate",children:t.product_title||t.brand_name||"Untitled"}),t.brand_style_guide&&e.jsx(Ge,{className:"text-xs bg-green-500/20 text-green-400",children:"Research"})]})},t.id))]})]}),Pe&&e.jsxs("div",{className:"p-2 bg-blue-500/10 border border-blue-500/20 rounded text-xs text-blue-400",children:["Using research from: ",e.jsx("strong",{children:Pe.product_title||Pe.brand_name})]}),!J&&e.jsx("p",{className:"text-xs text-slate-500",children:"Skip to let TikTok auto-research from your keywords, or import to inherit brand style + competitor signal."})]}),productImage:w,setProductImage:H,listingUrl:N,setListingUrl:fe,brandName:b,setBrandName:Z,category:F,setCategory:Q,productTitle:xe,setProductTitle:X,features:f,setFeatures:ee,brandIdentity:P,setBrandIdentity:te,targetAudience:U,setTargetAudience:se,competitors:O,setCompetitors:be,isNewListing:j,setIsNewListing:je,productDescription:I,setProductDescription:ae,marketplace:D,setMarketplace:ve,referenceImages:E,setReferenceImages:ie,imageModel:ye,setImageModel:Fe}),e.jsx(gs,{styleGuide:A,onChange:R,onSave:ts,isEditable:!!(i!=null&&i.id)}),!1]}),e.jsx("div",{className:"flex-1 space-y-6","data-tour":"image-output-area",children:(()=>{var s;const t=(i==null?void 0:i.tiktok_status)==="complete";return e.jsxs(e.Fragment,{children:[e.jsx(ps,{images:(i==null?void 0:i.tiktok_hero_images)||[],prompt:(s=i==null?void 0:i.image_prompts)==null?void 0:s.main,onEdit:ct,onCreateMore:()=>dt("main",(i==null?void 0:i.tiktok_hero_images)||[]),onUpload:ot,onDelete:lt,hasGeneratedImages:t,onSelectedIndexChange:a=>Ne(o=>({...o,main:a}))}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4",children:St.map(a=>{var o;return e.jsx("div",{children:e.jsx(hs,{imageType:a,images:(i==null?void 0:i[S(a.id)])||[],prompt:(o=i==null?void 0:i.image_prompts)==null?void 0:o[a.id],onEdit:ct,onCreateMore:()=>dt(a.id,(i==null?void 0:i[S(a.id)])||[]),onUpload:ot,onDelete:lt,hasGeneratedImages:t,onSelectedIndexChange:d=>Ne(m=>({...m,[a.id]:d}))})},a.id)})})]})})()})]}),De&&e.jsx(fs,{image:De,projectId:i==null?void 0:i.id,onClose:()=>qe(null),onApply:async t=>{await Qt(t)},onImageAdded:t=>{const s=S(De.type);p(a=>({...a,[s]:t}))}}),we&&e.jsx(xs,{imageType:we.imageType,existingImages:we.existingImages,mainImages:(i==null?void 0:i.tiktok_hero_images)||[],productImage:w,projectReferenceImages:E,createMoreReferenceImages:((i==null?void 0:i.create_more_reference_images)||{})[we.imageType]||[],onSaveCreateMoreRefs:async(t,s)=>{if(!(i!=null&&i.id))return;const a={...i.create_more_reference_images||{},[t]:s};try{await l.projects.update(i.id,{create_more_reference_images:a}),p(o=>({...o,create_more_reference_images:a}))}catch(o){console.error("Failed to save create more refs:",o)}},onClose:()=>Le(null),onCreate:async t=>{await Zt(t),Le(null)}}),Bt&&e.jsx("div",{className:"fixed inset-0 bg-black/70 z-50 flex items-center justify-center p-4",onClick:()=>le(!1),children:e.jsxs("div",{className:"bg-slate-900 border border-slate-700 rounded-xl max-w-6xl w-full max-h-[90vh] overflow-y-auto p-8",onClick:t=>t.stopPropagation(),children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(It,{className:"w-6 h-6 text-purple-400"}),e.jsx("h2",{className:"text-xl font-bold text-white",children:"Match Fonts Across Images"})]}),e.jsx("button",{onClick:()=>le(!1),className:"text-slate-400 hover:text-white text-2xl",children:"×"})]}),e.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-4 mb-6",children:[e.jsxs("p",{className:"text-sm text-slate-300",children:["These are the currently selected images from your project. Choose one image as the ",e.jsx("span",{className:"text-purple-400 font-semibold",children:"font reference"})," — its font style (family, weight, color, effects) will be applied to all other selected images. The images themselves won't change, only the text styling."]}),e.jsx("p",{className:"text-xs text-slate-500 mt-2",children:"To change which image is used for each type, go back and select a different thumbnail in the project view before opening this modal."})]}),e.jsxs("div",{className:"mb-8",children:[e.jsx("h3",{className:"text-sm font-semibold text-purple-400 mb-3",children:"Step 1: Choose the font source image"}),e.jsx("p",{className:"text-xs text-slate-400 mb-4",children:"Click the image whose font style you want all other images to match."}),e.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-7 gap-5",children:de().map(t=>e.jsxs("div",{className:`relative rounded-xl border-2 cursor-pointer transition-all ${(x==null?void 0:x.type)===t.type?"border-purple-500 ring-2 ring-purple-500/40 scale-[1.03] shadow-lg shadow-purple-500/20":"border-slate-700 hover:border-slate-500"}`,onClick:()=>{Qe(t);const s={};
1de().forEach(a=>{a.type!==t.type&&(s[a.type]=!0)}),Ae(s)},children:[e.jsx("img",{src:t.url,alt:t.name,className:"w-full aspect-square object-contain bg-slate-800 rounded-t-xl"}),e.jsx("div",{className:"bg-slate-800 rounded-b-xl px-2 py-1.5",children:e.jsx("span",{className:"block text-xs text-center text-slate-300 font-medium truncate",children:t.name})}),(x==null?void 0:x.type)===t.type&&e.jsx("div",{className:"absolute -top-2 -right-2 bg-purple-500 text-white text-[10px] font-bold px-2.5 py-1 rounded-full shadow-lg",children:"REF"})]},t.type))})]}),x&&e.jsxs("div",{className:"mb-6",children:[e.jsx("h3",{className:"text-sm font-semibold text-blue-400 mb-3",children:"Step 2: Select images to apply the font to"}),e.jsx("p",{className:"text-xs text-slate-400 mb-2",children:"All images are selected by default. Click to deselect any you don't want to change."}),e.jsx("p",{className:"text-xs text-slate-500 mb-4",children:"These are the currently active images for each type. To use a different variation, close this modal, select it in the image carousel for that type, then reopen Match Fonts."}),e.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-3 lg:grid-cols-6 gap-5",children:de().filter(t=>t.type!==x.type).map(t=>e.jsxs("div",{className:`relative rounded-xl border-2 cursor-pointer transition-all ${$[t.type]?"border-blue-500 ring-2 ring-blue-500/40 scale-[1.03] shadow-lg shadow-blue-500/20":"border-slate-700 hover:border-slate-500 opacity-40"}`,onClick:()=>Ae(s=>({...s,[t.type]:!s[t.type]})),children:[e.jsx("img",{src:t.url,alt:t.name,className:"w-full aspect-square object-contain bg-slate-800 rounded-t-xl"}),e.jsx("div",{className:"bg-slate-800 rounded-b-xl px-2 py-1.5",children:e.jsx("span",{className:"block text-xs text-center text-slate-300 font-medium truncate",children:t.name})}),$[t.type]&&e.jsx("div",{className:"absolute top-2 right-2 bg-blue-500 rounded-full p-1 shadow-lg",children:e.jsx(xt,{className:"w-4 h-4 text-white"})})]},t.type))})]}),x&&e.jsxs("div",{className:"flex items-center justify-between pt-5 border-t border-slate-700",children:[e.jsxs("span",{className:"text-sm text-slate-400",children:["Cost: ",e.jsxs("span",{className:"text-amber-400 font-semibold text-base",children:[Object.values($).filter(Boolean).length*5," tokens"]})," ","(",Object.values($).filter(Boolean).length," image",Object.values($).filter(Boolean).length!==1?"s":""," × 5)"]}),e.jsxs("div",{className:"flex gap-3",children:[e.jsx(h,{variant:"outline",onClick:()=>le(!1),className:"border-slate-600",children:"Cancel"}),e.jsx(h,{onClick:es,disabled:Xe||Object.values($).filter(Boolean).length===0,className:"bg-purple-600 hover:bg-purple-700 px-6",children:Xe?"Starting...":"Match Fonts"})]})]})]})})]})}export{Js 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.