import { useRef, useEffect, useState } from 'react'; import { useTheme } from 'providers/Theme/index'; import { IconLoader2 } from '@tabler/icons'; import Modal from 'components/Modal'; import StatusBadge from 'ui/StatusBadge'; const SpecDiffModal = ({ specDrift, onClose }) => { const diffRef = useRef(null); const { displayedTheme } = useTheme(); const [isRendering, setIsRendering] = useState(true); const addedCount = specDrift?.added?.length || 0; const modifiedCount = specDrift?.modified?.length || 0; const removedCount = specDrift?.removed?.length || 0; const versionLabel = specDrift?.versionChanged ? `v${specDrift.storedVersion || '?'} → v${specDrift.newVersion}` : null; useEffect(() => { const { Diff2Html } = window; if (!diffRef?.current || !Diff2Html || !specDrift?.unifiedDiff) { setIsRendering(false); return; } setIsRendering(true); const diffHtml = Diff2Html.html(specDrift.unifiedDiff, { drawFileList: false, matching: 'lines', outputFormat: 'side-by-side', synchronisedScroll: true, highlight: true, renderNothingWhenEmpty: false, colorScheme: displayedTheme }); // Safe: Diff2Html is loaded from a local static bundle (public/static/diff2Html.js) diffRef.current.innerHTML = diffHtml; setIsRendering(false); }, [displayedTheme, specDrift?.unifiedDiff]); return (
{modifiedCount > 0 && Updated: {modifiedCount}} {addedCount > 0 && Added: {addedCount}} {removedCount > 0 && Removed: {removedCount}} {versionLabel && {versionLabel}}

{specDrift?.storedSpecMissing ? 'The current spec file is missing. The full remote spec is shown below.' : 'Side-by-side diff of your current spec vs the updated spec from the spec URL.'}

{specDrift?.unifiedDiff ? ( <>
{specDrift?.storedSpecMissing ? 'Current Spec (missing)' : 'Current Spec'} Updated Spec
{isRendering && (
Loading diff...
)}
) : (
No text diff available.
)}
); }; export default SpecDiffModal;