import { useState } from 'react'; import { CheckIcon, ChevronDownIcon, InfoIcon, MinusIcon, XIcon, } from 'lucide-react'; import { OptionTip } from '../../components/seo/option-row'; import { classNames } from '../../lib/utils'; import { GROUP_LABELS, GROUP_TIPS, type AnalysisGroup, type AnalysisResult, } from '../analysis/analyzer'; import { isToDo, isToFix, resultTone } from './result-tone'; /** What a failing test offers to do about itself, next to its advice. */ export interface TestAction { label: string; run: () => void; } const GROUPS: AnalysisGroup[] = [ 'basic', 'additional', 'title', 'content', 'product', 'aeo', ]; const Group = ({ group, results, defaultOpen, actionFor, }: { group: AnalysisGroup; results: AnalysisResult[]; defaultOpen: boolean; actionFor?: (result: AnalysisResult) => TestAction | undefined; }): JSX.Element => { const [open, setOpen] = useState(defaultOpen); // A failed test that weighs nothing is advice ("to improve"), not "to fix"; // one Rank Math runs and the Recomaze rules do not ask for is neither. const toFix = results.filter(isToFix).length; const toImprove = results.filter( result => isToDo(result) && !isToFix(result) ).length; const allGood = toFix === 0 && toImprove === 0; const tip = GROUP_TIPS[group]; return (
{/* The count sits after the name and drops under it when the sidebar is narrow; a name squeezed beside it ran into it. */} {tip && {tip}}
{open && ( )}
); }; /** * The tests grouped the way Rank Math groups them, failing groups open, * with the reason each test fails and what to do about it. */ export const AnalysisList = ({ results, actionFor, }: { results: AnalysisResult[]; /** The way to fix a failing test here, when there is one. */ actionFor?: (result: AnalysisResult) => TestAction | undefined; }): JSX.Element => (
{GROUPS.filter(group => results.some(result => result.group === group)).map( group => { const own = results.filter(result => result.group === group); return ( isToDo(result) && result.max > 0)} actionFor={actionFor} /> ); } )}
);