amaniquery-frontend / src /components /chat /LegalDiffViewer.tsx
Benaah's picture
Upload folder using huggingface_hub
6a059d3 verified
Raw
History Blame Contribute Delete
7.24 kB
import React, { useMemo } from "react"
import ReactDiffViewer, { DiffMethod } from "react-diff-viewer-continued"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { GitCompare, ArrowRight } from "lucide-react"
import { GithubDiff } from "./types"
interface LegalDiffViewerProps {
diff: GithubDiff
className?: string
}
export function LegalDiffViewer({ diff, className }: LegalDiffViewerProps) {
// Calculate percentage/number change for the badge
const changeBadge = useMemo(() => {
try {
// Extract numbers from old and new text
const oldNumbers = diff.old_text.match(/(\d+(\.\d+)?)/g)?.map(Number) || []
const newNumbers = diff.new_text.match(/(\d+(\.\d+)?)/g)?.map(Number) || []
// Simple heuristic: if we find one number in each that changed
if (oldNumbers.length === 1 && newNumbers.length === 1) {
const oldVal = oldNumbers[0]
const newVal = newNumbers[0]
if (oldVal !== newVal) {
const percentChange = ((newVal - oldVal) / oldVal) * 100
const isIncrease = newVal > oldVal
return {
text: `${isIncrease ? "+" : ""}${percentChange.toFixed(1)}% ${isIncrease ? "Increase" : "Decrease"}`,
variant: isIncrease ? "destructive" : "default" as "default" | "destructive" | "outline" | "secondary",
color: isIncrease ? "bg-red-600" : "bg-green-600" // Higher taxes (increase) usually bad/red, lower good/green? Or just standard diff colors?
// Let's stick to standard: Green = Increase, Red = Decrease for numbers usually,
// BUT for taxes: Increase = Bad (Red), Decrease = Good (Green).
// Let's just use neutral or standard diff colors to avoid bias.
// For the badge, let's just show the change.
}
}
}
// Check for specific keywords like "increased from X to Y"
// This is handled by the diff view itself visually, but a badge is nice.
return null
} catch (e) {
return null
}
}, [diff.old_text, diff.new_text])
// Custom styles for react-diff-viewer-2 to match Kenyan flag theme
// Red (#B91C1C) for deleted, Green (#16A34A) for added
const newStyles = {
variables: {
light: {
diffViewerBackground: "transparent",
diffViewerColor: "currentColor",
addedBackground: "rgba(22, 163, 74, 0.2)", // Green #16A34A
addedColor: "currentColor",
removedBackground: "rgba(185, 28, 28, 0.2)", // Red #B91C1C
removedColor: "currentColor",
wordAddedBackground: "rgba(22, 163, 74, 0.4)",
wordRemovedBackground: "rgba(185, 28, 28, 0.4)",
addedGutterBackground: "rgba(22, 163, 74, 0.1)",
removedGutterBackground: "rgba(185, 28, 28, 0.1)",
gutterBackground: "transparent",
gutterBackgroundDark: "transparent",
highlightBackground: "rgba(255, 255, 255, 0.1)",
highlightGutterBackground: "rgba(255, 255, 255, 0.1)",
codeFoldGutterBackground: "transparent",
codeFoldBackground: "transparent",
emptyLineBackground: "transparent",
gutterColor: "currentColor",
addedGutterColor: "currentColor",
removedGutterColor: "currentColor",
codeFoldContentColor: "currentColor",
diffViewerTitleBackground: "transparent",
diffViewerTitleColor: "currentColor",
diffViewerTitleBorderColor: "transparent",
},
dark: {
diffViewerBackground: "transparent",
diffViewerColor: "currentColor",
addedBackground: "rgba(22, 163, 74, 0.2)", // Green
addedColor: "currentColor",
removedBackground: "rgba(185, 28, 28, 0.2)", // Red
removedColor: "currentColor",
wordAddedBackground: "rgba(22, 163, 74, 0.4)",
wordRemovedBackground: "rgba(185, 28, 28, 0.4)",
addedGutterBackground: "rgba(22, 163, 74, 0.1)",
removedGutterBackground: "rgba(185, 28, 28, 0.1)",
gutterBackground: "transparent",
gutterBackgroundDark: "transparent",
highlightBackground: "rgba(255, 255, 255, 0.1)",
highlightGutterBackground: "rgba(255, 255, 255, 0.1)",
codeFoldGutterBackground: "transparent",
codeFoldBackground: "transparent",
emptyLineBackground: "transparent",
gutterColor: "currentColor",
addedGutterColor: "currentColor",
removedGutterColor: "currentColor",
codeFoldContentColor: "currentColor",
diffViewerTitleBackground: "transparent",
diffViewerTitleColor: "currentColor",
diffViewerTitleBorderColor: "transparent",
}
},
line: {
padding: '10px 2px',
'&:hover': {
background: 'rgba(255, 255, 255, 0.05)',
},
},
content: {
fontFamily: 'inherit',
fontSize: '0.9rem',
}
}
return (
<Card className={`w-full overflow-hidden border-primary/20 bg-card/50 backdrop-blur-sm ${className}`}>
<CardHeader className="pb-2 border-b border-border/50 bg-muted/30">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<div className="p-2 rounded-lg bg-primary/10 text-primary">
<GitCompare className="w-5 h-5" />
</div>
<div>
<CardTitle className="text-base font-bold text-primary flex items-center gap-2">
{diff.title}
</CardTitle>
</div>
</div>
{changeBadge && (
<Badge variant={changeBadge.variant} className={`${changeBadge.color} text-white border-0`}>
{changeBadge.text}
</Badge>
)}
</div>
</CardHeader>
<CardContent className="p-0 overflow-x-auto">
<div className="min-w-[500px] text-sm">
{/* We force dark mode styles if the app is in dark mode, but react-diff-viewer-2
uses a 'useDarkTheme' prop. We can try to detect or just pass true/false.
For now, let's assume the app handles theme via class 'dark'.
Since we can't easily detect system preference here without hooks,
we'll rely on the parent passing a theme or default to light/dark based on CSS variables.
Actually, react-diff-viewer-2 styles object handles both light and dark keys,
but we need to tell it which one to use.
*/}
<ReactDiffViewer
oldValue={diff.old_text}
newValue={diff.new_text}
splitView={diff.highlight_type === "side_by_side"}
compareMethod={DiffMethod.WORDS}
styles={newStyles}
useDarkTheme={true} // Force dark theme styles for now as they look better in both modes with our transparent bg
leftTitle="Original Text"
rightTitle="Amended Text"
/>
</div>
</CardContent>
</Card>
)
}