1import{j as e}from"./vendor-trading-D1p3lq87.js";import{r as a,aa as de,ab as ce,ac as me,ad as ue,ae as xe,af as pe,ag as he,ah as ge,ai as be,aj as fe,ak as ye,al as je,am as we}from"./vendor-icons-6ckh54d_.js";import{L as H}from"./Layout-CUsvgNIy.js";import{P as O}from"./home2-CFGPzgUz.js";import{c as I}from"./slug-B26Z0VBR.js";import{b as R,c as ve,m as Ne,d as Ce,e as ke,i as Se,h as Ae}from"./blogService-FmYdNdDM.js";import{G as Be,H as Ee,q as Le,I as v,F as U}from"./App-DuU1U4az.js";import{L as Pe}from"./vendor-react-DQUjuWkt.js";import"./vendor-firebase-BholX5ft.js";import"./Icon-DjBwmRGQ.js";import"./OrderlyConnect-D8NMU3_e.js";import"./vendor-web3-BzpTdpCw.js";import"./SiteHeader-BuEhw28K.js";function V(){return Be()}async function Y(i){const{cloudName:y,uploadPreset:u,folder:d}=Ee;if(!y||!u)throw new Error("Cloudinary is not configured. Set cloudName and uploadPreset in src/config.js.");if(!i||!i.type?.startsWith("image/"))throw new Error("Please choose an image file.");const c=new FormData;c.append("file",i),c.append("upload_preset",u),d&&c.append("folder",d);const h=await fetch(`https://api.cloudinary.com/v1_1/${y}/image/upload`,{method:"POST",body:c}),g=await h.json();if(!h.ok)throw new Error(g?.error?.message||"Image upload failed.");return g.secure_url}const De=[{cmd:"undo",label:"Undo",icon:de},{cmd:"redo",label:"Redo",icon:ce},{divider:!0},{cmd:"bold",label:"Bold",icon:me},{cmd:"italic",label:"Italic",icon:ue},{cmd:"underline",label:"Underline",icon:xe},{divider:!0},{cmd:"formatBlock",arg:"P",label:"Paragraph",icon:pe},{cmd:"formatBlock",arg:"H2",label:"Heading",icon:he},{cmd:"formatBlock",arg:"H3",label:"Subheading",icon:ge},{divider:!0},{cmd:"insertUnorderedList",label:"Bullets",icon:be},{cmd:"insertOrderedList",label:"Numbers",icon:fe},{cmd:"formatBlock",arg:"BLOCKQUOTE",label:"Quote",icon:ye}],Ie=({value:i="",onChange:y,placeholder:u="Write the postâ¦"})=>{const d=a.useRef(null),c=a.useRef(null),h=a.useRef(i),[g,B]=a.useState(!1),[C,j]=a.useState("");a.useEffect(()=>{const s=d.current;s&&i!==h.current&&i!==s.innerHTML&&(s.innerHTML=i||"",h.current=i||"")},[i]);const b=()=>{const s=d.current?.innerHTML||"";h.current=s,y?.(s)},w=(s,l)=>{d.current?.focus(),document.execCommand(s,!1,l),b()},E=()=>{const s=window.prompt("Link URL","https://");s&&w("createLink",s)},F=(s,l="")=>{d.current?.focus();const n=String(l).replace(/"/g,""");document.execCommand("insertHTML",!1,`<img src="${s}" alt="${n}" />`),b()},k=async s=>{if(s){if(!V()){j("Cloudinary is not configured in src/config.js.");return}j(""),B(!0);try{const l=await Y(s);F(l,s.name.replace(/\.[^.]+$/,""))}catch(l){j(l.message||"Image upload failed.")}finally{B(!1),c.current&&(c.current.value="")}}},L=s=>{const l=Array.from(s.clipboardData?.files||[]).filter(n=>n.type.startsWith("image/"));l.length&&(s.preventDefault(),l.forEach(n=>k(n)))},S=s=>{const l=Array.from(s.dataTransfer?.files||[]).filter(n=>n.type.startsWith("image/"));l.length&&(s.preventDefault(),l.forEach(n=>k(n)))};return e.jsxs("div",{className:"overflow-hidden rounded-lg border border-white/10 bg-[#141414]",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-0.5 border-b border-white/10 bg-[#0d0d0d] px-2 py-1.5",children:[De.map((s,l)=>s.divider?e.jsx("span",{className:"mx-1 h-5 w-px bg-white/10"},`div-${l}`):e.jsx("button",{type:"button",title:s.label,onMouseDown:n=>n.preventDefault(),onClick:()=>
1w(s.cmd,s.arg),className:"rounded-md p-1.5 text-[#C8C8C8] hover:bg-white/10 hover:text-white",children:e.jsx(s.icon,{size:16})},`${s.cmd}-${s.arg||""}`)),e.jsx("button",{type:"button",title:"Link",onMouseDown:s=>s.preventDefault(),onClick:E,className:"rounded-md p-1.5 text-[#C8C8C8] hover:bg-white/10 hover:text-white",children:e.jsx(je,{size:16})}),e.jsx("button",{type:"button",title:"Upload image to Cloudinary",disabled:g,onMouseDown:s=>s.preventDefault(),onClick:()=>c.current?.click(),className:"rounded-md p-1.5 text-[#C8C8C8] hover:bg-white/10 hover:text-white disabled:opacity-50",children:e.jsx(we,{size:16})}),e.jsx("input",{ref:c,type:"file",accept:"image/*",hidden:!0,onChange:s=>k(s.target.files?.[0])}),g&&e.jsx("span",{className:"ml-2 text-[11px] font-semibold text-[#F0B90B]",children:"Uploadingâ¦"})]}),e.jsxs("div",{className:"relative",children:[!i||i==="<br>"||i==="<p><br></p>"?e.jsx("div",{className:"pointer-events-none absolute left-3 top-3 text-sm text-white/30",children:u}):null,e.jsx("div",{ref:d,contentEditable:!0,role:"textbox","aria-label":"Post body","data-placeholder":u,className:"blog-editor min-h-[280px] px-3 py-3 text-[15px] text-[#E8E8E8] leading-relaxed outline-none",onInput:b,onBlur:b,onPaste:L,onDrop:S,onDragOver:s=>s.preventDefault()})]}),C&&e.jsx("p",{className:"border-t border-rose-500/20 bg-rose-500/10 px-3 py-2 text-xs text-rose-200",children:C}),e.jsx("style",{children:` 2 .blog-editor h2 { 3 font-size: 1.35rem; 4 font-weight: 800; 5 color: #fff; 6 margin: 1.1rem 0 0.45rem; 7 } 8 .blog-editor h3 { 9 font-size: 1.1rem; 10 font-weight: 700; 11 color: #fff; 12 margin: 1rem 0 0.35rem; 13 } 14 .blog-editor p { margin: 0 0 0.8rem; } 15 .blog-editor ul { list-style: disc; padding-left: 1.25rem; margin: 0.6rem 0 0.9rem; } 16 .blog-editor ol { list-style: decimal; padding-left: 1.25rem; margin: 0.6rem 0 0.9rem; } 17 .blog-editor li { margin: 0.2rem 0; } 18 .blog-editor a { color: #F0B90B; text-decoration: underline; } 19 .blog-editor blockquote { 20 border-left: 3px solid #F0B90B; 21 padding-left: 0.85rem; 22 color: #A0A0A0; 23 margin: 0.8rem 0; 24 } 25 .blog-editor b, .blog-editor strong { font-weight: 700; color: #fff; } 26 .blog-editor img { 27 display: block; 28 max-width: 100%; 29 height: auto; 30 border-radius: 12px; 31 margin: 1rem 0; 32 } 33 `})]})},N="#F0B90B",Re=["Product","Roadmap","Compliance","Funding","Company","Security","Partnerships"],$="iotrader-admin",Q=()=>({title:"",slug:"",category:"Product",date:new Date().toISOString().slice(0,10),excerpt:"",cover:"",coverAlt:"",keywords:"",featured:!1,published:!0,bodyHtml:""}),x="w-full rounded-lg border border-white/10 bg-[#141414] text-white text-sm px-3 py-2.5 placeholder:text-white/30 focus:outline-none focus:ring-2 focus:ring-[#F0B90B]/40",Qe=()=>{const[i,y]=a.useState(!1),[u,d]=a.useState(null),[c,h]=a.useState(""),[g,B]=a.useState(""),[C,j]=a.useState(""),[b,w]=a.useState(!1),[E,F]=a.use
33State([]),[k,L]=a.useState(!1),[S,s]=a.useState("list"),[l,n]=a.useState(""),[r,P]=a.useState(Q),[J,D]=a.useState(!1),[M,q]=a.useState(!1),[_,z]=a.useState(!1),[W,A]=a.useState(""),[G,p]=a.useState(""),X=Le(),Z=V();a.useEffect(()=>{sessionStorage.getItem($)===v.email&&d({email:v.email}),y(!0)},[]);const T=async()=>{L(!0);try{F(await ve())}catch(t){p(t.message||"Could not load posts.")}finally{L(!1)}};a.useEffect(()=>{u&&T()},[u]);const ee=a.useMemo(()=>{const t=r.slug||I(r.title);return t?`${U}${R(t)}`:`${U}/blog/your-post.html`},[r.slug,r.title]),te=t=>{t.preventDefault(),j(""),w(!0);const o=c.trim().toLowerCase()===String(v.email).toLowerCase(),f=g===String(v.password);if(!o||!f){j("Invalid email or password."),w(!1);return}sessionStorage.setItem($,v.email),d({email:v.email}),w(!1)},se=()=>{sessionStorage.removeItem($),d(null),s("list")},ae=()=>{P(Q()),n(""),D(!1),s("edit"),A(""),p("")},re=t=>{P({title:t.title,slug:t.slug,category:t.category,date:t.date,excerpt:t.excerpt,cover:t.cover,coverAlt:t.coverAlt,keywords:t.keywords,featured:t.featured,published:t.published!==!1,bodyHtml:t.bodyHtml||Ne(t.bodyText||Ce(t.body))}),n(t.slug),D(!0),s("edit"),A(""),p("")},m=(t,o)=>{P(f=>{const K={...f,[t]:o};return t==="title"&&!J&&(K.slug=I(o)),K})},le=async t=>{if(t){p(""),z(!0);try{const o=await Y(t);P(f=>({...f,cover:o,coverAlt:f.coverAlt||f.title}))}catch(o){p(o.message||"Upload failed.")}finally{z(!1)}}},oe=async t=>{t.preventDefault(),q(!0),p(""),A("");try{if(Se(r.bodyHtml))throw new Error("Body is required.");const o=await Ae({...r,slug:r.slug||I(r.title)},{previousSlug:l});A(`Saved. Live at ${U}${R(o)}`),n(o),D(!0),await T(),s("list")}catch(o){p(o.message||"Save failed.")}finally{q(!1)}},ie=async t=>{if(window.confirm(`Delete â${t.title}â? This cannot be undone.`))try{await ke(t.slug),await T()}catch(o){p(o.message||"Delete failed.")}},ne=async t=>{try{await navigator.clipboard.writeText(t),A("URL copied.")}catch{p("Could not copy URL.")}};return i?u?e.jsxs(H,{activePage:"admin",children:[e.jsx(O,{title:"Blog admin",url:"/admin",robots:"noindex, nofollow"}),e.jsxs("div",{className:"max-w-6xl mx-auto px-4 lg:px-6 py-10 pb-24",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[11px] font-bold uppercase tracking-[0.22em]",style:{color:N},children:"IOTrader CMS"}),e.jsx("h1",{className:"mt-2 text-3xl font-black text-white",children:S==="edit"?l?"Edit post":"New post":"Blog posts"}),e.jsx("p",{className:"mt-1 text-sm text-[#A0A0A0]",children:u.email})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[S==="edit"?e.jsx("button",{type:"button",onClick:()=>s("list"),className:"rounded-full border border-white/15 px-4 py-2 text-sm font-semibold text-white/80 hover:text-white",children:"All posts"}):e.jsx("button",{type:"button",onClick:ae,className:"rounded-full px-4 py-2 text-sm font-bold text-black",style:{backgroundColor:N},children:"New post"}),e.jsx("button",{type:"button",onClick:se,className:"rounded-full border border-white/15 px-4 py-2 text-sm font-semibold text-white/80 hover:text-white",children:"Sign out"})]})]}),!Z&&e.jsxs("p",{className:"mt-6 rounded-xl border border-amber-500/30 bg-amber-500/10 px-4 py-3 text-sm text-amber-100",children:["Cloudinary is not set. Add ",e.jsx("code",{children:"cloudName"})," and ",e.jsx("code",{children:"uploadPreset"})," in"," ",e.jsx("code",{children:"src/config.js"}),", or paste an image URL."]}),W&&e.jsx("p",{className:"mt-6 rounded-xl border border-emerald-500/30 bg-emerald-500/10 px-4 py-3 text-sm text-emerald-100",children:W}),G&&e.jsx("p",{className:"mt-6 rounded-xl border border-rose-500/30 bg-rose-500/10 px-4 py-3 text-sm text-rose-100",children:G}),S==="list"?e.jsx("div",{className:"mt-8 overflow-hidden rounded-2xl border border-white/10",children:k?e.jsx("p",{className:"p-6 text-sm text-[#A0A0A0]",children:"Loading postsâ¦"}):E.length===0?e.jsx("p",{className:"p-6 text-sm text-[#A0A0A0]",children:"No Firebase posts yet. Static homepage posts still show until you publish here."}):e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-white/5 text-left text-xs uppercase tracking-wider text-[#A0A0A0]",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-3 font-semibold",children:"Post"}),e.jsx("th",{className:"px-4 py-3 font-semibold hidden md:table-cell",children:"URL"}),e.jsx("th",{className:"px-4 py-3 font-semibold",children:"Status"}),e.jsx("th",{className:"px-4 py-3 font-semibold text-right",children:"Actions"})]})}),e.jsx("tbody",{children:E.map(t=>{const o=`${U}${R(t.slug)}`;return e.jsxs("tr",{className:"border-t border-white/10",children:[e.jsxs("td",{className:"px-4 py-4",children:[e.jsx("p",{className:"font-bold text-white",children:t.title}),e.jsxs("p",{className:"text-xs text-[#8A8A8A] mt-1",children:[t.category," · ",t.date]})]}),e.jsx("td",{className:"px-4 py-4 hidden md:table-cell",children:e.jsx("button",{type:"button",onClick:()=>ne(o),className:"text-left text-xs text-[#F0B90B] hover:opacity-80 break-all",children:o})}),e.jsxs("td",{className:"px-4 py-4 whitespace-nowrap",children:[e.jsx("span",{className:t.published?"text-emerald-300":"text-amber-300",children:t.published?"Published":"Draft"}),t.featured&&e.jsx("span",{className:"ml-2 text-[10px] font-bold uppercase",style:{color:N},children:"Featured"})]}),e.jsxs("td",{className:"px-4 py-4 text-right whitespace-nowrap",children:[e.jsx(Pe,{to:R(t.slug),className:"text-xs font-semibold text-white/70 hover:text-white mr-3",children:"View"}),e.jsx("button",{type:"button",onClick:()=>re(t),className:"text-xs font-semibold text-[#F0B90B] mr-3",children:"Edit"}),e.jsx("button",{type:"button",onClick:()=>ie(t),className:"text-xs font-semibold text-rose-300",children:"Delete"})]})]},t.slug)})})]})}):e.jsxs("form",{onSubmit:oe,className:"mt-8 grid lg:grid-cols-[1fr_320px] gap-8",children:[e.jsxs("div",{className:"space-y-5 rounded-2xl border border-white/10 bg-[#111] p-5 sm:p-6",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-semibold text-gray-400 mb-1.5",children:"Title"}),e.jsx("input",{value:r.title,onChange:t=>m("title",t.target.value),className:x,required:!0})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-semibold text-gray-400 mb-1.5",children:"Slug"}),e.jsx("input",{value:r.slug,onChange:t=>{D(!0),m("slug",I(t.target.value))},className:x,required:!0}),e.jsxs("p",{className:"mt-2 text-xs text-[#A0A0A0] break-all",children:["Public link:"," ",e.jsx("span",{className:"text-[#F0B90B]",children:ee})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-semibold text-gray-400 mb-1.5",children:"Excerpt"}),e.jsx("textarea",{value:r.excerpt,onChange:t=>m("excerpt",t.target.value),className:`${x} min-h-[90px]`,required:!0})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-semibold text-gray-400 mb-1.5",children:"Body"}),e.jsx(Ie,{value:r.bodyHtml,onChange:t=>m("bodyHtml",t),placeholder:"Write the postâ¦"})]})]}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{className:"rounded-2xl border border-white/10 bg-[#111] p-5 space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-semibold text-gray-400 mb-1.5",children:"Category"}),e.jsx("select",{value:r.category,onChange:t=>m("category",t.target.value),className:x,children:Re.map(t=>e.jsx("option",{value:t,children:t},t))})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-semibold text-gray-400 mb-1.5",children:"Date"}),e.jsx("input",{type:"date",value:r.date,onChange:t=>m("date",t.target.value),className:x,required:!0})]}),e.jsxs("label",{className:"flex items-center gap-2 text-sm text-white",children:[e.jsx("input",{type:"checkbox",checked:r.published,onChange:t=>m("published",t.target.checked)}),"Published"]}),e.jsxs("label",{className:"flex items-center gap-2 text-sm text-white",children:[e.jsx("input",{type:"checkbox",checked:r.featured,onChange:t=>m("featured",t.target.checked)}),"Featured on /blog"]})]}),e.jsxs("div",{className:"rounded-2xl border border-white/10 bg-[#111] p-5 space-y-4",children:[e.jsx("p",{className:"text-xs font-semibold text-gray-400",children:"Cover image"}),r.cover&&e.jsx("img",{src:r.cover,alt:"",className:"w-full aspect-video object-cover rounded-xl"}),e.jsx("input",{type:"file",accept:"image/*",onChange:t=>le(t.target.files?.[0]),className:"block w-full text-xs text-[#A0A0A0]"}),_&&e.jsx("p",{className:"text-xs text-[#F0B90B]",children:"Uploading to Cloudinaryâ¦"}),e.jsx("input",{value:r.cover,onChange:t=>m("cover",t.target.value),className:x,placeholder:"Or paste image URL"}),e.jsx("input",{value:r.coverAlt,onChange:t=>m("coverAlt",t.target.value),className:x,placeholder:"Alt text"})]}),e.jsxs("div",{className:"rounded-2xl border border-white/10 bg-[#111] p-5",children:[e.jsx("label",{className:"block text-xs font-semibold text-gray-400 mb-1.5",children:"Keywords"}),e.jsx("input",{value:r.keywords,onChange:t=>m("keywords",t.target.value),className:x,placeholder:"IOTrader, $IOI, trading"})]}),e.jsx("button",{type:"submit",disabled:M||_,className:"w-full rounded-full py-2.5 text-sm font-bold text-black disabled:opacity-50",style:{backgroundColor:N},children:M?"Savingâ¦":"Publish post"})]})]})]})]}):e.jsxs(H,{activePage:"admin",children:[e.jsx(O,{title:"Blog admin",url:"/admin",robots:"noindex, nofollow"}),e.jsx("div",{className:"min-h-[70vh] flex items-center justify-center px-4",children:e.jsxs("form",{onSubmit:te,className:"w-full max-w-md rounded-2xl border border-white/10 bg-[#111] p-6 sm:p-8",children:[e.jsx("p",{className:"text-[11px] font-bold uppercase tracking-[0.22em]",style:{color:N},children:"IOTrader CMS"}),e.jsx("h1",{className:"mt-3 text-2xl font-black text-white",children:"Blog admin"}),e.jsx("p",{className:"mt-2 text-sm text-[#A0A0A0]",children:"Sign in with the static admin credentials from config.js."}),!X&&e.jsx("p",{className:"mt-4 text-sm text-rose-300",children:"Firebase env vars are missing."}),e.jsx("label",{className:"block mt-6 text-xs font-semibold text-gray-400 mb-1.5",children:"Email"}),e.jsx("input",{type:"email",value:c,onChange:t=>h(t.target.value),className:x,required:!0,autoComplete:"username"}),e.jsx("label",{className:"block mt-4 text-xs font-semibold text-gray-400 mb-1.5",children:"Password"}),e.jsx("input",{type:"password",value:g,onChange:t=>B(t.target.value),className:x,required:!0,autoComplete:"current-password"}),C&&e.jsx("p",{className:"mt-3 text-sm text-rose-300",children:C}),e.jsx("button",{type:"submit",disabled:b,className:"mt-6 w-full rounded-full py-2.5 text-sm font-bold text-black disabled:opacity-50",style:{backgroundColor:N},children:b?"Signing inâ¦":"Sign in"})]})})]}):e.jsxs(H,{activePage:"admin",children:[e.jsx(O,{title:"Admin",url:"/admin",robots:"noindex, nofollow"}),e.jsx("div",{className:"min-h-[50vh] flex items-center justify-center text-[#A0A0A0]",children:"Loadingâ¦"})]})};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.