sanity-plugin-ga-dashboard 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/index.d.mts +15 -0
- package/dist/api/index.d.ts +15 -0
- package/dist/api/index.esm.js +235 -0
- package/dist/api/index.esm.js.map +1 -0
- package/dist/api/index.js +260 -0
- package/dist/api/index.js.map +1 -0
- package/dist/index.d.mts +117 -0
- package/dist/index.d.ts +117 -0
- package/dist/index.esm.js +880 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +890 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/plugin.ts","../src/components/dashboard.tsx","../src/utils/ga-api.ts","../src/google-analytics-tool.tsx"],"sourcesContent":["import {definePlugin} from 'sanity'\nimport {BarChartIcon} from '@sanity/icons'\nimport {GoogleAnalyticsTool} from './google-analytics-tool'\nimport type {GoogleAnalyticsPluginConfig} from './types'\n\nexport const googleAnalyticsPlugin = (config: GoogleAnalyticsPluginConfig = {}) =>\n definePlugin({\n name: 'ga-dashboard',\n tools: (prev) => [\n ...prev,\n {\n name: 'ga-dashboard',\n title: 'Google Analytics',\n icon: BarChartIcon,\n component: () => GoogleAnalyticsTool(config),\n },\n ],\n })()\n","import {useState, useEffect, useCallback} from 'react'\nimport {\n AreaChart, Area, BarChart, Bar,\n XAxis, YAxis, CartesianGrid, Tooltip,\n ResponsiveContainer, PieChart, Pie, Cell, Legend,\n} from 'recharts'\nimport type {AnalyticsData, DateRange} from '../types'\nimport {fetchAnalyticsData} from '../utils/ga-api'\n\n/* ─────────────────────────────────────────────\n Constants\n───────────────────────────────────────────── */\nconst DATE_RANGES: {label: string; value: DateRange}[] = [\n {label: '7d', value: '7'},\n {label: '14d', value: '14'},\n {label: '30d', value: '30'},\n {label: '90d', value: '90'},\n]\n\nconst PALETTE = ['#4f8ef7','#3ecf8e','#f6b93b','#e55353','#a55eea','#26c0d3','#fd9644','#20bf6b']\n\nconst DEVICE_COLORS: Record<string, string> = {\n desktop: '#4f8ef7', mobile: '#3ecf8e', tablet: '#f6b93b',\n}\nconst CHANNEL_COLORS: Record<string, string> = {\n 'Organic Search': '#3ecf8e', 'Direct': '#4f8ef7', 'Referral': '#f6b93b',\n 'Organic Social': '#e55353', 'Email': '#a55eea', 'Paid Search': '#26c0d3', 'Display': '#fd9644',\n}\n\nconst METRIC_INFO: Record<string, string> = {\n 'Total Users': 'Unique users who visited your site in the selected period.',\n 'New Users': 'First-time visitors — users who have never visited before.',\n 'Sessions': 'Total browsing sessions. One user can have multiple sessions.',\n 'Page Views': 'Total pages viewed, including repeated views of the same page.',\n 'Avg. Duration': 'Average time a user spends in a single session.',\n 'Bounce Rate': 'Percentage of sessions where the user left without any interaction.',\n 'Engaged Sessions': 'Sessions lasting 10+ seconds, or with a conversion, or 2+ page views.',\n 'Engagement Rate': 'Percentage of total sessions that were engaged sessions.',\n 'Pages / Session': 'Average number of pages a user views per session.',\n 'Events / Session': 'Average number of events (clicks, scrolls, etc.) fired per session.',\n}\n\nconst SECTION_INFO: Record<string, string> = {\n 'Users & Sessions Over Time': 'Daily breakdown of users, sessions and page views over the selected date range.',\n 'Traffic by Hour — Today': 'How traffic is distributed across each hour of today.',\n 'Channel Grouping': 'Which marketing channels are driving sessions (Organic, Direct, Social, etc.).',\n 'Top Pages': 'Most visited pages ranked by page view count.',\n 'Top Landing Pages': 'First pages users arrive on, ranked by session count. High bounce rate may indicate poor landing experience.',\n 'Devices': 'Share of sessions split by device type (desktop, mobile, tablet).',\n 'New vs Returning': 'Ratio of first-time visitors to users who have visited before.',\n 'Browsers': 'Which web browsers your visitors are using.',\n 'Operating Systems': 'Which operating systems your visitors are running.',\n 'Top Events': 'All events fired on your site (clicks, scrolls, form submits, custom events).',\n 'Top Countries': 'Countries your users are visiting from, ranked by user count.',\n 'Top Cities': 'Cities your users are visiting from, ranked by user count.',\n 'Traffic Sources': 'Source and medium pairs showing where your traffic originates.',\n 'Top Referrers': 'Specific pages on other websites that linked to your site.',\n}\n\n/* ─────────────────────────────────────────────\n Sidebar tabs\n───────────────────────────────────────────── */\ntype Tab = 'overview' | 'traffic' | 'content' | 'audience' | 'geography' | 'events' | 'acquisition'\n\nconst TABS: {id: Tab; label: string; icon: string}[] = [\n {id: 'overview', label: 'Overview', icon: '▦'},\n {id: 'traffic', label: 'Traffic', icon: '↗'},\n {id: 'content', label: 'Content', icon: '≡'},\n {id: 'audience', label: 'Audience', icon: '◉'},\n {id: 'geography', label: 'Geography', icon: '⊕'},\n {id: 'events', label: 'Events', icon: '⚡'},\n {id: 'acquisition', label: 'Acquisition', icon: '⤴'},\n]\n\n/* ─────────────────────────────────────────────\n Formatters\n───────────────────────────────────────────── */\nconst fNum = (n: number) => n >= 1e6 ? `${(n/1e6).toFixed(1)}M` : n >= 1e3 ? `${(n/1e3).toFixed(1)}K` : n.toLocaleString()\nconst fDur = (s: number) => { const m = Math.floor(s/60); const sec = Math.round(s%60); return m > 0 ? `${m}m ${sec}s` : `${sec}s` }\nconst fPct = (v: number) => `${(v*100).toFixed(1)}%`\nconst fEngPct = (v: number) => `${(v*100).toFixed(0)}%`\n\n/* ─────────────────────────────────────────────\n Global CSS (injected once)\n───────────────────────────────────────────── */\nconst GLOBAL_CSS = `\n@keyframes ga-spin { to { transform: rotate(360deg); } }\n@keyframes ga-pulse { 0%,100%{box-shadow:0 0 0 3px rgba(62,207,142,.3)} 50%{box-shadow:0 0 0 7px rgba(62,207,142,.08)} }\n@keyframes ga-fadein { from{opacity:0;transform:translateY(4px)} to{opacity:1;transform:translateY(0)} }\n@keyframes ga-shimmer { 0%{background-position:-600px 0} 100%{background-position:600px 0} }\n.ga-skel {\n background:linear-gradient(90deg,#f1f5f9 25%,#e8eef4 50%,#f1f5f9 75%);\n background-size:1200px 100%; animation:ga-shimmer 1.4s infinite linear; border-radius:4px;\n}\n.ga-tooltip-wrap { position:relative; display:inline-flex; align-items:center; }\n.ga-tooltip-wrap .ga-tip {\n visibility:hidden; opacity:0; pointer-events:none;\n position:absolute; bottom:calc(100% + 6px); left:50%; transform:translateX(-50%);\n background:#1e293b; color:#f1f5f9; font-size:12px; line-height:1.5;\n padding:8px 12px; border-radius:7px; white-space:normal; width:220px;\n box-shadow:0 4px 16px rgba(0,0,0,.18); z-index:9999; transition:opacity .15s;\n}\n.ga-tooltip-wrap .ga-tip::after {\n content:''; position:absolute; top:100%; left:50%; transform:translateX(-50%);\n border:5px solid transparent; border-top-color:#1e293b;\n}\n.ga-tooltip-wrap:hover .ga-tip { visibility:visible; opacity:1; }\n.ga-info-btn {\n width:16px; height:16px; border-radius:50%; border:1.5px solid #94a3b8;\n background:transparent; color:#94a3b8; font-size:10px; font-weight:700;\n cursor:default; display:inline-flex; align-items:center; justify-content:center;\n margin-left:6px; flex-shrink:0; line-height:1; padding:0;\n}\n.ga-info-btn:hover { border-color:#4f8ef7; color:#4f8ef7; }\n.ga-tab-btn { border:none; background:none; cursor:pointer; width:100%; padding:0; }\n.ga-tab-btn:focus { outline:none; }\n.ga-date-btn { border:none; cursor:pointer; }\n.ga-retry-btn { border:none; cursor:pointer; }\n`\n\n/* ─────────────────────────────────────────────\n Sub-components\n───────────────────────────────────────────── */\n\nfunction InfoIcon({text}: {text: string}) {\n return (\n <span className=\"ga-tooltip-wrap\">\n <button className=\"ga-info-btn\" tabIndex={-1}>i</button>\n <span className=\"ga-tip\">{text}</span>\n </span>\n )\n}\n\nfunction Skel({w, h = 14, r = 4, style}: {w?: string|number; h?: number; r?: number; style?: React.CSSProperties}) {\n return <div className=\"ga-skel\" style={{width: w ?? '100%', height: h, borderRadius: r, flexShrink:0, ...style}} />\n}\n\nfunction Panel({title, children, info, style}: {\n title?: string; children: React.ReactNode; info?: string; style?: React.CSSProperties\n}) {\n return (\n <div style={{background:'#fff', border:'1px solid #e2e8f0', borderRadius:10,\n padding:'20px 22px', boxSizing:'border-box', ...style}}>\n {title && (\n <div style={{display:'flex', alignItems:'center', marginBottom:16}}>\n <span style={{fontSize:13, fontWeight:600, color:'#1e293b', letterSpacing:'0.01em'}}>{title}</span>\n {info && <InfoIcon text={info} />}\n </div>\n )}\n {children}\n </div>\n )\n}\n\nfunction SectionLabel({children}: {children: React.ReactNode}) {\n return <div style={{fontSize:11, fontWeight:700, color:'#94a3b8', textTransform:'uppercase', letterSpacing:'0.08em', marginBottom:14}}>{children}</div>\n}\n\nfunction DataTable({headers, rows, empty = 'No data', loading, skeletonRows = 6}: {\n headers: {label: string; align?: 'left'|'right'; width?: string}[]\n rows: (string | React.ReactNode)[][]\n empty?: string\n loading?: boolean\n skeletonRows?: number\n}) {\n return (\n <div style={{width:'100%', overflowX:'auto'}}>\n <table style={{width:'100%', borderCollapse:'collapse', fontSize:13, tableLayout:'fixed'}}>\n <thead>\n <tr>\n {headers.map((h,i) => (\n <th key={i} style={{padding:'6px 10px', textAlign:h.align??'left', color:'#94a3b8',\n fontWeight:600, fontSize:11, borderBottom:'1px solid #f1f5f9',\n textTransform:'uppercase', letterSpacing:'0.05em', width:h.width, whiteSpace:'nowrap'}}>\n {h.label}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {loading ? (\n Array.from({length: skeletonRows}).map((_,ri) => (\n <tr key={ri} style={{borderBottom:'1px solid #f8fafc'}}>\n {headers.map((_h,ci) => (\n <td key={ci} style={{padding:'9px 10px'}}>\n <Skel w={ci === 0 ? `${60 + (ri * 7) % 30}%` : '70%'} h={12} />\n </td>\n ))}\n </tr>\n ))\n ) : rows.length === 0 ? (\n <tr><td colSpan={headers.length} style={{padding:'28px', textAlign:'center', color:'#cbd5e1', fontSize:13}}>{empty}</td></tr>\n ) : rows.map((row,ri) => (\n <tr key={ri} style={{borderBottom:'1px solid #f8fafc', transition:'background .1s'}}\n onMouseEnter={e => (e.currentTarget.style.background='#f8fafc')}\n onMouseLeave={e => (e.currentTarget.style.background='')}>\n {row.map((cell,ci) => (\n <td key={ci} style={{padding:'9px 10px', textAlign:headers[ci]?.align??'left',\n color:ci===0?'#334155':ci===1?'#1e293b':'#94a3b8',\n fontWeight:ci===1?600:400, verticalAlign:'middle'}}>\n {cell}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )\n}\n\nfunction Donut({data, colors, info, loading}: {\n data: {name: string; value: number; percentage: number}[]\n colors: string[]\n info?: string\n loading?: boolean\n}) {\n if (loading) return (\n <div>\n <div style={{display:'flex',justifyContent:'center',padding:'16px 0'}}>\n <div className=\"ga-skel\" style={{width:120,height:120,borderRadius:'50%'}} />\n </div>\n <div style={{display:'flex',flexDirection:'column',gap:8,marginTop:4}}>\n {Array.from({length:3}).map((_,i) => (\n <div key={i} style={{display:'flex',alignItems:'center',gap:8}}>\n <div className=\"ga-skel\" style={{width:8,height:8,borderRadius:2,flexShrink:0}} />\n <Skel w={`${50 + i * 12}%`} h={11} />\n <Skel w={30} h={11} style={{marginLeft:'auto'}} />\n </div>\n ))}\n </div>\n </div>\n )\n if (data.length === 0) return <div style={{color:'#cbd5e1',fontSize:13,padding:'20px 0',textAlign:'center'}}>No data</div>\n return (\n <div>\n <div style={{height:180}}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <PieChart>\n <Pie data={data} dataKey=\"value\" nameKey=\"name\" cx=\"50%\" cy=\"50%\"\n innerRadius={48} outerRadius={76} paddingAngle={2}>\n {data.map((_,i) => <Cell key={i} fill={colors[i % colors.length]} />)}\n </Pie>\n <Tooltip formatter={(v) => fNum(Number(v))}\n contentStyle={{background:'#fff',border:'1px solid #e2e8f0',borderRadius:7,fontSize:13}} />\n </PieChart>\n </ResponsiveContainer>\n </div>\n {info && <div style={{fontSize:12,color:'#94a3b8',textAlign:'center',marginBottom:12}}>{info}</div>}\n <div style={{display:'flex',flexDirection:'column',gap:7}}>\n {data.map((d,i) => (\n <div key={d.name} style={{display:'flex',alignItems:'center',gap:8}}>\n <div style={{width:9,height:9,borderRadius:2,background:colors[i%colors.length],flexShrink:0}} />\n <span style={{flex:1,fontSize:13,color:'#475569',textTransform:'capitalize'}}>{d.name}</span>\n <span style={{fontSize:12,color:'#cbd5e1'}}>{d.percentage}%</span>\n <span style={{fontSize:13,fontWeight:600,color:'#1e293b',minWidth:40,textAlign:'right'}}>{fNum(d.value)}</span>\n </div>\n ))}\n </div>\n </div>\n )\n}\n\nfunction MetricCard({label, value, sub, color, info, loading}: {\n label: string; value: string; sub?: string; color: string; info?: string; loading?: boolean\n}) {\n return (\n <div style={{flex:'1 1 140px', minWidth:132, background:'#fff', border:'1px solid #e2e8f0',\n borderRadius:10, padding:'16px 18px', boxSizing:'border-box', transition:'box-shadow .15s'}}\n onMouseEnter={e => (e.currentTarget.style.boxShadow='0 4px 14px rgba(0,0,0,.07)')}\n onMouseLeave={e => (e.currentTarget.style.boxShadow='')}>\n <div style={{display:'flex',alignItems:'center',marginBottom:10}}>\n <span style={{fontSize:11,color:'#94a3b8',fontWeight:600,textTransform:'uppercase',letterSpacing:'0.06em',flex:1}}>{label}</span>\n {info && <InfoIcon text={info} />}\n </div>\n {loading\n ? <><Skel w=\"55%\" h={22} r={5} />{sub && <Skel w=\"40%\" h={11} style={{marginTop:6}} />}</>\n : <><div style={{fontSize:26,fontWeight:700,color,lineHeight:1,marginBottom:sub?4:0}}>{value}</div>\n {sub && <div style={{fontSize:12,color:'#94a3b8',marginTop:3}}>{sub}</div>}</>\n }\n </div>\n )\n}\n\nfunction ActiveBadge({count, loading}: {count: number; loading?: boolean}) {\n return (\n <div style={{display:'inline-flex',alignItems:'center',gap:10,background:'#f0fdf9',\n border:'1px solid #a7f3d0',borderRadius:10,padding:'12px 20px',marginBottom:20}}>\n <div style={{width:10,height:10,borderRadius:'50%',background:'#10b981',\n animation:'ga-pulse 2s infinite',flexShrink:0}} />\n {loading\n ? <Skel w={80} h={20} r={5} />\n : <span style={{fontSize:22,fontWeight:700,color:'#065f46'}}>{count.toLocaleString()}</span>\n }\n <span style={{fontSize:13,color:'#047857'}}>users active right now</span>\n <InfoIcon text=\"Real-time count of users active on your site in the last 30 minutes.\" />\n </div>\n )\n}\n\nfunction PathCell({path}: {path: string}) {\n return (\n <span title={path} style={{display:'block',overflow:'hidden',textOverflow:'ellipsis',\n whiteSpace:'nowrap',color:'#4f8ef7',fontSize:13}}>\n {path}\n </span>\n )\n}\n\nfunction EmptyTab() {\n return <div style={{display:'flex',justifyContent:'center',alignItems:'center',minHeight:300,color:'#cbd5e1',fontSize:14}}>No data to display</div>\n}\n\nfunction SkeletonChart({height}: {height: number}) {\n return (\n <div style={{position:'relative',height,overflow:'hidden'}}>\n <Skel w=\"100%\" h={height} r={6} />\n {/* fake axis lines */}\n <div style={{position:'absolute',bottom:0,left:0,right:0,display:'flex',justifyContent:'space-between',\n padding:'0 4px 6px',gap:4,pointerEvents:'none'}}>\n {Array.from({length:7}).map((_,i) => <Skel key={i} w={32} h={10} r={3} />)}\n </div>\n </div>\n )\n}\n\n/* ─────────────────────────────────────────────\n Tab views\n───────────────────────────────────────────── */\nfunction OverviewTab({data, loading}: {data: AnalyticsData; loading?: boolean}) {\n return (\n <div style={{animation:'ga-fadein .25s ease',overflowX:'hidden'}}>\n <ActiveBadge count={data.activeUsers} loading={loading} />\n\n <SectionLabel>Key Metrics</SectionLabel>\n <div style={{display:'flex',gap:10,flexWrap:'wrap',marginBottom:24}}>\n {([\n ['Total Users', fNum(data.overview.totalUsers), '#4f8ef7'],\n ['New Users', fNum(data.overview.newUsers), '#3ecf8e'],\n ['Sessions', fNum(data.overview.sessions), '#f6b93b'],\n ['Page Views', fNum(data.overview.pageViews), '#e55353'],\n ['Avg. Duration', fDur(data.overview.avgSessionDuration), '#a55eea'],\n ['Bounce Rate', fPct(data.overview.bounceRate), '#fd9644'],\n ] as [string,string,string][]).map(([l,v,c]) => (\n <MetricCard key={l} label={l} value={v} color={c} info={METRIC_INFO[l]} loading={loading} />\n ))}\n </div>\n\n <SectionLabel>Engagement</SectionLabel>\n <div style={{display:'flex',gap:10,flexWrap:'wrap'}}>\n {([\n ['Engaged Sessions', fNum(data.overview.engagedSessions), '#26c0d3'],\n ['Engagement Rate', fEngPct(data.overview.engagementRate), '#3ecf8e'],\n ['Pages / Session', data.overview.pagesPerSession.toFixed(1), '#8b5cf6'],\n ['Events / Session', data.overview.eventsPerSession.toFixed(1), '#f59e0b'],\n ] as [string,string,string][]).map(([l,v,c]) => (\n <MetricCard key={l} label={l} value={v} color={c} info={METRIC_INFO[l]} loading={loading} />\n ))}\n </div>\n </div>\n )\n}\n\nfunction TrafficTab({data, loading}: {data: AnalyticsData; loading?: boolean}) {\n const channelBar = data.channels.map(c => ({name:c.channel, Sessions:c.sessions, Users:c.users}))\n return (\n <div style={{animation:'ga-fadein .25s ease', display:'flex', flexDirection:'column', gap:20}}>\n <Panel title=\"Users, Sessions & Page Views\" info={SECTION_INFO['Users & Sessions Over Time']}>\n {loading\n ? <SkeletonChart height={300} />\n : <div style={{height:300}}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={data.timeSeries} margin={{top:4,right:8,left:0,bottom:0}}>\n <defs>\n {[['gU','#4f8ef7'],['gS','#3ecf8e'],['gP','#e55353']].map(([id,c]) => (\n <linearGradient key={id} id={id} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"5%\" stopColor={c} stopOpacity={0.18} />\n <stop offset=\"95%\" stopColor={c} stopOpacity={0} />\n </linearGradient>\n ))}\n </defs>\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"#f1f5f9\" />\n <XAxis dataKey=\"displayDate\" fontSize={11} tick={{fill:'#94a3b8'}} axisLine={false} tickLine={false} />\n <YAxis fontSize={11} tick={{fill:'#94a3b8'}} axisLine={false} tickLine={false} width={36} />\n <Tooltip contentStyle={{background:'#fff',border:'1px solid #e2e8f0',borderRadius:7,fontSize:13}} cursor={{stroke:'#f1f5f9'}} />\n <Legend wrapperStyle={{fontSize:13,paddingTop:10}} />\n <Area type=\"monotone\" dataKey=\"users\" name=\"Users\" stroke=\"#4f8ef7\" fill=\"url(#gU)\" strokeWidth={2} dot={false} />\n <Area type=\"monotone\" dataKey=\"sessions\" name=\"Sessions\" stroke=\"#3ecf8e\" fill=\"url(#gS)\" strokeWidth={2} dot={false} />\n <Area type=\"monotone\" dataKey=\"pageViews\" name=\"Pages\" stroke=\"#e55353\" fill=\"url(#gP)\" strokeWidth={2} dot={false} />\n </AreaChart>\n </ResponsiveContainer>\n </div>\n }\n </Panel>\n\n <Panel title=\"Traffic by Hour — Today\" info={SECTION_INFO['Traffic by Hour — Today']}>\n {loading\n ? <SkeletonChart height={220} />\n : <div style={{height:220}}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={data.hourlyToday} margin={{top:4,right:8,left:0,bottom:0}} barSize={12} barGap={3}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"#f1f5f9\" vertical={false} />\n <XAxis dataKey=\"label\" fontSize={11} tick={{fill:'#94a3b8'}} axisLine={false} tickLine={false} interval={1} />\n <YAxis fontSize={11} tick={{fill:'#94a3b8'}} axisLine={false} tickLine={false} width={32} />\n <Tooltip contentStyle={{background:'#fff',border:'1px solid #e2e8f0',borderRadius:7,fontSize:13}} />\n <Legend wrapperStyle={{fontSize:13,paddingTop:8}} />\n <Bar dataKey=\"users\" name=\"Users\" fill=\"#4f8ef7\" radius={[3,3,0,0]} />\n <Bar dataKey=\"sessions\" name=\"Sessions\" fill=\"#3ecf8e\" radius={[3,3,0,0]} />\n </BarChart>\n </ResponsiveContainer>\n </div>\n }\n </Panel>\n\n <Panel title=\"Channel Grouping\" info={SECTION_INFO['Channel Grouping']}>\n {loading\n ? <SkeletonChart height={200} />\n : <div style={{height:Math.max(200, data.channels.length * 46)}}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart data={channelBar} layout=\"vertical\" margin={{top:4,right:24,left:8,bottom:0}} barSize={11}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"#f1f5f9\" horizontal={false} />\n <XAxis type=\"number\" fontSize={11} tick={{fill:'#94a3b8'}} axisLine={false} tickLine={false} />\n <YAxis type=\"category\" dataKey=\"name\" fontSize={12} tick={{fill:'#475569'}} axisLine={false} tickLine={false} width={130} />\n <Tooltip contentStyle={{background:'#fff',border:'1px solid #e2e8f0',borderRadius:7,fontSize:13}} />\n <Legend wrapperStyle={{fontSize:13,paddingTop:8}} />\n <Bar dataKey=\"Sessions\" radius={[0,3,3,0]}>\n {channelBar.map((e,i) => <Cell key={i} fill={CHANNEL_COLORS[e.name] ?? PALETTE[i%PALETTE.length]} />)}\n </Bar>\n </BarChart>\n </ResponsiveContainer>\n </div>\n }\n </Panel>\n </div>\n )\n}\n\nfunction ContentTab({data, loading}: {data: AnalyticsData; loading?: boolean}) {\n return (\n <div style={{animation:'ga-fadein .25s ease', display:'flex', flexDirection:'column', gap:20}}>\n <Panel title=\"Top Pages\" info={SECTION_INFO['Top Pages']}>\n <DataTable loading={loading}\n headers={[{label:'Page Path'},{label:'Views',align:'right',width:'72px'},{label:'Users',align:'right',width:'62px'}]}\n rows={data.topPages.map(p => [<PathCell key={p.path} path={p.path}/>, fNum(p.pageViews), fNum(p.users)])}\n />\n </Panel>\n <Panel title=\"Top Landing Pages\" info={SECTION_INFO['Top Landing Pages']}>\n <DataTable loading={loading}\n headers={[{label:'Landing Page'},{label:'Sessions',align:'right',width:'80px'},{label:'Bounce',align:'right',width:'68px'}]}\n rows={data.landingPages.map(p => [<PathCell key={p.path} path={p.path}/>, fNum(p.sessions), fPct(p.bounceRate)])}\n />\n </Panel>\n </div>\n )\n}\n\nfunction AudienceTab({data, loading}: {data: AnalyticsData; loading?: boolean}) {\n return (\n <div style={{animation:'ga-fadein .25s ease', display:'flex', flexDirection:'column', gap:20}}>\n <div style={{display:'grid', gridTemplateColumns:'minmax(0,1fr) minmax(0,1fr)', gap:12}}>\n <Panel title=\"Devices\" info={SECTION_INFO['Devices']}>\n <Donut loading={loading}\n data={data.devices.map(d => ({name:d.device,value:d.sessions,percentage:d.percentage}))}\n colors={data.devices.map(d => DEVICE_COLORS[d.device.toLowerCase()] ?? '#4f8ef7')}\n />\n </Panel>\n <Panel title=\"New vs Returning\" info={SECTION_INFO['New vs Returning']}>\n <Donut loading={loading}\n data={data.newVsReturning.map(d => ({name:d.type,value:d.users,percentage:d.percentage}))}\n colors={['#4f8ef7','#3ecf8e']}\n />\n </Panel>\n <Panel title=\"Browsers\" info={SECTION_INFO['Browsers']}>\n <Donut loading={loading}\n data={data.browsers.map(d => ({name:d.browser,value:d.sessions,percentage:d.percentage}))}\n colors={PALETTE}\n />\n </Panel>\n <Panel title=\"Operating Systems\" info={SECTION_INFO['Operating Systems']}>\n <Donut loading={loading}\n data={data.operatingSystems.map(d => ({name:d.os,value:d.sessions,percentage:d.percentage}))}\n colors={PALETTE}\n />\n </Panel>\n </div>\n </div>\n )\n}\n\nfunction GeographyTab({data, loading}: {data: AnalyticsData; loading?: boolean}) {\n return (\n <div style={{animation:'ga-fadein .25s ease', display:'flex', flexDirection:'column', gap:20}}>\n <Panel title=\"Top Countries\" info={SECTION_INFO['Top Countries']}>\n <DataTable loading={loading}\n headers={[{label:'Country'},{label:'Users',align:'right',width:'70px'},{label:'Sessions',align:'right',width:'78px'}]}\n rows={data.countries.map(c => [c.country, fNum(c.users), fNum(c.sessions)])}\n />\n </Panel>\n <Panel title=\"Top Cities\" info={SECTION_INFO['Top Cities']}>\n <DataTable loading={loading}\n headers={[{label:'City'},{label:'Country',width:'110px'},{label:'Users',align:'right',width:'65px'},{label:'Sessions',align:'right',width:'75px'}]}\n rows={data.cities.map(c => [\n c.city,\n <span key={c.city} style={{fontSize:12,color:'#94a3b8'}}>{c.country}</span>,\n fNum(c.users),\n fNum(c.sessions),\n ])}\n />\n </Panel>\n </div>\n )\n}\n\nfunction EventsTab({data, loading}: {data: AnalyticsData; loading?: boolean}) {\n if (!loading && data.topEvents.length === 0) return <EmptyTab />\n return (\n <div style={{animation:'ga-fadein .25s ease'}}>\n <Panel title=\"Top Events\" info={SECTION_INFO['Top Events']}>\n <DataTable loading={loading}\n headers={[{label:'Event Name'},{label:'Count',align:'right',width:'80px'},{label:'Users',align:'right',width:'70px'}]}\n rows={data.topEvents.map(e => [e.name, fNum(e.count), fNum(e.usersCount)])}\n />\n </Panel>\n </div>\n )\n}\n\nfunction AcquisitionTab({data, loading}: {data: AnalyticsData; loading?: boolean}) {\n return (\n <div style={{animation:'ga-fadein .25s ease', display:'flex', flexDirection:'column', gap:20}}>\n <Panel title=\"Traffic Sources\" info={SECTION_INFO['Traffic Sources']}>\n <DataTable loading={loading}\n headers={[{label:'Source / Medium'},{label:'Sessions',align:'right',width:'82px'},{label:'Users',align:'right',width:'65px'}]}\n rows={data.trafficSources.map(s => [s.source||'(direct)', fNum(s.sessions), fNum(s.users)])}\n />\n </Panel>\n <Panel title=\"Top Referrers\" info={SECTION_INFO['Top Referrers']}>\n <DataTable loading={loading}\n headers={[{label:'Referrer'},{label:'Sessions',align:'right',width:'82px'},{label:'Users',align:'right',width:'65px'}]}\n rows={data.referrers.map(r => [\n <span key={r.referrer} title={r.referrer} style={{display:'block',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap',fontSize:13}}>{r.referrer}</span>,\n fNum(r.sessions),\n fNum(r.users),\n ])}\n />\n </Panel>\n </div>\n )\n}\n\n/* ─────────────────────────────────────────────\n Main Dashboard\n───────────────────────────────────────────── */\nexport function Dashboard({apiUrl}: {apiUrl: string}) {\n const [data, setData] = useState<AnalyticsData | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n const [dateRange, setDateRange] = useState<DateRange>('30')\n const [activeTab, setActiveTab] = useState<Tab>('overview')\n\n const loadData = useCallback(async () => {\n try {\n setLoading(true); setError(null)\n setData(await fetchAnalyticsData(apiUrl, dateRange))\n } catch (err: unknown) {\n console.error('Failed to fetch analytics data', err)\n setError(err instanceof Error ? err.message : 'Failed to fetch analytics')\n } finally {\n setLoading(false)\n }\n }, [apiUrl, dateRange])\n\n useEffect(() => { loadData() }, [loadData])\n\n const H = 'calc(100vh - 51px)' /* 51px = Sanity Studio topbar */\n\n /* ── Loading state ── */\n if (loading && !data) return (\n <div style={{display:'flex',justifyContent:'center',alignItems:'center',minHeight:'100vh',flexDirection:'column',gap:14,background:'#f8fafc'}}>\n <div style={{width:36,height:36,border:'3px solid #e2e8f0',borderTopColor:'#4f8ef7',borderRadius:'50%',animation:'ga-spin .8s linear infinite'}} />\n <div style={{color:'#94a3b8',fontSize:14}}>Loading analytics…</div>\n <style>{GLOBAL_CSS}</style>\n </div>\n )\n\n /* ── Error state ── */\n if (error && !data) return (\n <div style={{display:'flex',justifyContent:'center',alignItems:'center',height:H,background:'#f8fafc'}}>\n <style>{GLOBAL_CSS}</style>\n <div style={{maxWidth:480,width:'100%',background:'#fff',border:'1px solid #e2e8f0',borderRadius:12,padding:32}}>\n <div style={{fontWeight:700,color:'#dc2626',marginBottom:8,fontSize:15}}>Failed to load analytics</div>\n <div style={{fontSize:13,color:'#64748b',marginBottom:20,lineHeight:1.6}}>{error}</div>\n <button className=\"ga-retry-btn\" onClick={loadData}\n style={{padding:'9px 22px',background:'#4f8ef7',color:'#fff',borderRadius:7,cursor:'pointer',fontSize:13,fontWeight:600}}>\n Retry\n </button>\n </div>\n </div>\n )\n\n if (!data) return null\n\n /* ── Layout ── */\n return (\n <div style={{height:H,background:'#f8fafc',overflow:'hidden',\n fontFamily:'-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,sans-serif',\n display:'flex',justifyContent:'center',alignItems:'stretch'}}>\n <style>{GLOBAL_CSS}</style>\n <div style={{display:'flex',width:'100%',height:'100%',overflow:'hidden',\n boxShadow:'0 0 0 1px #e2e8f0'}}>\n\n {/* ═══ Sidebar ═══ */}\n <div style={{width:180,background:'#fff',borderRight:'1px solid #e2e8f0',\n display:'flex',flexDirection:'column',flexShrink:0,overflow:'hidden'}}>\n\n {/* Brand */}\n <div style={{padding:'20px 16px 16px',borderBottom:'1px solid #f1f5f9'}}>\n <div style={{fontSize:13,fontWeight:700,color:'#1e293b',letterSpacing:'0.01em'}}>Analytics</div>\n <div style={{fontSize:11,color:'#94a3b8',marginTop:2}}>Google Analytics 4</div>\n </div>\n\n {/* Date range */}\n <div style={{padding:'12px 12px 8px'}}>\n <div style={{fontSize:10,fontWeight:700,color:'#cbd5e1',textTransform:'uppercase',letterSpacing:'0.07em',marginBottom:6}}>Date Range</div>\n <div style={{display:'flex',gap:4,flexWrap:'wrap'}}>\n {DATE_RANGES.map(r => (\n <button key={r.value} className=\"ga-date-btn\" onClick={() => setDateRange(r.value)}\n style={{padding:'4px 8px',fontSize:11,fontWeight:dateRange===r.value?700:400,borderRadius:5,\n border:dateRange===r.value?'1.5px solid #4f8ef7':'1.5px solid #e2e8f0',\n background:dateRange===r.value?'#eff6ff':'#fff',\n color:dateRange===r.value?'#4f8ef7':'#64748b',cursor:'pointer'}}>\n {r.label}\n </button>\n ))}\n </div>\n </div>\n\n {/* Tabs */}\n <nav style={{flex:1,overflow:'auto',padding:'8px 8px'}}>\n <div style={{fontSize:10,fontWeight:700,color:'#cbd5e1',textTransform:'uppercase',letterSpacing:'0.07em',marginBottom:6,paddingLeft:8}}>Sections</div>\n {TABS.map(tab => {\n const active = activeTab === tab.id\n return (\n <button key={tab.id} className=\"ga-tab-btn\" onClick={() => setActiveTab(tab.id)}\n style={{display:'flex',alignItems:'center',gap:9,padding:'9px 10px',borderRadius:7,marginBottom:2,\n background:active?'#eff6ff':'transparent',\n color:active?'#4f8ef7':'#64748b',\n fontWeight:active?600:400,fontSize:13}}>\n <span style={{fontSize:14,opacity:0.8}}>{tab.icon}</span>\n <span>{tab.label}</span>\n {active && <span style={{marginLeft:'auto',width:4,height:4,borderRadius:'50%',background:'#4f8ef7'}} />}\n </button>\n )\n })}\n </nav>\n\n {/* Refresh */}\n <div style={{padding:'12px',borderTop:'1px solid #f1f5f9'}}>\n <button className=\"ga-retry-btn\" onClick={loadData}\n style={{width:'100%',padding:'8px',background:'#f8fafc',border:'1px solid #e2e8f0',\n borderRadius:7,fontSize:12,color:loading?'#94a3b8':'#475569',cursor:'pointer',\n display:'flex',alignItems:'center',justifyContent:'center',gap:6,fontWeight:500}}>\n {loading\n ? <><div style={{width:12,height:12,border:'2px solid #e2e8f0',borderTopColor:'#4f8ef7',borderRadius:'50%',animation:'ga-spin .8s linear infinite'}} />Refreshing…</>\n : <>↻ Refresh</>}\n </button>\n </div>\n </div>\n\n {/* ═══ Main content ═══ */}\n <div style={{flex:1,overflow:'auto',padding:'24px 28px'}}>\n\n {/* Page header */}\n <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:22}}>\n <div>\n <h2 style={{margin:0,fontSize:18,fontWeight:700,color:'#1e293b'}}>\n {TABS.find(t => t.id === activeTab)?.label}\n </h2>\n <div style={{fontSize:12,color:'#94a3b8',marginTop:3}}>Last {dateRange} days</div>\n </div>\n {error && (\n <div style={{background:'#fffbeb',border:'1px solid #fcd34d',borderRadius:7,padding:'8px 14px',fontSize:12,color:'#92400e'}}>\n ⚠ Showing cached data\n </div>\n )}\n </div>\n\n {/* Active tab content */}\n {activeTab === 'overview' && <OverviewTab data={data} loading={loading} />}\n {activeTab === 'traffic' && <TrafficTab data={data} loading={loading} />}\n {activeTab === 'content' && <ContentTab data={data} loading={loading} />}\n {activeTab === 'audience' && <AudienceTab data={data} loading={loading} />}\n {activeTab === 'geography' && <GeographyTab data={data} loading={loading} />}\n {activeTab === 'events' && <EventsTab data={data} loading={loading} />}\n {activeTab === 'acquisition' && <AcquisitionTab data={data} loading={loading} />}\n </div>\n </div>\n </div>\n )\n}\n","import type {\n AnalyticsData,\n BrowserData,\n ChannelData,\n CityData,\n CountryData,\n DateRange,\n DeviceCategory,\n EventData,\n HourlyDataPoint,\n LandingPage,\n OsData,\n OverviewMetrics,\n ReferrerData,\n TimeSeriesDataPoint,\n TopPage,\n TrafficSource,\n UserTypeData,\n} from '../types'\n\nexport async function fetchAnalyticsData(\n apiUrl: string,\n dateRange: DateRange,\n): Promise<AnalyticsData> {\n const res = await fetch(`${apiUrl}?range=${dateRange}`, {cache: 'no-store'})\n if (!res.ok) {\n const err = await res.json().catch(() => null)\n throw new Error(\n (err as {error?: string})?.error || `Analytics API error: ${res.status} ${res.statusText}`,\n )\n }\n return parseResponse(await res.json())\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nconst mv = (row: any, i: number): number => parseFloat(row?.metricValues?.[i]?.value ?? '0')\nconst dv = (row: any, i: number): string => row?.dimensionValues?.[i]?.value ?? ''\n\nfunction totalOf(data: any): number {\n if (!data?.rows) return 0\n return data.rows.reduce((s: number, r: any) => s + mv(r, 0), 0)\n}\n\nfunction parseOverview(d: any): OverviewMetrics {\n const row = d?.rows?.[0]\n if (!row) return {totalUsers:0,newUsers:0,sessions:0,pageViews:0,avgSessionDuration:0,bounceRate:0,engagedSessions:0,engagementRate:0,pagesPerSession:0,eventsPerSession:0}\n return {\n totalUsers: mv(row, 0),\n newUsers: mv(row, 1),\n sessions: mv(row, 2),\n pageViews: mv(row, 3),\n avgSessionDuration: mv(row, 4),\n bounceRate: mv(row, 5),\n engagedSessions: mv(row, 6),\n engagementRate: mv(row, 7),\n pagesPerSession: mv(row, 8),\n eventsPerSession: mv(row, 9),\n }\n}\n\nfunction parseTimeSeries(d: any): TimeSeriesDataPoint[] {\n if (!d?.rows) return []\n return d.rows.map((row: any) => {\n const s = dv(row, 0)\n return {\n date: `${s.slice(0,4)}-${s.slice(4,6)}-${s.slice(6,8)}`,\n displayDate: `${s.slice(4,6)}/${s.slice(6,8)}`,\n users: mv(row, 0),\n sessions: mv(row, 1),\n pageViews: mv(row, 2),\n }\n })\n}\n\nfunction parseHourly(d: any): HourlyDataPoint[] {\n if (!d?.rows) return []\n return d.rows.map((row: any) => {\n const h = parseInt(dv(row, 0), 10)\n const suffix = h < 12 ? 'AM' : 'PM'\n const display = h === 0 ? '12AM' : h <= 12 ? `${h}${suffix}` : `${h - 12}${suffix}`\n return {hour: dv(row, 0), label: display, users: mv(row, 0), sessions: mv(row, 1)}\n })\n}\n\nfunction parseTopPages(d: any): TopPage[] {\n if (!d?.rows) return []\n return d.rows.map((row: any) => ({path: dv(row, 0), pageViews: mv(row, 0), users: mv(row, 1)}))\n}\n\nfunction parseLandingPages(d: any): LandingPage[] {\n if (!d?.rows) return []\n return d.rows.map((row: any) => ({\n path: dv(row, 0),\n sessions: mv(row, 0),\n users: mv(row, 1),\n bounceRate: mv(row, 2),\n }))\n}\n\nfunction parseWithPercentage(d: any, dimIdx: number, metricIdx: number): {name: string; sessions: number; percentage: number}[] {\n if (!d?.rows) return []\n const total = totalOf(d)\n return d.rows.map((row: any) => {\n const sessions = mv(row, metricIdx)\n return {name: dv(row, dimIdx), sessions, percentage: total > 0 ? Math.round((sessions / total) * 1000) / 10 : 0}\n })\n}\n\nfunction parseDevices(d: any): DeviceCategory[] {\n return parseWithPercentage(d, 0, 0).map(x => ({device: x.name, sessions: x.sessions, percentage: x.percentage}))\n}\n\nfunction parseBrowsers(d: any): BrowserData[] {\n return parseWithPercentage(d, 0, 0).map(x => ({browser: x.name, sessions: x.sessions, percentage: x.percentage}))\n}\n\nfunction parseOS(d: any): OsData[] {\n return parseWithPercentage(d, 0, 0).map(x => ({os: x.name, sessions: x.sessions, percentage: x.percentage}))\n}\n\nfunction parseCountries(d: any): CountryData[] {\n if (!d?.rows) return []\n return d.rows.map((row: any) => ({country: dv(row, 0), users: mv(row, 0), sessions: mv(row, 1)}))\n}\n\nfunction parseCities(d: any): CityData[] {\n if (!d?.rows) return []\n return d.rows.map((row: any) => ({city: dv(row, 0), country: dv(row, 1), users: mv(row, 0), sessions: mv(row, 1)}))\n}\n\nfunction parseSources(d: any): TrafficSource[] {\n if (!d?.rows) return []\n return d.rows.map((row: any) => ({\n source: [dv(row, 0), dv(row, 1)].filter(Boolean).join(' / '),\n sessions: mv(row, 0),\n users: mv(row, 1),\n }))\n}\n\nfunction parseChannels(d: any): ChannelData[] {\n if (!d?.rows) return []\n return d.rows.map((row: any) => ({\n channel: dv(row, 0),\n sessions: mv(row, 0),\n users: mv(row, 1),\n engagementRate: mv(row, 2),\n }))\n}\n\nfunction parseNewVsReturning(d: any): UserTypeData[] {\n if (!d?.rows) return []\n const total = totalOf(d)\n return d.rows.map((row: any) => {\n const users = mv(row, 0)\n return {\n type: dv(row, 0),\n users,\n percentage: total > 0 ? Math.round((users / total) * 1000) / 10 : 0,\n }\n })\n}\n\nfunction parseEvents(d: any): EventData[] {\n if (!d?.rows) return []\n return d.rows.map((row: any) => ({name: dv(row, 0), count: mv(row, 0), usersCount: mv(row, 1)}))\n}\n\nfunction parseReferrers(d: any): ReferrerData[] {\n if (!d?.rows) return []\n return d.rows.map((row: any) => ({referrer: dv(row, 0) || '(direct)', sessions: mv(row, 0), users: mv(row, 1)}))\n}\n\nfunction parseActiveUsers(d: any): number {\n return parseInt(d?.rows?.[0]?.metricValues?.[0]?.value ?? '0', 10)\n}\n\nfunction parseResponse(raw: any): AnalyticsData {\n return {\n activeUsers: parseActiveUsers(raw.activeUsers),\n overview: parseOverview(raw.overview),\n timeSeries: parseTimeSeries(raw.timeSeries),\n hourlyToday: parseHourly(raw.hourlyToday),\n topPages: parseTopPages(raw.topPages),\n landingPages: parseLandingPages(raw.landingPages),\n devices: parseDevices(raw.devices),\n browsers: parseBrowsers(raw.browsers),\n operatingSystems: parseOS(raw.operatingSystems),\n countries: parseCountries(raw.countries),\n cities: parseCities(raw.cities),\n trafficSources: parseSources(raw.trafficSources),\n channels: parseChannels(raw.channels),\n newVsReturning: parseNewVsReturning(raw.newVsReturning),\n topEvents: parseEvents(raw.topEvents),\n referrers: parseReferrers(raw.referrers),\n }\n}\n","import {Dashboard} from './components/dashboard'\nimport type {GoogleAnalyticsPluginConfig} from './types'\n\nexport function GoogleAnalyticsTool({apiUrl}: GoogleAnalyticsPluginConfig) {\n return <Dashboard apiUrl={apiUrl || '/api/analytics'} />\n}\n\nexport function ConfigurationGuide() {\n const monoStyle: React.CSSProperties = {\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n fontSize: 12,\n background: '#f4f4f5',\n padding: '2px 6px',\n borderRadius: 4,\n color: '#333',\n }\n\n const stepStyle: React.CSSProperties = {\n fontSize: 13,\n color: '#444',\n lineHeight: 1.7,\n }\n\n return (\n <div style={{display: 'flex', justifyContent: 'center', padding: 40, fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'}}>\n <div style={{maxWidth: 600, width: '100%', background: '#fff', border: '1px solid #e8e8e8', borderRadius: 12, padding: 36}}>\n <h2 style={{margin: '0 0 8px', fontSize: 20, fontWeight: 700, color: '#111'}}>\n Google Analytics Setup Required\n </h2>\n <p style={{margin: '0 0 24px', fontSize: 14, color: '#777'}}>\n Add the following to <code style={monoStyle}>.env.local</code> in your Next.js app and restart the server:\n </p>\n\n <div style={{background: '#f9fafb', border: '1px solid #e8e8e8', borderRadius: 8, padding: '16px 20px', marginBottom: 24}}>\n <div style={{marginBottom: 12}}>\n <div style={{fontSize: 13, fontWeight: 600, color: '#111', marginBottom: 2}}>GA_PROPERTY_ID</div>\n <div style={{fontSize: 12, color: '#777'}}>Numeric property ID from Google Analytics → Admin → Property Settings</div>\n </div>\n <div style={{marginBottom: 12}}>\n <div style={{fontSize: 13, fontWeight: 600, color: '#111', marginBottom: 2}}>GA_SERVICE_ACCOUNT_EMAIL</div>\n <div style={{fontSize: 12, color: '#777'}}><code style={monoStyle}>client_email</code> from your service account JSON key file</div>\n </div>\n <div>\n <div style={{fontSize: 13, fontWeight: 600, color: '#111', marginBottom: 2}}>GA_PRIVATE_KEY</div>\n <div style={{fontSize: 12, color: '#777'}}><code style={monoStyle}>private_key</code> from your service account JSON key file</div>\n </div>\n </div>\n\n <div style={{marginBottom: 20}}>\n <div style={{fontSize: 13, fontWeight: 600, color: '#111', marginBottom: 10}}>Setup Steps</div>\n <ol style={{margin: 0, paddingLeft: 20, display: 'flex', flexDirection: 'column', gap: 4}}>\n {[\n 'Open Google Cloud Console and enable the \"Google Analytics Data API\"',\n 'Go to IAM & Admin → Service Accounts → Create Service Account',\n 'Create a JSON key and download it',\n 'In Google Analytics → Admin → Account Access Management, add the service account email with Viewer role',\n <>Copy <code style={monoStyle}>client_email</code> and <code style={monoStyle}>private_key</code> from the JSON into your .env.local</>,\n ].map((step, i) => (\n <li key={i} style={stepStyle}>{step}</li>\n ))}\n </ol>\n </div>\n\n <pre style={{margin: 0, background: '#1e1e2e', color: '#cdd6f4', borderRadius: 8, padding: '14px 18px', fontSize: 12, lineHeight: 1.6, overflow: 'auto'}}>\n <code>{`# .env.local\\nGA_PROPERTY_ID=123456789\\nGA_SERVICE_ACCOUNT_EMAIL=my-sa@project.iam.gserviceaccount.com\\nGA_PRIVATE_KEY=\"-----BEGIN PRIVATE KEY-----\\\\nMIIE...\\\\n-----END PRIVATE KEY-----\\\\n\"`}</code>\n </pre>\n </div>\n </div>\n )\n}\n"],"mappings":"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","names":["Fragment","jsx","jsxs"]}
|