1import{j as e}from"./ui-CYi4GrVi.js";import{a as s}from"./react-vendor-CG7WfdSN.js";import{u as r,T as t,a,b as i,c as n,d as l,e as o}from"./table-Dni0kan0.js";import{u as d,S as c}from"./switch-nyTl9U0q.js";import{c as m,E as h,s as p,V as u,B as x,n as g,k as j,K as v,T as f,F as y,G as _,J as b,r as N}from"./index-iEuQkT4g.js";import{I as w}from"./input-D19wRQsy.js";import{S as k,a as S,b as A,c as C,d as q}from"./select-DGMTmxRf.js";import{S as z}from"./skeleton-B6QodLIn.js";import{A as L,a as O}from"./alert-BsDNiuWy.js";import{L as P}from"./loader-circle-BgawIOK8.js";import{S as T}from"./search-CyVLK_r3.js";import"./supabase-BrKiwD5U.js";import"./charts-ChniAfy4.js";import"./chevron-up-CnuaC_y6.js";import"./check-DOMrFRp9.js"; 2/** 3 * @license lucide-react v0.462.0 - ISC 4 * 5 * This source code is licensed under the ISC license. 6 * See the LICENSE file in the root directory of this source tree. 7 */const V=m("Rocket",[["path",{d:"M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z",key:"m3kijz"}],["path",{d:"m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z",key:"1fmvmk"}],["path",{d:"M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0",key:"1f8sc4"}],["path",{d:"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5",key:"qeys4"}]]),F=["name","description","image_urls","short_description","filter_options","pricing"];function M(e){const s={name:!!e.name?.trim(),description:!!e.description?.trim(),image_urls:Array.isArray(e.image_urls)&&e.image_urls.length>0,short_description:!!e.short_description?.trim(),filter_options:!!e.f
7ilter_options&&Object.keys(e.filter_options).length>0,pricing:!!e.pricing&&Object.keys(e.pricing).length>0},r=Object.keys(s).filter(e=>!s[e]);return{filled:F.length-r.length,total:F.length,missing:r}}const I="all";function K(){const{data:m,isLoading:F,error:K}=r({queryKey:["admin","vendors"],queryFn:async()=>{const[e,s]=await Promise.all([p.from("vendor_stats").select("vendor_id, vendor_type, name, is_visible, impressions_30d, clicks_30d, requests_30d, conversion_rate").neq("vendor_type","shop").order("vendor_type").order("name"),p.rpc("admin_get_featured_orders")]);if(e.error)throw e.error;const r=e.data??[],t=r.reduce((e,s)=>((e[s.vendor_type]??=[]).push(s.vendor_id),e),{}),a=await Promise.all(Object.entries(t).map(async([e,s])=>{const r=u[e];if(!r)return[];const{data:t}=await p.from(r).select("id, description, image_urls, short_description, filter_options, pricing").in("id",s);return t??[]})),i=new Map;for(const l of a)for(const e of l)i.set(e.id,{description:e.description??null,image_urls:e.image_urls??null,short_description:e.short_description??null,filter_options:e.filter_options??null,pricing:e.pricing??null});const n=new Map((s.data??[]).map(e=>[e.vendor_id,e.featured_order]));return r.map(e=>({...e,...i.get(e.vendor_id),conversion_rate:parseFloat(e.conversion_rate)||0,featured_order:n.get(e.vendor_id)??null}))},staleTime:12e4,retry:!1}),Z=function(){const e=h();return d({mutationFn:async({vendorId:e,vendorType:s,is_visible:r})=>{const t=u[s];if(!t)throw new Error(`Onbekend vendor type: ${s}`);const{error:a}=await p.from(t).update({is_visible:r}).eq("id",e);if(a)throw a},onSuccess:()=>{e.invalidateQueries({queryKey:["admin","vendors"]})}})}(),$=function(){const e=h();return d({mutationFn:async({vendorId:e,vendorType:s,featured_order:r})=>{const t=u[s];if(!t)throw new Error(`Onbekend vendor type: ${s}`);const{error:a}=await p.from(t).update({featured_order:r}).eq("id",e);if(a)throw a},onSuccess:()=>{e.invalidateQueries({queryKey:["admin","vendors"]})}})}(),B=d({mutationFn:async()=>{const{error:e}=await p.rpc("admin_trigger_vendor_build");if(e)throw e}}),[E,W]=s.useState(""),[D,G]=s.useState(I),[Q,R]=s.useState("hidden"),[H,J]=s.useState({}),[U,X]=s.useState({}),Y=s.useMemo(()=>[...new Set((m??[]).map(e=>e.vendor_type))].sort(),[m]),ee=s.useMemo(()=>m?m.filter(e=>{const s=D===I||e.vendor_type===D,r=!E||e.name.toLowerCase().includes(E.toLowerCase()),t="all"===Q||"visible"===Q&&e.is_visible||"hidden"===Q&&!e.is_visible;return s&&r&&t}).sort((e,s)=>M(s).filled-M(e).filled||e.vendor_type.localeCompare(s.vendor_type)||e.name.localeCompare(s.name,"nl")):[],[m,D,Q,E]),se=e=>{const s=e.vendor_id;return s in H?H[s]:s in U?null!=U[s]?String(U[s]):"":null!=e.featured_order?String(e.featured_order):""};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold text-gray-900",children:"Leveranciers"}),e.jsx("p",{className:"text-sm text-gray-500 mt-1",children:"Beheer zichtbaarheid en uitgelichte volgorde van alle leveranciers. Wijzigingen gaan elke nacht automatisch live op de website."})]}),e.jsxs(x,{onClick:async()=>{try{await B.mutateAsync(),N.success("Build gestart. De site is over een paar minuten bijgewerkt.")}catch(e){const s=e instanceof Error?e.message:"Onbekende fout.";N.error(`Publiceren mislukt: ${s}`)}},disabled:B.isPending,className:"shrink-0",children:[B.isPending?e.jsx(P,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(V,{className:"h-4 w-4 mr-2"}),"Publiceer nu"]})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-3",children:[e.jsxs("div",{className:"relative flex-1",children:[e.jsx(T,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400"}),e.jsx(w,{placeholder:"Zoek op naam...",value:E,onChange:e=>W(e.target.value),className:"pl-9"})]}),e.jsxs(k,{value:D,onValueChange:G,children:[e.jsx(S,{className:"w-full sm:w-52",children:e.jsx(A,{placeholder:"Alle types"})}),e.jsxs(C,{children:[e.jsx(q,{value:I,children:"Alle types"}),Y.map(s=>e.jsx(q,{value:s,children:g(s)},s))]})]}),e.jsxs(k,{value:Q,onValueChange:e=>R(e),children:[e.jsx(S,{className:"w-full sm:w-40",children:e.jsx(A,{})}),e.jsxs(C,{children:[e.jsx(q,{value:"all",children:"Alle"}),e.jsx(q,{value:"visible",children:"Zichtbaar"}),e.jsx(q,{value:"hidden",children:"Verborgen"})]})]})]}),e.jsx("div",{className:"bg-white rounded-lg border shadow-sm overflow-hidden",children:K?e.jsx(L,{className:"m-4 bg-red-50 border-red-200",children:e.jsx(O,{className:"text-red-700",children:"Fout bij laden van leveranciers. Controleer de RLS-policies in Supabase."})}):F?e.jsx("div",{className:"p-4 space-y-2",children:Array.from({length:6}).map((s,r)=>e.jsx(z,{className:"h-12 w-full"},r))}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"px-4 py-2 border-b bg-gray-50 text-xs text-gray-500",children:[ee.length," leverancier",1!==ee.length?"s":"","all"!==Q&&" · "+("hidden"===Q?"verborgen":"zichtbaar"),D!==I&&` · ${g(D)}`]}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(t,{children:[e.jsx(a,{children:e.jsxs(i,{children:[e.jsx(n,{children:"Naam"}),e.jsx(n,{children:"Type"}),e.jsx(n,{children:"Profiel"}),e.jsx(n,{className:"text-right",children:"Impressies (30d)"}),e.jsx(n,{className:"text-right",children:"Klikken (30d)"}),e.jsx(n,{className:"text-right",children:"Aanvragen (30d)"}),e.jsx(n,{className:"text-right w-28",children:"Volgorde"}),e.jsx(n,{className:"text-right",children:"Zichtbaar"})]})}),e.jsx(l,{children:0===ee.length?e.jsx(i,{children:e.jsx(o,{colSpan:8,className:"text-center text-gray-400 py-8",children:"Geen leveranciers gevonden"})}):ee.map(s=>{const{filled:r,total:t,missing:a}=M(s),n=r===t,l=n?"bg-green-500":r>=t-2?"bg-amber-400":"bg-red-400";return e.jsxs(i,{children:[e.jsx(o,{className:"font-medium",children:s.name}),e.jsx(o,{children:e.jsx(j,{variant:"outline",className:"text-xs",children:v[s.vendor_type]??s.vendor_type})}),e.jsx(o,{children:e.jsx(f,{delayDuration:100,children:e.jsxs(y,{children:[e.jsx(_,{asChild:!0,children:e.jsxs("div",{className:"flex items-center gap-2 cursor-default w-fit",children:[e.jsx("div",{className:"flex gap-0.5",children:Array.from({length:t}).map((s,t)=>e.jsx("div",{className:`h-2.5 w-2.5 rounded-sm ${t<r?l:"bg-gray-200"}`},t))}),e.jsxs("span",{className:"text-xs font-medium "+(n?"text-green-600":"text-gray-500"),children:[r,"/",t]})]})}),e.jsx(b,{side:"right",className:"text-xs",children:n?e.jsx("span",{children:"Profiel volledig"}):e.jsxs("div",{children:[e.jsx("p",{className:"font-medium mb-1",children:"Ontbreekt:"}),e.jsx("ul",{className:"space-y-0.5",children:a.map(s=>e.jsxs("li",{children:["⢠",s]},s))})]})})]})})}),e.jsx(o,{className:"text-right text-gray-600",children:s.impressions_30d.toLocaleStr
7ing("nl-NL")}),e.jsx(o,{className:"text-right text-gray-600",children:s.clicks_30d.toLocaleString("nl-NL")}),e.jsx(o,{className:"text-right text-gray-600",children:s.requests_30d}),e.jsx(o,{className:"text-right",children:e.jsx(w,{type:"text",inputMode:"numeric",className:"w-20 h-8 text-sm text-right ml-auto",placeholder:"â",value:se(s),onChange:e=>J(r=>({...r,[s.vendor_id]:e.target.value})),onBlur:()=>(async(e,s)=>{const r=H[e];if(void 0===r)return;const t=""===r?null:parseInt(r,10);if(""!==r&&isNaN(t))N.error("Volgorde moet een getal zijn.");else try{await $.mutateAsync({vendorId:e,vendorType:s,featured_order:t}),X(s=>({...s,[e]:t})),J(s=>{const r={...s};return delete r[e],r}),N.success("Volgorde opgeslagen")}catch{N.error("Opslaan mislukt.")}})(s.vendor_id,s.vendor_type)})}),e.jsx(o,{className:"text-right",children:e.jsx(c,{checked:s.is_visible,onCheckedChange:()=>(async(e,s,r)=>{try{await Z.mutateAsync({vendorId:e,vendorType:s,is_visible:!r}),N.success(r?"Verborgen":"Zichtbaar gezet")}catch{N.error("Wijziging mislukt.")}})(s.vendor_id,s.vendor_type,s.is_visible),disabled:Z.isPending})})]},s.vendor_id)})})]})})]})})]})}export{K as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.