'use client'
import { useEffect, useRef } from 'react'
import { DiffEditor } from '@monaco-editor/react'
import { IoCheckmarkOutline, IoArrowBackOutline } from 'react-icons/io5'
interface DiffViewerProps {
originalContent: string
modifiedContent: string
fileName?: string
className?: string
onRevert?: () => void
onAccept?: () => void
isLoading?: boolean
}
export default function DiffViewer({
originalContent,
modifiedContent,
fileName,
className = '',
onRevert,
onAccept,
isLoading = false
}: DiffViewerProps) {
const diffEditorRef = useRef<any>(null)
const handleEditorDidMount = (editor: any) => {
diffEditorRef.current = editor
// Configure the diff editor
editor.updateOptions({
readOnly: true,
renderSideBySide: true,
ignoreTrimWhitespace: false,
renderWhitespace: 'boundary',
wordWrap: 'on',
fontSize: 13,
lineHeight: 18,
minimap: { enabled: false },
folding: false,
lineNumbers: 'on',
glyphMargin: false,
scrollBeyondLastLine: false,
})
}
return (
<div className={`h-full flex flex-col bg-slate-900/40 backdrop-blur-sm ${className}`}>
{/* Monaco Diff Editor */}
<div className="flex-1">
<DiffEditor
original={originalContent}
modified={modifiedContent}
language="markdown" // Default to markdown, could be made configurable
theme="vs-dark"
onMount={handleEditorDidMount}
options={{
readOnly: true,
renderSideBySide: true,
ignoreTrimWhitespace: false,
renderWhitespace: 'boundary',
wordWrap: 'on',
fontSize: 13,
lineHeight: 18,
minimap: { enabled: false },
folding: false,
lineNumbers: 'on',
glyphMargin: false,
scrollBeyondLastLine: false,
automaticLayout: true,
}}
/>
</div>
{/* Minimal status bar */}
<div className="h-8 bg-slate-800/95 backdrop-blur-md border-t border-slate-700/50 flex items-center justify-between px-4 text-xs text-slate-400">
<div className="flex items-center gap-4">
<span className="text-slate-300">Diff View</span>
{fileName && (
<span className="text-slate-500 bg-slate-700/30 px-1.5 py-0.5 rounded text-[10px]">
{fileName.split('.').pop()?.toUpperCase() || 'TXT'}
</span>
)}
</div>
{(onRevert || onAccept) && (
<div className="flex items-center gap-1.5">
{onRevert && (
<button
onClick={onRevert}
disabled={isLoading}
className="group relative overflow-hidden bg-red-500/20 hover:bg-red-500/30 border border-red-500/30 text-red-400 hover:text-red-300 px-2 py-0.5 rounded text-[10px] font-medium transition-all duration-150 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-1"
>
{isLoading ? (
<>
<div className="w-2.5 h-2.5 border border-current border-t-transparent rounded-full animate-spin opacity-70"></div>
<span>Reverting...</span>
</>
) : (
<>
<IoArrowBackOutline className="w-2.5 h-2.5" />
<span>Revert</span>
</>
)}
</button>
)}
{onAccept && (
<button
onClick={onAccept}
disabled={isLoading}
className="group relative overflow-hidden bg-slate-700 hover:bg-slate-600 border border-slate-600 text-slate-200 px-2 py-0.5 rounded text-[10px] font-medium transition-all duration-150 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-1"
>
{isLoading ? (
<>
<div className="w-2.5 h-2.5 border border-current border-t-transparent rounded-full animate-spin opacity-70"></div>
<span>Accepting...</span>
</>
) : (
<>
<IoCheckmarkOutline className="w-2.5 h-2.5" />
<span>Accept</span>
</>
)}
</button>
)}
</div>
)}
</div>
</div>
)
}