1import{v as y,b as f,j as e,i,C as m,p as x,m as v,o as N,D as _,w as b,B as h,s as o}from"./index-Dge1Tx5E.js";import{C as p}from"./copy-CcqZ2hn6.js";import{U as w}from"./user-BMgFdDcI.js";import{C}from"./check-wzas0hBJ.js";import{T}from"./trash-2-DPzuZW0N.js";const $=()=>{const{toast:n}=y(),{data:c,isLoading:u,refetch:d}=f({queryKey:["admin-duplicates"],refetchInterval:12*60*60*1e3,queryFn:async()=>{const{data:t,error:r}=await o.rpc("find_duplicate_tools");if(r)throw r;const s=new Map;return t==null||t.forEach(a=>{const l=`${a.match_type}:${a.duplicate_group}`;s.has(l)||s.set(l,{group_key:a.duplicate_group,match_type:a.match_type,tools:[]}),s.get(l).tools.push(a)}),Array.from(s.values()).sort((a,l)=>l.tools.length-a.tools.length)}}),j=async(t,r)=>{try{const s=r.tools.filter(a=>a.tool_id!==t);for(const a of s){const{error:l}=await o.rpc("admin_reject_tool",{tool_id:a.tool_id});if(l)throw l}n({title:"Success",description:`Kept 1 tool and removed ${s.length} duplicates`}),d()}catch(s){n({title:"Error",description:s.message||"Failed to resolve duplicates",variant:"destructive"})}},g=async t=>{try{const{error:r}=await o.rpc("admin_reject_tool",{tool_id:t});if(r)throw r;n({title:"Success",description:"Tool removed successfully"}),d()}catch(r){n({title:"Error",description:r.message||"Failed to remove tool",variant:"destructive"})}};return u?e.jsxs("div",{className:"space-y-6",children:[e.jsx("h1",{className:"text-3xl font-bold",children:"Duplicate Tools"}),e.jsx("div",{className:"text-center py-20 text-gray-600",children:"Loading duplicates..."})]}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex justify-between items-center",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-3xl font-bold text-gray-900",children:"Duplicate Tools"}),e.jsx("p",{className:"text-gray-600 mt-2",children:"Tools with matching names or URLs that may be duplicates"})]}),e.jsxs(i,{variant:"secondary",className:"text-lg px-4 py-2",children:[(c==null?void 0:c.length)||0," duplicate groups found"]})]}),!c||c.length===0?e.jsx(m,{className:"text-center py-12",children:e.jsxs(x,{children:[e.jsx(p,{className:"w-16 h-16 text-gray-400 mx-auto mb-4"}),e.jsx("h3",{className:"text-xl font-semibold text-gray-600 mb-2",children:"No Duplicates Found"}),e.jsx("p",{className:"text-gray-500",children:"All tools appear to be unique"})]})}):e.jsx("div",{className:"space-y-6",children:c.map((t,r)=>e.jsxs(m,{className:"border-red-200 bg-red-50",children:[e.jsx(v,{children:e.jsxs(N,{className:"flex items-center gap-2 text-red-800",children:[e.jsx(p,{className:"w-5 h-5"}),"Duplicate Group ",r+1,e.jsx(i,{variant:"outline",className:"ml-2",children:t.match_type==="name"?`Same Name: ${t.group_key}`:`Same URL: ${t.group_key}`}),e.jsxs(i,{variant:"secondary",children:[t.tools.length," tools"]})]})}),e.jsx(x,{children:e.jsx("div",{className:"space-y-4",children:t.tools.map((s,a)=>e.jsxs("div",{className:"flex items-center justify-between p-4 bg-white rounded-lg border",children:[e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-2",children:[e.jsx("a",{href:`/tool/${s.tool_slug||s.tool_id}`,target:"_blank",rel:"noopener noreferrer",className:"font-semibold text-lg text-blue-700 hover:underline cursor-pointer",children:s.tool_name}),a===0&&e.jsx(i,{className:"bg-blue-100 text-blue-800",children:"Latest"}),e.jsx(i,{variant:"outline",children:s.tool_tier})]}),e.jsxs("div",{className:"space-y-1 text-sm text-gray-600",children:[s.tool_url&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(_,{className:"w-4 h-4"}),e.jsx("a",{href:s.tool_url,target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:underline truncate",children:s.tool_url})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(w,{className:"w-4 h-4"}),e.jsx("span",{children:s.user_name||s.user_email||"Unknown User"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(b,{className:"w-4 h-4"}),e.jsxs("span",{children:["Added ",new Date(s.tool_created_at).toLocaleDateString()]})]})]}),s.tool_description&&e.jsx("p",{className:"text-sm text-gray-700 mt-2 line-clamp-2",children:s.tool_description})]}),e.jsxs("div",{className:"flex gap-2 ml-4",children:[e.jsxs(h,{size:"sm",onClick:()=>j(s.tool_id,t),className:"bg-green-600 hover:bg-green-700",children:[e.jsx(C,{className:"w-4 h-4 mr-1"})," Keep This"]}),e.jsxs(h,{size:"sm",variant:"destructive",onClick:()=>g(s.tool_id),children:[e.jsx(T,{className:"w-4 h-4 mr-1"})," Remove"]})]})]},s.tool_id))})})]},r))})]})};export{$ 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.