PageSourceSearch

https://blank-canvas-creation-5570.lovable.app/assets/AdminCategoryEditPage-6658ab62.js

js blank-canvas-creation-5570.lovable.app collected 2026-10-03 03:25:10 UTC 13,708 bytes, 1 lines download raw bytes

1import{h as se,u as te,r as m,j as e}from"./vendor-react-a835ee61.js";import{u as ae,B as F,A as p,h as j}from"./index-fad5f9b7.js";import{L as n}from"./label-1971670c.js";import{T as ie,a as re,b as M,c as O}from"./tabs-7ceaeca0.js";import{S as R,a as z,b as B,c as G,d as S}from"./select-8ceb069b.js";import{T as w}from"./textarea-fa3c9c1d.js";import{P as ne}from"./progress-84d4ab26.js";import{I as oe}from"./ImageUpload-b0a8be0b.js";import{g as b}from"./aiService-25c8acd9.js";import{L as T,V as le,aG as ce,az as de}from"./vendor-icons-11b98caa.js";import"./vendor-supabase-722fbc27.js";import"./vendor-radix-core-99f1042f.js";import"./vendor-radix-primitive-4e369f64.js";import"./vendor-radix-dropdown-menu-86d2342e.js";import"./vendor-radix-menu-7fb79491.js";import"./vendor-radix-label-5f29298f.js";import"./vendor-radix-tabs-eead257f.js";import"./vendor-radix-select-2329efca.js";import"./vendor-radix-number-d203b311.js";import"./vendor-radix-visually-hidden-4f55a9a1.js";import"./vendor-radix-progress-0a063c60.js";const me=j,g=["da","no","se","fi","de","nl","fr","it","es","pt","be","ch","lu","gb"],k={da:"Danish",no:"Norwegian",se:"Swedish",fi:"Finnish",de:"German",nl:"Dutch",fr:"French",it:"Italian",es:"Spanish",pt:"Portuguese",be:"French (Belgium)",ch:"German (Switzerland)",lu:"German (Luxembourg)",gb:"English (UK)"},pe=()=>({name:"",slug:"",parent_id:"null",image_url:"",image_alt_text:"",sort_order:0,customs_code:"",description:"",description_long:"",meta_title:"",meta_description:"",...Object.fromEntries(g.flatMap(a=>[[`name_${a}`,""],[`slug_${a}`,""],[`description_${a}`,""],[`description_long_${a}`,""],[`meta_title_${a}`,""],[`meta_description_${a}`,""]]))}),ue=a=>({name:a.name||"",slug:a.slug||"",parent_id:a.parent_id?a.parent_id.toString():"null",image_url:a.image_url||"",image_alt_text:a.image_alt_text||"",sort_order:a.sort_order||0,customs_code:a.customs_code||"",description:a.description||"",description_long:a.description_long||"",meta_title:a.meta_title||"",meta_description:a.meta_description||"",...Object.fromEntries(g.flatMap(o=>[[`name_${o}`,a[`name_${o}`]||""],[`slug_${o}`,a[`slug_${o}`]||""],[`description_${o}`,a[`description_${o}`]||""],[`description_long_${o}`,a[`description_long_${o}`]||""],[`meta_title_${o}`,a[`meta_title_${o}`]||""],[`meta_description_${o}`,a[`meta_description_${o}`]||""]]))}),Ie=()=>{const{id:a}=se(),o=te(),{toast:f}=ae(),x=!a||a==="new",[t,h]=m.useState(pe()),[V,q]=m.useState([]),[U,D]=m.useState(!0),[E,C]=m.useState(!1),[v,L]=m.useState(!1),[J,A]=m.useState(0),[K,H]=m.useState({}),[y,Q]=m.useState(""),[W,X]=m.useState([]);m.useEffect(()=>{(async()=>{D(!0);try{const[i,r,u]=await Promise.all([j.from("product_categories").select("*").order("sort_order",{ascending:!0}),j.from("translation_rules").select("language_code, rules"),j.from("translation_settings").select("global_instructions").limit(1).single()]);if(i.data&&q(i.data),r.data){const c={};r.data.forEach(_=>{c[_.language_code]=_.rules}),H(c)}u.data&&Q(u.data.global_instructions||"");try{const{data:c}=await me.from("customs_codes").select("code, title, rate").order("sort_order",{ascending:!0});c&&X(c)}catch(c){console.warn("Failed to load customs codes:",c)}if(!x&&i.data){const c=i.data.find(_=>_.id.toString()===a);c&&h(ue(c))}}catch(i){console.error("Failed to load data:",i)}finally{D(!1)}})()},[a,x]);const l=s=>{const{name:i,value:r}=s.target;h(u=>({...u,[i]:r})),i==="name"&&!t.slug&&x&&h(u=>({...u,[i]:r,slug:r.toLowerCase().replace(/\s+/g,"-").replace(/[^a-z0-9-]/g,"")}))},P=async s=>{s.preventDefault(),C(!0);try{const i={...t,parent_id:t.parent_id==="null"?null:parseInt(t.parent_id),sort_order:parseInt(t.sort_order)};if(x){const{error:r}=await j.from("product_categories").insert([i]);if(r)throw r;f({title:"Success",description:"Category created successfully"}),o("/admin/categories")}else{const{error:r}=await j.from("product_categories").update(i).eq("id",a);if(r)throw r;f({title:"Success",description:"Category updated successfully"})}}catch(i){console.error("Error saving category:",i,JSON.stringify(i)),f({title:"Error",description:i.message||"Failed to save category",variant:"destructive"})}finally{C(!1)}},Y=async()=>{var u,c,_,I;if(!t.description&&!t.description_long&&!t.meta_title&&!t.meta_description){f({title:"No content",description:"Please add English content first.",variant:"destructive"});return}if(!window.confirm("Auto-translate empty fields to all languages?"))return;L(!0),A(0);const s=g.length;let i=0;const r={};for(const d of g){const N=k[d],$=K[d]||"";try{t.description&&!((u=t[`description_${d}`])!=null&&u.trim())&&(r[`description_${d}`]=await b("translate",t.description,N,$,y)),t.description_long&&!((c=t[`description_long_${d}`])!=null&&c.trim())&&(r[`description_long_${d}`]=await b("translate",t.description_long,N,$,y)),t.meta_title&&!((_=t[`meta_title_${d}`])!=null&&_.trim())&&(r[`meta_title_${d}`]=await b("translate",t.meta_title,N,$,y)),t.meta_description&&!((I=t[`meta_description_${d}`])!=null&&I.trim())&&(r[`meta_description_${d}`]=await b("translate",t.meta_description,N,$,y))}catch(ee){console.error(`Translation failed for ${N}:`,ee)}i++,A(Math.round(i/s*100))}h(d=>({...d,...r})),L(!1),f({title:"Translations complete",description:`Translated to ${Object.keys(r).length} fields.`})},Z=(s,i)=>e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"bg-muted/40 rounded-lg p-3 space-y-1 text-xs text-muted-foreground",children:[e.jsx("p",{className:"font-medium text-foreground text-sm",children:"English Reference"}),t.name&&e.jsxs("p",{children:[e.jsx("span",{className:"font-medium",children:"Name:"})," ",t.name]}),t.meta_title&&e.jsxs("p",{children:[e.jsx("span",{className:"font-medium",children:"Meta Title:"})," ",t.meta_title]}),t.meta_description&&e.jsxs("p",{children:[e.jsx("span",{className:"font-medium",children:"Meta Desc:"})," ",t.meta_description]}),t.description&&e.jsxs("p",{children:[e.jsx("span",{className:"font-medium",children:"Short Desc:"})," ",t.description.substring(0,120),"..."]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:`name_${s}`,children:"Name"}),e.jsx(p,{id:`name_${s}`,name:`name_${s}`,value:t[`name_${s}`],onChange:l})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:`slug_${s}`,children:"Slug"}),e.jsx(p,{id:`slug_${s}`,name:`slug_${s}`,value:t[`slug_${s}`],onChange:l})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:`meta_title_${s}`,children:"Meta Title"}),e.jsx(p,{id:`meta_title_${s}`,name:`meta_title_${s}`,value:t[`meta_title_${s}`],onChange:l,placeholder:"Page title for search engines"}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[(t[`meta_title_${s}`]||"").length,"/60 chars"]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:`meta_description_${s}`,children:"Meta Description"}),e.jsx(p,{id:`meta_description_${s}`,name:`meta_description_${s}`,value:t[`meta_description_${s}`],onChange:l,placeholder:"Search result snippet"}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[(t[`meta_description_${s}`]||"").length,"/160 chars"]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:`description_${s}`,children:"Short Description (SEO, ~70 words)"}),e.jsx(w,{id:`description_${s}`,name:`description_${s}`,value:t[`description_${s}`],onChange:l,rows:3}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[(t[`description_${s}
1`]||"").split(/\s+/).filter(Boolean).length," words"]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:`description_long_${s}`,children:"Long Description (SEO, ~250 words)"}),e.jsx(w,{id:`description_long_${s}`,name:`description_long_${s}`,value:t[`description_long_${s}`],onChange:l,rows:6}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[(t[`description_long_${s}`]||"").split(/\s+/).filter(Boolean).length," words"]})]})]});return U?e.jsx("div",{className:"flex items-center justify-center h-64",children:e.jsx(T,{className:"h-8 w-8 animate-spin"})}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx(F,{variant:"ghost",size:"icon",onClick:()=>o("/admin/categories"),children:e.jsx(le,{className:"h-5 w-5"})}),e.jsx("h1",{className:"text-3xl font-bold",children:x?"Add New Category":`Edit: ${t.name}`})]}),e.jsxs(F,{onClick:P,disabled:E,children:[E?e.jsx(T,{className:"mr-2 h-4 w-4 animate-spin"}):e.jsx(ce,{className:"mr-2 h-4 w-4"}),E?"Saving...":x?"Create Category":"Save Changes"]})]}),e.jsx("div",{className:"bg-white rounded-lg shadow p-6",children:e.jsx("form",{onSubmit:P,children:e.jsxs(ie,{defaultValue:"en",children:[e.jsxs(re,{className:"flex-wrap h-auto",children:[e.jsx(M,{value:"en",children:"English"}),g.map(s=>e.jsx(M,{value:s,className:"text-xs",children:k[s]},s))]}),e.jsxs(O,{value:"en",className:"space-y-4 mt-4",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:"name",children:"Name (English)"}),e.jsx(p,{id:"name",name:"name",value:t.name,onChange:l,required:!0})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:"slug",children:"Slug (English)"}),e.jsx(p,{id:"slug",name:"slug",value:t.slug,onChange:l,required:!0})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:"parent_id",children:"Parent Category"}),e.jsxs(R,{value:t.parent_id,onValueChange:s=>h(i=>({...i,parent_id:s})),children:[e.jsx(z,{children:e.jsx(B,{placeholder:"Select parent category"})}),e.jsxs(G,{children:[e.jsx(S,{value:"null",children:"None (Top Level)"}),V.filter(s=>s.id.toString()!==a).map(s=>e.jsx(S,{value:s.id.toString(),children:s.name},s.id))]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:"sort_order",children:"Sort Order"}),e.jsx(p,{id:"sort_order",name:"sort_order",type:"number",value:t.sort_order,onChange:l})]})]}),e.jsxs("div",{className:"space-y-2 max-w-md",children:[e.jsx(n,{htmlFor:"customs_code",children:"Customs Code"}),e.jsxs(R,{value:t.customs_code||"__none__",onValueChange:s=>h(i=>({...i,customs_code:s==="__none__"?"":s})),children:[e.jsx(z,{children:e.jsx(B,{placeholder:"Select customs code"})}),e.jsxs(G,{children:[e.jsx(S,{value:"__none__",children:"None"}),W.map(s=>e.jsxs(S,{value:s.code,children:[s.code," — ",s.title," (",((Number(s.rate)||0)*100).toFixed(1),"%)"]},s.code))]})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Default customs code for all products in this category. Products with their own customs code override this."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{children:"Category Image"}),e.jsx(oe,{initialUrl:t.image_url,onUpload:s=>h(i=>({...i,image_url:s})),bucketName:"category_images",recommendedSize:"1:1 square · 1200×1200 px"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:"image_alt_text",children:"Image Alt Text"}),e.jsx(p,{id:"image_alt_text",name:"image_alt_text",value:t.image_alt_text,onChange:l})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:"meta_title",children:"Meta Title (English)"}),e.jsx(p,{id:"meta_title",name:"meta_title",value:t.meta_title,onChange:l,placeholder:"Page title for search engines"}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[(t.meta_title||"").length,"/60 chars"]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:"meta_description",children:"Meta Description (English)"}),e.jsx(p,{id:"meta_description",name:"meta_description",value:t.meta_description,onChange:l,placeholder:"Search result snippet"}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[(t.meta_description||"").length,"/160 chars"]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:"description",children:"Short Description (English, ~70 words)"}),e.jsx(w,{id:"description",name:"description",value:t.description,onChange:l,rows:3,placeholder:"SEO description mentioning products, materials, sizes, and payment options..."}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[t.description.split(/\s+/).filter(
1Boolean).length," words"]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(n,{htmlFor:"description_long",children:"Long Description (English, ~250 words)"}),e.jsx(w,{id:"description_long",name:"description_long",value:t.description_long,onChange:l,rows:8,placeholder:"Detailed SEO text..."}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[t.description_long.split(/\s+/).filter(Boolean).length," words"]})]}),e.jsxs("div",{className:"border rounded-lg p-4 bg-muted/30 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h4",{className:"font-medium text-sm",children:"Auto-Translate All SEO Content"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Translate to all ",g.length," languages"]})]}),e.jsxs(F,{type:"button",onClick:Y,disabled:v||!t.description&&!t.description_long&&!t.meta_title&&!t.meta_description,variant:"outline",size:"sm",children:[v?e.jsx(T,{className:"mr-2 h-4 w-4 animate-spin"}):e.jsx(de,{className:"mr-2 h-4 w-4"}),v?"Translating...":"Auto-Translate All"]})]}),v&&e.jsx(ne,{value:J,className:"h-2"})]})]}),g.map(s=>e.jsx(O,{value:s,className:"space-y-4 mt-4",children:Z(s)},s))]})})})]})};export{Ie 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.