PageSourceSearch

https://lehnerdigitalwebsite.replit.app/assets/admin-article-editor-d4edkqx5.js

js lehnerdigitalwebsite.replit.app collected 2026-10-03 03:56:11 UTC 31,873 bytes, 57 lines download raw bytes

1import{c as _,r,j as e,v as ee,R as Me,w as Pe,x as be,y as Re,z as fe,D as Le,E as Oe,u as Ue,n as ze,s as ye,m as Be,h as me,L as Y,B,q as U,H as M,I as $,t as H,X as qe,J as xe}from"./index-D0ytri6Z.js";import{A as Fe}from"./arrow-left-Do6ZUn1z.js";import{E as Z,L as De,a as He,S as Ge,T as Qe}from"./trash-2-BdadaBAH.js";import{Q as Ke}from"./quote-D9K-2Unz.js";import{L as te,C as Je}from"./link-2-BKfNnhQY.js";/**
2 * @license lucide-react v0.545.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const Ve=[["path",{d:"m18 15-6-6-6 6",key:"153udz"}]],pe=_("chevron-up",Ve);/**
7 * @license lucide-react v0.545.0 - ISC
8 *
9 * This source code is licensed under the ISC license.
10 * See the LICENSE file in the root directory of this source tree.
11 */const We=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M7 3v18",key:"bbkbws"}],["path",{d:"M3 7.5h4",key:"zfgn84"}],["path",{d:"M3 12h18",key:"1i2n21"}],["path",{d:"M3 16.5h4",key:"1230mu"}],["path",{d:"M17 3v18",key:"in4fa5"}],["path",{d:"M17 7.5h4",key:"myr1c1"}],["path",{d:"M17 16.5h4",key:"go4c1d"}]],Xe=_("film",We);/**
12 * @license lucide-react v0.545.0 - ISC
13 *
14 * This source code is licensed under the ISC license.
15 * See the LICENSE file in the root directory of this source tree.
16 */const Ye=[["circle",{cx:"9",cy:"12",r:"1",key:"1vctgf"}],["circle",{cx:"9",cy:"5",r:"1",key:"hp0tcf"}],["circle",{cx:"9",cy:"19",r:"1",key:"fkjjf6"}],["circle",{cx:"15",cy:"12",r:"1",key:"1tmaij"}],["circle",{cx:"15",cy:"5",r:"1",key:"19l28e"}],["circle",{cx:"15",cy:"19",r:"1",key:"f4zoj3"}]],Ze=_("grip-vertical",Ye);/**
17 * @license lucide-react v0.545.0 - ISC
18 *
19 * This source code is licensed under the ISC license.
20 * See the LICENSE file in the root directory of this source tree.
21 */const et=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",ry:"2",key:"1m3agn"}],["circle",{cx:"9",cy:"9",r:"2",key:"af1f0g"}],["path",{d:"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21",key:"1xmnt7"}]],tt=_("image",et);/**
22 * @license lucide-react v0.545.0 - ISC
23 *
24 * This source code is licensed under the ISC license.
25 * See the LICENSE file in the root directory of this source tree.
26 */const st=[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]],ge=_("save",st);/**
27 * @license lucide-react v0.545.0 - ISC
28 *
29 * This source code is licensed under the ISC license.
30 * See the LICENSE file in the root directory of this source tree.
31 */const at=[["path",{d:"M8.34 8.34 2 9.27l5 4.87L5.82 21 12 17.77 18.18 21l-.59-3.43",ke
vendor: 5,859 bytes, lines 31-56
31y:"16m0ql"}],["path",{d:"M18.42 12.76 22 9.27l-6.91-1L12 2l-1.44 2.91",key:"1vt8nq"}],["line",{x1:"2",x2:"22",y1:"2",y2:"22",key:"a6p6uj"}]],it=_("star-off",at);/**
32 * @license lucide-react v0.545.0 - ISC
33 *
34 * This source code is licensed under the ISC license.
35 * See the LICENSE file in the root directory of this source tree.
36 */const rt=[["path",{d:"M21 5H3",key:"1fi0y6"}],["path",{d:"M15 12H3",key:"6jk70r"}],["path",{d:"M17 19H3",key:"z6ezky"}]],we=_("text-align-start",rt);/**
37 * @license lucide-react v0.545.0 - ISC
38 *
39 * This source code is licensed under the ISC license.
40 * See the LICENSE file in the root directory of this source tree.
41 */const nt=[["path",{d:"M12 4v16",key:"1654pz"}],["path",{d:"M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2",key:"e0r10z"}],["path",{d:"M9 20h6",key:"s66wpe"}]],lt=_("type",nt);/**
42 * @license lucide-react v0.545.0 - ISC
43 *
44 * This source code is licensed under the ISC license.
45 * See the LICENSE file in the root directory of this source tree.
46 */const ot=[["path",{d:"m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72",key:"ul74o6"}],["path",{d:"m14 7 3 3",key:"1r5n42"}],["path",{d:"M5 6v4",key:"ilb8ba"}],["path",{d:"M19 14v4",key:"blhpug"}],["path",{d:"M10 2v2",key:"7u0qdc"}],["path",{d:"M7 8H3",key:"zfb6yr"}],["path",{d:"M21 16h-4",key:"1cnmox"}],["path",{d:"M11 3H9",key:"1obp7u"}]],I=_("wand-sparkles",ot);/**
47 * @license lucide-react v0.545.0 - ISC
48 *
49 * This source code is licensed under the ISC license.
50 * See the LICENSE file in the root directory of this source tree.
51 */const ct=[["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["line",{x1:"21",x2:"16.65",y1:"21",y2:"16.65",key:"13gj7c"}],["line",{x1:"11",x2:"11",y1:"8",y2:"14",key:"1vmskp"}],["line",{x1:"8",x2:"14",y1:"11",y2:"11",key:"durymu"}]],dt=_("zoom-in",ct);/**
52 * @license lucide-react v0.545.0 - ISC
53 *
54 * This source code is licensed under the ISC license.
55 * See the LICENSE file in the root directory of this source tree.
56 */const ut=[["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["line",{x1:"21",x2:"16.65",y1:"21",y2:"16.65",key:"13gj7c"}],["line",{x1:"8",x2:"14",y1:"11",y2:"11",key:"durymu"}]],ht=_("zoom-out",ut),q=r.forwardRef(({className:t,...l},i)=>e.jsx("textarea",{className:ee("flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",t),ref:i,...l}));q.displayName="Textarea";function mt(t,l,{checkForDefaultPrevented:i=!0}={}){return function(o){if(t?.(o),i===!1||!o.defaultPrevented)return l?.(o)}}var xt=Me[" useInsertionEffect ".trim().toString()]||Pe;function pt({prop:t,defaultProp:l,onChange:i=()=>{},caller:x}){const[o,h,m]=gt({defaultProp:l,onChange:i}),c=t!==void 0,v=c?t:o;{const d=r.useRef(t!==void 0);r.useEffect(()=>{const b=d.current;b!==c&&console.warn(`${x} is changing from ${b?"controlled":"uncontrolled"} to ${c?"controlled":"uncontrolled"}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),d.current=c},[c,x])}const g=r.useCallback(d=>{if(c){const b=bt(d)?d(t):d;b!==t&&m.current?.(b)}else h(d)},[c,t,h,m]);return[v,g]}function gt({defaultProp:t,onChange:l}){const[i,x]=r.useState(t),o=r.useRef(i),h=r.useRef(l);return xt(()=>{h.current=l},[l]),r.useEffect(()=>{o.current!==i&&(h.current?.(i),o.current=i)},[i,o]),[i,x,h]}function bt(t){return typeof t=="function"}var G="Switch",[ft]=Re(G),[yt,wt]=ft(G),ve=r.forwardRef((t,l)=>{const{__scopeSwitch:i,name:x,checked:o,defaultChecked:h,required:m,disabled:c,value:v="on",onCheckedChange:g,form:d,...b}=t,[y,w]=r.useState(null),f=be(l,k=>w(k)),j=r.useRef(!1),N=y?d||!!y.closest("form"):!0,[A,p]=pt({prop:o,defaultProp:h??!1,onChange:g,caller:G});return e.jsxs(yt,{scope:i,checked:A,disabled:c,children:[e.jsx(fe.button,{type:"button",role:"switch","aria-checked":A,"aria-required":m,"data-state":Ce(A),"data-disabled":c?"":void 0,disabled:c,value:v,...b,ref:f,onClick:mt(t.onClick,k=>{p(E=>!E),N&&(j.current=k.isPropagationStopped(),j.current||k.stopPropagation())})}),N&&e.jsx(ke,{control:y,bubbles:!j.current,name:x,value:v,checked:A,required:m,disabled:c,form:d,style:{transform:"translateX(-100%)"}})]})});ve.displayName=G;var je="SwitchThumb",Ne=r.forwardRef((t,l)=>{const{__scopeSwitch:i,...x}=t,o=wt(je,i);return e.jsx(fe.span,{"data-state":Ce(o.checked),"data-disabled":o.disabled?"":void 0,...x,ref:l})});Ne.displayName=je;var vt="SwitchBubbleInput",ke=r.forwardRef(({__scopeSwitch:t,control:l,checked:i,bubbles:x=!0,...o},h)=>{const m=r.useRef(null),c=be(m,h),v=Le(i),g=Oe(l);return r.useEffect(()=>{const d=m.current;if(!d)return;const b=window.HTMLInputElement.prototype,w=Object.getOwnPropertyDescriptor(b,"checked").set;if(v!==i&&w){const f=new Event("click",{bubbles:x});w.call(d,i),d.dispatchEvent(f)}},[v,i,x]),e.jsx("input",{type:"checkbox","aria-hidden":!0,defaultChecked:i,...o,tabIndex:-1,ref:c,style:{...o.style,...g,position:"absolute",pointerEvents:"none",opacity:0,margin:0}})});ke.displayName=vt;function Ce(t){return t?"checked":"unchecked"}var Se=ve,jt=Ne;const se=r.forwardRef(({className:t,...l},i)=>e.jsx(Se,{className:ee("peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",t),...l,ref:i,children:e.jsx(jt,{className:ee("pointer-events-none block h-4 w-4 roun
56ded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0")})}));se.displayName=Se.displayName;const ie=[{type:"paragraph",label:"Paragraph",icon:we},{type:"heading",label:"Heading",icon:lt},{type:"quote",label:"Pull Quote",icon:Ke},{type:"image",label:"Image",icon:tt},{type:"feature_image",label:"Feature Image",icon:dt},{type:"feature_image_small",label:"Feature Image Small",icon:ht},{type:"video",label:"Video",icon:Xe},{type:"link",label:"Featured Link",icon:te}];function Nt(t){return ie.find(l=>l.type===t)?.label||t}function kt({type:t}){const l=ie.find(i=>i.type===t);return l?e.jsx(l.icon,{className:"w-4 h-4"}):e.jsx(we,{className:"w-4 h-4"})}async function ae(t,l,i,x,o,h){const m=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json","x-admin-secret":i},body:JSON.stringify(l)});if(!m.body){h("No response body");return}const c=m.body.getReader(),v=new TextDecoder;let g="";for(;;){const{done:d,value:b}=await c.read();if(d)break;g+=v.decode(b,{stream:!0});const y=g.split(`
57`);g=y.pop()||"";for(const w of y)if(w.startsWith("data: "))try{const f=JSON.parse(w.slice(6));if(f.error){h(f.error);return}if(f.done){o(f.fullContent||"");return}f.delta&&x(f.delta)}catch{}}}function Ct({block:t,articleTitle:l,articleSummary:i,secret:x,onUpdate:o,onDelete:h,onMoveUp:m,onMoveDown:c,isFirst:v,isLast:g}){const[d,b]=r.useState(!0),[y,w]=r.useState(!1),[f,j]=r.useState("");function N(p,k){o(t.id,{[p]:k})}async function A(){w(!0);let p="";await ae("/api/ai/generate-article-block",{blockType:t.blockType,articleTitle:l,articleSummary:i,seedText:f},x,k=>{p+=k},k=>{const E=k||p;if(t.blockType==="quote"||t.blockType==="link")try{const F=JSON.parse(E.replace(/```json\n?|```/g,"").trim());o(t.id,F)}catch{o(t.id,{content:E})}else o(t.id,{content:E});w(!1)},k=>{w(!1)})}return e.jsxs("div",{className:"border border-white/10 rounded-xl bg-slate-900/50 overflow-hidden mb-3","data-testid":`block-${t.id}`,children:[e.jsxs("div",{className:"flex items-center gap-3 px-4 py-3 border-b border-white/10 bg-slate-900",children:[e.jsx(Ze,{className:"w-4 h-4 text-slate-600 cursor-grab"}),e.jsx(kt,{type:t.blockType}),e.jsx("span",{className:"text-sm font-medium text-slate-300",children:Nt(t.blockType)}),e.jsxs("div",{className:"flex items-center gap-1 ml-auto",children:[e.jsx("button",{onClick:A,disabled:y,className:"p-1.5 rounded hover:bg-white/10 text-indigo-400 hover:text-indigo-300 transition-colors disabled:opacity-50",title:"AI generate","data-testid":`btn-ai-block-${t.id}`,children:y?e.jsx(U,{className:"w-3.5 h-3.5 animate-spin"}):e.jsx(I,{className:"w-3.5 h-3.5"})}),e.jsx("button",{onClick:()=>m(t.id),disabled:v,className:"p-1.5 rounded hover:bg-white/10 text-slate-400 hover:text-white transition-colors disabled:opacity-30","data-testid":`btn-move-up-${t.id}`,children:e.jsx(pe,{className:"w-3.5 h-3.5"})}),e.jsx("button",{onClick:()=>c(t.id),disabled:g,className:"p-1.5 rounded hover:bg-white/10 text-slate-400 hover:text-white transition-colors disabled:opacity-30","data-testid":`btn-move-down-${t.id}`,children:e.jsx(xe,{className:"w-3.5 h-3.5"})}),e.jsx("button",{onClick:()=>b(!d),className:"p-1.5 rounded hover:bg-white/10 text-slate-400 hover:text-white transition-colors",children:d?e.jsx(pe,{className:"w-3.5 h-3.5"}):e.jsx(xe,{className:"w-3.5 h-3.5"})}),e.jsx("button",{onClick:()=>h(t.id),className:"p-1.5 rounded hover:bg-red-500/20 text-slate-400 hover:text-red-400 transition-colors","data-testid":`btn-delete-block-${t.id}`,children:e.jsx(Qe,{className:"w-3.5 h-3.5"})})]})]}),d&&e.jsxs("div",{className:"p-4 space-y-3",children:[e.jsx("div",{className:"flex gap-2",children:e.jsx($,{value:f,onChange:p=>j(p.target.value),placeholder:"AI hint (optional)...",className:"text-xs h-7 bg-slate-800 border-white/10 text-slate-400 placeholder:text-slate-600","data-testid":`input-seed-${t.id}`})}),["heading","quote","link","feature_image","feature_image_small","image","video"].includes(t.blockType)&&e.jsx($,{value:t.title||"",onChange:p=>N("title",p.target.value),placeholder:t.blockType==="quote"?"Attribution":t.blockType==="link"?"Link title":"Title / heading text",className:"bg-slate-800 border-white/10 text-white","data-testid":`input-title-${t.id}`}),["paragraph","quote","link","image","feature_image","feature_image_small"].includes(t.blockType)&&e.jsx(q,{value:t.content||"",onChange:p=>N("content",p.target.value),placeholder:t.blockType==="paragraph"?"Paragraph text... (**bold**, _italic_)":t.blockType==="quote"?"Quote text...":t.blockType==="link"?"Description...":"Caption (optional)...",rows:t.blockType==="paragraph"?5:3,className:"bg-slate-800 border-white/10 text-white resize-none","data-testid":`textarea-content-${t.id}`}),t.blockType==="video"&&e.jsx($,{value:t.content||"",onChange:p=>N("content",p.target.value),placeholder:"YouTube or Vimeo URL",className:"bg-slate-800 border-white/10 text-white","data-testid":`input-video-${t.id}`}),["image","feature_image","feature_image_small"].includes(t.blockType)&&e.jsx($,{value:t.imageUrl||"",onChange:p=>N("imageUrl",p.target.value),placeholder:"Image URL",className:"bg-slate-800 border-white/10 text-white","data-testid":`input-image-url-${t.id}`}),t.blockType==="link"&&e.jsx($,{value:t.metadata?.url||"",onChange:p=>N("metadata",{url:p.target.value}),placeholder:"https://...",className:"bg-slate-800 border-white/10 text-white","data-testid":`input-link-url-${t.id}`})]})]})}function St({value:t,onChange:l,secret:i,articleTitle:x}){const{toast:o}=ye(),[h,m]=r.useState("preview"),[c,v]=r.useState(t),[g,d]=r.useState(""),[b,y]=r.useState(!1);async function w(){y(!0);try{const N=await(await fetch("/api/ai/generate-thumbnail",{method:"POST",headers:{"Content-Type":"application/json","x-admin-secret":i},body:JSON.stringify({prompt:g||void 0,articleTitle:x})})).json();N.url?(l(N.url),m("preview"),d("")):o({title:"Generation failed",description:N.error||"Unknown error",variant:"destructive"})}catch{o({title:"Error",description:"Could not generate image",variant:"destructive"})}y(!1)}function f(){l(c.trim()),m("preview")}return e.jsxs("div",{children:[e.jsx(M,{className:"text-slate-400 text-xs mb-1.5 block",children:"Thumbnail / Hero Image"}),t&&h==="preview"&&e.jsxs("div",{className:"relative group rounded-xl overflow-hidden border border-white/10",children:[e.jsx("img",{src:t,alt:"Hero preview",className:"w-full h-44 object-cover","data-testid":"img-hero-preview"}),e.jsxs("div",{className:"absolute inset-0 bg-black/60 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center gap-3",children:[e.jsxs("button",{onClick:()=>{v(t),m("url")},className:"px-3 py-1.5 rounded-lg bg-white/10 hover:bg-white/20 text-white text-xs font-medium transition-colors flex items-center gap-1.5","data-testid":"btn-change-thumbnail-url",children:[e.jsx(te,{className:"w-3.5 h-3.5"}),"Change URL"]}),e.jsxs("button",{onClick:()=>m("ai"),className:"px-3 py-1.5 rounded-lg bg-indigo-500/80 hover:bg-indigo-500 text-white text-xs font-medium transition-colors flex items-center gap-1.5","data-testid":"btn-regenerate-thumbnail",children:[e.jsx(I,{className:"w-3.5 h-3.5"}),"Regenerate"]}),e.jsxs("button",{onClick:()=>l(""),className:"px-3 py-1.5 rounded-lg bg-red-500/70 hover:bg-red-500 text-white text-xs font-medium transition-colors flex items-center gap-1.5","data-testid":"btn-remove-thumbnail",children:[e.jsx(qe,{className:"w-3.5 h-3.5"}),"Remove"]})]})]}),!t&&h==="preview"&&e.jsxs("div",{className:"rounded-xl border border-dashed border-white/15 bg-slate-900/40 h-44 flex flex-col items-center justify-center gap-3",children:[e.jsx("p",{className:"text-xs text-slate-500",children:"No thumbnail set"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{onClick:()=>{v(""),m("url")},className:"px-3 py-1.5 rounded-lg bg-white/8 hover:bg-white/15 text-slate-300 text-xs font-medium transition-colors flex items-center gap-1.5 border border-white/10","data-testid":"btn-add-thumbn
57ail-url",children:[e.jsx(te,{className:"w-3.5 h-3.5"}),"Paste URL"]}),e.jsxs("button",{onClick:()=>m("ai"),className:"px-3 py-1.5 rounded-lg bg-indigo-600/70 hover:bg-indigo-600 text-white text-xs font-medium transition-colors flex items-center gap-1.5","data-testid":"btn-ai-generate-thumbnail",children:[e.jsx(I,{className:"w-3.5 h-3.5"}),"AI Generate"]})]})]}),h==="url"&&e.jsxs("div",{className:"space-y-2",children:[e.jsx($,{value:c,onChange:j=>v(j.target.value),onKeyDown:j=>j.key==="Enter"&&f(),placeholder:"https://...",className:"bg-slate-900 border-white/10 text-white",autoFocus:!0,"data-testid":"input-hero-image"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{onClick:f,className:"px-3 py-1.5 rounded-lg bg-indigo-600 hover:bg-indigo-500 text-white text-xs font-medium transition-colors flex items-center gap-1.5",children:[e.jsx(Je,{className:"w-3.5 h-3.5"}),"Apply"]}),e.jsx("button",{onClick:()=>m("preview"),className:"px-3 py-1.5 rounded-lg bg-white/8 hover:bg-white/15 text-slate-400 text-xs font-medium transition-colors border border-white/10",children:"Cancel"}),e.jsxs("button",{onClick:()=>m("ai"),className:"ml-auto px-3 py-1.5 rounded-lg bg-indigo-500/20 hover:bg-indigo-500/30 text-indigo-300 text-xs font-medium transition-colors flex items-center gap-1.5",children:[e.jsx(I,{className:"w-3.5 h-3.5"}),"AI Generate instead"]})]})]}),h==="ai"&&e.jsxs("div",{className:"rounded-xl border border-indigo-500/20 bg-indigo-500/5 p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(I,{className:"w-4 h-4 text-indigo-400"}),e.jsx("span",{className:"text-sm font-medium text-indigo-300",children:"AI Image Generation"})]}),e.jsx("textarea",{value:g,onChange:j=>d(j.target.value),placeholder:`Leave blank to auto-generate from article title${x?`: "${x}"`:""}. Or describe the image you want…`,rows:3,className:"w-full bg-slate-900 border border-white/10 rounded-lg px-3 py-2 text-sm text-white placeholder-slate-500 focus:outline-none focus:border-indigo-500/50 resize-none","data-testid":"input-thumbnail-prompt"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{onClick:w,disabled:b,className:"px-4 py-1.5 rounded-lg bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 text-white text-xs font-medium transition-colors flex items-center gap-1.5","data-testid":"btn-generate-thumbnail",children:b?e.jsxs(e.Fragment,{children:[e.jsx(U,{className:"w-3.5 h-3.5 animate-spin"}),"Generating…"]}):e.jsxs(e.Fragment,{children:[e.jsx(I,{className:"w-3.5 h-3.5"}),"Generate"]})}),e.jsx("button",{onClick:()=>m("preview"),disabled:b,className:"px-3 py-1.5 rounded-lg bg-white/8 hover:bg-white/15 text-slate-400 text-xs font-medium transition-colors border border-white/10 disabled:opacity-50",children:"Cancel"})]}),b&&e.jsxs("p",{className:"text-xs text-slate-500 flex items-center gap-1.5",children:[e.jsx("span",{className:"w-1 h-1 rounded-full bg-indigo-400 animate-pulse"}),"This usually takes 10–15 seconds…"]})]})]})}function Et(){const{id:t}=Ue(),l=t==="new",i=l?null:parseInt(t||"0"),[,x]=ze(),{toast:o}=ye(),{secret:h,logout:m}=Be();function c(s,n,a){return fetch(n,{method:s,headers:{"Content-Type":"application/json","x-admin-secret":h||""},body:a?JSON.stringify(a):void 0}).then(u=>u.json())}function v(){m(),x("/admin/login")}const[g,d]=r.useState(""),[b,y]=r.useState(""),[w,f]=r.useState(""),[j,N]=r.useState(""),[A,p]=r.useState(""),[k,E]=r.useState(""),[F,re]=r.useState(""),[Q,ne]=r.useState(!1),[K,le]=r.useState(!1),[P,R]=r.useState([]),[D,Te]=r.useState(""),[oe,J]=r.useState(!1),[L,V]=r.useState(null),[S,ce]=r.useState(i),{data:C}=me({queryKey:["/api/articles",i],queryFn:()=>fetch(`/api/articles/${i}`).then(s=>s.json()),enabled:!l&&!!i}),{data:W=[]}=me({queryKey:["/api/articles",i,"blocks"],queryFn:()=>fetch(`/api/articles/${i}/blocks`).then(s=>s.json()),enabled:!l&&!!i});r.useEffect(()=>{C&&(d(C.title||""),y(C.subtitle||""),f(C.summary||""),N(C.metaDescription||""),p((C.tags||[]).join(", ")),E(C.readTimeMinutes?.toString()||""),re(C.heroImageUrl||""),ne(C.published),le(C.featured),ce(C.id))},[C]),r.useEffect(()=>{W.length>0&&R(W)},[W]);async function de(){const s={title:g||"Untitled",subtitle:b||null,summary:w||null,metaDescription:j||null,tags:A.split(",").map(n=>
57n.trim()).filter(Boolean),readTimeMinutes:k?parseInt(k):null,heroImageUrl:F||null,published:Q,featured:K};try{let n;S?n=await c("PATCH",`/api/articles/${S}`,s):(n=await c("POST","/api/articles",s),ce(n.id),x(`/admin/article/${n.id}`,{replace:!0}));for(const a of P)a.id<0?await c("POST",`/api/articles/${n.id}/blocks`,{blockType:a.blockType,title:a.title,content:a.content,imageUrl:a.imageUrl,metadata:a.metadata,sortOrder:a.sortOrder}):await c("PATCH",`/api/article-blocks/${a.id}`,{title:a.title,content:a.content,imageUrl:a.imageUrl,metadata:a.metadata,sortOrder:a.sortOrder});if(H.invalidateQueries({queryKey:["/api/articles/published"]}),H.invalidateQueries({queryKey:["/api/articles",S||n.id]}),H.invalidateQueries({queryKey:["/api/articles",S||n.id,"blocks"]}),o({title:"Saved!",description:"Article saved successfully."}),n.id){const a=await fetch(`/api/articles/${n.id}/blocks`).then(u=>u.json());R(a)}}catch{o({title:"Error",description:"Failed to save article.",variant:"destructive"})}}const ue=r.useRef(-1);function Ie(s){const n={id:ue.current--,articleId:S||0,blockType:s,title:null,content:null,imageUrl:null,metadata:null,sortOrder:P.length};R(a=>[...a,n])}function _e(s,n){R(a=>a.map(u=>u.id===s?{...u,...n}:u))}async function Ae(s){s>0&&(await c("DELETE",`/api/article-blocks/${s}`),H.invalidateQueries({queryKey:["/api/articles",S,"blocks"]})),R(n=>n.filter(a=>a.id!==s))}function he(s,n){R(a=>{const u=a.findIndex(z=>z.id===s);if(u<0)return a;const O=n==="up"?u-1:u+1;if(O<0||O>=a.length)return a;const T=[...a];return[T[u],T[O]]=[T[O],T[u]],T.map((z,Ee)=>({...z,sortOrder:Ee}))})}async function $e(){if(!D.trim())return;J(!0);let s="";await ae("/api/ai/generate-article",{prompt:D},h||"",n=>{s+=n},n=>{const a=n||s;try{const u=JSON.parse(a.replace(/```json\n?|```/g,"").trim());if(d(u.title||""),y(u.subtitle||""),f(u.summary||""),N(u.metaDescription||""),p((u.tags||[]).join(", ")),E(u.readTimeMinutes?.toString()||""),u.blocks&&Array.isArray(u.blocks)){const O=u.blocks.map((T,z)=>({id:ue.current--,articleId:S||0,blockType:T.blockType||"paragraph",title:T.title||null,content:T.content||null,imageUrl:T.imageUrl||null,metadata:T.metadata||null,sortOrder:z}));R(O)}}catch{o({title:"Parse error",description:"AI returned unexpected format.",variant:"destructive"})}J(!1)},n=>{o({title:"AI Error",description:n,variant:"destructive"}),J(!1)})}async function X(s){V(s);let n="";await ae("/api/ai/generate-article-field",{field:s,articleTitle:g,articleSummary:w,articleTags:A.split(",").map(a=>a.trim())},h||"",a=>{n+=a},a=>{const u=(a||n).trim();s==="summary"&&f(u),s==="metaDescription"&&N(u),s==="subtitle"&&y(u),V(null)},a=>{V(null)})}return e.jsxs("div",{className:"min-h-screen bg-slate-950 text-white",children:[e.jsx("header",{className:"sticky top-0 z-50 border-b border-white/10 bg-slate-950/95 backdrop-blur-sm",children:e.jsxs("div",{className:"max-w-5xl mx-auto px-6 h-14 flex items-center gap-4",children:[e.jsxs(Y,{href:"/articles",className:"flex items-center gap-2 text-sm text-slate-400 hover:text-white transition-colors",children:[e.jsx(Fe,{className:"w-4 h-4"}),"Articles"]}),e.jsx("span",{className:"text-white/20",children:"/"}),e.jsx("span",{className:"text-sm text-slate-300 truncate max-w-xs",children:g||"New Article"}),e.jsxs("div",{className:"flex items-center gap-2 ml-auto",children:[S&&e.jsx(Y,{href:`/article/${S}`,target:"_blank",children:e.jsxs(B,{variant:"ghost",size:"sm",className:"text-slate-400 hover:text-white",children:[e.jsx(Z,{className:"w-4 h-4 mr-1.5"}),"Preview"]})}),e.jsxs(B,{onClick:de,size:"sm",className:"bg-indigo-600 hover:bg-indigo-500 text-white","data-testid":"btn-save-article",children:[e.jsx(ge,{className:"w-4 h-4 mr-1.5"}),"Save"]}),e.jsx("button",{onClick:v,className:"p-2 rounded-lg text-slate-500 hover:text-white hover:bg-white/10 transition-colors",title:"Sign out","data-testid":"btn-logout",children:e.jsx(De,{className:"w-4 h-4"})})]})]})}),e.jsxs("div",{className:"max-w-5xl mx-auto px-6 py-10 grid grid-cols-1 lg:grid-cols-[1fr_280px] gap-10",children:[e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{className:"rounded-xl border border-indigo-500/20 bg-indigo-500/5 p-5",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx(I,{className:"w-4 h-4 text-indigo-400"}),e.jsx("span",{className:"text-sm font-semibold text-indigo-300",children:"AI Article Generator"})]}),e.jsx(q,{value:D,onChange:s=>Te(s.target.value),placeholder:"Describe the article topic, e.g. 'How AI automation reduces operational costs for mid-size businesses'...",rows:3,className:"bg-slate-900 border-white/10 text-white mb-3 resize-none","data-testid":"textarea-ai-prompt"}),e.jsx(B,{onClick:$e,disabled:oe||!D.trim(),className:"bg-indigo-600 hover:bg-indigo-500 text-white w-full","data-testid":"btn-generate-article",children:oe?e.jsxs(e.Fragment,{children:[e.jsx(U,{className:"w-4 h-4 mr-2 animate-spin"}),"Writing your article… this takes 15–30 seconds"]}):e.jsxs(e.Fragment,{children:[e.jsx(I,{className:"w-4 h-4 mr-2"}),"Generate Full Article"]})})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(M,{className:"text-slate-400 text-xs mb-1.5 block",children:"Title *"}),e.jsx($,{value:g,onChange:s=>d(s.target.value),placeholder:"Article title",className:"bg-slate-900 border-white/10 text-white text-lg font-['Lora']","data-testid":"input-article-title"})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-1.5",children:[e.jsx(M,{className:"text-slate-400 text-xs",children:"Subtitle"}),e.jsxs("button",{onClick:()=>X("subtitle"),disabled:L==="subtitle",className:"text-xs text-indigo-400 hover:text-indigo-300 flex items-center gap-1 disabled:opacity-50",children:[L==="subtitle"?e.jsx(U,{className:"w-3 h-3 animate-spin"}):e.jsx(I,{className:"w-3 h-3"}),"AI"]})]}),e.jsx($,{value:b,onChange:s=>y(s.target.value),placeholder:"Optional subtitle",className:"bg-slate-900 border-white/10 text-white","data-testid":"input-article-subtitle"})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-1.5",children:[e.jsx(M,{className:"text-slate-400 text-xs",children:"Summary"}),e.jsxs("button",{onClick:()=>X("summary"),disabled:L==="summary",className:"text-xs text-indigo-400 hover:text-indigo-300 flex items-center gap-1 disabled:opacity-50",children:[L==="summary"?e.jsx(U,{className:"w-3 h-3 animate-spin"}):e.jsx(I,{className:"w-3 h-3"}),"AI"]})]}),e.jsx(q,{value:w,onChange:s=>
57f(s.target.value),placeholder:"2-3 sentence summary shown on listing cards...",rows:3,className:"bg-slate-900 border-white/10 text-white resize-none","data-testid":"textarea-article-summary"})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-1.5",children:[e.jsxs(M,{className:"text-slate-400 text-xs",children:["Meta Description",e.jsxs("span",{className:`ml-2 text-xs ${j.length>160?"text-red-400":"text-slate-500"}`,children:[j.length,"/160"]})]}),e.jsxs("button",{onClick:()=>X("metaDescription"),disabled:L==="metaDescription",className:"text-xs text-indigo-400 hover:text-indigo-300 flex items-center gap-1 disabled:opacity-50",children:[L==="metaDescription"?e.jsx(U,{className:"w-3 h-3 animate-spin"}):e.jsx(I,{className:"w-3 h-3"}),"AI"]})]}),e.jsx(q,{value:j,onChange:s=>N(s.target.value),placeholder:"SEO meta description (150-160 chars)...",rows:2,className:"bg-slate-900 border-white/10 text-white resize-none","data-testid":"textarea-meta-description"})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx(M,{className:"text-slate-400 text-xs mb-1.5 block",children:"Tags (comma-separated)"}),e.jsx($,{value:A,onChange:s=>p(s.target.value),placeholder:"AI, Automation, Strategy",className:"bg-slate-900 border-white/10 text-white","data-testid":"input-article-tags"})]}),e.jsxs("div",{children:[e.jsx(M,{className:"text-slate-400 text-xs mb-1.5 block",children:"Read Time (minutes)"}),e.jsx($,{value:k,onChange:s=>E(s.target.value),placeholder:"5",type:"number",min:"1",className:"bg-slate-900 border-white/10 text-white","data-testid":"input-read-time"})]})]}),e.jsx(St,{value:F,onChange:re,secret:h||"",articleTitle:g})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsx("h2",{className:"text-base font-semibold text-white",children:"Content Blocks"}),e.jsxs("span",{className:"text-xs text-slate-500",children:[P.length," block",P.length!==1?"s":""]})]}),P.length===0&&e.jsx("div",{className:"text-center py-10 border border-dashed border-white/10 rounded-xl text-slate-500 text-sm",children:"No blocks yet. Add one below or generate with AI."}),P.map((s,n)=>e.jsx(Ct,{block:s,articleTitle:g,articleSummary:w,secret:h||"",onUpdate:_e,onDelete:Ae,onMoveUp:a=>he(a,"up"),onMoveDown:a=>he(a,"down"),isFirst:n===0,isLast:n===P.length-1},s.id)),e.jsxs("div",{className:"mt-4",children:[e.jsx("p",{className:"text-xs text-slate-500 mb-2",children:"Add block:"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:ie.map(({type:s,label:n,icon:a})=>e.jsxs("button",{onClick:()=>Ie(s),className:"flex items-center gap-1.5 px-3 py-1.5 rounded-lg border border-white/10 bg-slate-900 text-xs text-slate-300 hover:text-white hover:border-indigo-500/40 hover:bg-indigo-500/10 transition-all","data-testid":`btn-add-block-${s}`,children:[e.jsx(a,{className:"w-3.5 h-3.5"}),n]},s))})]})]})]}),e.jsx("div",{className:"space-y-6",children:e.jsxs("div",{className:"rounded-xl border border-white/10 bg-slate-900/50 p-5 space-y-4 sticky top-20",children:[e.jsx("h3",{className:"text-sm font-semibold text-white",children:"Publish Settings"}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs(M,{className:"text-slate-300 text-sm flex items-center gap-2",children:[Q?e.jsx(Z,{className:"w-4 h-4 text-green-400"}):e.jsx(He,{className:"w-4 h-4 text-slate-500"}),"Published"]}),e.jsx(se,{checked:Q,onCheckedChange:ne,"data-testid":"switch-published"})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs(M,{className:"text-slate-300 text-sm flex items-center gap-2",children:[K?e.jsx(Ge,{className:"w-4 h-4 text-yellow-400"}):e.jsx(it,{className:"w-4 h-4 text-slate-500"}),"Featured"]}),e.jsx(se,{checked:K,onCheckedChange:le,"data-testid":"switch-featured"})]}),e.jsx("div",{className:"pt-2 border-t border-white/10",children:e.jsxs(B,{onClick:de,className:"w-full bg-indigo-600 hover:bg-indigo-500 text-white","data-testid":"btn-save-sidebar",children:[e.jsx(ge,{className:"w-4 h-4 mr-2"}),"Save Article"]})}),S&&e.jsx("div",{className:"pt-2 border-t border-white/10 space-y-2",children:e.jsx(Y,{href:`/article/${S}`,children:e.jsxs(B,{variant:"ghost",size:"sm",className:"w-full text-slate-400 hover:text-white justify-start",children:[e.jsx(Z,{className:"w-4 h-4 mr-2"}),"View article"]})})})]})})]})]})}export{Et 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.