1import{U as o,O as e,B as f,I as i,X as I,d as k,e as U,h as R,i as H,T as c,C as q,p as h,Z as l}from"./index-IBHyG7M_.js";import{L as n}from"./label-DPfgYCkJ.js";import{T as z,b as M,c as p,a as j}from"./tabs-F1J2brUq.js";import{T as Q,d as V,e as N,c as x,a as X,b as d}from"./table-CG-0Fq2Z.js";import{B as Z}from"./badge-CXQjseq-.js";import{I as $}from"./ImageUpload-Cj2mnw_2.js";import{P as G}from"./plus-CSRmdP_D.js";import{S as K}from"./search-CrgSiNi5.js";import{P as W}from"./pencil-Bs1O0sP_.js";import{T as Y}from"./trash-2-DdyChubd.js";const w={name:"",slug:"",tagline:"",description:"",external_url:"",features:"[]",benefits:"[]",pricing:"{}",color:"#000000",is_published:!1,seo_title:"",seo_description:"",sort_order:0,logo_url:"",screenshots:"[]"};function de(){const[C,O]=o.useState([]),[J,m]=o.useState(!1),[g,b]=o.useState(null),[r,t]=o.useState(w),[u,S]=o.useState(""),v=async()=>{const s=await h.products.list();O(s||[])};o.useEffect(()=>{v()},[]);const T=()=>{t(w),b(null),m(!0)},P=async s=>{const a=await h.products.get(s);a&&(t({name:a.name||"",slug:a.slug||"",tagline:a.tagline||"",description:a.description||"",external_url:a.external_url||"",features:JSON.stringify(a.features||[]),benefits:JSON.stringify(a.benefits||[]),pricing:JSON.stringify(a.pricing||{}),color:a.color||"#000000",is_published:a.is_published||!1,seo_title:a.seo_title||"",seo_description:a.seo_description||"",sort_order:a.sort_order||0,logo_url:a.logo_url||"",screenshots:JSON.stringify(a.screenshots||[])}),b(s),m(!0))},L=()=>{try{const s=JSON.parse(r.features);if(!Array.isArray(s))return l.error('Features must be a JSON array (e.g., ["feature1", "feature2"])'),!1}catch{return l.error("Invalid JSON in Features field"),!1}try{const s=JSON.parse(r.benefits);if(!Array.isArray(s))return l.error('Benefits must be a JSON array (e.g., ["benefit1", "benefit2"])'),!1}catch{return l.error("Invalid JSON in Benefits field"),!1}try{const s=JSON.parse(r.pricing);if(typeof s!="object"||Array.isArray(s)||s===null)return l.error('Pricing must be a JSON object (e.g., {"basic": 99, "pro": 199})'),!1}catch{return l.error("Invalid JSON in Pricing field"),!1}try{const s=JSON.parse(r.screenshots);if(!Array.isArray(s))return l.error("Screenshots must be a JSON array of image URLs"),!1}catch{return l.error("Invalid JSON in Screenshots field"),!1}return!0},F=s=>/^#[0-9A-F]{6}$/i.test(s)?!0:(l.error("Color must be a valid hex format (e.g., #FF5733)"),!1),D=async()=>{if(!r.name.trim()){l.error("Name is required");return}if(!r.slug.trim()){l.error("Slug is required");return}if(F(r.color)&&L())try{const s=r.features?JSON.parse(r.features):[],a=r.benefits?JSON.parse(r.benefits):[],B=r.pricing?JSON.parse(r.pricing):{},A=r.screenshots?JSON.parse(r.screenshots):[],_={name:r.name,slug:r.slug,tagline:r.tagline||null,description:r.description||null,external_url:r.external_url||null,features:s,benefits:a,pricing:B,color:r.color,is_published:r.is_published,seo_title:r.seo_title||null,seo_description:r.seo_description||null,sort_order:r.sort_order,logo_url:r.logo_url||null,screenshots:A};g?(await h.products.update(g,_),l.success("Product updated")):(await h.products.create(_),l.success("Product created")),m(!1),v()}catch(s){console.error("Save error:",s),l.error(s.message||"Failed to save product")}},E=async s=>{if(confirm("Delete this product?"))try{await h.products.delete(s),l.success("Product deleted"),v()}catch(a){l.error(a.message||"Failed to delete product")}},y=C.filter(s=>{var a;return s.name.toLowerCase().includes(u.toLowerCase())||((a=s.tagline)==null?void 0:a.toLowerCase().includes(u.toLowerCase()))});return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h1",{className:"text-2xl font-display font-bold text-foreground",children:"Products"}),e.jsxs(f,{onClick:T,className:"gap-2",children:[e.jsx(G,{className:"w-4 h-4"}),"New Product"]})]}),e.jsxs("div",{className:"relative max-w-sm",children:[e.jsx(K,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground"}),e.jsx(i,{value:u,onChange:s=>S(s.target.value),placeholder:"Search products...",className:"pl-9"}),u&&e.jsx("button",{onClick:()=>S(""),className:"absolute right-2 top-1/2 -translate-y-1/2",children:e.jsx(I,{className:"w-4 h-4 text-muted-foreground"})})]}),e.jsx("div",{className:"rounded-lg border border-border overflow-hidden",children:e.jsxs(Q,{children:[e.jsx(V,{children:e.jsxs(N,{children:[e.jsx(x,{children:"Name"}),e.jsx(x,{children:"Tagline"}),e.jsx(x,{children:"Status"}),e.jsx(x,{children:"Created"}),e.jsx(x,{className:"w-20",children:"Actions"})]})}),e.jsxs(X,{children:[y.map(s=>e.jsxs(N,{children:[e.jsx(d,{className:"font-medium max-w-xs truncate",children:s.name}),e.jsx(d,{className:"text-sm text-muted-foreground max-w-xs truncate",children:s.tagline}),e.jsx(d,{children:e.jsx(Z,{variant:s.is_published?"default":"secondary",children:s.is_published?"Published":"Draft"})}),e.jsx(d,{className:"text-sm text-muted-foreground",children:new Date(s.created_at).toLocaleDateString()}),e.jsx(d,{children:e.jsxs("div",{className:"flex gap-1",children:[e.jsx(f,{variant:"ghost",size:"icon",onClick:()=>P(s.id),children:e.jsx(W,{className:"w-4 h-4"})}),e.jsx(f,{variant:"ghost",size:"icon",onClick:()=>E(s.id),children:e.jsx(Y,{className:"w-4 h-4 text-destructive"})})]})})]},s.id)),y.length===0&&e.jsx(N,{children:e.jsx(d,{colSpan:5,className:"text-center py-8 text-muted-foreground",children:u?"No results found":"No products yet"})})]})]})}),e.jsx(k,{open:J,onOpenChange:m,children:e.jsxs(U,{className:"max-w-4xl max-h-[90vh] overflow-y-auto",children:[e.jsx(R,{children:e.jsx(H,{children:g?"Edit Product":"New Product"})}),e.jsxs(z,{defaultValue:"basic",className:"space-y-4",children:[e.jsxs(M,{className:"grid w-full grid-cols-4",children:[e.jsx(p,{value:"basic",children:"Basic"}),e.jsx(p,{value:"media",children:"Media"}),e.jsx(p,{value:"details",children:"Details"}),e.jsx(p,{value:"seo",children:"SEO"})]}),e.jsxs(j,{value:"basic",className:"space-y-4",children:[e.jsxs("div",{className:"grid sm:grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx(n,{children:"Name *"}),e.jsx(i,{value:r.name,onChange:s=>t({...r,name:s.target.value})})]}),e.jsxs("div",{children:[e.jsx(n,{children:"Slug *"}),e.jsx(i,{value:r.slug,onChange:s=>t({...r,slug:s.target.value})})]})]}),e.jsxs("div",{children:[e.jsx(n,{children:"Tagline"}),e.jsx(i,{value:r.tagline,onChange:s=>t({...r,tagline:s.target.value}),placeholder:"Short tagline"})]}),e.jsxs("div",{children:[e.jsx(n,{children:"Description"}),e.jsx(c,{value:r.description,onChange:s=>t({...r,description:s.target.value}),rows:4})]}
1),e.jsxs("div",{children:[e.jsx(n,{children:"External URL"}),e.jsx(i,{value:r.external_url,onChange:s=>t({...r,external_url:s.target.value}),placeholder:"https://..."})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"checkbox",id:"pub",checked:r.is_published,onChange:s=>t({...r,is_published:s.target.checked}),className:"w-4 h-4"}),e.jsx(n,{htmlFor:"pub",className:"cursor-pointer",children:"Published"})]})]}),e.jsxs(j,{value:"media",className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(n,{children:"Logo / Hero Image"}),e.jsx($,{value:r.logo_url,onChange:s=>t({...r,logo_url:s}),folder:"products"})]}),e.jsxs("div",{children:[e.jsx(n,{children:"Screenshots (JSON URLs)"}),e.jsx(c,{value:r.screenshots,onChange:s=>t({...r,screenshots:s.target.value}),rows:4,className:"font-mono text-sm",placeholder:'["https://...", "https://..."]'}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Enter JSON array of image URLs"})]}),e.jsxs("div",{children:[e.jsx(n,{children:"Color Theme"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{type:"color",value:r.color,onChange:s=>t({...r,color:s.target.value}),className:"w-12 h-10 rounded cursor-pointer"}),e.jsx(i,{value:r.color,onChange:s=>t({...r,color:s.target.value})})]})]})]}),e.jsxs(j,{value:"details",className:"space-y-4",children:[e.jsx(q,{className:"p-3 bg-muted/30 text-xs text-muted-foreground",children:"Enter JSON for features, benefits, and pricing. Examples below."}),e.jsxs("div",{children:[e.jsx(n,{children:"Features (JSON array)"}),e.jsx(c,{value:r.features,onChange:s=>t({...r,features:s.target.value}),rows:3,className:"font-mono text-sm",placeholder:'["Feature 1", "Feature 2"]'})]}),e.jsxs("div",{children:[e.jsx(n,{children:"Benefits (JSON array)"}),e.jsx(c,{value:r.benefits,onChange:s=>t({...r,benefits:s.target.value}),rows:3,className:"font-mono text-sm",placeholder:'["Benefit 1", "Benefit 2"]'})]}),e.jsxs("div",{children:[e.jsx(n,{children:"Pricing (JSON)"}),e.jsx(c,{value:r.pricing,onChange:s=>t({...r,pricing:s.target.value}),rows:3,className:"font-mono text-sm",placeholder:'{"plan": "pricing_details"}'})]}),e.jsxs("div",{children:[e.jsx(n,{children:"Sort Order"}),e.jsx(i,{type:"number",value:r.sort_order,onChange:s=>t({...r,sort_order:parseInt(s.target.value)||0})})]})]}),e.jsxs(j,{value:"seo",className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(n,{children:"SEO Title"}),e.jsx(i,{value:r.seo_title,onChange:s=>t({...r,seo_title:s.target.value}),maxLength:60}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:[r.seo_title.length,"/60"]})]}),e.jsxs("div",{children:[e.jsx(n,{children:"SEO Description"}),e.jsx(c,{value:r.seo_description,onChange:s=>t({...r,seo_description:s.target.value}),maxLength:160,rows:3}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:[r.seo_description.length,"/160"]})]})]})]}),e.jsx(f,{onClick:D,className:"w-full bg-gradient-electric text-white",children:g?"Update Product":"Create Product"})]})})]})}export{de 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.