@@ -51,15 +51,13 @@ interface BrowserVersion {
5151 version : string ;
5252 visitors : number ;
5353 pageviews : number ;
54- sessions : number ;
5554}
5655
5756interface BrowserEntry {
5857 name : string ;
5958 browserName : string ;
6059 visitors : number ;
6160 pageviews : number ;
62- sessions : number ;
6361 percentage : number ;
6462 versions : BrowserVersion [ ] ;
6563}
@@ -71,8 +69,8 @@ interface ScreenResolutionEntry {
7169}
7270
7371interface DeviceData {
74- device_type : string [ ] ;
7572 browser_name : string [ ] ;
73+ browser_versions : string [ ] ;
7674 os_name : string [ ] ;
7775 screen_resolution : ScreenResolutionEntry [ ] ;
7876 connection_type : string [ ] ;
@@ -131,8 +129,6 @@ const getConnectionIcon = (connection: string): React.ReactNode => {
131129 return < GlobeIcon className = "h-4 w-4 text-primary" /> ;
132130} ;
133131
134- // API already provides clean, normalized data - no transformation needed
135-
136132export function WebsiteAudienceTab ( {
137133 websiteId,
138134 dateRange,
@@ -152,8 +148,8 @@ export function WebsiteAudienceTab({
152148 {
153149 id : 'device-data' ,
154150 parameters : [
155- 'device_type' ,
156151 'browser_name' ,
152+ 'browser_versions' ,
157153 'os_name' ,
158154 'screen_resolution' ,
159155 'connection_type' ,
@@ -172,18 +168,14 @@ export function WebsiteAudienceTab({
172168 } = useBatchDynamicQuery ( websiteId , dateRange , batchQueries ) ;
173169
174170 const handleRefresh = useCallback ( async ( ) => {
175- if ( ! isRefreshing ) {
176- return ;
177- }
178-
179171 try {
180172 await refetchBatch ( ) ;
181173 } catch ( error ) {
182174 console . error ( 'Failed to refresh audience data:' , error ) ;
183175 } finally {
184176 setIsRefreshing ( false ) ;
185177 }
186- } , [ isRefreshing , refetchBatch , setIsRefreshing ] ) ;
178+ } , [ refetchBatch , setIsRefreshing ] ) ;
187179
188180 useEffect ( ( ) => {
189181 if ( isRefreshing ) {
@@ -192,15 +184,12 @@ export function WebsiteAudienceTab({
192184 } , [ isRefreshing , handleRefresh ] ) ;
193185
194186 const onAddFilter = useCallback (
195- ( field : string , value : string , _tableTitle ?: string ) => {
196- // The field parameter now contains the correct filter field from the tab configuration
197- const filter = {
187+ ( field : string , value : string ) => {
188+ addFilter ( {
198189 field,
199190 operator : 'eq' as const ,
200191 value,
201- } ;
202-
203- addFilter ( filter ) ;
192+ } ) ;
204193 } ,
205194 [ addFilter ]
206195 ) ;
@@ -216,8 +205,8 @@ export function WebsiteAudienceTab({
216205 languages : [ ] ,
217206 } ,
218207 device : {
219- device_type : [ ] ,
220208 browser_name : [ ] ,
209+ browser_versions : [ ] ,
221210 os_name : [ ] ,
222211 screen_resolution : [ ] ,
223212 connection_type : [ ] ,
@@ -230,36 +219,52 @@ export function WebsiteAudienceTab({
230219 ) ;
231220 const deviceResult = batchResults . find ( ( r ) => r . queryId === 'device-data' ) ;
232221
222+ const geographicData = geographicResult ?. data || { } ;
223+ const deviceData = deviceResult ?. data || { } ;
224+
233225 return {
234226 geographic : {
235- countries : geographicResult ?. data ? .country || [ ] ,
236- regions : geographicResult ?. data ? .region || [ ] ,
237- cities : geographicResult ?. data ? .city || [ ] ,
238- timezones : geographicResult ?. data ? .timezone || [ ] ,
239- languages : geographicResult ?. data ? .language || [ ] ,
227+ countries : geographicData . country || [ ] ,
228+ regions : geographicData . region || [ ] ,
229+ cities : geographicData . city || [ ] ,
230+ timezones : geographicData . timezone || [ ] ,
231+ languages : geographicData . language || [ ] ,
240232 } ,
241233 device : {
242- device_type : deviceResult ?. data ?. device_type || [ ] ,
243- browser_name : deviceResult ?. data ?. browser_name || [ ] ,
244- os_name : deviceResult ?. data ? .os_name || [ ] ,
245- screen_resolution : deviceResult ?. data ? .screen_resolution || [ ] ,
246- connection_type : deviceResult ?. data ? .connection_type || [ ] ,
234+ browser_name : deviceData . browser_name || [ ] ,
235+ browser_versions : deviceData . browser_versions || [ ] ,
236+ os_name : deviceData . os_name || [ ] ,
237+ screen_resolution : deviceData . screen_resolution || [ ] ,
238+ connection_type : deviceData . connection_type || [ ] ,
247239 } ,
248240 } ;
249241 } , [ batchResults ] ) ;
250242
251243 const processedBrowserData = useMemo ( ( ) : BrowserEntry [ ] => {
252- // API already provides clean data with percentages and sorting
253- return ( processedData . device . browser_name || [ ] ) . map ( ( browser : any ) => ( {
254- ...browser ,
255- browserName : browser . name ,
256- sessions : browser . sessions || 0 ,
257- versions : [ ] , // No versions in simple browser data
258- } ) ) ;
259- } , [ processedData . device . browser_name ] ) ;
244+ const browserVersions = processedData . device . browser_versions || [ ] ;
245+ const browserData = processedData . device . browser_name || [ ] ;
246+
247+ return browserData . map ( ( browser : any ) => {
248+ const versions = browserVersions
249+ . filter ( ( version : any ) => version . name . startsWith ( `${ browser . name } ` ) )
250+ . map ( ( version : any ) => ( {
251+ version : version . name . slice ( browser . name . length + 1 ) ,
252+ visitors : version . visitors ,
253+ pageviews : version . pageviews ,
254+ } ) ) ;
255+
256+ return {
257+ ...browser ,
258+ browserName : browser . name ,
259+ versions,
260+ } ;
261+ } ) ;
262+ } , [
263+ processedData . device . browser_name ,
264+ processedData . device . browser_versions ,
265+ ] ) ;
260266
261267 const processedConnectionData = useMemo ( ( ) : ConnectionEntry [ ] => {
262- // API already provides sorted data with percentages
263268 return ( processedData . device . connection_type || [ ] ) . map ( ( item : any ) => ( {
264269 ...item ,
265270 iconComponent : getConnectionIcon ( item . name || '' ) ,
0 commit comments