PageSourceSearch

https://supboard-99.nl/assets/admin.reviews-Cd6VYF09.js

js supboard-99.nl collected 2026-10-04 13:19:45 UTC 13,034 bytes, 5 lines download raw bytes

1import{f as V,o as de,r as w,g as O,t as z,j as e,L as ce}from"./index-Do8mD6pF.js";import{u as B}from"./useMutation-B7Kpq7dq.js";import{a as ue,b as me,e as he,f as pe,t as xe}from"./admin.functions-H4BTKk5Q.js";import{B as x}from"./button-CoCXTVGk.js";import{I as fe}from"./input-RYdXA4TJ.js";import{C as J}from"./checkbox-YcY6TgAb.js";import{B as D}from"./badge-rJicgyJo.js";import{T as ge,a as ve,b as R,c as A,d as je,e as v}from"./table-Bs35C6ff.js";import{S as U,a as X,b as Y,c as ee,d as k}from"./select-DB8vudTy.js";import{T as be,a as te,b as se,c as ne}from"./tooltip-LyZy8asW.js";import{S as re}from"./star-Bi6S0Mf7.js";import{S as we}from"./search-Dyg-mmg-.js";import{F as ke}from"./funnel-DFvSLc8-.js";import{L as ae}from"./languages-CcvKkcK8.js";import{T as Ce}from"./trash-2-BQhj1Epk.js";import{E as Ne}from"./external-link-DnE10sVq.js";import"./index-CP5i-fIZ.js";import"./utils-BQHNewu7.js";import"./index-C2DUn5Tj.js";import"./index-C9S6YAR9.js";import"./index-D1QhAgz9.js";import"./index-BPiKO5TK.js";import"./check-CLaQp3W1.js";import"./createLucideIcon-CefKMquq.js";import"./index-CbYSbq0z.js";import"./index-ZGQFb1Lq.js";import"./index-DG86zuJb.js";import"./index-B-GIJM5U.js";import"./index-D9u8BhLz.js";import"./chevron-down-BjD882sW.js";function ye(N){if(!N)return"—";const L=Date.now()-new Date(N).getTime(),y=Math.floor(L/1e3);if(y<60)return"zojuist";const j=Math.floor(y/60);if(j<60)return`${j} min geleden`;const b=Math.floor(j/60);if(b<24)return`${b} u geleden`;const h=Math.floor(b/24);if(h<30)return`${h} d geleden`;const f=Math.floor(h/30);return f<12?`${f} mnd geleden`:`${Math.floor(f/12)} jr geleden`}function st(){const N=V(ue),L=V(me),y=V(he),j=V(pe),b=V(xe),h=de(),[f,G]=w.useState(""),[a,g]=w.useState("all"),[P,I]=w.useState("all"),[M,Q]=w.useState("updated_desc"),[u,_]=w.useState(new Set),{data:S=[],isLoading:H}=O({queryKey:["admin-reviews"],queryFn:()=>N()}),{data:K=[]}=O({queryKey:["admin-domains"],queryFn:()=>L()}),q=B({mutationFn:t=>y({data:{review_ids:Array.from(u),published:t}}),onSuccess:(t,r)=>{z.success(r?"Gepubliceerd":"Gedepubliceerd"),_(new Set),h.invalidateQueries({queryKey:["admin-reviews"]})},onError:t=>z.error(t.message)}),Z=B({mutationFn:()=>j({data:{review_ids:Array.from(u)}}),onSuccess:t=>{z.success(`${t.deleted} review(s) verwijderd`),_(new Set),h.invalidateQueries({queryKey:["admin-reviews"]})},onError:t=>z.error(t.message)}),$=B({mutationFn:async t=>{const r=Array.from(u);let i=0,l=0,o=0,c=0;const d=[];for(const n of r)try{const s=await b({data:{review_id:n,overwrite:t.overwrite,publish:t.publish}});i++,o+=s.updated??0,c+=s.skipped??0,s.errors?.length&&d.push(`${n}: ${s.errors.join("; ")}`)}catch(s){l++,d.push(`${n}: ${s.message}`)}return{ok:i,fail:l,updated:o,skipped:c,total:r.length,errs:d}},onSuccess:t=>{z.success(`Vertaald: ${t.ok}/${t.total} reviews — ${t.updated} talen bijgewerkt${t.skipped?`, ${t.skipped} overgeslagen`:""}${t.fail?`, ${t.fail} mislukt`:""}`),t.errs.length&&console.warn("Vertaal-issues:",t.errs),_(new Set),h.invalidateQueries({queryKey:["admin-reviews"]})},onError:t=>z.error(t.message)}),T=w.useMemo(()=>{const t=f.trim().toLowerCase();let r=S.filter(i=>{const l=i.review_translations??[];if(t&&!((i.product_name??"").toLowerCase()+" "+l.map(s=>`${s.h1??""} ${s.slug??""}`).join(" ").toLowerCase()).includes(t))return!1;const o=l.length,c=l.filter(n=>n.published).length,d=l.filter(n=>n.hasContent).length;if(P!=="all"){const n=l.find(s=>s.domain_id===P);return a==="published"?!!n?.published:a==="unpublished"?!!n&&!n.published:a==="empty"?!n:a==="with_content"?!!n?.hasContent:a==="no_content"?!!n&&!n.hasContent:!!n}return a==="empty"?o===0:a==="published"?o>0&&c===o:a==="partial"?c>0&&c<o:a==="unpublished"?o>0&&c===0:a==="with_content"?d>0:a==="no_content"?o>0&&d===0:!0});return r=[...r].sort((i,l)=>{switch(M){case"name_asc":return(i.product_name??"").localeCompare(l.product_name??"");case"updated_asc":return(new Date(i.updated_at).getTime()||0)-(new Date(l.updated_at).getTime()||0);case"pub_desc":{const o=(i.review_translations??[]).filter(d=>d.published).length;return(l.review_translations??[]).filter(d=>d.published).length-o}case"words_desc":{const o=(i.review_translations??[]).reduce((d,n)=>d+(n.wordCount??0),0);return(l.review_translations??[]).reduce((d,n)=>d+(n.wordCount??0),0)-o}default:return(new Date(l.updated_at).getTime()||0)-(new Date(i.updated_at).getTime()||0)}}),r},[S,f,a,P,M]),m=w.useMemo(()=>
1{let t=0,r=0,i=0,l=0,o=0,c=0;for(const d of S){const n=d.review_translations??[],s=n.length,p=n.filter(F=>F.published).length,E=n.filter(F=>F.hasContent).length;s===0?l++:p===s?t++:p===0?i++:r++,E>0?o++:s>0&&c++}return{total:S.length,pub:t,partial:r,unpub:i,empty:l,withContent:o,noContent:c}},[S]),W=T.length>0&&T.every(t=>u.has(t.id)),ie=()=>{const t=new Set(u);W?T.forEach(r=>t.delete(r.id)):T.forEach(r=>t.add(r.id)),_(t)},le=t=>{const r=new Set(u);r.has(t)?r.delete(t):r.add(t),_(r)},oe=()=>{G(""),g("all"),I("all"),Q("updated_desc")};return e.jsx(be,{delayDuration:150,children:e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-wrap items-end justify-between gap-4",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-bold flex items-center gap-2",children:[e.jsx(re,{className:"h-6 w-6"})," Reviews"]}),e.jsxs("p",{className:"text-sm text-muted-foreground mt-1",children:[m.total," reviews · ",m.pub," volledig live · ",m.partial," gedeeltelijk · ",m.unpub," concept · ",m.empty," zonder vertaling"]})]}),e.jsx(x,{asChild:!0,variant:"outline",children:e.jsx(ce,{to:"/admin/bulk-reviews",children:"+ Genereer nieuwe (Wayback + AI)"})})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(C,{active:a==="all",onClick:()=>g("all"),label:"Alles",count:m.total,tone:"muted"}),e.jsx(C,{active:a==="with_content",onClick:()=>g("with_content"),label:"Heeft content",count:m.withContent,tone:"success"}),e.jsx(C,{active:a==="no_content",onClick:()=>g("no_content"),label:"Leeg / geen content",count:m.noContent,tone:"destructive"}),e.jsx("span",{className:"w-px self-stretch bg-border mx-1"}),e.jsx(C,{active:a==="published",onClick:()=>g("published"),label:"Volledig live",count:m.pub,tone:"success"}),e.jsx(C,{active:a==="partial",onClick:()=>g("partial"),label:"Gedeeltelijk",count:m.partial,tone:"warning"}),e.jsx(C,{active:a==="unpublished",onClick:()=>g("unpublished"),label:"Alleen concept",count:m.unpub,tone:"muted"}),e.jsx(C,{active:a==="empty",onClick:()=>g("empty"),label:"Zonder vertaling",count:m.empty,tone:"destructive"})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 rounded-md border bg-background p-3",children:[e.jsxs("div",{className:"relative flex-1 min-w-[240px]",children:[e.jsx(we,{className:"absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground"}),e.jsx(fe,{value:f,onChange:t=>G(t.target.value),placeholder:"Zoek op productnaam, h1 of slug…",className:"pl-9"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ke,{className:"h-4 w-4 text-muted-foreground"}),e.jsxs(U,{value:P,onValueChange:I,children:[e.jsx(X,{className:"w-44",children:e.jsx(Y,{placeholder:"Domein"})}),e.jsxs(ee,{children:[e.jsx(k,{value:"all",children:"Alle domeinen"}),K.map(t=>e.jsx(k,{value:t.id,children:t.host},t.id))]})]}),e.jsxs(U,{value:M,onValueChange:t=>Q(t),children:[e.jsx(X,{className:"w-52",children:e.jsx(Y,{placeholder:"Sorteren"})}),e.jsxs(ee,{children:[e.jsx(k,{value:"updated_desc",children:"Laatst bijgewerkt"}),e.jsx(k,{value:"updated_asc",children:"Oudst bijgewerkt"}),e.jsx(k,{value:"name_asc",children:"Productnaam A → Z"}),e.jsx(k,{value:"pub_desc",children:"Meest gepubliceerd"}),e.jsx(k,{value:"words_desc",children:"Meeste content"})]})]}),(f||a!=="all"||P!=="all"||M!=="updated_desc")&&e.jsx(x,{variant:"ghost",size:"sm",onClick:oe,children:"Wis filters"})]})]}),u.size>0&&e.jsxs("div",{className:"flex flex-wrap items-center gap-2 rounded-md border border-primary/30 bg-primary/5 px-3 py-2 text-sm",children:[e.jsxs(D,{variant:"secondary",children:[u.size," geselecteerd"]}),e.jsx("div",{className:"flex-1"}),e.jsx(x,{size:"sm",variant:"outline",disabled:q.isPending,onClick:()=>q.mutate(!0),children:"Publiceer alle talen"}),e.jsx(x,{size:"sm",variant:"outline",disabled:q.isPending,onClick:()=>q.mutate(!1),children:"Depubliceer alle talen"}),e.jsxs(x,{size:"sm",variant:"outline",disabled:$.isPending,onClick:()=>{confirm(`Vertaal ${u.size} review(s) naar alle ontbrekende talen en publiceer ze?
2
3Bestaande vertalingen blijven ongewijzigd.`)&&$.mutate({overwrite:!1,publish:!0})},title:"Vult ontbrekende taalversies aan via AI en zet ze live",children:[e.jsx(ae,{className:"h-4 w-4"}),$.isPending?`Vertalen… (${u.size})`:"Vertaal + publiceer"]}),e.jsxs(x,{size:"sm",variant:"outline",disabled:$.isPending,onClick:()=>{confirm(`Overschrijf ALLE taalversies van ${u.size} review(s) met een nieuwe AI-vertaling?`)&&$.mutate({overwrite:!0,publish:!0})},children:[e.jsx(ae,{className:"h-4 w-4"}),$.isPending?"Vertalen…":"Hervertaal alles"]}),e.jsxs(x,{size:"sm",variant:"destructive",disabled:Z.isPending,onClick:()=>{confirm(`${u.size} review(s) definitief verwijderen?
4
5Alle vertalingen gaan verloren.`)&&Z.mutate()},children:[e.jsx(Ce,{className:"h-3.5 w-3.5 mr-1"}),"Verwijder"]}),e.jsx(x,{size:"sm",variant:"ghost",onClick:()=>
5_(new Set),children:"Annuleer"})]}),e.jsx("div",{className:"rounded-md border bg-background",children:e.jsxs(ge,{children:[e.jsx(ve,{children:e.jsxs(R,{children:[e.jsx(A,{className:"w-10",children:e.jsx(J,{checked:W,onCheckedChange:ie})}),e.jsx(A,{children:"Review"}),e.jsx(A,{className:"w-44",children:"Content"}),e.jsx(A,{children:"Status per domein"}),e.jsx(A,{className:"w-36",children:"Bijgewerkt"}),e.jsx(A,{className:"text-right w-32",children:"Acties"})]})}),e.jsxs(je,{children:[H&&e.jsx(R,{children:e.jsx(v,{colSpan:6,className:"text-center py-12 text-muted-foreground",children:"Laden…"})}),!H&&T.length===0&&e.jsx(R,{children:e.jsx(v,{colSpan:6,className:"text-center py-12 text-muted-foreground",children:S.length===0?"Nog geen reviews. Genereer er via Bulk-reviews.":"Geen reviews voor deze filters."})}),T.map(t=>{const r=t.review_translations??[],i=r[0]?.slug??null,l=r[0]?.h1??null,o=r.filter(s=>s.hasContent).length,c=r.length,d=r.reduce((s,p)=>s+(p.wordCount??0),0),n=t.product_name??l??"Zonder product";return e.jsxs(R,{"data-state":u.has(t.id)?"selected":void 0,children:[e.jsx(v,{onClick:s=>s.stopPropagation(),children:e.jsx(J,{checked:u.has(t.id),onCheckedChange:()=>le(t.id)})}),e.jsx(v,{children:e.jsxs("div",{className:"space-y-0.5",children:[e.jsxs("div",{className:"font-medium",children:[n,t.rating!=null&&e.jsxs("span",{className:"ml-2 inline-flex items-center gap-0.5 text-xs text-amber-600",children:[e.jsx(re,{className:"h-3 w-3 fill-current"})," ",Number(t.rating).toFixed(1)]})]}),e.jsx("div",{className:"font-mono text-xs text-muted-foreground",children:i?`/${i.replace(/^\//,"")}`:"—"})]})}),e.jsx(v,{children:c===0?e.jsx("span",{className:"text-xs text-muted-foreground italic",children:"geen vertalingen"}):o===0?e.jsx(D,{variant:"outline",className:"border-destructive/40 text-destructive",children:"✕ leeg"}):e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(D,{className:"bg-emerald-600 hover:bg-emerald-700",children:["✓ ",o,"/",c]}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[d," woorden"]})]})}),e.jsx(v,{children:e.jsx("div",{className:"flex flex-wrap gap-1",children:K.map(s=>{const p=r.find(F=>F.domain_id===s.id);if(!p)return e.jsxs(te,{children:[e.jsx(se,{asChild:!0,children:e.jsx(D,{variant:"outline",className:"border-dashed text-muted-foreground",children:s.locale})}),e.jsxs(ne,{children:["Geen vertaling op ",s.host]})]},s.id);const E=p.published;return e.jsxs(te,{children:[e.jsx(se,{asChild:!0,children:e.jsx(D,{variant:"outline",className:E?"border-emerald-500/50 text-emerald-700 bg-emerald-50":"border-amber-500/50 text-amber-700 bg-amber-50",children:s.locale})}),e.jsxs(ne,{children:[E?"Live":"Concept"," op ",s.host,p.slug&&e.jsxs("div",{className:"font-mono text-xs",children:["/",p.slug.replace(/^\//,"")]})]})]},s.id)})})}),e.jsx(v,{className:"text-xs text-muted-foreground",children:ye(t.updated_at)}),e.jsx(v,{className:"text-right",children:i&&e.jsx(x,{asChild:!0,size:"sm",variant:"ghost",children:e.jsx("a",{href:`/${i.replace(/^\//,"")}`,target:"_blank",rel:"noreferrer",children:e.jsx(Ne,{className:"h-4 w-4"})})})})]},t.id)})]})]})})]})})}function C({active:N,onClick:L,label:y,count:j,tone:b}){const h=N?{muted:"bg-foreground text-background",success:"bg-emerald-600 text-white",warning:"bg-amber-500 text-white",destructive:"bg-destructive text-destructive-foreground"}[b]:"bg-muted text-foreground hover:bg-muted/70";return e.jsxs("button",{onClick:L,className:`inline-flex items-center gap-2 rounded-full px-3 py-1 text-xs font-medium transition ${h}`,children:[y,e.jsx("span",{className:"rounded-full bg-background/20 px-1.5 py-0.5 text-[10px]",children:j})]})}export{st 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.