PageSourceSearch

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

js shopsavvy.com collected 2026-09-24 09:00:45 UTC 12,006 bytes, 1 lines download raw bytes

1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[594],{49902:function(e,t,s){(window.__NEXT_P=window.__NEXT_P||[]).push(["/admin/analytics/retention-cohort",function(){return s(99801)}])},99801:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return RetentionCohortGrid}});var a=s(24246),r=s(27378),n=s(88038),l=s.n(n),c=s(73977);function getRetentionColor(e){return null===e?"bg-gray-100 text-gray-400":e>=50?"bg-green-500 text-white":e>=40?"bg-green-400 text-white":e>=30?"bg-green-300 text-gray-900":e>=25?"bg-yellow-300 text-gray-900":e>=20?"bg-yellow-400 text-gray-900":e>=15?"bg-orange-300 text-gray-900":e>=10?"bg-orange-400 text-white":e>=5?"bg-red-400 text-white":"bg-red-500 text-white"}let d=["d1","d2","d3","d4","d5","d6","d7","d8","d9","d10","d11","d12","d13","d14"],i=["w1","w2","w3","w4"],o=["m1","m2"];function RetentionCohortGrid(){let{auth:e}=(0,c.XL)(),[t,s]=(0,r.useState)([]),[n,x]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[g,p]=(0,r.useState)(""),[u,y]=(0,r.useState)(""),[b,j]=(0,r.useState)([]),[w,f]=(0,r.useState)(!0),[N,v]=(0,r.useState)(!0),[k,C]=(0,r.useState)(!0),[S]=(0,r.useState)(["ios","android","web","extension"]);(0,r.useEffect)(()=>{let e=new Date,t=new Date(e.getTime()-2592e6);y(e.toISOString().split("T")[0]),p(t.toISOString().split("T")[0])},[]);let fetchData=async()=>{if(g&&u){x(!0),m(null);try{let t=new URLSearchParams;t.append("dateStart",g),t.append("dateEnd",u),b.length>0&&b.forEach(e=>t.append("platform",e));let a=await e.currentUser.getIdToken(),r=await fetch("/api/admin/analytics/retention-cohort-grid?".concat(t.toString()),{headers:{Authorization:"Bearer ".concat(a)}});if(!r.ok){let e=await r.text();throw Error("HTTP ".concat(r.status,": ").concat(r.statusText," - ").concat(e))}let n=await r.json();s(n.data)}catch(e){console.error("Fetch error:",e),m(e instanceof Error?e.message:"Failed to fetch data")}finally{x(!1)}}};(0,r.useEffect)(()=>{g&&u&&fetchData()},[g,u,b]);let handlePlatformChange=(e,t)=>
1{t?j([...b,e]):j(b.filter(t=>t!==e))},formatValue=e=>null===e?"-":"".concat(e.toFixed(1),"%"),E=(()=>{let e={},s=[...d,...i,...o];return s.forEach(s=>{let a=t.map(e=>e[s]).filter(e=>null!==e);e[s]=a.length>0?a.reduce((e,t)=>e+t,0)/a.length:null}),e})();return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(l(),{children:(0,a.jsx)("title",{children:"Retention Cohort Grid - ShopSavvy Admin"})}),(0,a.jsx)("div",{className:"min-h-screen bg-gray-50 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 Grid"}),(0,a.jsx)("p",{className:"text-gray-600",children:"Track user retention over time. Each row is a cohort of users who had their first session on that date. Values show what percentage returned on each subsequent day/week/month."}),(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)("span",{className:"px-3 py-1 text-sm bg-blue-600 text-white rounded",children:"Retention Grid"}),(0,a.jsx)("a",{href:"/admin/analytics/retention-cohort-users",className:"px-3 py-1 text-sm bg-gray-200 text-gray-700 rounded hover:bg-gray-300",children:"User Explorer"})]})]}),(0,a.jsxs)("div",{className:"bg-white rounded-lg shadow mb-6 p-6",children:[(0,a.jsx)("h2",{className:"text-lg font-semibold mb-4",children:"Filters"}),(0,a.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 mb-1",children:"Start Date"}),(0,a.jsx)("input",{type:"date",value:g,onChange:e=>p(e.target.value),className:"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 text-gray-900 bg-white"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 mb-1",children:"End Date"}),(0,a.jsx)("input",{type:"date",value:u,onChange:e=>y(e.target.value),className:"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 text-gray-900 bg-white"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 mb-2",children:"Platforms"}),(0,a.jsx)("div",{className:"flex flex-wrap gap-2",children:S.map(e=>(0,a.jsxs)("label",{className:"flex items-center",children:[(0,a.jsx)("input",{type:"checkbox",checked:b.includes(e),onChange:t=>handlePlatformChange(e,t.target.checked),className:"mr-1"}),(0,a.jsx)("span",{className:"text-sm",children:e})]},e))})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 mb-2",children:"Show Columns"}),(0,a.jsxs)("div",{className:"flex flex-wrap gap-2",children:[(0,a.jsxs)("label",{className:"flex items-center",children:[(0,a.jsx)("input",{type:"checkbox",checked:w,onChange:e=>f(e.target.checked),className:"mr-1"}),(0,a.jsx)("span",{className:"text-sm",children:"Daily (D1-D14)"})]}),(0,a.jsxs)("label",{className:"flex items-center",children:[(0,a.jsx)("input",{type:"checkbox",checked:N,onChange:e=>v(e.target.checked),className:"mr-1"}),(0,a.jsx)("span",{className:"text-sm",children:"Weekly (W1-W4)"})]}),(0,a.jsxs)("label",{className:"flex items-center",children:[(0,a.jsx)("input",{type:"checkbox",checked:k,onChange:e=>C(e.target.checked),className:"mr-1"}),(0,a.jsx)("span",{className:"text-sm",children:"Monthly (M1-M2)"})]})]})]})]})]}),(0,a.jsxs)("div",{className:"bg-white rounded-lg shadow mb-6 p-4",children:[(0,a.jsx)("h3",{className:"text-sm font-semibold text-gray-700 mb-2",children:"Retention Color Scale"}),(0,a.jsxs)("div",{className:"flex flex-wrap gap-2 text-xs",children:[(0,a.jsx)("span",{className:"px-2 py-1 rounded bg-red-500 text-white",children:"0-5%"}),(0,a.jsx)("span",{className:"px-2 py-1 rounded bg-red-400 text-white",children:"5-10%"}),(0,a.jsx)("span",{className:"px-2 py-1 rounded bg-orange-400 text-white",children:"10-15%"}),(0,a.jsx)("span",{className:"px-2 py-1 rounded bg-orange-300 text-gray-900",children:"15-20%"}),(0,a.jsx)("span",{className:"px-2 py-1 rounded bg-yellow-400 text-gray-900",children:"20-25%"}),(0,a.jsx)("span",{className:"px-2 py-1 rounded bg-yellow-300 text-gray-900",children:"25-30%"}),(0,a.jsx)("span",{className:"px-2 py-1 rounded bg-green-300 text-gray-900",children:"30-40%"}),(0,a.jsx)("span",{className:"px-2 py-1 rounded bg-green-400 text-white",children:"40-50%"}),(0,a.jsx)("span",{className:"px-2 py-1 rounded bg-green-500 text-white",children:"50%+"}),(0,a.jsx)("span",{className:"px-2 py-1 rounded bg-gray-100 text-gray-400",children:"- (not yet)"})]})]}),n&&(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 retention data..."})}),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]})}),!n&&!h&&t.length>0&&(0,a.jsxs)("div",{className:"bg-white rounded-lg shadow overflow-hidden",children:[(0,a.jsx)("div",{className:"px-6 py-4 border-b border-gray-200",children:(0,a.jsxs)("h3",{className:"text-lg font-semibold",children:["Retention Grid (",t.length," cohorts)"]}
1)}),(0,a.jsx)("div",{className:"overflow-x-auto",children:(0,a.jsxs)("table",{className:"min-w-full",children:[(0,a.jsx)("thead",{className:"bg-gray-50",children:(0,a.jsxs)("tr",{children:[(0,a.jsx)("th",{className:"px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider sticky left-0 bg-gray-50 z-10",children:"Cohort Date"}),(0,a.jsx)("th",{className:"px-3 py-2 text-center text-xs font-medium text-gray-500 uppercase tracking-wider",children:"Size"}),w&&d.map(e=>(0,a.jsx)("th",{className:"px-2 py-2 text-center text-xs font-medium text-gray-500 uppercase tracking-wider",children:e.toUpperCase()},e)),w&&N&&(0,a.jsx)("th",{className:"px-1 py-2 bg-gray-200"}),N&&i.map(e=>(0,a.jsx)("th",{className:"px-2 py-2 text-center text-xs font-medium text-gray-500 uppercase tracking-wider",children:e.toUpperCase()},e)),N&&k&&(0,a.jsx)("th",{className:"px-1 py-2 bg-gray-200"}),k&&o.map(e=>(0,a.jsx)("th",{className:"px-2 py-2 text-center text-xs font-medium text-gray-500 uppercase tracking-wider",children:e.toUpperCase()},e))]})}),(0,a.jsxs)("tbody",{className:"bg-white divide-y divide-gray-200",children:[(0,a.jsxs)("tr",{className:"bg-blue-50 font-semibold",children:[(0,a.jsx)("td",{className:"px-3 py-2 whitespace-nowrap text-sm text-gray-900 sticky left-0 bg-blue-50 z-10",children:"Average"}),(0,a.jsx)("td",{className:"px-3 py-2 whitespace-nowrap text-sm text-center text-gray-500",children:"-"}),w&&d.map(e=>(0,a.jsx)("td",{className:"px-2 py-2 whitespace-nowrap text-xs text-center ".concat(getRetentionColor(E[e])),children:formatValue(E[e])},e)),w&&N&&(0,a.jsx)("td",{className:"px-1 py-2 bg-gray-200"}),N&&i.map(e=>(0,a.jsx)("td",{className:"px-2 py-2 whitespace-nowrap text-xs text-center ".concat(getRetentionColor(E[e])),children:formatValue(E[e])},e)),N&&k&&(0,a.jsx)("td",{className:"px-1 py-2 bg-gray-200"}),k&&o.map(e=>(0,a.jsx)("td",{className:"px-2 py-2 whitespace-nowrap text-xs text-center ".concat(getRetentionColor(E[e])),children:formatValue(E[e])},e))]}),t.map((e,t)=>(0,a.jsxs)("tr",{className:"hover:bg-gray-50",children:[(0,a.jsx)("td",{className:"px-3 py-2 whitespace-nowrap text-sm sticky left-0 bg-white z-10",children:(0,a.jsx)("a",{href:"/admin/analytics/retention-cohort-users?date=".concat(e.cohort_date),className:"text-blue-600 hover:text-blue-800 hover:underline",title:"View users in this cohort",children:e.cohort_date})}),(0,a.jsx)("td",{className:"px-3 py-2 whitespace-nowrap text-sm text-center text-gray-600",children:e.cohort_size.toLocaleString()}),w&&d.map(t=>(0,a.jsx)("td",{className:"px-2 py-2 whitespace-nowrap text-xs text-center ".concat(getRetentionColor(e[t])),children:formatValue(e[t])},t)),w&&N&&(0,a.jsx)("td",{className:"px-1 py-2 bg-gray-200"}),N&&i.map(t=>(0,a.jsx)("td",{className:"px-2 py-2 whitespace-nowrap text-xs text-center ".concat(getRetentionColor(e[t])),children:formatValue(e[t])},t)),N&&k&&(0,a.jsx)("td",{className:"px-1 py-2 bg-gray-200"}),k&&o.map(t=>(0,a.jsx)("td",{className:"px-2 py-2 whitespace-nowrap text-xs text-center ".concat(getRetentionColor(e[t])),children:formatValue(e[t])},t))]},t))]})]})})]}),!n&&!h&&0===t.length&&(0,a.jsxs)("div",{className:"bg-white rounded-lg shadow p-6 text-center",children:[(0,a.jsx)("div",{className:"text-gray-600",children:"No cohort data found for the selected filters."}),(0,a.jsx)("div",{className:"text-sm text-gray-500 mt-2",children:"Try adjusting your date range or removing some filters."})]}),(0,a.jsxs)("div",{className:"mt-6 text-sm text-gray-500",children:[(0,a.jsxs)("p",{children:[(0,a.jsx)("strong",{children:"Note:"}),' This grid shows retention for "truly new users" - users whose absolute first session ever was on the cohort date. This excludes returning users who may have used the app before the analysis window.']}),(0,a.jsxs)("ul",{className:"list-disc ml-5 mt-2",children:[(0,a.jsxs)("li",{children:[(0,a.jsx)("strong",{children:"D1-D14:"})," Percentage of users who returned on exactly that day after their first session"]}),(0,a.jsxs)("li",{children:[(0,a.jsx)("strong",{children:"W1-W4:"})," Percentage who returned any time during that week (W1 = days 1-7, W2 = days 8-14, etc.)"]}),(0,a.jsxs)("li",{children:[(0,a.jsx)("strong",{children:"M1-M2:"})," Percentage who returned any time during that month (M1 = days 1-30, M2 = days 31-60)"]}),(0,a.jsxs)("li",{children:[(0,a.jsx)("strong",{children:"-"})," indicates not enough time has passed to calculate retention for that period"]})]})]})]})})]})}}},function(e){e.O(0,[9774,2888,179],function(){return e(e.s=49902)}),_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.