PageSourceSearch

https://shopsavvy.com/_next/static/chunks/pages/admin/analytics/retention-cohort-users-673f358a02ee1e18.js

js shopsavvy.com collected 2026-10-01 10:33:08 UTC 12,653 bytes, 1 lines download raw bytes

1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[8308],{69922:function(e,t,s){(window.__NEXT_P=window.__NEXT_P||[]).push(["/admin/analytics/retention-cohort-users",function(){return s(3512)}])},3512:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return RetentionCohortUsersPage}});var a=s(24246),r=s(27378),n=s(88038),i=s.n(n),l=s(79894),o=s.n(l),d=s(86677),c=s(73977);let x=[{value:"D1",label:"D1",description:"Day 1"},{value:"W1",label:"W1",description:"Days 1-7"},{value:"M1",label:"M1",description:"Days 1-30"}];function getUserId(e){return e.user_path.replace("users/","")}function getPlatformColor(e){switch(e){case"ios":return"bg-blue-100 text-blue-800";case"android":return"bg-green-100 text-green-800";case"web":return"bg-purple-100 text-purple-800";case"extension":return"bg-orange-100 text-orange-800";default:return"bg-gray-100 text-gray-800"}}function UserCard(e){var t;let{user:s,showPeriodActivity:r=!1,periodLabel:n="D1"}=e;return(0,a.jsx)(o(),{href:"/admin/users/".concat(getUserId(s)),target:"_blank",className:"block p-4 bg-white rounded-lg border border-gray-200 hover:border-blue-500 hover:shadow-md transition-all",children:(0,a.jsxs)("div",{className:"space-y-3",children:[(0,a.jsxs)("div",{className:"flex items-start justify-between gap-2",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("div",{className:"font-medium text-sm text-gray-900 truncate",children:s.display_name?s.display_name:s.email?s.email:s.user_path.replace("users/","")}),(0,a.jsx)("div",{className:"text-xs text-gray-500 font-mono truncate",children:getUserId(s)})]}),s.platform&&(0,a.jsx)("span",{className:"px-2 py-1 text-xs rounded flex-shrink-0 ".concat(getPlatformColor(s.platform)),children:s.platform})]}),(0,a.jsxs)("div",{className:"grid grid-cols-2 gap-x-4 gap-y-1 text-xs",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("span",{className:"text-gray-500",children:"Sessions:"}),(0,a.jsx)("span",{className:"ml-1 text-gray-900 font-medium",children:s.sessions_count||0})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("span",{className:"text-gray-500",children:"Expeditions:"}),(0,a.jsx)("span",{className:"ml-1 text-gray-900 font-medium",children:s.expeditions_count||0})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("span",{className:"text-gray-500",children:"Watched:"}),(0,a.jsx)("span",{className:"ml-1 text-gray-900 font-medium",children:s.watched_products_count||0})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("span",{className:"text-gray-500",children:"Searches:"}),(0,a.jsx)("span",{className:"ml-1 text-gray-900 font-medium",children:s.watched_searches_count||0})]})]}),r&&(s.period_sessions||s.period_expeditions)&&(0,a.jsxs)("div",{className:"pt-2 border-t border-gray-100",children:[(0,a.jsxs)("div",{className:"text-xs text-green-700 font-medium mb-1",children:[n," Activity:"]}),(0,a.jsxs)("div",{className:"flex gap-4 text-xs",children:[void 0!==s.period_sessions&&s.period_sessions>0&&(0,a.jsxs)("span",{className:"text-green-600",children:[s.period_sessions," session",1!==s.period_sessions?"s":""]}),void 0!==s.period_expeditions&&s.period_expeditions>0&&(0,a.jsxs)("span",{className:"text-green-600",children:[s.period_expeditions," expedition",1!==s.period_expeditions?"s":""]})]})]}),s.first_session_time&&(0,a.jsxs)("div",{className:"text-xs text-gray-400",children:["First session: ",(t=s.first_session_time)?new Date(t).toLocaleString():"N/A"]})]})})}function RetentionCohortUsersPage(){let e=(0,d.useRouter)(),{auth:t}=(0,c.XL)(),[s,n]=(0,r.useState)(null),[l,o]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[g,u]=(0,r.useState)(""),[p,y]=(0,r.useState)([]),[j,f]=(0,r.useState)("D1");(0,r.useEffect)(()=>{if(!e.isReady)return;let t=e.query.date;if(t&&/^\d{4}-\d{2}-\d{2}$/.test(t))u(t);else if(!g){let e=new Date;e.setDate(e.getDate()-1),u(e.toISOString().split("T")[0])}},[e.isReady,e.query.date]);let fetchData=async()=>{if(g){o(!0),m(null);try{let e=new URLSearchParams;e.append("cohortDate",g),p.length>0&&p.forEach(t=>e.append("platform",t)),e.append("retentionPeriod",j),e.append("limit","200");let s=await t.currentUser.getIdToken(),a=await fetch("/api/admin/analytics/retention-cohort
1-users?".concat(e.toString()),{headers:{Authorization:"Bearer ".concat(s)}});if(!a.ok){let e=await a.text();throw Error("HTTP ".concat(a.status,": ").concat(a.statusText," - ").concat(e))}let r=await a.json();n(r)}catch(e){console.error("Fetch error:",e),m(e instanceof Error?e.message:"Failed to fetch data")}finally{o(!1)}}};(0,r.useEffect)(()=>{g&&fetchData()},[g,p,j]);let handleDateChange=t=>{u(t),e.push("/admin/analytics/retention-cohort-users?date=".concat(t),void 0,{shallow:!0})},handlePlatformChange=(e,t)=>{t?y([...p,e]):y(p.filter(t=>t!==e))},canGoForward=()=>{if(!g)return!1;let e=new Date(g+"T00:00:00");e.setDate(e.getDate()+1);let t=new Date;return t.setDate(t.getDate()-1),e<=t};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(i(),{children:(0,a.jsx)("title",{children:"Retention Cohort Users - ShopSavvy Admin"})}),(0,a.jsx)("div",{className:"min-h-screen bg-gray-100 p-6",children:(0,a.jsxs)("div",{className:"max-w-full mx-auto",children:[(0,a.jsxs)("div",{className:"mb-6",children:[(0,a.jsx)("h1",{className:"text-3xl font-bold text-gray-900 mb-2",children:"Cohort Retention Users"}),(0,a.jsx)("p",{className:"text-gray-600",children:"Explore individual users in each cohort. See who came on D0 (left) and who returned within the selected period (right)."}),(0,a.jsxs)("div",{className:"flex gap-2 mt-4",children:[(0,a.jsx)("a",{href:"/admin/analytics/cohort-daily",className:"px-3 py-1 text-sm bg-gray-200 text-gray-700 rounded hover:bg-gray-300",children:"Daily Metrics"}),(0,a.jsx)("a",{href:"/admin/analytics/retention-cohort",className:"px-3 py-1 text-sm bg-gray-200 text-gray-700 rounded hover:bg-gray-300",children:"Retention Grid"}),(0,a.jsx)("span",{className:"px-3 py-1 text-sm bg-blue-600 text-white rounded",children:"User Explorer"})]})]}),(0,a.jsxs)("div",{className:"bg-white rounded-lg shadow mb-6 p-6",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("button",{onClick:()=>{let t=new Date(g+"T00:00:00");t.setDate(t.getDate()-1);let s=t.toISOString().split("T")[0];u(s),e.push("/admin/analytics/retention-cohort-users?date=".concat(s),void 0,{shallow:!0})},className:"flex items-center gap-2 px-4 py-2 bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-lg transition-colors",children:[(0,a.jsx)("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,a.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})}),(0,a.jsx)("span",{children:"Previous Day"})]}),(0,a.jsxs)("div",{className:"text-center",children:[(0,a.jsx)("div",{className:"text-2xl font-bold text-gray-900",children:g&&function(e){let t=new Date(e+"T00:00:00");return t.toLocaleDateString("en-US",{weekday:"long",year:"numeric",month:"long",day:"numeric"})}(g)}),(0,a.jsx)("div",{className:"flex items-center justify-center gap-4 mt-2",children:(0,a.jsx)("input",{type:"date",value:g,onChange:e=>handleDateChange(e.target.value),className:"px-3 py-1 border border-gray-300 rounded-md text-sm text-gray-900 bg-white"})})]}),(0,a.jsxs)("button",{onClick:()=>{let t=new Date(g+"T00:00:00");t.setDate(t.getDate()+1);let s=new Date;if(s.setDate(s.getDate()-1),t<=s){let s=t.toISOString().split("T")[0];u(s),e.push("/admin/analytics/retention-cohort-users?date=".concat(s),void 0,{shallow:!0})}},disabled:!canGoForward(),className:"flex items-center gap-2 px-4 py-2 rounded-lg transition-colors ".concat(canGoForward()?"bg-gray-100 hover:bg-gray-200 text-gray-700":"bg-gray-50 text-gray-300 cursor-not-allowed"),children:[(0,a.jsx)("span",{children:"Next Day"}),(0,a.jsx)("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,a.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]})]}),(0,a.jsxs)("div",{className:"mt-4 pt-4 border-t border-gray-200",children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 mb-2",children:"Filter by Platform"}),(0,a.jsx)("div",{className:"flex flex-wrap gap-3",children:["ios","android","web","extension"].map(e=>(0,a.jsxs)("label",{className:"flex items-center",children:[(0,a.jsx)("input",{type:"checkbox",checked:p.includes(e),onChange:t=>handlePlatformChange(e,t.target.checked),className:"mr-2"}),(0,a.jsx)("span",{className:"px-2 py-1 text-xs rounded ".concat(getPlatformColor(e)),children:e})]},e))})]}),(0,a.jsxs)("div",{className:"mt-4 pt-4 border-t border-gray-200",children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 mb-2",children:"Retention Period"}),(0,a.jsx)("div",{className:"flex gap-2",children:x.map(e=>(0,a.jsxs)("button",{onClick:()=>f(e.value),className:"px-4 py-2 text-sm rounded-lg transition-colors ".concat(j===e.value?"bg-blue-600 text-white":"bg-gray-100 text-gray-700 hover:bg-gray-200"),children:[(0,a.jsx)("span",{className:"font-medium",children:e.label}),(0,a.jsxs)("span",{className:"ml-1 text-xs opacity-75",children:["(",e.description,")"]})]},e.value))})]})]}),s&&!l&&(0,a.jsxs)("div",{className:"bg-white rounded-lg shadow mb-6 p-6",children:[(0,a.jsxs)("div",{className:"grid grid-cols-4 gap-6",children:[(0,a.jsxs)("div",{className:"text-center",children:[(0,a.jsx)("div",{className:"text-3xl font-bold text-gray-900",children:s.cohortSize.toLocaleStr
1ing()}),(0,a.jsx)("div",{className:"text-sm text-gray-500",children:"Total Cohort Size"})]}),(0,a.jsxs)("div",{className:"text-center",children:[(0,a.jsx)("div",{className:"text-3xl font-bold text-blue-600",children:s.d0Users.length.toLocaleString()}),(0,a.jsx)("div",{className:"text-sm text-gray-500",children:"D0 Users (Showing)"})]}),(0,a.jsxs)("div",{className:"text-center",children:[(0,a.jsx)("div",{className:"text-3xl font-bold text-green-600",children:s.retainedUsers.length.toLocaleString()}),(0,a.jsxs)("div",{className:"text-sm text-gray-500",children:["Returned in ",j]})]}),(0,a.jsxs)("div",{className:"text-center",children:[(0,a.jsxs)("div",{className:"text-3xl font-bold text-purple-600",children:[s.retentionRate,"%"]}),(0,a.jsxs)("div",{className:"text-sm text-gray-500",children:[j," Retention Rate"]})]})]}),s.meta.hasMore&&(0,a.jsxs)("div",{className:"mt-4 text-center text-sm text-gray-500",children:["Showing first ",s.meta.limit," users of ",s.cohortSize," total"]})]}),l&&(0,a.jsx)("div",{className:"bg-white rounded-lg shadow p-6 text-center",children:(0,a.jsx)("div",{className:"text-gray-600",children:"Loading cohort users..."})}),h&&(0,a.jsx)("div",{className:"bg-red-50 border border-red-200 rounded-lg p-4 mb-6",children:(0,a.jsxs)("div",{className:"text-red-800",children:["Error: ",h]})}),s&&!l&&!h&&(0,a.jsxs)("div",{className:"grid grid-cols-2 gap-6",children:[(0,a.jsxs)("div",{className:"bg-gray-50 rounded-lg p-4",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,a.jsxs)("h2",{className:"text-xl font-semibold text-gray-900",children:["D0 Users (",s.d0Users.length,")"]}),(0,a.jsxs)("span",{className:"text-sm text-gray-500",children:["First session on ",g]})]}),(0,a.jsx)("div",{className:"space-y-3 max-h-[calc(100vh-400px)] overflow-y-auto",children:0===s.d0Users.length?(0,a.jsx)("div",{className:"text-center text-gray-500 py-8",children:"No users in this cohort"}):s.d0Users.map(e=>(0,a.jsx)(UserCard,{user:e},e.user_path))})]}),(0,a.jsxs)("div",{className:"bg-green-50 rounded-lg p-4",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,a.jsxs)("h2",{className:"text-xl font-semibold text-green-800",children:["Returned ",j," (",s.retainedUsers.length,")"]}),(0,a.jsxs)("span",{className:"text-sm text-green-600",children:[s.retentionRate,"% retention"]})]}),(0,a.jsx)("div",{className:"space-y-3 max-h-[calc(100vh-400px)] overflow-y-auto",children:0===s.retainedUsers.length?(0,a.jsxs)("div",{className:"text-center text-gray-500 py-8",children:["No users returned in ",j]}):s.retainedUsers.map(e=>(0,a.jsx)(UserCard,{user:e,showPeriodActivity:!0,periodLabel:j},e.user_path))})]})]}),(0,a.jsx)("div",{className:"mt-6 text-sm text-gray-500",children:(0,a.jsxs)("p",{children:[(0,a.jsx)("strong",{children:"How to use:"})," Use the arrows or date picker to navigate between cohort dates. Each cohort shows users whose ",(0,a.jsx)("em",{children:"absolute first session ever"})," was on that date (truly new users). Click on any user card to view their full profile in a new tab."]})})]})})]})}}},function(e){e.O(0,[9894,9774,2888,179],function(){return e(e.s=69922)}),_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.