PageSourceSearch

https://careerplatform.io/assets/admin.reviews-v7wKt5VG.js

js careerplatform.io collected 2026-09-24 15:05:59 UTC 7,264 bytes, 1 lines download raw bytes

1import{a as b,bx as P,by as D,bz as Q,bA as E,b0 as L,e as B,r as x,f as w,j as e,b8 as F,b9 as z,ba as K,be as M,a9 as $,bf as U,bg as H,bh as T,bi as a,bj as I,bk as n,S as O,b6 as G,G as V,B as j,bB as J,b1 as W,u as X,s as q,L as Y,t as u}from"./index-DNidg_Qc.js";const Z=[{value:"all",label:"All"},{value:"pending",label:"Pending"},{value:"approved",label:"Approved"},{value:"rejected",label:"Rejected"}];function ae(){const r=X(),[c,l]=x.useState("checking");return x.useEffect(()=>{(async()=>{const{data:g}=await q.auth.getUser(),t=g?.user?.id;if(!t){r({to:"/auth"});return}const{data:d}=await q.from("user_roles").select("role").eq("user_id",t).eq("role","admin").maybeSingle();l(d?"ok":"denied")})()},[r]),c==="checking"?e.jsx("div",{className:"container mx-auto max-w-6xl px-4 py-10 text-sm text-muted-foreground",children:"Checking access…"}):c==="denied"?e.jsx("div",{className:"container mx-auto max-w-6xl px-4 py-10 text-sm text-destructive",children:"Access denied - you are not an admin."}):e.jsxs("div",{className:"container mx-auto max-w-6xl px-4 py-10",children:[e.jsx(Y,{to:"/admin",className:"inline-flex items-center text-sm text-muted-foreground hover:text-foreground mb-6",children:"← Back to admin"}),e.jsx(ee,{})]})}function ee(){const r=b(P),c=b(D),l=b(Q),g=b(E),t=L(),d=B({queryKey:["admin","reviews"],queryFn:()=>r({data:void 0})}),h=d.data?.reviews??[],N=h.filter(s=>s.status==="pending").length,[p,_]=x.useState("pending"),[A,C]=x.useState({}),y=x.useMemo(()=>p==="all"?h:h.filter(s=>s.status===p),[h,p]),v=w({mutationFn:s=>c({data:s}),onMutate:async s=>{await t.cancelQueries({queryKey:["admin","reviews"]});const m=t.getQueryData(["admin","reviews"]);return t.setQueryData(["admin","reviews"],i=>i&&{reviews:i.reviews.map(o=>o.id===s.id?{...o,status:s.status}:o)}),{prev:m}},onError:(s,m,i)=>{i?.prev&&t.setQueryData(["admin","reviews"],i.prev),u.error(s.message||"Update failed")},onSuccess:()=>t.invalidateQueries({queryKey:["admin","reviews"]})}),k=w({mutationFn:s=>l({data:{id:s}}),onSuccess:()=>{u.success("Photo removed"),t.invalidateQueries({queryKey:["admin","reviews"]})},onError:s=>u.error(s.message||"Failed to remove photo")}),R=w({mutationFn:s=>g({data:{id:s}}),onSuccess:()=>{u.success("Review deleted"),t.invalidateQueries({queryKey:["admin","reviews"]})},onError:s=>u.error(s.message||"Failed to delete")});return e.jsxs("div",{children:[e.jsx("div",{className:"flex items-end justify-between gap-4 mb-6 flex-wrap",children:e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-bold",children:"Review queue"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"Approve or reject user-submitted reviews. Approved reviews appear on the homepage."})]})}),e.jsx(F,{value:p,onValueChange:s=>_(s),className:"mb-4",children:e.jsx(z,{children:Z.map(s=>e.jsxs(K,{value:s.value,children:[s.label,s.value==="pending"&&N>0&&e.jsx(M,{variant:"secondary",className:"ml-2",children:N})]},s.value))})}),e.jsx($,{className:"p-0 overflow-hidden",children:d.isLoading?e.jsx("div",{className:"p-8 text-sm text-muted-foreground",children:"Loading reviews…"}):d.isError?e.jsx("div",{className:"p-8 text-sm text-destructive",children:d.error.message}):y.length===0?e.jsx("div",{className:"p-8 text-sm text-muted-foreground",children:"No reviews in this view."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(U,{children:[e.jsx(H,{children:e.jsxs(T,{children:[e.jsx(a,{children:"Date"}),e.jsx(a,{}),e.jsx(a,{children:"Name"}),e.jsx(a,{children:"Role"}),e.jsx(a,{children:"Stars"}),e.jsx(a,{children:"Quote"}),e.jsx(a,{children:"Tool"}),e.jsx(a,{children:"LinkedIn"}),e.jsx(a,{children:"Status"}),e.jsx(a,{className:"text-right",children:"Actions"})]})}),e.jsx(I,{children:y.map(s=>{const m=!!A[s.id],i=s.quote.length>100&&!m?`${s.quote.slice(0,100)}…`:s.quote,o=(s.reported_count??0)>0;return e.jsxs(T,{children:[e.jsx(n,{className:"whitespace-nowrap text-xs text-muted-foreground",children:new Date(s.submitted_at).toLocaleDateString()}),e.jsx(n,{children:s.photo_url?e.jsx("div",{className:"relative",children:e.jsx("img",{src:s.photo_url,alt:s.name,className:`w-10 h-10 rounded-full object-cover border ${o?"border-rose-400 ring-2 ring-rose-200":"border-slate-200"}`})}):e.jsx("div",{className:"w-8 h-8 rounded-full bg-slate-100 text-slate-500 text-xs font-semibold flex items-center justify-center",children:(s.name?.trim()?.[0]||"?").toUpperCase()})}),e.jsx(n,{className:"font-medium",children:s.name}),e.jsx(n,{className:"text-sm text-muted-foreground",children:s.role}),e.jsx(n,{children:e.jsx("div",{className:"flex items-center gap-0.5",children:Array.from({length:5}).map((f,S)=>e.jsx(O,{className:`w-3.5 h-3.5 ${S<s.stars?"fill-amber-400 text-amber-400":"text-slate-300"}`},S))})}),e.jsx(n,{className:"max-w-[24rem]",children:e.jsx("button",{type:"button",onClick:()=>C(f=>({...f,[s.id]:!f[s.id]})),className:"text-left text-sm text-slate-700 hover:text-slate-900",title:s.quote.length>100?m?"Click to collapse":"Click to expand":void 0,children:i})}),e.jsx(n,{className:"text-xs",children:s.tool||" - "}),e.jsx(n,{className:"text-xs",children:s.linkedin_url?e.jsxs("a",{href:s.linkedin_url,target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1 text-blue-600 hover:text-blue-800 hover:underline max-w-[12rem] truncate",children:[e.jsx("span",{className:"truncate",children:s.linkedin_url.replace(/^https?:\/\/(www\.)?/,"")}),e.jsx(G,{className:"w-3 h-3 shrink-0"})]}):" - "}),e.jsx(n,{children:e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(se,{status:s.status}),o&&e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-[11px] font-semibold rounded-md border bg-rose-100 text-rose-700 border-rose-200",children:[e.jsx(V,{className:"w-3 h-3"}),"Reported",(s.reported_count??0)>1?` ×${s.reported_count}`:""]})]})}),e.jsx(n,{className:"text-right whitespace-nowrap",children:e.jsxs("div",{className:"flex flex-wrap items-center justify-end gap-1.5",children:[s.status!=="approved"&&e.jsx(j,{size:"sm",variant:"default",disabled:v.isPending,onClick:()=>v.mutate({id:s.id,status:"approved"}),children:"Approve"}),s.status!=="rejected"&&e.jsx(j,{size:"sm",variant:"outline",disabled:v.isPending,onClick:()=>v.mutate({id:s.id,status:"rejected"}),children:"Reject"}),s.photo_url&&e.jsxs(j,{size:"sm",variant:"outline",disabled:k.isPending,onClick:()=>{confirm("Remove this photo? The review text stays live.")&&k.mutate(s.id)},title:"Remove photo only",children:[e.jsx(J,{className:"w-3.5 h-3.5 mr-1"}),"Remove photo"]}),e.jsxs(j,{size:"sm",variant:"destructive",disabled:R.isPending,onClick:()=>{confirm("Delete this review entirely? This cannot be undone.")&&R.mutate(s.id)},children:[e.jsx(W,{className:"w-3.5 h-3.5 mr-1"}),"Delete"]})]})})]},s.id)})})]})})})]})}function se({status:r}){const l={pending:{label:"Pending",cls:"bg-amber-100 text-amber-800 border-amber-200"},approved:{label:"Approved",cls:"bg-emerald-100 text-emerald-800 border-emerald-200"},rejected:{label:"Rejected",cls:"bg-rose-100 text-rose-700 border-rose-200"}}[r];return e.jsx("span",{className:`inline-flex items-center px-2 py-0.5 text-[11px] font-semibold rounded-md border ${l.cls}`,children:l.label})}export{ee as ReviewsAdmin,ae 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.