Skip to content

Commit

Permalink
Stats: add location views query hook (#97951)
Browse files Browse the repository at this point in the history
* Add location views query

* Implement useLocationViewsQuery hook

* Normalize country views

* Fix country views render

* Remove 'useShortNumber' prop
  • Loading branch information
Initsogar authored Jan 6, 2025
1 parent 264b8a1 commit 8be8e8b
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,21 @@ import { mapMarker } from '@wordpress/icons';
import { useTranslate } from 'i18n-calypso';
import React, { useState } from 'react';
import QuerySiteStats from 'calypso/components/data/query-site-stats';
import useLocationViewsQuery, {
StatsLocationViewsData,
} from 'calypso/my-sites/stats/hooks/use-location-views-query';
import { useShouldGateStats } from 'calypso/my-sites/stats/hooks/use-should-gate-stats';
import { QueryStatsParams } from 'calypso/my-sites/stats/hooks/utils';
import StatsListCard from 'calypso/my-sites/stats/stats-list/stats-list-card';
import StatsModulePlaceholder from 'calypso/my-sites/stats/stats-module/placeholder';
import statsStrings from 'calypso/my-sites/stats/stats-strings';
import { useSelector } from 'calypso/state';
import {
isRequestingSiteStatsForQuery,
getSiteStatsNormalizedData,
} from 'calypso/state/stats/lists/selectors';
import { getSelectedSiteId } from 'calypso/state/ui/selectors';
import EmptyModuleCard from '../../../components/empty-module-card/empty-module-card';
import { SUPPORT_URL, JETPACK_SUPPORT_URL_TRAFFIC } from '../../../const';
import Geochart from '../../../geochart';
import StatsCardSkeleton from '../shared/stats-card-skeleton';
import StatsInfoArea from '../shared/stats-info-area';
import type { StatsStateProps } from '../types';

import './style.scss';

Expand Down Expand Up @@ -50,16 +48,15 @@ const StatsLocations: React.FC< StatsModuleLocationsProps > = ( { query, summary
const isOdysseyStats = config.isEnabled( 'is_running_in_jetpack_site' );
const supportUrl = isOdysseyStats ? JETPACK_SUPPORT_URL_TRAFFIC : SUPPORT_URL;

const {
data = [],
isLoading: isRequestingData,
isError,
} = useLocationViewsQuery< StatsLocationViewsData >( siteId, 'country', query );

// Use StatsModule to display paywall upsell.
const shouldGateStatsModule = useShouldGateStats( statType );

const isRequestingData = useSelector( ( state: StatsStateProps ) =>
isRequestingSiteStatsForQuery( state, siteId, statType, query )
);
const data = useSelector( ( state ) =>
getSiteStatsNormalizedData( state, siteId, statType, query )
) as [ id: number, label: string ];

const [ selectedOption, setSelectedOption ] = useState( OPTION_KEYS.COUNTRIES );
const optionLabels = {
[ OPTION_KEYS.COUNTRIES ]: {
Expand Down Expand Up @@ -138,7 +135,7 @@ const StatsLocations: React.FC< StatsModuleLocationsProps > = ( { query, summary
withHero
/>
) }
{ ( ( ! isRequestingData && !! data?.length ) || shouldGateStatsModule ) && (
{ ( ( ! isRequestingData && ! isError && data ) || shouldGateStatsModule ) && (
// show data or an overlay
<>
{ /* @ts-expect-error TODO: Refactor StatsListCard with TypeScript. */ }
Expand Down Expand Up @@ -167,7 +164,6 @@ const StatsLocations: React.FC< StatsModuleLocationsProps > = ( { query, summary
metricLabel={ translate( 'Visitors' ) }
loader={ isRequestingData && <StatsModulePlaceholder isLoading={ isRequestingData } /> }
splitHeader
useShortNumber
heroElement={ <Geochart query={ query } skipQuery /> }
mainItemLabel={ optionLabels[ selectedOption ]?.headerLabel }
toggleControl={ toggleControlComponent }
Expand All @@ -176,7 +172,7 @@ const StatsLocations: React.FC< StatsModuleLocationsProps > = ( { query, summary
? {
url: summaryUrl,
label:
data.length >= 10
Array.isArray( data ) && data.length >= 10
? translate( 'View all', {
context: 'Stats: Button link to show more detailed stats information',
} )
Expand All @@ -189,22 +185,25 @@ const StatsLocations: React.FC< StatsModuleLocationsProps > = ( { query, summary
/>
</>
) }
{ ! isRequestingData && ! data?.length && ! shouldGateStatsModule && (
// show empty state
<StatsCard
title={ translate( 'Locations' ) }
isEmpty
emptyMessage={ emptyMessage }
footerAction={
summaryUrl
? {
url: summaryUrl,
label: translate( 'View more' ),
}
: undefined
}
/>
) }
{ ! isRequestingData &&
Array.isArray( data ) &&
! data?.length &&
! shouldGateStatsModule && (
// show empty state
<StatsCard
title={ translate( 'Locations' ) }
isEmpty
emptyMessage={ emptyMessage }
footerAction={
summaryUrl
? {
url: summaryUrl,
label: translate( 'View more' ),
}
: undefined
}
/>
) }
</>
);
};
Expand Down
46 changes: 46 additions & 0 deletions client/my-sites/stats/hooks/use-location-views-query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { useQuery } from '@tanstack/react-query';
import wpcom from 'calypso/lib/wp';
import { normalizers } from 'calypso/state/stats/lists/utils';
import getDefaultQueryParams from './default-query-params';
import { processQueryParams, QueryStatsParams } from './utils';

export interface StatsLocationViewsData {
date: string;
days?: Array< { date: string; views: Record< string, number > } >;
summary?: Record< string, number >;
countryInfo?: Record< string, unknown >;
}

function queryStatsLocationViews(
siteId: number,
geoMode: 'country' | 'region' | 'city',
query: QueryStatsParams
): Promise< StatsLocationViewsData > {
return wpcom.req.get( `/sites/${ siteId }/stats/location-views/${ geoMode }`, query );
}

const useLocationViewsQuery = < T = StatsLocationViewsData >(
siteId: number,
geoMode: 'country' | 'region' | 'city',
query: QueryStatsParams
) => {
return useQuery( {
...getDefaultQueryParams(),
queryKey: [ 'stats', 'location-views', siteId, geoMode, query ],
queryFn: () =>
queryStatsLocationViews( siteId, geoMode, processQueryParams( query ) ) as Promise< T >,
select: ( data ) => {
const normalizedStats = normalizers.statsCountryViews(
data as StatsLocationViewsData,
query
);

return Array.isArray( normalizedStats ) && normalizedStats?.length && query?.max
? normalizedStats.slice( 0, query.max )
: normalizedStats;
},
staleTime: 1000 * 60 * 5, // Cache for 5 minutes
} );
};

export default useLocationViewsQuery;

0 comments on commit 8be8e8b

Please sign in to comment.