1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9189,3022],{52599:function(e,t,r){(window.__NEXT_P=window.__NEXT_P||[]).push(["/admin/dashboard",function(){return r(77740)}])},98560:function(e,t,r){"use strict";r.d(t,{Z:function(){return l}});var s=r(85893),a=r(86010);function l(e){let t=e.size||20;return(0,s.jsx)("div",{className:(0,a.default)("flex flex-row",e.className),children:(0,s.jsxs)("svg",{"aria-hidden":"true",className:(0,a.default)("mr-2 text-white animate-spin dark:text-gray-600 fill-black stroke-1","w-".concat(t," h-").concat(t)),viewBox:"0 0 100 101",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[(0,s.jsx)("path",{d:"M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z",fill:"currentColor"}),(0,s.jsx)("path",{d:"M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z",fill:"currentFill"})]})})}},77740:function(e,t,r){"use strict";r.r(t);var s=r(85893),a=r(67294),l=r(73999),i=r(98560),n=r(80359),d=r(11163),o=r(87066),c=r(9008),u=r.n(c),h=r(92409),x=r(41664),m=r.n(x),p=r(2914),g=r(90109),f=r(78728),b=r(60115),j=r(37743),w=r(82602),N=r(875),v=r(71087);t.default=()=>{let e;let{user:t,admin:r}=(0,n.Z)(),[c,x]=(0,a.useState)(!0),[y,S]=(0,a.useState)(null),[A,I]=(0,a.useState)([]),[_,C]=(0,a.useState)({}),[k,D]=(0,a.useState)({}),[E,U]=(0,a.useState)(!0),[L,T]=(0,a.useState)(null),[P,F]=(0,a.useState)([]),[Z,O]=(0,a.useState)(!0),[V,B]=(0,a.useState)([]),[J,M]=(0,a.useState)(!0),[Q,R]=(0,a.useState)(null),q=(0,d.useRouter)(),[z,K]=(0,a.useState)("idle"),[X,$]=(0,a.useState)([]),[W,G]=(0,a.useState)(!0),[H,Y]=(0,a.useState)(null),[ee,et]=(0,a.useState)(null),[er,es]=(0,a.useState)(null),[ea,el]=(0,a.useState)("idle"),[ei,en]=(0,a.useState)([]),[ed,eo]=(0,a.useState)(!0),[ec,eu]=(0,a.useState)(null),[eh,ex]=(0,a.useState)("7d"),[em,ep]=(0,a.useState)([]),[eg,ef]=(0,a.useState)(!0),[eb,ej]=(0,a.useState)(null),[ew,eN]=(0,a.useState)(null),[ev,ey]=(0,a.useState)([]),[eS,eA]=(0,a.useState)(!0),[eI,e_]=(0,a.useState)(null),[eC,ek]=(0,a.useState)(""),[eD,eE]=(0,a.useState)("idle"),[eU,eL]=(0,a.useState)(null),eT=async()=>{let e=eC.trim();if(!e){eL("Please enter a user ID"),eE("error");return}if(!t){eL("No signed-in Firebase user for this session."),eE("error");return}eE("loading"),eL(null);try{let r=await t.getIdToken(),{data:s}=await o.Z.post("".concat(h.J,"/admin/impersonate_user"),{targetUserId:e},{headers:{Authorization:"Bearer ".concat(r)},withCredentials:!0}),a=null==s?void 0:s.customToken;if(!a)throw Error("Backend did not return customToken");let l=(0,f.getAuthClient)();await (0,j._p)(l,a),eE("success"),eL(null)}catch(e){var r,s;eE("error"),eL((null==e?void 0:null===(s=e.response)||void 0===s?void 0:null===(r=s.data)||void 0===r?void 0:r.error)||(null==e?void 0:e.message)||"Impersonation failed â see console for details.")}},eP=async()=>{el("running");try{let e=await (0,v.Q)(),{data:t}=await o.Z.post("".concat(h.J,"/admin/embed_faqs"),{faqs:b.p},{headers:e,withCredentials:!0});t.success?el("done"):el("error")}catch(e){el("error")}},eF=async()=>{K("running");try{let{data:e}=await o.Z.post("/api/admin/generate-sitemap");if(e.success)K("done");else throw Error(e.error)}catch(e){K("error")}};(0,a.useEffect)(()=>{if(c)return;let e=(0,g.JU)(f.firestore,"meta","sitemaps"),t=(0,g.cf)(e,e=>{if(e.exists()){var t,r;let s=e.data();et(null!==(t=s.sitemapsCreated)&&void 0!==t?t:null),es(null!==(r=s.indexUrl)&&void 0!==r?r:null)}else et(null),es(null)},e=>{});return()=>t()},[c]),(0,a.useEffect)(()=>{!0===r?x(!1):!1===r&&setTimeout(()=>q.push("/"),100)},[r,q]);let eZ=async e=>{try{if(!e.length)return{emails:{},owners:{}};let t={};for(let r=0;r<e.length;r+=10){let s=e.slice(r,r+10),a=(0,g.IO)((0,g.hJ)(f.firestore,"projectIndex"),(0,g.ar)("__name__","in",s));
1(await (0,g.PL)(a)).forEach(e=>{let r=e.data();(null==r?void 0:r.ownerUid)&&(t[e.id]=r.ownerUid)})}let r=Array.from(new Set(Object.values(t))).filter(Boolean),s={};for(let e=0;e<r.length;e+=10){let t=r.slice(e,e+10),a=(0,g.IO)((0,g.hJ)(f.firestore,"users"),(0,g.ar)("__name__","in",t));(await (0,g.PL)(a)).forEach(e=>{let t=e.data();(null==t?void 0:t.email)&&(s[e.id]=t.email)})}let a={};for(let r of e){let e=t[r];e&&s[e]&&(a[r]=s[e])}return{emails:a,owners:t}}catch(e){return{emails:{},owners:{}}}},eO=async()=>{try{let e=(0,g.IO)((0,g.hJ)(f.firestore,"feedback"),(0,g.ar)("status","==","unread"),(0,g.Xo)("timestamp","asc")),t=(await (0,g.PL)(e)).docs.map(e=>({id:e.id,...e.data()}));F(t)}catch(e){T("Error fetching unread feedback")}finally{O(!1)}},eV=async e=>{try{let t=(0,g.JU)(f.firestore,"feedback",e);await (0,g.r7)(t,{status:"read"}),F(t=>t.filter(t=>t.id!==e))}catch(e){}};(0,a.useEffect)(()=>{let e=async()=>{try{let e=await (0,v.Q)(),t=await o.Z.get("".concat(h.J,"/count_namespaces"),{headers:e,withCredentials:!0});if(t.data){S(t.data.namespace_count);let e=t.data.namespace_names||[];I(e);let{emails:r,owners:s}=await eZ(e);C(r),D(s)}else T("Failed to fetch namespace data.")}catch(e){T("An error occurred while fetching namespace data.")}finally{U(!1)}};c||(e(),eO(),eX(),e$(),eM(),eQ())},[c,eh,null==t?void 0:t.uid]),(0,a.useEffect)(()=>{if(!c){let e=window.setTimeout(()=>{eR()},0);return()=>window.clearTimeout(e)}},[c]);let eB=e=>{let t=(e||"").trim();if(!t)return"(no address)";for(let e of t.split("\n")){let t=e.trim();if(t)return t}return t},eJ=e=>{let t=(e||"").split("/");return{userId:t[1]||"",projectId:t[3]||"",caseId:t[5]||""}},eM=async()=>{eo(!0),eu(null);try{var e,t,r,s,a,l,i;let n=null;if("all"!==eh){let e="14d"===eh?14:7,t=new Date;t.setHours(0,0,0,0),t.setDate(t.getDate()-e),n=g.EK.fromDate(t)}let d=(await (0,g.PL)((0,g.hJ)(f.firestore,"publicShares"))).docs.map(e=>({id:e.id,...e.data()})),o=new Map;for(let t of d){let r="".concat(t.ownerUid,"__").concat(t.projectId);o.has(r)||o.set(r,{ownerUid:t.ownerUid,projectId:t.projectId,slug:t.slug,shortId:null!==(e=t.shortId)&&void 0!==e?e:void 0,listed:!!t.listed})}let c=[];for(let[e,d]of o.entries()){let{ownerUid:o,projectId:u,slug:h,shortId:x,listed:m}=d,p=x?"".concat(h,"-").concat(x):h,b=(0,g.JU)(f.firestore,"users",o,"projects",u),j=await (0,g.QT)(b),N=j.exists()&&j.data().projectName||"(untitled board)",v=j.exists()&&String(j.data().shareAlias||"").trim()||void 0,y=(0,g.hJ)(f.firestore,"users",o,"projects",u,"analytics_shared_views"),S=(n?await (0,g.PL)((0,g.IO)(y,(0,g.ar)("createdAt",">=",n))):await (0,g.PL)(y)).docs.map(e=>e.data()).filter(e=>e.viewerUid!==o).filter(e=>!(0,w.tb)(e)),A=S.length,I=new Set,_=null;for(let e of S){e.viewerUid&&I.add(e.viewerUid);let n=(null===(r=e.createdAt)||void 0===r?void 0:null===(t=r.toDate)||void 0===t?void 0:t.call(r))?e.createdAt.toDate().getTime():(null===(a=e.timestamp)||void 0===a?void 0:null===(s=a.toDate)||void 0===s?void 0:s.call(a))?e.timestamp.toDate().getTime():(null===(i=e.created_at)||void 0===i?void 0:null===(l=i.toDate)||void 0===l?void 0:l.call(i))?e.created_at.toDate().getTime():null;n&&(null===_||n>_)&&(_=n)}c.push({id:e,ownerUid:o,projectId:u,projectName:N,slug:p,shareAlias:v,listed:m,totalViews:A,uniqueVisitors:I.size,lastViewAtMs:_})}c.sort((e,t)=>{var r,s;let a=null!==(r=e.lastViewAtMs)&&void 0!==r?r:0,l=null!==(s=t.lastViewAtMs)&&void 0!==s?s:0;return l!==a?l-a:t.totalViews-e.totalViews});let u=c.filter(e=>e.totalViews>0);en(u)}catch(e){eu("Error fetching shared boards")}finally{eo(!1)}},eQ=async()=>{ef(!0),ej(null);try{let e=await (0,g.PL)((0,g.B$)(f.firestore,"cases")),r=[];e.forEach(e=>{let s=e.data(),a=(null==s?void 0:s.emailThreads)||{};if(a&&"object"==typeof a){if(null==t?void 0:t.uid){let{userId:r}=eJ(e.ref.path);if(r!==t.uid)return}["combined","electric","gas"].forEach(t=>{let l=a[t];if(!l||"sent"!==l.status)return;let i=(l.threadId||"").toString().trim();if(!i)return;let n=e.ref.path,{userId:d,projectId:o,caseId:c}=eJ(n);r.push({id:"".concat(e.id,"-").concat(t),path:n,userId:d,projectId:o,caseId:c||e.id,propertyAddress:eB((null==s?void 0:s.propertyAddress)||""),fuelType:t,supplierName:(l.supplierName||"").trim()||"Utility supplier",threadId:i,nextChaserDueAt:l.nextChaserDueAt})})}}),ep(r)}catch(e){ej("Failed to load chaser targets.")}finally{ef(!1)}},eR=async()=>{eA(!0),e_(null);try{let[e,t]=await Promise.all([(0,g.PL)((0,g.hJ)(f.firestore,"houseBoardCopies")),(0,g.PL)((0,g.IO)((0,g.B$)(f.firestore,"projects"),(0,g.ar)("allowViewerCopy","==",!0)))]),r
1=new Map;e.forEach(e=>{let t=e.data();if((0,w.IT)(t))return;let s=String((null==t?void 0:t.sourceOwnerUid)||"").trim(),a=String((null==t?void 0:t.sourceProjectId)||"").trim();if(!s||!a)return;let l="".concat(s,"__").concat(a),i=String((null==t?void 0:t.sourceProjectName)||"").trim()||"Untitled board",n=r.get(l);if(!n){r.set(l,{ownerUid:s,projectId:a,projectName:i,activeCopies:(null==t?void 0:t.active)===!0?1:0});return}(null==t?void 0:t.active)===!0&&(n.activeCopies+=1),"Untitled board"===n.projectName&&"Untitled board"!==i&&(n.projectName=i)}),t.forEach(e=>{let t=e.ref.path.split("/"),s=String(t[1]||"").trim(),a=String(e.id||"").trim();if(!s||!a)return;let l=e.data(),i="".concat(s,"__").concat(a),n=String((null==l?void 0:l.projectName)||"").trim()||"Untitled board",d=r.get(i);if(d){"Untitled board"===d.projectName&&"Untitled board"!==n&&(d.projectName=n);return}r.set(i,{ownerUid:s,projectId:a,projectName:n,activeCopies:0})});let s=[];for(let e of r.values()){let t=(0,g.JU)(f.firestore,"users",e.ownerUid,"projects",e.projectId),r=await (0,g.QT)(t);if(!r.exists())continue;let a=r.data();(null==a?void 0:a.allowViewerCopy)===!0&&s.push({...e,projectName:String((null==a?void 0:a.projectName)||"").trim()||e.projectName,shareSlug:String((null==a?void 0:a.shareSlug)||"").trim()||void 0,shareId:String((null==a?void 0:a.shareId)||"").trim()||void 0,shareAlias:String((null==a?void 0:a.shareAlias)||"").trim()||void 0})}s.sort((e,t)=>t.activeCopies-e.activeCopies||e.projectName.localeCompare(t.projectName)),ey(s)}catch(e){e_("Failed to load board copies.")}finally{eA(!1)}},eq=V.reduce((e,t)=>{let r=t.userId||"N/A";return e[r]||(e[r]=[]),e[r].push(t),e},{}),ez=X.filter(e=>"board"===e.videoId),eK=ez.reduce((e,t)=>{let r=t.userId||"N/A";return e[r]||(e[r]=[]),e[r].push(t),e},{}),eX=async()=>{M(!0),R(null);try{let e=g.EK.now(),t=g.EK.fromMillis(e.toMillis()-6048e5),r=(0,g.IO)((0,g.hJ)(f.firestore,"tourStarts"),(0,g.ar)("startedAt",">=",t),(0,g.Xo)("startedAt","desc")),s=(await (0,g.PL)(r)).docs.map(e=>{let t=e.data();return{id:e.id,...t}}).filter(e=>!(0,w.WZ)(e.ipAddress)).filter(e=>"3uVi5djXAIT3zaI8RaKpqEMOg5k1"!==e.userId),a={};s.forEach(e=>{e.userId&&(a[e.userId]=(a[e.userId]||0)+1)});let l=s.map(e=>({...e,userStartCount:a[e.userId||""]||0}));B(l)}catch(e){R("Error fetching tour starts")}finally{M(!1)}},e$=async()=>{G(!0),Y(null);try{let e=g.EK.now(),t=g.EK.fromMillis(e.toMillis()-6048e5),r=(0,g.IO)((0,g.hJ)(f.firestore,"videotourStarts"),(0,g.ar)("startedAt",">=",t),(0,g.Xo)("startedAt","desc")),s=(await (0,g.PL)(r)).docs.map(e=>{let t=e.data();return{id:e.id,...t}}).filter(e=>!(0,w.WZ)(e.ipAddress)),a={};s.forEach(e=>{e.userId&&(a[e.userId]=(a[e.userId]||0)+1)});let l=s.map(e=>({...e,userStartCount:a[e.userId||""]||0}));$(l)}catch(e){Y("Error fetching video tour starts")}finally{G(!1)}};return c||!t?(0,s.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,s.jsx)(i.Z,{})}):(0,s.jsxs)("div",{className:"flex flex-col h-screen",children:[(0,s.jsx)(u(),{children:(0,s.jsx)("title",{children:"Zelica â Admin"})}),(0,s.jsx)(l.Z,{}),(0,s.jsx)("div",{className:"flex flex-col h-full w-full p-4 mt-20",children:(0,s.jsx)("main",{className:"flex flex-col items-center flex-1 pb-4",children:(0,s.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 w-full max-w-6xl",children:[(0,s.jsxs)("div",{className:"p-6 bg-white rounded-lg shadow-md flex flex-col items-center border border-gray-300",children:[(0,s.jsx)("h2",{className:"text-xl font-semibold mb-4 text-center",children:"House Boards"}),(0,s.jsx)("p",{className:"text-sm text-slate-600 text-center min-h-[72px]",children:"Battery & Grid Storage board operations now live on a dedicated admin page: note runners, exports, candidate queues, and tracker support."}),(0,s.jsx)(m(),{href:"/admin/house-boards/battery-grid-storage",children:(0,s.jsx)("button",{className:"mt-4 w-56 px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-lg",children:"Battery & Grid Storage"})})]}),(0,s.jsxs)("div",{className:"p-6 bg-white rounded-lg shadow-md flex flex-col border border-gray-300",children:[(0,s.jsx)("h2",{className:"text-xl font-semibold mb-4 text-center",children:"Board Copies"}),(0,s.jsx)("div",{className:"py-2 flex justify-center",children:eS?(0,s.jsx)(i.Z,{}):eI?(0,s.jsx)("span",{className:"text-red-600",children:eI}
1):0===ev.length?(0,s.jsx)("p",{className:"text-center",children:"No copied boards found."}):(0,s.jsx)("div",{className:"w-full max-h-64 overflow-y-auto text-sm",children:(0,s.jsxs)("table",{className:"w-full text-left",children:[(0,s.jsx)("thead",{children:(0,s.jsxs)("tr",{className:"border-b",children:[(0,s.jsx)("th",{className:"py-1 pr-2",children:"Board"}),(0,s.jsx)("th",{className:"py-1 pr-0 text-right",children:"Active copies"})]})}),(0,s.jsx)("tbody",{children:ev.map(e=>(0,s.jsxs)("tr",{className:"border-b last:border-b-0",children:[(0,s.jsx)("td",{className:"py-1 pr-2 align-top",children:(()=>{let t=(0,N.O$)({shareAlias:e.shareAlias,shareSlug:e.shareSlug,shareId:e.shareId});return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("div",{className:"font-medium",children:e.projectName}),t?(0,s.jsx)("a",{href:t,target:"_blank",rel:"noopener noreferrer",className:"text-xs text-blue-600 underline break-all",children:t}):(0,s.jsx)("div",{className:"text-xs text-gray-500",children:"No share URL"})]})})()}),(0,s.jsx)("td",{className:"py-1 pr-0 text-right align-top",children:e.activeCopies.toLocaleString()})]},e.projectId))})]})})})]}),(0,s.jsxs)("div",{className:"p-6 bg-white rounded-lg shadow-md flex flex-col border border-gray-300",children:[(0,s.jsx)("h2",{className:"text-xl font-semibold mb-4 text-center",children:"Shared Boards"}),(0,s.jsx)("div",{className:"flex justify-center",children:(0,s.jsxs)("select",{className:"border border-gray-300 rounded px-2 py-1 text-sm w-1/2",value:eh,onChange:e=>ex(e.target.value),children:[(0,s.jsx)("option",{value:"all",children:"All time"}),(0,s.jsx)("option",{value:"14d",children:"Last 14 days"}),(0,s.jsx)("option",{value:"7d",children:"Last 7 days"})]})}),(0,s.jsx)("div",{className:"py-4 flex justify-center",children:ed?(0,s.jsx)(i.Z,{}):ec?(0,s.jsx)("span",{className:"text-red-600",children:ec}):0===ei.length?(0,s.jsx)("p",{className:"text-center",children:"No shared board views."}):(0,s.jsx)("div",{className:"w-full max-h-64 overflow-y-auto text-sm",children:(0,s.jsxs)("table",{className:"w-full text-left",children:[(0,s.jsx)("thead",{children:(0,s.jsxs)("tr",{className:"border-b",children:[(0,s.jsx)("th",{className:"py-1 pr-2",children:"Board"}),(0,s.jsx)("th",{className:"py-1 pr-2 text-right",children:"Views"}),(0,s.jsx)("th",{className:"py-1 pr-0 text-right",children:"Unique visitors"})]})}),(0,s.jsx)("tbody",{children:ei.map(e=>(0,s.jsxs)("tr",{className:"border-b last:border-b-0",children:[(0,s.jsxs)("td",{className:"py-1 pr-2 align-top",children:[(()=>{let t=(0,N.O$)({shareAlias:e.shareAlias,shareSlug:e.slug,shareId:""})||"/share/".concat(e.slug);return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("div",{className:"font-medium",children:e.projectName||"(untitled board)"}),(0,s.jsx)("a",{href:t,target:"_blank",rel:"noopener noreferrer",className:"text-xs text-blue-600 underline break-all",children:t})]})})(),(0,s.jsxs)("div",{className:"text-xs mt-1 text-gray-600",children:["Public:"," ",e.listed?(0,s.jsx)("span",{className:"inline-flex items-center rounded-full bg-green-100 px-2 py-0.5 text-xs text-green-800",children:"Yes"}):(0,s.jsx)("span",{className:"inline-flex items-center rounded-full bg-gray-100 px-2 py-0.5 text-xs text-gray-700",children:"No"})]}),e.lastViewAtMs&&(0,s.jsxs)("div",{className:"text-xs text-gray-500 mt-1",children:["Last viewed:",(0,s.jsx)("br",{}),new Date(e.lastViewAtMs).toLocaleString()]})]}),(0,s.jsx)("td",{className:"py-1 pr-2 text-right align-top",children:e.totalViews.toLocaleString()}),(0,s.jsx)("td",{className:"py-1 pr-0 text-right align-top",children:e.uniqueVisitors.toLocaleString()})]},e.id))})]})})})]}),(0,s.jsxs)("div",{className:"p-6 bg-white rounded-lg shadow-md flex flex-col border border-gray-300",children:[(0,s.jsx)("h2",{className:"text-xl font-semibold mb-4 text-center",children:"Tours"}),J?(0,s.jsx)(i.Z,{}):Q?(0,s.jsx)("span",{className:"text-red-600",children:Q}):0===V.length?(0,s.jsx)("p",{className:"text-center",children:"No tour starts in the last 7 days."}):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)("h2",{className:"font-semibold mb-4",children:[Object.keys(eq).length," users started a tour in the last 7 days:"]}),(0,s.jsx)("div",{className:"h-48 overflow-y-auto w-full text-left",children:(0,s.jsx)("div",{className:"text-gray-600",children:Object.entries(eq).map(e=>{let[t,r]=e;return(0,s.jsxs)("div",{className:"mb-6 border-b-2 border-gray-300",children:[(0,s.jsxs)("p",{className:"font-semibold mb-2",children:[(0,s.jsx)("strong",{children:"User ID:"})," ","N/A"!==t?t:"No user ID"]}),(0,s.jsxs)("p",{className:"mb-2",children:[(0,s.jsx)("strong",{children:"Total tour starts:"})," ",r.length]}),(0,s.jsx)("div",{className:"border-l-2 border-blue-300",children:r.map(e=>(0,s.jsxs)("div",{className:"ml-1 mb-4",children:[(0,s.jsxs)("p",{children:[(0,s.jsx)("strong",{children:"IP:"})," ",e.ipAddress?(0,s.jsx)("a",{href:"https://whatismyipaddress.com/ip/".concat(e.ipAddress),target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 underline",children:e.ipAddress}):"N/A"]}),(0,s.jsxs)("p",{children:[(0,s.jsx)("strong",{children:"Status:"})," ",e.status||"N/A"]}),(0,s.jsxs)("p",{children:[(0,s.jsx)("strong",{children:"Current Step:"})," ",e.currentStep||"N/A"]}),(0,s.jsxs)("p",{children:[(0,s.jsx)("strong",{children:"Started at:"}
1)," ",e.startedAt?new Date(e.startedAt.toDate()).toLocaleString():"N/A"]})]},e.id))})]},t)})})})]})]}),(e="Video tours",(0,s.jsxs)("div",{className:"p-6 bg-white rounded-lg shadow-md flex flex-col border border-gray-300",children:[(0,s.jsx)("h2",{className:"text-xl font-semibold mb-4 text-center",children:e}),W?(0,s.jsx)(i.Z,{}):H?(0,s.jsx)("span",{className:"text-red-600",children:H}):0===ez.length?(0,s.jsx)("p",{className:"text-center",children:"No video tour starts in the last 7 days."}):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)("h2",{className:"font-semibold mb-4",children:[Object.keys(eK).length," users started a video tour in the last 7 days:"]}),(0,s.jsx)("div",{className:"h-48 overflow-y-auto w-full text-left",children:(0,s.jsx)("div",{className:"text-gray-600",children:Object.entries(eK).map(e=>{let[t,r]=e;return(0,s.jsxs)("div",{className:"mb-6 border-b-2 border-gray-300",children:[(0,s.jsxs)("p",{className:"font-semibold mb-2",children:[(0,s.jsx)("strong",{children:"User ID:"})," ","N/A"!==t?t:"No user ID"]}),(0,s.jsxs)("p",{className:"mb-2",children:[(0,s.jsx)("strong",{children:"Total video tour starts:"})," ",r.length]}),(0,s.jsx)("div",{className:"border-l-2 border-blue-300",children:r.map(e=>(0,s.jsxs)("div",{className:"ml-1 mb-4",children:[(0,s.jsxs)("p",{children:[(0,s.jsx)("strong",{children:"IP:"})," ",e.ipAddress?(0,s.jsx)("a",{href:"https://whatismyipaddress.com/ip/".concat(e.ipAddress),target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 underline",children:e.ipAddress}):"N/A"]}),(0,s.jsxs)("p",{children:[(0,s.jsx)("strong",{children:"Started at:"})," ",e.startedAt?new Date(e.startedAt.toDate()).toLocaleString():"N/A"]})]},e.id))})]},t)})})})]})]})),(0,s.jsxs)("div",{className:"p-6 bg-white rounded-lg shadow-md flex flex-col items-center border border-gray-300",children:[(0,s.jsx)("h2",{className:"text-xl font-semibold mb-4",children:"Unread Feedback"}),Z?(0,s.jsx)(i.Z,{}):0===P.length?(0,s.jsx)("p",{children:"No unread feedback."}):(0,s.jsx)("ul",{className:"list-disc pl-5 w-full text-left",children:P.map(e=>(0,s.jsxs)("li",{className:"mb-4",children:[(0,s.jsxs)("p",{children:[(0,s.jsx)("strong",{children:"User ID:"})," ",e.userId]}),(0,s.jsxs)("p",{children:[(0,s.jsx)("strong",{children:"User IP:"})," ",e.ip]}),e.feedbackEmail&&(0,s.jsxs)("p",{children:[(0,s.jsx)("strong",{children:"Email:"})," ",e.feedbackEmail]}),e.pageUrl&&(0,s.jsxs)("p",{children:[(0,s.jsx)("strong",{children:"Sent from:"})," ",e.pageUrl]}),(0,s.jsxs)("p",{children:[(0,s.jsx)("strong",{children:"Timestamp:"})," ",e.timestamp?e.timestamp.toDate().toLocaleString():"N/A"]}),(0,s.jsx)("p",{className:"text-2xl",children:e.emoji}),(0,s.jsxs)("p",{children:[(0,s.jsx)("strong",{children:"Feedback:"})," ",e.feedback]}),(0,s.jsx)("button",{className:"px-4 py-2 bg-red-500 text-white rounded mt-2",onClick:()=>eV(e.id),children:"Dismiss"})]},e.id))})]}),(0,s.jsxs)("div",{className:"p-6 bg-white rounded-lg shadow-md flex flex-col items-center border border-gray-300",children:[(0,s.jsx)("h2",{className:"text-xl font-semibold mb-2",children:"Sitemap"}),(0,s.jsxs)("p",{className:"text-gray-600 mb-2",children:["Last generated:\xa0",ee?new Date(ee.toDate()).toLocaleString():"â"]}),er&&(0,s.jsx)("p",{className:"mb-4",children:(0,s.jsx)("a",{href:er,target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 underline",children:"View sitemap index"})}),(0,s.jsx)("button",{onClick:()=>{"running"!==z&&window.confirm("\uD83D\uDED1 Are you sure you want to regenerate sitemap?")&&eF()},disabled:"running"===z,className:"px-4 py-2 bg-green-500 hover:bg-green-600 text-white rounded-full",children:"running"===z?"Generatingâ¦":"done"===z?"Done!":"Regenerate sitemap"}),"error"===z&&(0,s.jsx)("p",{className:"text-red-600 mt-2",children:"Failed to regenerate"})]}),(0,s.jsxs)("div",{className:"p-6 bg-white rounded-lg shadow-md flex flex-col items-center border border-gray-300",children:[(0,s.jsx)("h2",{className:"text-xl font-semibold mb-2",children:"FAQ Embeddings"}),(0,s.jsx)("p",{className:"text-gray-600 mb-4 text-center",children:"Rebuild FAQ embeddings from FAQList.tsx and refresh the chatbotâs FAQ knowledge."}),(0,s.jsx)("button",{onClick:eP,disabled:"running"===ea,className:"px-4 py-2 bg-indigo-500 hover:bg-indigo-600 text-white rounded-full",children:"running"===ea?"Rebuildingâ¦":"done"===ea?"Rebuilt!":"Rebuild FAQ embeddings"}),"error"===ea&&(0,s.jsx)("p",{className:"text-red-600 mt-2",children:"Failed to rebuild FAQs"})]}),(0,s.jsxs)("div",{className:"p-6 bg-white rounded-lg shadow-md flex flex-col items-center border border-amber-400",children:[(0,s.jsxs)("h2",{className:"text-xl font-semibold mb-2 flex items-center gap-2",children:[(0,s.jsx)(p.ghb,{className:"text-amber-500"}),"Impersonate user"]}),(0,s.jsx)("p",{className:"text-gray-600 mb-4 text-center text-sm",children:"Paste a Firebase user ID to temporarily sign in as that user in this browser. Youâll see their board exactly as they do."}),(0,s.jsxs)("p",{className:"text-xs text-gray-500 mb-2",children:["Current auth UID: ",(0,s.jsx)("span",{className:"font-mono break-all",children:null==t?void 0:t.uid})]}),(0,s.jsx)("input",{type:"text",value:eC,onChange:e=>{ek(e.target.value),eL(null),eE("idle")},placeholder:"Target Firebase user ID",className:"w-full border border-gray-300 rounded px-3 py-2 text-sm mb-3 font-mono"}),(0,s.jsx)("button",{onClick:eT,disabled:"loading"===eD,className:"w-full px-4 py-2 bg-amber-500 hover:bg-amber-600 text-white rounded-lg text-sm disabled:opacity-60",children:"loading"===eD?"Impersonatingâ¦":"Impersonate user"}),"success"===eD&&(0,s.jsx)("p",{className:"mt-3 text-xs text-green-700",children:"â
Signed in as target user. Reload the main app to view their board."}),"error"===eD&&eU&&(0,s.jsx)("p",{className:"mt-3 text-xs text-red-600",children:eU}),(0,s.jsx)("p",{className:"mt-3 text-[11px] text-gray-500 text-center",children:"Note: this will replace your current admin session in this browser. To stop impersonating, sign out and sign back in as yourself."})]}),(0,s.jsxs)("div",{className:"p-6 bg-white rounded-lg shadow-md flex flex-col items-center border border-gray-300",children:[(0,s.jsx)("h2",{className:"text-xl font-semibold mb-4",children:"Users"}),(0,s.jsx)(p.I$,{className:"text-purple-500 text-4xl mb-4"}),(0,s.jsx)(m(),{href:"/admin/list_users",children:(0,s.jsx)("button",{className:"w-44 px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-lg",children:"View all users"})}),(0,s.jsx)(m(),{href:"/admin/get_user_data",children:(0,s.jsx)("button",{className:"w-44 mt-5 px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-lg",children:"View user data"})})]}),(0,s.jsxs)("div",{className:"p-6 bg-white rounded-lg shadow-md flex flex-col items-center border border-gray-300",children:[(0,s.jsx)("h2",{className:"text-xl font-semibold mb-4 text-center",children:"Board tidy-up"}),(0,s.jsx)(m(),{href:"/admin/board_tidy_up",children:(0,s.jsx)("button",{className:"w-44 px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-lg",children:"Open tidy-up"})})]}),(0,s.jsxs)("div",{className:"p-6 bg-white rounded-lg shadow-md flex flex-col items-center border border-gray-300",children:[(0,s.jsx)("h2",{className:"text-xl font-semibold mb-4 text-center",children:"Discovery leads"}),(0,s.jsx)(m(),{href:"/admin/prospects",children:(0,s.jsx)("button",{className:"w-44 px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-lg",children:"Discovery leads"})})]}),(0,s.jsxs)("div",{className:"p-6 bg-white rounded-lg shadow-md flex flex-col items-center border border-gray-300",children:[(0,s.jsx)("h2",{className:"text-xl font-semibold mb-4",children:"Tags"}),(0,s.jsx)(m(),{href:"/admin/manage_tags",children:(0,s.jsx)("button",{className:"w-44 px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-lg",children:"Manage tags"})})]})]})})})]})}},71087:function(e,t,r){"use strict";r.d(t,{Q:function(){return a},S:function(){return l}});var s=r(78728);let a=async()=>{let e=(0,s.getAuthClient)().currentUser;if(!e)throw Error("Signed-in user required.");let t=await e.getIdToken();return{Authorization:"Bearer ".concat(t)}},l=async function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=await a(),s=new Headers(t.headers);return s.set("Authorization",r.Authorization),fetch(e,{...t,headers:s})}},82602:function(e,t,r){"use strict";r.d(t,{IT:function(){return d},WZ:function(){return i},tb:function(){return n}});let s=new Set(["127.0.0.1","152.37.105.3","130.255.31.57"]),a=["2a01:4b00:b018:b100:"],l=e=>(null==e?void 0:e.ip_address_client)||(null==e?void 0:e.ipAddress)||(null==e?void 0:e.ip_address_server)||null,i=e=>!!e&&(!!s.has(e)||a.some(t=>e.startsWith(t))),n=e=>i(l(e)),d=e=>!!e&&((null==e?void 0:e.copierIsAdmin)===!0||i((null==e?void 0:e.copierIpAddress)||(null==e?void 0:e.ip_address_client)||(null==e?void 0:e.ipAddress)||(null==e?void 0:e.ip_address_server)||null))}},function(e){e.O(0,[7627,5937,3609,2876,1086,6556,1664,6052,5587,4932,3999,2888,9774,179],function(){return e(e.s=52599)}),_N_E=e.O()}]);
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.