1import{r as x,b as K,u as Y,j as e,H as Z,B as m,A as ee,aB as se,O as $,d as O,Q as te,V as U,v as re,f as S,W as E,X as le,e as ie}from"./index-B46WE3Zi.js";import{P as ae}from"./papaparse.min-BT3kdy-H.js";const I={insert:"Insert only (new posts)",update:"Insert + Update existing"},D=(o,f=140)=>{if(o==null)return"(empty)";const p=typeof o=="string"?o:JSON.stringify(o);return p.length>f?p.slice(0,f)+"â¦":p},de=()=>{const[o,f]=x.useState(null),[p,k]=x.useState(null),[N,B]=x.useState("insert"),[d,l]=x.useState("idle"),[r,h]=x.useState(null),[g,v]=x.useState(null),[P,j]=x.useState(""),y=x.useRef(null),{toast:b}=K(),V=Y(),M=s=>{s.target.files&&s.target.files[0]&&(f(s.target.files[0]),k(null),h(null),v(null),j(""),l("idle"))},q=()=>{f(null),k(null),h(null),v(null),j(""),l("idle"),y.current&&(y.current.value="")},_=(s,t)=>ie.functions.invoke("bulk-import-blog-posts",{body:{posts:s,mode:N,preview:t}}),J=()=>{if(!o){b({title:"No file selected",description:"Please upload a CSV file to continue.",variant:"destructive"});return}l("previewing"),h(null),j(""),ae.parse(o,{header:!0,skipEmptyLines:!0,complete:async s=>{const t=s.data,a=[],n=[];for(let i=0;i<t.length;i++){const c=t[i],w=c.title?.trim(),T=c.slug?.trim(),F=c.content_html?.trim(),G=c.meta_description?.trim(),Q=c.og_image_original?.trim(),X=c.category?.trim();if(!w||!T||!F){a.push(`Row ${i+2}: Missing required fields (title, slug, or content_html). Title found: ${w||"N/A"}`);continue}n.push({title:w,slug:T,subtitle:G||null,content:F,featured_image:Q||null,author:"Baltic Tours",categoryName:X||null,published:!0,_rowIndex:i+2})}if(n.length===0){l("idle"),v({created:0,updated:0,skipped:0,failed:a.length,errors:a,warnings:[],changes:[],total:t.length}),l("results"),b({title:"Import Failed",description:"No valid rows found in CSV.",variant:"destructive"});return}k(n);try{const{data:i,error:c}=await _(n,!0);if(c)throw new Error(c.message||"Edge function invocation failed");const w={...i,errors:[...a,...i.errors||[]],failed:(i.failed||0)+a.length};h(w),l("preview")}catch(i){l("idle"),b({title:"Preview Failed",description:i.message||"An error occurred.",variant:"destructive"})}},error:s=>{l("idle"),b({title:"CSV Parsing Error",description:s.message,variant:"destructive"})}})},u=r?(r.created||0)+(r.updated||0):0,C=P.trim()===String(u),W=async()=>{if(!(!C||u===0)){l("executing");try{const{data:s,error:t}=await _(p,!1);if(t)throw new Error(t.message||"Edge function invocation failed");v(s),l("results"),b({title:"Import Complete",description:`${s.created||0} created, ${s.updated||0} updated.`}),y.current&&(y.current.value="")}catch(s){l("preview"),b({title:"Import Failed",description:s.message||"An error occurred.",variant:"destructive"})}}},H=s=>{if(!s||s.length===0)return;const t=new Blob([s.join(` 2`)],{type:"text/plain"}),a=URL.createObjectURL(t),n=document.createElement("a");n.href=a,n.download=`blog-import-errors-${new Date().getTime()}.txt`,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(a)},R=s=>e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-4",children:[e.jsxs("div",{className:"bg-green-50 rounded-lg p-4 border border-green-100 flex items-center gap-4",children:[e.jsx(S,{className:"w-8 h-8 text-green-600"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium text-green-800",children:"Created"}),e.jsx("p",{className:"text-2xl font-bold text-green-900",children:s.created||0})]})]}),e.jsxs("div",{className:"bg-blue-50 rounded-lg p-4 border border-blue-100 flex items-center gap-4",children:[e.jsx(S,{className:"w-8 h-8 text-blue-600"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium text-blue-800",children:"Updated"}),e.jsx("p",{className:"text-2xl font-bold text-blue-900",children:s.updated||0})]})]}),e.jsxs("div",{className:"bg-yellow-50 rounded-lg p-4 border border-yellow-100 flex items-center gap-4",children:[e.jsx(E,{className:"w-8 h-8 text-yellow-600"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium text-yellow-800",children:"Skipped"}),e.jsx("p",{className:"text-2xl font-bold text-yellow-900",children:s.skipped||0})]})]}),e.jsxs("div",{className:"bg-red-50 rounded-lg p-4 border border-red-100 flex items-center gap-4",children:[e.jsx(E,{className:"w-8 h-8 text-red-600"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium text-red-800",children:"Failed"}),e.jsx("p",{className:"text-2xl font-bold text-red-900",children:s.failed||0})]})]})]}),A=(s,t="Error Details",a="text-red-600")=>!s||s.length===0?null:e.jsxs("div",{className:"mt-6",children:[e.jsxs("div",{className:"flex justify-between items-center mb-3",children:[e.jsxs("h3",{className:"font-semibold text-gray-900 flex items-center gap-2",children:[e.jsx(E,{className:`w-5 h-5 ${a}`})," ",t]}),e.jsxs(m,{variant:"outline",size:"sm",onClick:()=>H(s),className:"flex items-center gap-2",children:[e.jsx(le,{className:"w-4 h-4"})," Download Error Log"]})]}),e.jsx("div",{className:"bg-gray-900 text-gray-100 rounded-lg p-4 text-sm font-mono max-h-64 overflow-y-auto whitespace-pre-wrap",children:s.map((n,i)=>e.jsx("div",{className:"mb-1 text-red-400 border-b border-gray-800 pb-1 last:border-0",children:n},i))})]}),z=s=>!s||s.length===0?null:e.jsxs("div",{className:"mt-6 border border-amber-200 rounded-lg overflow-hidden",children:[e.jsxs("div",{className:"bg-amber-50 px-4 py-3 border-b border-amber-200 flex items-center gap-2",children:[e.jsx(U,{className:"w-4 h-4 text-amber-700"}),e.jsxs("h4",{className:"font-semibold text-amber-900 text-sm",children:["Field-level changes on existing posts (",s.length," field",s.length!==1?"s":"",")"]})]}),e.jsx("div",{className:"max-h-72 overflow-auto",children:e.jsxs("table",{className:"w-full text-xs",children:[e.jsx("thead",{className:"bg-gray-50 sticky top-0",children:e.jsxs("tr",{className:"text-left text-gray-600",children:[e.jsx("th",{className:"px-3 py-2 font-semibold",children:"Row"}),e.jsx("th",{className:"px-3 py-2 font-semibold",children:"Slug"}),e.jsx("th",{className:"px-3 py-2 font-semibold",children:"Field"}),e.jsx("th",{className:"px-3 py-2 font-semibold text-gray-500",children:"Current value"}),e.jsx("th",{className:"px-3 py-2 font-semibold text-blue-700",children:"Incoming value"})]})}),e.jsx("tbody",{className:"divide-y divide-gray-100",children:s.map((t,a)=>e.jsxs("tr",{className:"align-top",children:[e.jsx("td",{className:"px-3 py-2 text-gray-500",children:t.row}),e.jsx("td",{className:"px-3 py-2 font-medium text-gray-800",children:t.slug}),e.jsx("td",{className:"px-3 py-2 font-mono text-gray-700",children:t.field}),e.jsx("td",{className:"px-3 py-2 text-gray-500",title:typeof t.currentValue=="string"?t.currentValue:JSON.stringify(t.currentValue),children:D(t.currentValue)}),e.jsx("td",{className:"px-3 py-2 text-blue-800",title:typeof t.incomingValue=="string"?t.incomingValue:JSON.stringify(t.incomingValue),children:D(t.incomingValue)})]},a))})]})})]}),L=d==="previewing"||d==="executing";return e.jsxs("div",{className:"min-h-screen bg-gray-50 py-8",children:[e.jsx(Z,{children:e.jsx("title",{children:"Admin - Bulk Import Blog Posts"})}),e.jsxs("div",{className:"container mx-auto px-4 max-w-4xl",children:[e.jsx("div",{className:"flex flex-col md:flex-row justify-between items-start md:items-center mb-8 gap-4",children:e.jsxs("div",{children:[e.jsxs(m,{variant:"ghost",className:"mb-2 pl-0 hover:pl-2 transition-all",onClick:()=>V("/admin/blog"),children:[e.jsx(ee,{className:"w-4 h-4 mr-2"})," Back to Blog Posts"]}),e.jsx("h1",{className:"text-3xl font-bold text-gray-900",children:"Bulk Import Blog Posts"}),e.jsx("p",{className:"text-gray-500 mt-1",children:"Upload a CSV file to bulk create or update blog posts. Nothing is written until you preview and confirm."})]})}),e.jsxs("div",{className:"bg-white rounded-xl shadow-sm border border-gray-200 p-6 md:p-8 mb-8",children:[d==="idle"&&e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsxs("div",{className:"bg-blue-50 text-blue-800 p-4 rounded-lg border border-blue-100 flex gap-3 text-sm",children:[e.jsx(se,{className:"w-5 h-5 flex-shrink-0 mt-0.5"}),e.jsxs("div",{children:[e.jsx("p",{className:"font-semibold mb-1",children:"CSV Format Requirements:"}),e.jsxs("ul",{className:"list-disc pl-5 space-y-1 text-blue-700",children:[e.jsxs("li",{children:["Required columns: ",e.jsx("strong",{children:"title"}),", ",e.jsx("strong",{children:"slug"}),", ",e.jsx("strong",{children:"content_html"})]}),e.jsxs("li",{children:["Optional columns: ",e.jsx("strong",{children:"meta_description"})," (subtitle), ",e.jsx("strong",{children:"og_image_original"})," (featured_image), ",e.jsx("strong",{children:"category"})]}),e.jsx("li",{children:"Categories matched exactly by name (case-insensitive)."}),e.jsxs("li",{children:["New posts are marked ",e.jsx("strong",{children:"published"})," with author âBaltic Toursâ. Existing posts are never force-published or re-authored."]})]})]})]}),e.jsxs("div",{className:"flex flex-col gap-3",children:[e.jsx("label",{className:"text-sm font-medium text-gray-700",children:"Import mode"}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-3",children:[e.jsxs("button",{type:"button",onClick:()=>B("insert"),className:`flex-1 text-left p-4 rounded-lg border-2 transition-colors ${N==="insert"?"border-[var(--primary-blue)] bg-blue-50":"border-gray-200 bg-white hover:border-gray-300"}`,children:[e.jsx("p",{className:"font-semibold text-sm text-gray-900",children:I.insert}),e.jsx("p",{className:"text-xs text-gray-500 mt-1",children:"Existing posts are left completely untouched. Safe default."})]}),e.jsxs("button",{type:"button",onClick:()=>B("update"),className:`flex-1 text-left p-4 rounded-lg border-2 transition-colors ${N==="update"?"border-amber-500 bg-amber-50":"border-gray-200 bg-white hover:border-gray-300"}`,children:[e.jsx("p",{className:"font-semibold text-sm text-gray-900",children:I.update}),e.jsx("p",{className:"text-xs text-gray-500 mt-1",children:"Existing posts are updated, but only where the CSV has a non-blank value. Blank cells never replace existing content."})]})]})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-4 items-center",children:[e.jsx("input",{type:"file",accept:".csv",ref:y,onChange:M,className:"block w-full text-sm text-gray-500 file:mr-4 file:py-2.5 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100 border border-gray-300 rounded-md",disabled:L}),e.jsxs(m,{onClick:J,disabled:!o||L,className:"w-full sm:w-auto bg-[var(--primary-blue)] text-white hover:bg-blue-700 min-w-[160px]",children:[e.jsx($,{className:"w-4 h-4 mr-2"})," Preview Import"]})]})]}),(d==="previewing"||d==="preview")&&e.jsxs("div",{className:"space-y-5",children:[d==="previewing"&&e.jsxs("div",{className:"flex items-center justify-center py-12",children:[e.jsx(O,{className:"w-6 h-6 animate-spin text-[var(--primary-blue)]"}),e.jsx("span",{className:"ml-3 text-sm text-gray-600",children:"Generating previewâ¦"})]}),d==="preview"&&r&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-gray-700",children:[e.jsx($,{className:"w-4 h-4 text-[var(--primary-blue)]"}),e.jsx("span",{className:"font-semibold",children:"Preview"}),e.jsx("span",{className:"text-gray-400",children:"·"}),e.jsxs("span",{children:["Mode: ",e.jsx("strong",{children:I[r.mode||N]})]}),e.jsx("span",{className:"text-gray-400",children:"·"}),e.jsxs("span",{children:[p?.length||0," valid rows"]})]}),R(r),r.mode==="insert"&&(r.skipped||0)>0&&e.jsxs("div",{className:"bg-yellow-50 border border-yellow-200 rounded-lg p-4 text-sm text-yellow-800 flex gap-3",children:[e.jsx(te,{className:"w-5 h-5 flex-shrink-0"}),e.jsxs("div",{children:[e.jsx("strong",{children:r.skipped})," existing post",r.skipped!==1?"s":""," will be left untouched (insert-only mode). Switch to âInsert + Update existingâ and re-preview to modify them."]})]}),z(r.changes),r.warnings&&r.warnings.length>0&&e.jsx("div",{className:"bg-yellow-50 text-yellow-800 rounded-lg p-4 text-sm max-h-64 overflow-y-auto border border-yellow-200",children:r.warnings.map((s,t)=>e.jsx("div",{className:"mb-1 border-b border-yellow-200 pb-1 last:border-0",children:s},t))}),A(r.errors),u>0?e.jsxs("div",{className:"border-2 border-amber-300 rounded-lg p-4 bg-amber-50 space-y-3",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(U,{className:"w-5 h-5 text-amber-700 flex-shrink-0 mt-0.5"}),e.jsxs("div",{className:"text-sm text-amber-900",children:[e.jsx("p",{className:"font-semibold",children:"Confirm before writing"}),e.jsxs("p",{className:"mt-1",children:["This will write ",e.jsx("strong",{children:u})," row",u!==1?"s":""," (",r.created," created, ",r.updated," updated). Type ",e.jsx("strong",{className:"font-mono",children:u})," below to enable the execute button. Nothing is written until you confirm."]})]})]}),e.jsx("input",{type:"text",value:P,onChange:s=>j(s.target.value),placeholder:`Type ${u} to confirm`,className:"w-full max-w-xs rounded-md border border-amber-300 bg-white px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-amber-400"}),e.jsxs("div",{className:"flex justify-end gap-3",children:[e.jsx(m,{variant:"outline",onClick:()=>{l("idle"),h(null),j("")},children:"Back"}),e.jsxs(m,{onClick:W,disabled:!C,className:C?"bg-amber-600 hover:bg-amber-700 text-white":"",children:[e.jsx(re,{className:"w-4 h-4 mr-2"})," Confirm & Execute"]})]})]}):e.jsxs("div",{className:"flex justify-end gap-3",children:[e.jsx(m,{variant:"outline",onClick:()=>{l("idle"),h(null)},children:"Back"}),e.jsx(m,{disabled:!0,className:"opacity-60 cursor-not-allowed",children:"Nothing to write"})]})]})]}),d==="executing"&&e.jsxs("div",{className:"flex items-center justify-center py-12",children:[e.jsx(O,{className:"w-6 h-6 animate-spin text-[var(--primary-blue)]"}),e.jsx("span",{className:"ml-3 text-sm text-gray-600",children:"Writingâ¦"})]}),d==="results"&&g&&e.jsxs("div",{className:"space-y-6 animate-in fade-in slide-in-from-bottom-4 duration-500",children:[e.jsxs("div",{className:"flex items-center gap-2 text-green-700",children:[e.jsx(S,{className:"w-5 h-5"}),e.jsx("span",{className:"font-semibold",children:"Import complete"})]}),R(g),g.warnings&&g.warnings.length>0&&e.jsx("div",{className:"bg-yellow-50 text-yellow-800 rounded-lg p-4 text-sm max-h-64 overflow-y-auto border border-yellow-200",children:g.warnings.map((s,t)=>e.jsx("div",{className:"mb-1 border-b border-yellow-200 pb-1 last:border-0",children:s},t))}),A(g.errors),e.jsxs("div",{className:"flex justify-end gap-3 pt-2",children:[e.jsx(m,{variant:"outline",onClick:q,children:"Import Another"}),e.jsx(m,{onClick:()=>V("/admin/blog"),children:"Done"})]})]})]})]})]})};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.