import { Spinner, Button } from '@wordpress/components'; import { useState, useEffect } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import apiFetch from '@wordpress/api-fetch'; import PageAnalytics from '../../shared/PageAnalytics'; import Analysis from '../../shared/Analysis'; import AnalysisHeader from '../../shared/AnalysisHeader'; import AnalysisHeaderContent from '../../shared/AnalysisHeaderContent'; import AnalysisContent from '../../shared/AnalysisContent'; import AnalysisFilters from '../../shared/AnalysisFilters'; import PageModalButtonWithType from '../../shared/PageModalButtonWithType'; import NoDataPlaceholder from '../../shared/NoDataPlaceholder'; import { decodeHtmlEntities, formatTrendValue } from '../../shared/utils'; import Table from '../../shared/Table'; const DEFAULT_DATE_RANGE_VALUE = '30'; const DATE_RANGE_OPTIONS = Object.entries( { '30': __( '30d', 'liana-with-growthstack' ), '90': __( '90d', 'liana-with-growthstack' ), '365': __( '1y', 'liana-with-growthstack' ), } ).map( ( [ key, value ] ) => { return { label: value, value: key, }; } ); const ENDPOINT = '/growthstack/v1/analytics/most-popular/'; function getEndpointPath( dateRange, postType ) { const searchParams = new URLSearchParams( { 'date-range': dateRange, } ); if ( postType ) { searchParams.set( 'post-type', postType ); } return `${ ENDPOINT }?${ searchParams.toString() }`; } function getPages( items ) { return Object.values( items || [] ) .map( ( page: any ) => { const engagedCount = page.engaged_count ? page.engaged_count : 0; const viewCount = page.view_count ? page.view_count : 0; const engagedPercentage = engagedCount > 0 ? Math.round( ( engagedCount / viewCount ) * 100 ) : 0; return { title: decodeHtmlEntities( page.title ), url: page.url, viewCount: page.view_count, engagedCount: page.engaged_count, engagedPercentage, engagedPercentageRendered: formatTrendValue( engagedPercentage, 'percentage' ), type: page.type, modal: page.modal, }; } ) .sort( ( a, b ) => { return b.viewCount - a.viewCount; } ); } function getLandingPages( items ) { return Object.values( items || [] ) .map( ( page: any ) => { return { title: decodeHtmlEntities( page.title ), url: page.url, landingCount: page.landing_count, type: page.type, modal: page.modal, }; } ) .sort( ( a, b ) => { return b.landingCount - a.landingCount; } ); } export default function SitePopularPages( props ) { const { getCachedData, setCachedData } = props; const [ dateRange, setDateRange ] = useState( DEFAULT_DATE_RANGE_VALUE ); const [ postType, setPostType ] = useState( '' ); const [ pages, setPages ] = useState( [] ); const [ landingPages, setLandingPages ] = useState( [] ); const [ postTypeOptions, setPostTypeOptions ] = useState( [] ); const [ data, setData ] = useState( null ); const [ error, setError ] = useState( null ); const [ isModalOpen, setIsModalOpen ] = useState( false ); const [ modalData, setModalData ] = useState( null ); useEffect( () => { const endpointPath = getEndpointPath( dateRange, postType ); const cached = getCachedData( endpointPath ); if ( cached?.isFetched ) { setData( cached.data ); setError( cached.error ); setPostTypeOptions( cached.data?.available_post_types || [] ); return; } setData( null ); setError( null ); setPages( [] ); setLandingPages( [] ); apiFetch( { path: endpointPath } ) .then( ( response ) => { const responseData = response || null; setData( responseData ); setPostTypeOptions( responseData?.available_post_types || [] ); setCachedData( endpointPath, responseData, null ); } ) .catch( ( fetchError ) => { setError( fetchError ); setCachedData( endpointPath, null, fetchError ); // eslint-disable-next-line no-console console.error( 'Failed to fetch most popular pages', fetchError ); } ); }, [ dateRange, postType, getCachedData, setCachedData ] ); useEffect( () => { setPages( getPages( data?.most_popular_pages ) ); setLandingPages( getLandingPages( data?.most_popular_landing_pages ) ); }, [ data ] ); const isLoading = ! data && ! error; const availablePostTypes = [ { label: __( 'All post types', 'liana-with-growthstack' ), value: '', }, ...postTypeOptions, ]; return ( <>

{ __( 'Most Popular', 'liana-with-growthstack' ) }

{ DATE_RANGE_OPTIONS.map( ( option ) => ( ) ) }

{ __( 'Most Popular Pages', 'liana-with-growthstack' ) }

{ __( 'The most popular pages on your site.', 'liana-with-growthstack' ) }

{ isLoading && } { error && (
{ __( "There's an error fetching the data.", 'liana-with-growthstack' ) }
) } { pages.length > 0 && ( <> ( { setModalData( row.original .modal ); setIsModalOpen( true ); } } /> ), }, { Header: __( 'Views', 'liana-with-growthstack' ), accessor: 'viewCount', }, { Header: __( 'Engagement', 'liana-with-growthstack' ), accessor: 'engagedPercentage', Cell: ( { row } ) => ( { row.original .engagedPercentageRendered } ), }, ] } data={ pages } /> { isModalOpen && ( setIsModalOpen( false ) } data={ modalData } /> ) } ) } { pages.length === 0 && ! isLoading && (

{ __( "There's no data to show yet.", 'liana-with-growthstack' ) }

) }

{ __( 'Most Popular Landing Pages', 'liana-with-growthstack' ) }

{ __( 'The most popular landing pages on your site.', 'liana-with-growthstack' ) }

{ isLoading && } { error && (
{ __( "There's an error fetching the data.", 'liana-with-growthstack' ) }
) } { landingPages.length > 0 && ( <>
( { setModalData( row.original .modal ); setIsModalOpen( true ); } } /> ), }, { Header: __( 'Landing Sessions', 'liana-with-growthstack' ), accessor: 'landingCount', }, ] } data={ landingPages } /> ) } { landingPages.length === 0 && ! isLoading && (

{ __( "There's no data to show yet.", 'liana-with-growthstack' ) }

) } ); }