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 { useOutgoingLinksData } from './useOutgoingLinksData'; import { getOutgoingLinksColumns } from './columns'; import useSettingsData from '@/hooks/useSettingsData'; import useLicenseData from '@/hooks/useLicenseData'; import UpsellOverlay from '@/components/Upsell/UpsellOverlay'; import UpsellCopy from '@/components/Upsell/UpsellCopy'; type OutgoingLinksBlockProps = { /** 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 most clicked outgoing links. * * Displays the clicked URL, total click count with a proportional bar, and a * percentage change column that reflects the active comparison mode (previous * period or year-over-year). An expand button opens the full table in the * DataTableOverlay. * * @param {Object} props - Component props. * @param {string} props.className - Additional CSS classes for the Block wrapper. * @return {JSX.Element} The outgoing links block. */ const OutgoingLinksBlock = memo( ({ className = '' }: OutgoingLinksBlockProps ) => { const { getValue } = useSettingsData(); const { isLicenseValid } = useLicenseData(); const isEnabled = !! getValue( 'track_external_links' ); const { data, isLoading, scrapingProgress } = useOutgoingLinksData( isEnabled ); const firstCycleCompleted = !! window.burst_settings?.external_links_first_cycle_completed || 100 === scrapingProgress; const navigate = useNavigate(); const location = useRouterState({ select: ( s ) => s.location }); const columns = useMemo( () => getOutgoingLinksColumns(), []); const topData = useMemo( () => data.slice( 0, TOP_N ), [ data ]); /** * Navigate to the fullscreen overlay with the outgoing_links variant active. */ const handleExpand = () => { navigate({ to: '/table/$variant', params: { variant: 'outgoing_links' }, search: { from: location.pathname, allowed: 'outgoing_links', dataTableId: 'outgoing-links', ...location.search } }); }; const hasData = 0 < topData.length; if ( ! isLicenseValid ) { return (

{ __( 'Outgoing links tracking is a Pro feature.', 'burst-statistics' ) }

); } return ( { __( 'Outgoing links', 'burst-statistics' ) } { isEnabled && hasData && ( ) } } /> { ! isEnabled && (

{ __( 'External link tracking has been disabled.', 'burst-statistics' ) }

{ __( 'You can enable it in the settings page to start tracking outgoing link clicks.', 'burst-statistics' ) }

) } { isEnabled && ( row.url } barColumnKey="clicks" isLoading={ isLoading } emptyState={ firstCycleCompleted ? __( 'No outgoing link clicks recorded yet.', 'burst-statistics' ) : '' } /> ) } { isEnabled && ! firstCycleCompleted && (
{ __( 'Burst is gathering all used external links on your site, data will appear when this is completed.', 'burst-statistics' ) } { 'number' === typeof scrapingProgress && ` (${ scrapingProgress }%)` }
) }
); }); OutgoingLinksBlock.displayName = 'OutgoingLinksBlock'; export default OutgoingLinksBlock;