import { memo, useMemo } from 'react'; import { __ } from '@wordpress/i18n'; import { useNavigate, useRouterState } from '@tanstack/react-router'; import { Block } from '@/components/Blocks/Block'; import { BlockHeading } from '@/components/Blocks/BlockHeading'; import { BlockContent } from '@/components/Blocks/BlockContent'; import Icon from '@/utils/Icon'; import { BarDataTable } from '@/components/DataTable/BarDataTable'; import { useNotFoundPagesData } from './useNotFoundPagesData'; import MetricInfo from '@/components/Common/MetricInfo'; import { formatNumber } from '@/utils/formatting'; import type { BarColumn } from '@/components/DataTable/BarDataTable'; import type { NotFoundPageRow } from './useNotFoundPagesData'; type NotFoundPagesBlockProps = { /** Additional CSS class names passed to the wrapping Block. */ className?: string; }; /** Maximum rows shown in the compact block view. */ const TOP_N = 5; /** * Compact dashboard block showing the top 404 pages. */ const NotFoundPagesBlock = memo( ({ className = '' }: NotFoundPagesBlockProps ) => { const { data, isLoading } = useNotFoundPagesData(); const navigate = useNavigate(); const location = useRouterState({ select: ( s ) => s.location }); const siteUrl = ( window as unknown as { burst_settings?: { site_url?: string } }) ?.burst_settings?.site_url ?? window.location.origin; const columns = useMemo[]>( () => [ { key: 'page_url', label: __( 'Page URL', 'burst-statistics' ), align: 'left', minWidth: 160, cell: ( row ) => { const pageUrl = `${siteUrl.replace( /\/$/, '' )}${row.page_url}`; return ( { row.page_url } ); } }, { key: 'hits', label: __( 'Hits', 'burst-statistics' ), align: 'right', minWidth: 80, cell: ( row ) => ( { formatNumber( row.hits ) } ) } ], [ siteUrl ] ); const filteredData = useMemo( () => { return data.slice( 0, TOP_N ); }, [ data ]); const handleExpand = () => { navigate({ to: '/table/$variant', params: { variant: 'not_found_pages' }, search: { from: location.pathname, allowed: 'not_found_pages', dataTableId: 'not-found-pages', ...location.search } }); }; return ( {__( '404 Pages', 'burst-statistics' )} {/* Expand to overlay. */} } /> row.page_url} barColumnKey="hits" isLoading={isLoading} emptyState={__( 'No 404 pages recorded yet.', 'burst-statistics' )} /> ); }); NotFoundPagesBlock.displayName = 'NotFoundPagesBlock'; export default NotFoundPagesBlock;