import { useState, useEffect, useCallback } from '@wordpress/element'; import apiFetch from '@wordpress/api-fetch'; import { __ } from '@wordpress/i18n'; import ProrankButton from '../../../components/ProrankButton'; interface DeliveryExplanation { method: string; url_accept_negotiation: boolean; covers_css_backgrounds: boolean; message: string; recommendation: string; } interface CompetitorBlock { slug: string; label: string; plugin_active: boolean; } interface ImageDeliveryHealth { status: string; delivery_method: string; negotiation_active: boolean; avif_enabled: boolean; webp_enabled: boolean; htaccess_exists: boolean; htaccess_readable: boolean; htaccess_writable: boolean; has_prorank_block: boolean; prorank_after_competitor: boolean; stale_competitors: CompetitorBlock[]; issues: Array<{ code: string; message: string }>; can_repair: boolean; delivery_explanation: DeliveryExplanation; manual_instructions: string; } /** * Delivery Health panel for Performance -> Image Optimisation. * * Surfaces whether ProRank actually OWNS the active image-delivery layer so AVIF * wins over stale competitor (e.g. Seraphinite) WebP-only rewrites, and offers a * one-click safe repair. When .htaccess is not writable, shows manual instructions. */ const ImageDeliveryHealthPanel = () => { const [health, setHealth] = useState(null); const [loading, setLoading] = useState(true); const [repairing, setRepairing] = useState(false); const [message, setMessage] = useState(''); const loadHealth = useCallback(() => { setLoading(true); apiFetch({ path: '/prorank-seo/v1/image-optimization/delivery-health' }) .then((data: any) => { setHealth(data as ImageDeliveryHealth); setLoading(false); }) .catch(() => setLoading(false)); }, []); useEffect(() => { loadHealth(); }, [loadHealth]); const runRepair = () => { setRepairing(true); setMessage(''); apiFetch({ path: '/prorank-seo/v1/image-optimization/delivery-health/repair', method: 'POST', }) .then((result: any) => { setRepairing(false); setMessage(result?.message || ''); if (result?.health) { setHealth(result.health as ImageDeliveryHealth); } else { loadHealth(); } }) .catch(() => { setRepairing(false); setMessage(__('Repair failed. Apply the rules manually.', 'prorank-seo')); }); }; if (loading || !health) { return null; } const statusLabel = health.status === 'healthy' ? __('Healthy — ProRank owns AVIF delivery', 'prorank-seo') : health.status === 'warning' ? __('Needs attention', 'prorank-seo') : __('Error', 'prorank-seo'); const explanation = health.delivery_explanation; return (

{__('Delivery Health', 'prorank-seo')}

{statusLabel}

{explanation?.message && (

{explanation.message}

)} {explanation?.recommendation && (

{explanation.recommendation}

)} {health.issues?.length > 0 && (
    {health.issues.map((issue) => (
  • {issue.message}
  • ))}
)}
  • {__('ProRank block present:', 'prorank-seo')}{' '} {health.has_prorank_block ? __('Yes', 'prorank-seo') : __('No', 'prorank-seo')}
  • {__('.htaccess writable:', 'prorank-seo')}{' '} {health.htaccess_writable ? __('Yes', 'prorank-seo') : __('No', 'prorank-seo')}
  • {health.prorank_after_competitor && (
  • {__('ProRank block is AFTER a competitor block (wrong order).', 'prorank-seo')}
  • )} {health.stale_competitors?.length > 0 && (
  • {__('Stale competitor blocks:', 'prorank-seo')}{' '} {health.stale_competitors.map((c) => c.label).join(', ')}
  • )}
{health.can_repair && ( {repairing ? __('Repairing…', 'prorank-seo') : __('Repair delivery (make ProRank own AVIF)', 'prorank-seo')} )} {!health.htaccess_writable && health.manual_instructions && (

{__( '.htaccess is not writable. Add these rules manually at the TOP of your .htaccess:', 'prorank-seo' )}

            {health.manual_instructions}
          
)} {message &&

{message}

}
); }; export default ImageDeliveryHealthPanel;