PageSourceSearch

https://snapio.ai/assets/ManagerAssetsPage-vN92Khu_.js

js snapio.ai collected 2026-10-05 14:41:03 UTC 21,570 bytes, 1 lines download raw bytes

1import{F as Ge,r as l,l as Je,ab as te,j as e,B as r,aH as D,U as We,R as _e,t as Ze,v as Xe,X as ae,b7 as ne,aw as q,aP as T,I as Ye,aG as ke,W as es,a5 as ze,b0 as ss,a4 as ts,G as le,H as re,J as ie,K as ce,aZ as as,Z as oe,b3 as de,bf as Fe,a7 as Pe,aQ as V,ae as me,a6 as ns}from"./index-BSiIgY1-.js";import{P as ls}from"./progress-Dl3ybV_L.js";import{C as rs}from"./copy-CUOwVQ9R.js";import{C as is}from"./chevrons-up-down-CN5-ch52.js";function g(a){if(!a||a===0)return"—";const i=1024,h=["B","KB","MB","GB"],j=Math.floor(Math.log(a)/Math.log(i));return parseFloat((a/Math.pow(i,j)).toFixed(1))+" "+h[j]}function cs(a){return new Date(a).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"})}function f(a){return a==null?void 0:a.startsWith("video/")}function Ue(a){var i;return((i=a==null?void 0:a.split("/")[1])==null?void 0:i.toUpperCase().replace("JPEG","JPG"))||"?"}function os({bytes:a}){if(!a)return e.jsx("span",{className:"text-muted-foreground text-sm",children:"—"});const i=a/(1024*1024),h=a/1024;return i>=1?e.jsx("span",{className:"font-semibold text-red-500 dark:text-red-400 text-sm",children:g(a)}):h>=300?e.jsx("span",{className:"font-medium text-amber-500 dark:text-amber-400 text-sm",children:g(a)}):e.jsx("span",{className:"text-sm text-muted-foreground",children:g(a)})}function H({col:a,sortKey:i,sortDir:h}){return a!==i?e.jsx(is,{className:"h-3.5 w-3.5 opacity-30 ml-1"}):h==="asc"?e.jsx(ns,{className:"h-3.5 w-3.5 ml-1 text-primary"}):e.jsx(Pe,{className:"h-3.5 w-3.5 ml-1 text-primary"})}function fs(){const{toast:a}=Ge(),[i,h]=l.useState(""),[j,De]=l.useState(""),[b,G]=l.useState(0),[xe,ue]=l.useState(!1),[he,pe]=l.useState(!1),[fe,Te]=l.useState(!1),B=100,[u,Be]=l.useState("fileSize"),[z,ge]=l.useState("desc"),[N,Ae]=l.useState({}),[y,x]=l.useState(new Set),[F,A]=l.useState(null),[w,U]=l.useState([]),[m,$]=l.useState(null),[J,je]=l.useState(75),[$e,Ne]=l.useState(!1),[W,Ie]=l.useState(75),[o,P]=l.useState(null),[Me,ye]=l.useState(null),I=l.useRef(null),[we,ve]=l.useState(!1),_=l.useRef(!1);l.useEffect(()=>{const s=setTimeout(()=>{De(i),G(0)},300);return()=>clearTimeout(s)},[i]),l.useEffect(()=>{x(new Set)},[b,j]);const{data:S,isLoading:Z,refetch:Oe}=Je({queryKey:["/api/manager/assets/all-files","manager_asset",j,b],queryFn:async()=>{const s=new URLSearchParams({usageContext:"manager_asset",limit:B.toString(),offset:(b*B).toString(),sortBy:"size_desc"});j&&s.set("search",j);const t=await fetch(`/api/manager/assets/all-files?${s}`);if(!t.ok)throw new Error("Failed to fetch");return t.json()}}),M=(S==null?void 0:S.files)||[];l.useEffect(()=>{if(M.length===0)return;const s=M.filter(t=>N[t.id]===void 0).map(t=>t.id);s.length!==0&&fetch("/api/manager/assets/batch-usage",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({fileIds:s})}).then(t=>t.json()).then(t=>{t.usage&&Ae(n=>({...n,...t.usage}))}).catch(()=>{})},[M]);const c=[...M].sort((s,t)=>{let n=0;return u==="fileSize"?n=s.fileSize-t.fileSize:u==="fileName"?n=s.fileName.localeCompare(t.fileName):u==="uploadedAt"?n=new Date(s.uploadedAt).getTime()-new Date(t.uploadedAt).getTime():u==="mimeType"&&(n=s.mimeType.localeCompare(t.mimeType)),z==="asc"?n:-n}).filter(s=>!(xe&&N[s.id]!==!1||he&&N[s.id]!==!0||fe&&s.fileSize<=300*1024)),X=(S==null?void 0:S.total)||0,O=Math.ceil(X/B),E=s=>{u===s?ge(t=>t==="asc"?"desc":"asc"):(Be(s),ge(s==="fileSize"?"desc":"asc"))},be=c.length>0&&c.every(s=>y.has(s.id)),Se=y.size>0,Ee=()=>{x(be?new Set:new Set(c.map(s=>s.id)))},Ke=s=>{x(t=>{const n=new Set(t);return n.has(s)?n.delete(s):n.add(s),n})},Ce=()=>{x(new Set(c.filter(s=>N[s.id]===!1).map(s=>s.id)))},Le=()=>{x(new Set(c.filter(s=>s.fileSize>300*1024&&!f(s.mimeType)).map(s=>s.id)))},C=c.filter(s=>y.has(s.id)),v=C.filter(s=>!f(s.mimeType)),k=C.filter(s=>f(s.mimeType)),K=c.filter(s=>N[s.id]===!1).length,L=c.filter(s=>s.fileSize>300*1024).length,Qe=c.reduce((s,t)=>s+(t.fileSize||0),0),Q=te({mutationFn:async s=>{const t=await fetch(`/api/manager/assets/check-usage/${s}`);if(!t.ok)throw new Error("Failed");return t.json()}}),Y=te({mutationFn:async({fileId:s,force:t})=>{await me("DELETE",`/api/manager/assets/${s}?force=${t}`)},onSuccess:()=>{V.invalidateQueries({queryKey:["/api/manager/assets/all-files"]}),a({title:"Asset deleted"}),A(null),U([])},onError:s=>a({title:"Failed to delete",description:s.message,variant:"destructive"})}),ee=te({mutationFn:async({fileId:s,quality:t})=>(await me("POST",`/api/manager/assets/compress/${s}`,{quality:t})).json(),onSuccess:s=>{V.invalidateQueries({queryKey:["/api/manager/assets/all-files"]}),a({title:s.savedBytes>0?"Compressed":"Already optimal",description:s.savedBytes>0?`Saved ${g(s.savedBytes)} (${s.savedPercent}%)`:void 0}),$(null)},onError:s=>a({title:"Compression failed",description:s.message,variant:"destructive"})}),Re=async s=>{A(s),U([]);try{const t=await Q.mutateAsync(s.id);U(t.usages||[])}catch{}},qe=async s=>{try{await navigator.clipboard.writeText(s.url),ye(s.id),setTimeout(()=>ye(null),2e3),a({title:"URL copied"})}catch{a({title:"Copy failed",variant:"destructive"})}},Ve=async s=>{var n;const t=(n=s.target.files)==null?void 0:n[0];if(t){ve(!0);try{const d=new FormData;if(d.append("file",t),!(await fetch("/api/manager/assets/upload",{method:"POST",body:d})).ok)throw new Error("Upload failed");V.invalidateQueries({queryKey:["/api/manager/assets/all-files"]}),a({title:"Asset uploaded"})}catch(d){a({title:"Upload failed",description:d.message,variant:"destructive"})}finally{ve(!1),I.current&&(I.current.value="")}}},He=async()=>{_.current=!1,P({current:0,total:C.length,results:[],done:!1,totalSaved:0});let s=0;const t=[];for(let n=0;n<C.length&&!_.current;n++){const d=C[n];P(p=>p?{...p,current:n+1}:null);try{const se=(await(await me("POST",`/api/manager/assets/compress/${d.id}`,{quality:f(d.mimeType)?void 0:W})).json()).savedBytes||0;s+=se,t.push({fileId:d.id,fileName:d.fileName,status:se>0?"done":"skipped",savedBytes:se})}catch(p){t.push({fileId:d.id,fileName:d.fileName,status:"error",savedBytes:0,error:p.message})}P({current:n+1,total:C.length,results:[...t],done:!1,totalSaved:s})}P(n=>n?{...n,done:!0}:null),V.invalidateQueries({queryKey:["/api/manager/assets/all-files"]}),x(new Set)},R=()=>{_.current=!0,Ne(!1),P(null)};return e.jsxs("div",{className:"container mx-auto p-6 space-y-5",children:[e.jsxs("div",{className:"flex items-center justify-between flex-wrap gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold",children:"Asset Manager"}),e.jsx("p",{className:"text-muted-foreground text-sm",children:"Manage manager-uploaded assets — track usage, find large files, compress"})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{ref:I,type:"file",accept:"image/*,video/*",className:"hidden",onChange:Ve}),e.jsxs(r,{variant:"outline",onClick:()=>{var s;return(s=I.current)==null?void 0:s.click()},disabled:we,children:[we?e.jsx(D,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(We,{className:"h-4 w-4 mr-2"}),"Upload"]}),e.jsxs(r,{variant:"outline",onClick:()=>Oe(),disabled:Z,children:[e.jsx(_e,{className:`h-4 w-4 mr-2 ${Z?"animate-spin":""}`}),"Reload"]})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-3 items-center",children:[e.jsxs("div",{className:"relative flex-1 min-w-[200px] max-w-sm",children:[e.jsx(Ze,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),e.jsx(Xe,{placeholder:"Search by filename…",value:i,onChange:s=>h(s.target.value),className:"pl-9"}),i&&e.jsx("button",{className:"absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",onClick:()=>h(""),children:e.jsx(ae,{className:"h-4 w-4"})})]}),e.jsxs(r,{variant:fe?"default":"outline",size:"sm",onClick:()=>Te(s=>!s),children:[e.jsx(ne,{className:"h-3.5 w-3.5 mr-1.5"}),"Large only",L>0&&e.jsx("span",{className:"ml-1.5 bg-amber-500 text-white text-[10px] px-1.5 py-0.5 rounded-full",children:L})]}),e.jsxs(r,{variant:he?"default":"outline",size:"sm",onClick:()=>{pe(s=>!s),ue(!1)},children:[e.jsx(q,{className:"h-3.5 w-3.5 mr-1.5"}),"Used only"]}),e.jsxs(r,{variant:xe?"default":"outline",size:"sm",onClick:()=>{ue(s=>!s),pe(!1)},children:[e.jsx(ae,{className:"h-3.5 w-3.5 mr-1.5"}),"Unused only",K>0&&e.jsx("span",{className:"ml-1.5 bg-gray-500 text-white text-[10px] px-1.5 py-0.5 rounded-full",children:K})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-x-6 gap-y-1 text-sm text-muted-foreground",children:[e.jsxs("span",{children:[c.length," asset",c.length!==1?"s":""," shown",X>B&&` (${X} total)`]}),e.jsxs("span",{className:"font-medium text-foreground",children:[g(Qe)," total"]}),L>0&&e.jsxs("span",{className:"text-amber-500 font-medium",children:[L," over 300 KB"]}),K>0&&e.jsxs("span",{className:"text-muted-foreground",children:[K," unused"]})]}),Se&&e.jsxs("div",{className:"flex flex-wrap items-center gap-3 bg-primary/5 border border-primary/20 rounded-lg px-4 py-3",children:[e.jsxs("span",{className:"text-sm font-medium",children:[y.size," selected",v.length>0&&` · ${v.length} image${v.length!==1?"s":""}`,k.length>0&&` · ${k.length} video${k.length!==1?"s":""}`]}),e.jsxs(r,{size:"sm",onClick:()=>Ne(!0),children:[e.jsx(T,{className:"h-3.5 w-3.5 mr-1.5"}),"Compress selected"]}),e.jsxs(r,{variant:"ghost",size:"sm",onClick:()=>x(new Set),children:[e.jsx(ae,{className:"h-3.5 w-3.5 mr-1"}),"Clear selection"]})]}),Z?e.jsx("div",{className:"flex items-center justify-center h-48",children:e.jsx(D,{className:"h-8 w-8 animate-spin text-muted-foreground"})}):c.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center h-48 text-muted-foreground border rounded-lg",children:[e.jsx(Ye,{className:"h-10 w-10 mb-3 opacity-40"}),e.jsx("p",{children:"No assets found"})]}):e.jsx("div",{className:"border rounded-lg overflow-hidden",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsxs("thead",{children:[e.jsxs("tr",{className:"bg-muted/50 border-b text-xs text-muted-foreground uppercase tracking-wide",children:[e.jsx("th",{className:"w-10 px-3 py-3",children:e.jsx(ke,{checked:be,onCheckedChange:Ee,"aria-label":"Select all"})}),e.jsx("th",{className:"w-14 px-2 py-3 text-left",children:"Preview"}),e.jsx("th",{className:"px-3 py-3 text-left cursor-pointer hover:text-foreground select-none",onClick:()=>E("fileName"),children:e.jsxs("span",{className:"flex items-center",children:["File name ",e.jsx(H,{col:"fileName",sortKey:u,sortDir:z})]})}),e.jsx("th",{className:"px-3 py-3 text-right cursor-pointer hover:text-foreground select-none w-28",onClick:()=>E("fileSize"),children:e.jsxs("span",{className:"flex items-center justify-end",children:["Size ",e.jsx(H,{col:"fileSize",sortKey:u,sortDir:z})]})}),e.jsx("th",{className:"px-3 py-3 text-left cursor-pointer hover:text-foreground select-none w-20",onClick:()=>E("mimeType"),children:e.jsxs("span",{className:"flex items-center",children:["Type ",e.jsx(H,{col:"mimeType",sort
1Key:u,sortDir:z})]})}),e.jsx("th",{className:"px-3 py-3 text-left w-24",children:e.jsxs("span",{className:"flex items-center gap-1",children:["Status",e.jsx("button",{className:"text-[10px] underline underline-offset-2 normal-case tracking-normal font-normal hover:text-foreground ml-1",onClick:Ce,title:"Select all unused",children:"sel unused"})]})}),e.jsx("th",{className:"px-3 py-3 text-left cursor-pointer hover:text-foreground select-none w-32",onClick:()=>E("uploadedAt"),children:e.jsxs("span",{className:"flex items-center",children:["Uploaded ",e.jsx(H,{col:"uploadedAt",sortKey:u,sortDir:z})]})}),e.jsx("th",{className:"px-3 py-3 text-right w-36",children:"Actions"})]}),e.jsx("tr",{className:"border-b bg-muted/20",children:e.jsx("td",{colSpan:8,className:"px-3 py-1.5",children:e.jsxs("div",{className:"flex gap-3 text-xs text-muted-foreground items-center",children:[e.jsx("span",{className:"font-medium",children:"Quick select:"}),e.jsx("button",{className:"hover:text-foreground underline underline-offset-2",onClick:Le,children:"Images > 300 KB"}),e.jsx("button",{className:"hover:text-foreground underline underline-offset-2",onClick:Ce,children:"All unused"}),e.jsx("button",{className:"hover:text-foreground underline underline-offset-2",onClick:()=>x(new Set(c.map(s=>s.id))),children:"All on page"}),Se&&e.jsx("button",{className:"hover:text-foreground underline underline-offset-2 text-muted-foreground/60",onClick:()=>x(new Set),children:"Clear"})]})})})]}),e.jsx("tbody",{className:"divide-y",children:c.map(s=>{const t=y.has(s.id),n=N[s.id],d=N[s.id]!==void 0,p=f(s.mimeType);return e.jsxs("tr",{className:`hover:bg-muted/30 transition-colors ${t?"bg-primary/5":""}`,children:[e.jsx("td",{className:"px-3 py-2",children:e.jsx(ke,{checked:t,onCheckedChange:()=>Ke(s.id),"aria-label":`Select ${s.fileName}`})}),e.jsx("td",{className:"px-2 py-2",children:e.jsx("div",{className:"w-10 h-10 rounded overflow-hidden bg-muted border flex-shrink-0 relative",children:p?e.jsx("div",{className:"w-full h-full flex items-center justify-center bg-gray-900",children:e.jsx(es,{className:"h-4 w-4 text-white"})}):e.jsx("img",{src:s.url,alt:"",className:"w-full h-full object-cover",loading:"lazy"})})}),e.jsx("td",{className:"px-3 py-2 max-w-xs",children:e.jsx("span",{className:"font-medium truncate block",title:s.fileName,children:s.fileName})}),e.jsx("td",{className:"px-3 py-2 text-right whitespace-nowrap",children:e.jsx(os,{bytes:s.fileSize})}),e.jsx("td",{className:"px-3 py-2",children:e.jsx("span",{className:"text-xs text-muted-foreground font-mono",children:Ue(s.mimeType)})}),e.jsx("td",{className:"px-3 py-2",children:d?n?e.jsx(ze,{variant:"secondary",className:"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 border-0 text-xs font-medium",children:"Used"}):e.jsx(ze,{variant:"secondary",className:"bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400 border-0 text-xs font-medium",children:"Unused"}):e.jsx("span",{className:"text-xs text-muted-foreground/50",children:"…"})}),e.jsx("td",{className:"px-3 py-2 text-xs text-muted-foreground whitespace-nowrap",children:cs(s.uploadedAt)}),e.jsx("td",{className:"px-3 py-2",children:e.jsxs("div",{className:"flex items-center justify-end gap-1",children:[e.jsx("button",{title:"Copy URL",className:"p-1.5 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors",onClick:()=>qe(s),children:Me===s.id?e.jsx(q,{className:"h-3.5 w-3.5 text-green-500"}):e.jsx(rs,{className:"h-3.5 w-3.5"})}),e.jsx("button",{title:"Open in new tab",className:"p-1.5 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors",onClick:()=>window.open(s.url,"_blank"),children:e.jsx(ss,{className:"h-3.5 w-3.5"})}),e.jsx("button",{title:"Compress",className:"p-1.5 rounded hover:bg-muted text-muted-foreground hover:text-foreground transition-colors",onClick:()=>{$(s),je(75)},children:e.jsx(T,{className:"h-3.5 w-3.5"})}),e.jsx("button",{title:"Delete",className:"p-1.5 rounded hover:bg-red-50 dark:hover:bg-red-950 text-muted-foreground hover:text-red-500 transition-colors",onClick:()=>Re(s),children:e.jsx(ts,{className:"h-3.5 w-3.5"})})]})})]},s.id)})})]})})}),O>1&&e.jsxs("div",{className:"flex items-center justify-center gap-2 pt-2",children:[e.jsx(r,{variant:"outline",size:"sm",onClick:()=>G(s=>Math.max(0,s-1)),disabled:b===0,children:"Previous"}),e.jsxs("span",{className:"text-sm text-muted-foreground px-4",children:["Page ",b+1," of ",O]}),e.jsx(r,{variant:"outline",size:"sm",onClick:()=>G(s=>Math.min(O-1,s+1)),disabled:b>=O-1,children:"Next"})]}),e.jsx(le,{open:!!F,onOpenChange:s=>{s||(A(null),U([]))},children:e.jsxs(re,{children:[e.jsxs(ie,{children:[e.jsxs(ce,{className:"flex items-center gap-2",children:[e.jsx(as,{className:"h-5 w-5 text-destructive"}),"Delete Asset"]}),e.jsx(oe,{children:F&&`"${F.fileName}"`})]}),e.jsxs("div",{className:"py-2 space-y-3",children:[Q.isPending&&e.jsxs("div",{className:"flex items-center gap-2 text-muted-foreground text-sm",children:[e.jsx(D,{className:"h-4 w-4 animate-spin"})," Checking usage…"]}),!Q.isPending&&w.length===0&&e.jsxs("div",{className:"flex items-center gap-2 text-green-600 dark:text-green-400 text-sm",children:[e.jsx(q,{className:"h-4 w-4"})," Not used anywhere — safe to delete."]}),w.length>0&&e.jsxs("div",{className:"bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg p-3 space-y-2",children:[e.jsxs("p",{className:"flex items-center gap-2 text-amber-700 dark:text-amber-400 font-medium text-sm",children:[e.jsx(ne,{className:"h-4 w-4 shrink-0"}),"Used in ",w.length," place",w.length!==1?"s":""]}
1),e.jsx("ul",{className:"text-xs text-amber-600 dark:text-amber-300 space-y-1 ml-6",children:w.map((s,t)=>e.jsxs("li",{className:"list-disc",children:[s.table,".",s.column," #",s.id,s.name&&` — ${s.name}`]},t))})]})]}),e.jsxs(de,{children:[e.jsx(r,{variant:"outline",onClick:()=>{A(null),U([])},children:"Cancel"}),e.jsx(r,{variant:"destructive",onClick:()=>F&&Y.mutate({fileId:F.id,force:w.length>0}),disabled:Y.isPending||Q.isPending,children:Y.isPending?e.jsxs(e.Fragment,{children:[e.jsx(D,{className:"h-4 w-4 mr-2 animate-spin"}),"Deleting…"]}):w.length>0?"Delete Anyway":"Delete"})]})]})}),e.jsx(le,{open:!!m,onOpenChange:s=>{s||$(null)},children:e.jsx(re,{className:"max-w-md",children:m&&e.jsxs(e.Fragment,{children:[e.jsxs(ie,{children:[e.jsx(ce,{children:"Compress Asset"}),e.jsx(oe,{className:"truncate",children:m.fileName})]}),e.jsxs("div",{className:"space-y-4 py-2",children:[e.jsx("div",{className:"bg-muted rounded-lg overflow-hidden flex items-center justify-center",style:{height:180},children:f(m.mimeType)?e.jsx("video",{src:m.url,controls:!0,className:"h-full object-contain"}):e.jsx("img",{src:m.url,alt:"",className:"h-full object-contain"})}),e.jsxs("div",{className:"flex gap-4 text-sm text-muted-foreground",children:[e.jsxs("span",{children:["Current size: ",e.jsx("strong",{className:"text-foreground",children:g(m.fileSize)})]}),e.jsxs("span",{children:["Format: ",e.jsx("strong",{className:"text-foreground",children:Ue(m.mimeType)})]})]}),!f(m.mimeType)&&e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"text-sm font-medium whitespace-nowrap w-16",children:"Quality"}),e.jsx(Fe,{value:[J],onValueChange:s=>je(s[0]),min:30,max:95,step:5,className:"flex-1"}),e.jsxs("span",{className:"text-sm font-bold w-10 text-right",children:[J,"%"]})]}),f(m.mimeType)&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"Video will be re-encoded with H.264 at up to 1080p."})]}),e.jsxs(de,{children:[e.jsx(r,{variant:"outline",onClick:()=>$(null),children:"Cancel"}),e.jsx(r,{onClick:()=>ee.mutate({fileId:m.id,quality:J}),disabled:ee.isPending,children:ee.isPending?e.jsxs(e.Fragment,{children:[e.jsx(D,{className:"h-4 w-4 mr-2 animate-spin"}),"Compressing…"]}):e.jsxs(e.Fragment,{children:[e.jsx(T,{className:"h-4 w-4 mr-2"}),"Compress"]})})]})]})})}),e.jsx(le,{open:$e,onOpenChange:s=>{s||R()},children:e.jsxs(re,{className:"max-w-lg",children:[e.jsxs(ie,{children:[e.jsxs(ce,{className:"flex items-center gap-2",children:[e.jsx(T,{className:"h-5 w-5"}),"Compress ",y.size," file",y.size!==1?"s":""]}),e.jsx(oe,{children:"Images are converted to WebP. Videos are re-encoded with H.264."})]}),e.jsxs("div",{className:"space-y-4 py-2",children:[v.length>0&&!o&&e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"text-sm font-medium whitespace-nowrap w-24",children:"Image quality"}),e.jsx(Fe,{value:[W],onValueChange:s=>Ie(s[0]),min:30,max:95,step:5,className:"flex-1"}),e.jsxs("span",{className:"text-sm font-bold w-10 text-right",children:[W,"%"]})]}),!o&&e.jsxs("ul",{className:"text-sm text-muted-foreground space-y-1",children:[v.length>0&&e.jsxs("li",{children:["· ",v.length," image",v.length!==1?"s":""," → WebP compression"]}),k.length>0&&e.jsxs("li",{children:["· ",k.length," video",k.length!==1?"s":""," → H.264 re-encode (slow)"]})]}),o&&e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsx("span",{className:"font-medium",children:o.done?"Finished":`Processing ${o.current} of ${o.total}…`}),o.totalSaved>0&&e.jsxs("span",{className:"text-green-600 font-semibold",children:[g(o.totalSaved)," saved"]})]}),e.jsx(ls,{value:o.current/o.total*100}),e.jsx("div",{className:"max-h-52 overflow-y-auto divide-y border rounded-md bg-muted/30",children:o.results.map(s=>e.jsxs("div",{className:"flex items-center gap-2 px-3 py-1.5 text-xs",children:[s.status==="done"&&e.jsx(q,{className:"h-3.5 w-3.5 text-green-500 shrink-0"}),s.status==="skipped"&&e.jsx(Pe,{className:"h-3.5 w-3.5 text-muted-foreground shrink-0"}),s.status==="error"&&e.jsx(ne,{className:"h-3.5 w-3.5 text-red-500 shrink-0"}),e.jsx("span",{className:"truncate flex-1",children:s.fileName}),s.status==="done"&&e.jsxs("span",{className:"text-green-600 shrink-0",children:["−",g(s.savedBytes)]}),s.status==="skipped"&&e.jsx("span",{className:"text-muted-foreground shrink-0",children:"already optimal"}),s.status==="error"&&e.jsx("span",{className:"text-red-500 shrink-0",children:"failed"})]},s.fileId))})]})]}),e.jsx(de,{children:o?o.done?e.jsx(r,{onClick:R,className:"flex-1",children:"Done"}):e.jsx(r,{variant:"outline",onClick:R,children:"Stop"}):e.jsxs(e.Fragment,{children:[e.jsx(r,{variant:"outline",onClick:R,children:"Cancel"}),e.jsxs(r,{onClick:He,children:[e.jsx(T,{className:"h-4 w-4 mr-2"})," Start Compressing"]})]})})]})})]})}export{fs 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.