← back to Norma
components/email-analyzer/CompareModal.tsx
146 lines
'use client';
import type { VersionEntry } from './VersionTimeline';
import ProsConsPanel, { type ProsConsData } from './ProsConsPanel';
import { sanitizeHtml } from './sanitize';
import ScorePanel from './ScorePanel';
import ResizableModal from '../shared/ResizableModal';
/* ─── Types ──────────────────────────────────────────────────────────────── */
interface CompareModalProps {
compareA: VersionEntry;
compareB: VersionEntry;
prosConsData: ProsConsData | null;
prosConsLoading: boolean;
onClose: () => void;
/** When a suggestion is clicked, modal closes and this fires with the chat instruction. */
onApplySuggestion?: (suggestion: string, label: string) => void;
}
/* ─── Component ──────────────────────────────────────────────────────────── */
export default function CompareModal({
compareA,
compareB,
prosConsData,
prosConsLoading,
onClose,
onApplySuggestion,
}: CompareModalProps) {
return (
<ResizableModal
modalId="email-analyzer-compare-versions"
title={`Compare: v${compareA.versionNumber} vs v${compareB.versionNumber}`}
onClose={onClose}
defaultWidth={1000}
>
<div style={{ margin: '-16px -20px' }}>
{/* Side-by-side content */}
<div style={{ display: 'flex', minHeight: 300 }}>
<div
style={{
flex: 1,
padding: 16,
borderRight: '1px solid var(--color-border)',
}}
>
<div
style={{
fontSize: 12,
fontWeight: 600,
color: 'var(--color-text-muted)',
marginBottom: 8,
textTransform: 'uppercase',
letterSpacing: '0.06em',
}}
>
v{compareA.versionNumber}: {compareA.label}
</div>
<div
style={{
fontSize: 13,
lineHeight: 1.7,
color: 'var(--color-text)',
}}
dangerouslySetInnerHTML={{
__html: sanitizeHtml(compareA.content),
}}
/>
</div>
<div style={{ flex: 1, padding: 16 }}>
<div
style={{
fontSize: 12,
fontWeight: 600,
color: 'var(--color-text-muted)',
marginBottom: 8,
textTransform: 'uppercase',
letterSpacing: '0.06em',
}}
>
v{compareB.versionNumber}: {compareB.label}
</div>
<div
style={{
fontSize: 13,
lineHeight: 1.7,
color: 'var(--color-text)',
}}
dangerouslySetInnerHTML={{
__html: sanitizeHtml(compareB.content),
}}
/>
</div>
</div>
{/* Pros/Cons analysis */}
<div
style={{
borderTop: '1px solid var(--color-border)',
padding: '14px 20px',
}}
>
<ProsConsPanel
data={prosConsData}
loading={prosConsLoading}
prosLabel={`v${compareB.versionNumber} does better`}
consLabel={`v${compareA.versionNumber} did better`}
compact
/>
</div>
{/* Live score + suggestions to improve v B */}
<div
style={{
borderTop: '1px solid var(--color-border)',
padding: '14px 20px',
background: 'var(--color-surface-el)',
}}
>
<div
style={{
fontSize: 12,
fontWeight: 700,
color: 'var(--color-text-muted)',
marginBottom: 10,
textTransform: 'uppercase',
letterSpacing: '0.06em',
}}
>
Score v{compareB.versionNumber} + live improvement suggestions
</div>
<ScorePanel
email={compareB.content}
autoRunKey={compareB.id}
onApplySuggestion={(suggestion, label) => {
onApplySuggestion?.(suggestion, label);
onClose();
}}
/>
</div>
</div>
</ResizableModal>
);
}