PageSourceSearch

https://ecominsights.lovable.app/assets/AdminKeywordSupplierMappings-D_zmZoXS.js

js ecominsights.lovable.app collected 2026-10-03 03:31:55 UTC 10,123 bytes, 1 lines download raw bytes

1import{b9 as X,a4 as Z,cv as ee,r as j,t as K,a5 as _,s as l,j as e,aU as k,q as P,C,a as S,b as D,cm as se,c as T,B as d,al as ae,e as L,ak as g,S as te,ba as re,bb as ie,bc as H,bd as o,bf as ne,bg as p,E as I,am as B,an as le,ao as ce,$ as de,a0 as oe,a1 as pe,a2 as he,a3 as me,ae as h,af as xe,ag as ue,ah as je,ai as ge,aj as A,bV as ye,b8 as we}from"./index-CA5JHsqG.js";import{A as ve,a as fe,b as Ne,c as be,d as _e,e as ke,f as Ce,g as Se}from"./alert-dialog-DhhEVg46.js";import{F as De}from"./factory-Eh6AYegd.js";const E={keyword_pattern:"",match_type:"contains",supplier_terms_csv:"",priority:0,enabled:!0,notes:""},qe=()=>{const{toast:m}=X(),w=Z(),{isAdmin:q,loading:O}=ee(),[v,Q]=j.useState(""),[t,i]=j.useState(E),[R,x]=j.useState(!1),[f,N]=j.useState(null),[u,z]=j.useState(""),{data:V=[],isLoading:U}=K({queryKey:["keyword-supplier-mappings"],enabled:!!q,queryFn:async()=>{const{data:s,error:a}=await l.from("keyword_supplier_mappings").select("*").order("priority",{ascending:!1}).order("keyword_pattern",{ascending:!0});if(a)throw a;return s||[]}}),{data:n,isFetching:W,refetch:F}=K({queryKey:["supplier-preview-test",u],enabled:!1,queryFn:async()=>{const{data:s,error:a}=await l.rpc("preview_suppliers_for_keyword",{_term:u,_limit:10});if(a)throw a;return s}}),b=_({mutationFn:async s=>{const a=s.supplier_terms_csv.split(",").map(c=>c.trim()).filter(Boolean),r={keyword_pattern:s.keyword_pattern.trim(),match_type:s.match_type,supplier_terms:a,priority:Number(s.priority)||0,enabled:s.enabled,notes:s.notes.trim()||null};if(!r.keyword_pattern)throw new Error("Keyword pattern is required");if(a.length===0)throw new Error("Add at least one supplier term");if(s.id){const{error:c}=await l.from("keyword_supplier_mappings").update(r).eq("id",s.id);if(c)throw c}else{const{data:c}=await l.auth.getUser(),{error:M}=await l.from("keyword_supplier_mappings").insert({...r,created_by:c.user?.id??null});if(M)throw M}},onSuccess:()=>{w.invalidateQueries({queryKey:["keyword-supplier-mappings"]}),x(!1),i(E),m({title:"Mapping saved"})},onError:s=>m({title:"Could not save",description:s.message,variant:"destructive"})}),Y=_({mutationFn:async({id:s,enabled:a})=>{const{error:r}=await l.from("keyword_supplier_mappings").update({enabled:a}).eq("id",s);if(r)throw r},onSuccess:()=>w.invalidateQueries({queryKey:["keyword-supplier-mappings"]}),onError:s=>m({title:"Could not update",description:s.message,variant:"destructive"})}),$=_({mutationFn:async s=>{const{error:a}=await l.from("keyword_supplier_mappings").delete().eq("id",s);if(a)throw a},onSuccess:()=>{w.invalidateQueries({queryKey:["keyword-supplier-mappings"]}),N(null),m({title:"Mapping deleted"})},onError:s=>m({title:"Could not delete",description:s.message,variant:"destructive"})}),y=V.filter(s=>{if(!v.trim())return!0;const a=v.toLowerCase();return s.keyword_pattern.toLowerCase().includes(a)||s.supplier_terms.some(r=>r.toLowerCase().includes(a))||(s.notes??"").toLowerCase().includes(a)}),G=()=>{i(E),x(!0)},J=s=>{i({id:s.id,keyword_pattern:s.keyword_pattern,match_type:s.match_type,supplier_terms_csv:s.supplier_terms.join(", "),priority:s.priority,enabled:s.enabled,notes:s.notes??""}),x(!0)};return O?e.jsx(k,{children:e.jsx("main",{className:"container mx-auto px-4 py-8",children:e.jsx(P,{className:"h-64 w-full"})})}):q?e.jsxs(k,{children:[e.jsxs("main",{className:"container mx-auto px-4 py-8 space-y-6",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4 flex-wrap",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl sm:text-3xl font-bold flex items-center gap-2",children:[e.jsx(De,{className:"w-6 h-6 text-primary"}),"Keyword → Supplier Mappings"]}),e.jsxs("p",{className:"text-muted-foreground text-sm mt-1 max-w-2xl",children:["Define how Intelligence Pulse keywords expand into supplier searches. E.g. map ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"shoes"})," to",e.jsx("code",{className:"text-xs bg-muted px-1 rounded mx-1",children:"footwear, sneaker, athletic shoe"}),". Enabled rules are applied automatically by the supplier preview."]})]}),e.jsxs(d,{onClick:G,className:"gap-1",children:[e.jsx(ae,{className:"w-4 h-4"})," New mapping"]})]}),e.jsxs(C,{children:[e.jsxs(S,{children:[e.jsx(D,{className:"text-base",children:"Test a keyword"}),e.jsx(T,{children:"See how many suppliers a keyword finds with the current mappings applied."})]}),e.jsxs(L,{className:"space-y-3",children:[e.jsxs("div",{className:"flex gap-2",children:[e.jsx(g,{placeholder:"e.g. shoes",value:u,onChange:s=>
1z(s.target.value),onKeyDown:s=>{s.key==="Enter"&&u.trim()&&F()}}),e.jsxs(d,{variant:"outline",onClick:()=>F(),disabled:!u.trim()||W,children:[e.jsx(te,{className:"w-4 h-4 mr-1"}),"Test"]})]}),n&&n.length>0&&e.jsxs("div",{className:"text-sm",children:[e.jsxs("p",{className:"text-muted-foreground mb-2",children:["Matched ",e.jsx("strong",{children:Number(n[0]?.total_count??0)})," suppliers. Top ",n.length,":"]}),e.jsx("ul",{className:"space-y-1",children:n.map((s,a)=>e.jsxs("li",{className:"flex justify-between border-b border-border py-1 text-xs",children:[e.jsx("span",{className:"truncate",children:s.name}),e.jsxs("span",{className:"text-muted-foreground shrink-0 ml-2",children:[s.country??"—"," · ",(s.total_shipments??0).toLocaleString()," ship."]})]},a))})]}),n&&n.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"No suppliers matched."})]})]}),e.jsxs(C,{children:[e.jsxs(S,{className:"flex flex-row items-center justify-between gap-3 space-y-0",children:[e.jsxs("div",{children:[e.jsx(D,{className:"text-base",children:"Mapping rules"}),e.jsxs(T,{children:[y.length," rule",y.length===1?"":"s"]})]}),e.jsx(g,{placeholder:"Search patterns or terms...",value:v,onChange:s=>Q(s.target.value),className:"max-w-xs"})]}),e.jsx(L,{children:U?e.jsx("div",{className:"space-y-2",children:[...Array(4)].map((s,a)=>e.jsx(P,{className:"h-12 w-full"},a))}):y.length===0?e.jsx("div",{className:"text-center py-12 text-sm text-muted-foreground",children:'No mapping rules yet. Click "New mapping" to create one.'}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(re,{children:[e.jsx(ie,{children:e.jsxs(H,{children:[e.jsx(o,{children:"Pattern"}),e.jsx(o,{children:"Match"}),e.jsx(o,{children:"Supplier terms"}),e.jsx(o,{className:"w-20",children:"Priority"}),e.jsx(o,{className:"w-20",children:"Enabled"}),e.jsx(o,{className:"w-32 text-right",children:"Actions"})]})}),e.jsx(ne,{children:y.map(s=>e.jsxs(H,{children:[e.jsxs(p,{className:"font-medium",children:[e.jsx("div",{children:s.keyword_pattern}),s.notes&&e.jsx("div",{className:"text-xs text-muted-foreground mt-0.5",children:s.notes})]}),e.jsx(p,{children:e.jsx(I,{variant:"outline",className:"capitalize",children:s.match_type})}),e.jsx(p,{children:e.jsx("div",{className:"flex flex-wrap gap-1 max-w-md",children:s.supplier_terms.map((a,r)=>e.jsx(I,{variant:"secondary",className:"text-xs",children:a},r))})}),e.jsx(p,{children:s.priority}),e.jsx(p,{children:e.jsx(B,{checked:s.enabled,onCheckedChange:a=>Y.mutate({id:s.id,enabled:a})})}),e.jsxs(p,{className:"text-right",children:[e.jsx(d,{variant:"ghost",size:"sm",onClick:()=>J(s),children:e.jsx(le,{className:"w-4 h-4"})}),e.jsx(d,{variant:"ghost",size:"sm",onClick:()=>N(s.id),children:e.jsx(ce,{className:"w-4 h-4 text-destructive"})})]})]},s.id))})]})})})]})]}),e.jsx(de,{open:R,onOpenChange:x,children:e.jsxs(oe,{className:"max-w-lg",children:[e.jsxs(pe,{children:[e.jsx(he,{children:t.id?"Edit mapping":"New mapping"}),e.jsx(me,{children:"When a user's keyword matches the pattern, the supplier search is expanded with the listed supplier terms."})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(h,{children:"Keyword pattern"}),e.jsx(g,{value:t.keyword_pattern,onChange:s=>i({...t,keyword_pattern:s.target.value}),placeholder:"shoes"})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(h,{children:"Match type"}),e.jsxs(xe,{value:t.match_type,onValueChange:s=>i({...t,match_type:s}),children:[e.jsx(ue,{children:e.jsx(je,{})}),e.jsxs(ge,{children:[e.jsx(A,{value:"contains",children:"Contains"}),e.jsx(A,{value:"exact",children:"Exact"}),e.jsx(A,{value:"regex",children:"Regex"})]})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(h,{children:"Priority"}),e.jsx(g,{type:"number",value:t.priority,onChange:s=>i({...t,priority:Number(s.target.value)})})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(h,{children:"Supplier terms (comma-separated)"}),e.jsx(ye,{value:t.supplier_terms_csv,onChange:s=>i({...t,supplier_terms_csv:s.target.value}),placeholder:"footwear, sneaker, athletic shoe",rows:3})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(h,{children:"Notes (optional)"}),e.jsx(g,{value:t.notes,onChange:s=>i({...t,notes:s.target.value}),placeholder:"Why this mapping exists"})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(h,{children:"Enabled"}),e.jsx(B,{checked:t.enabled,onCheckedChange:s=>i({...t,enabled:s})})]})]}),e.jsxs(we,{children:[e.jsx(d,{variant:"ghost",onClick:()=>x(!1),children:"Cancel"}),e.jsx(d,{onClick:()=>b.mutate(t),disabled:b.isPending,children:b.isPending?"Saving...":"Save"})]})]})}),e.jsx(ve,{open:!!f,onOpenChange:s=>!s&&N(null),children:e.jsxs(fe,{children:[e.jsxs(Ne,{children:[e.jsx(be,{children:"Delete mapping?"}),e.jsx(_e,{children:"This cannot be undone. Supplier previews will stop expanding this keyword."})]}),e.jsxs(ke,{children:[e.jsx(Ce,{children:"Cancel"}),e.jsx(Se,{onClick:()=>f&&$.mutate(f),className:"bg-destructive text-destructive-foreground hover:bg-destructive/90",children:"Delete"})]})]})})]}):e.jsx(k,{children:e.jsx("main",{className:"container mx-auto px-4 py-8",children:e.jsx(C,{children:e.jsxs(S,{children:[e.jsxs(D,{className:"flex items-center gap-2",children:[e.jsx(se,{className:"w-5 h-5 text-destructive"}),"Admin access required"]}),e.jsx(T,{children:"You need administrator privileges to manage keyword → supplier mappings."})]})})})})};export{qe 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.