Upload folder using huggingface_hub
Browse files
client/src/components/Refinity.tsx
CHANGED
|
@@ -54,6 +54,7 @@ const Refinity: React.FC = () => {
|
|
| 54 |
const [taskMenuOpen, setTaskMenuOpen] = React.useState<boolean>(false);
|
| 55 |
const [pastedTranslation, setPastedTranslation] = React.useState<string>('');
|
| 56 |
const [taskStageNote, setTaskStageNote] = React.useState<string>('');
|
|
|
|
| 57 |
|
| 58 |
const task = React.useMemo(() => tasks.find(t => t.id === selectedTaskId) || tasks[0], [tasks, selectedTaskId]);
|
| 59 |
const taskVersions = React.useMemo(() => versions.filter(v => v.taskId === (task?.id || '')), [versions, task?.id]);
|
|
@@ -385,7 +386,7 @@ const Refinity: React.FC = () => {
|
|
| 385 |
<div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
|
| 386 |
<span className="relative z-10">Revise</span>
|
| 387 |
</button>
|
| 388 |
-
<button onClick={()=>{ setPreviewVersionId(v.id);
|
| 389 |
</div>
|
| 390 |
)}
|
| 391 |
</div>
|
|
@@ -403,6 +404,7 @@ const Refinity: React.FC = () => {
|
|
| 403 |
version={taskVersions.find(v => v.id === previewVersionId) || null}
|
| 404 |
onBack={()=>setStage('flow')}
|
| 405 |
onEdit={()=>{ if (previewVersionId) { setCurrentVersionId(previewVersionId); setStage('editor'); } }}
|
|
|
|
| 406 |
/>
|
| 407 |
)}
|
| 408 |
|
|
@@ -513,7 +515,12 @@ const EditorPane: React.FC<{ source: string; initialTranslation: string; onBack:
|
|
| 513 |
|
| 514 |
export default Refinity;
|
| 515 |
|
| 516 |
-
const PreviewPane: React.FC<{ version: Version | null; onBack: ()=>void; onEdit: ()=>void }>=({ version, onBack, onEdit })=>{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 517 |
if (!version) return (
|
| 518 |
<div>
|
| 519 |
<div className="text-gray-700">No version selected.</div>
|
|
@@ -522,6 +529,18 @@ const PreviewPane: React.FC<{ version: Version | null; onBack: ()=>void; onEdit:
|
|
| 522 |
</div>
|
| 523 |
</div>
|
| 524 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 525 |
return (
|
| 526 |
<div>
|
| 527 |
<div className="mb-3 text-gray-700 text-sm">Original: {version.originalAuthor} · Revised by: {version.revisedBy || '—'} (v{version.versionNumber})</div>
|
|
@@ -530,12 +549,18 @@ const PreviewPane: React.FC<{ version: Version | null; onBack: ()=>void; onEdit:
|
|
| 530 |
<div className="relative rounded-xl bg-white/10 backdrop-blur-md ring-1 ring-inset ring-white/30 shadow-[inset_0_0.5px_0_rgba(255,255,255,0.5),inset_0_-1px_1.5px_rgba(0,0,0,0.12)] p-6">
|
| 531 |
<div className="pointer-events-none absolute inset-0 rounded-xl opacity-50 [background:linear-gradient(to_bottom,rgba(255,255,255,0.3),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.28),rgba(255,255,255,0)_28%)]" />
|
| 532 |
<div className="pointer-events-none absolute inset-0 rounded-xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-45" />
|
| 533 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 534 |
</div>
|
| 535 |
</div>
|
| 536 |
<div className="mt-4 flex gap-3">
|
| 537 |
<button onClick={onEdit} className="relative overflow-hidden inline-flex items-center justify-center gap-2 px-4 py-2 text-sm font-medium rounded-2xl text-white ring-1 ring-inset ring-white/50 backdrop-blur-md backdrop-brightness-110 backdrop-saturate-150 bg-indigo-600/70 active:translate-y-0.5 transition-all duration-200">Revise</button>
|
| 538 |
<button onClick={onBack} className="relative overflow-hidden inline-flex items-center justify-center gap-2 px-4 py-2 text-sm font-medium rounded-2xl text-black ring-1 ring-inset ring-white/50 backdrop-blur-md bg-white/30 active:translate-y-0.5 transition-all duration-200">Back</button>
|
|
|
|
| 539 |
</div>
|
| 540 |
</div>
|
| 541 |
);
|
|
|
|
| 54 |
const [taskMenuOpen, setTaskMenuOpen] = React.useState<boolean>(false);
|
| 55 |
const [pastedTranslation, setPastedTranslation] = React.useState<string>('');
|
| 56 |
const [taskStageNote, setTaskStageNote] = React.useState<string>('');
|
| 57 |
+
const [showPreviewDiff, setShowPreviewDiff] = React.useState<boolean>(false);
|
| 58 |
|
| 59 |
const task = React.useMemo(() => tasks.find(t => t.id === selectedTaskId) || tasks[0], [tasks, selectedTaskId]);
|
| 60 |
const taskVersions = React.useMemo(() => versions.filter(v => v.taskId === (task?.id || '')), [versions, task?.id]);
|
|
|
|
| 386 |
<div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
|
| 387 |
<span className="relative z-10">Revise</span>
|
| 388 |
</button>
|
| 389 |
+
<button onClick={()=>{ setPreviewVersionId(v.id); setShowPreviewDiff(true); setStage('preview'); }} className="relative overflow-hidden inline-flex items-center justify-center gap-2 px-3 py-2 text-sm font-medium rounded-2xl text-black ring-1 ring-inset ring-white/50 backdrop-blur-md bg-white/30 active:translate-y-0.5 transition-all duration-200">Compare</button>
|
| 390 |
</div>
|
| 391 |
)}
|
| 392 |
</div>
|
|
|
|
| 404 |
version={taskVersions.find(v => v.id === previewVersionId) || null}
|
| 405 |
onBack={()=>setStage('flow')}
|
| 406 |
onEdit={()=>{ if (previewVersionId) { setCurrentVersionId(previewVersionId); setStage('editor'); } }}
|
| 407 |
+
compareInitially={showPreviewDiff}
|
| 408 |
/>
|
| 409 |
)}
|
| 410 |
|
|
|
|
| 515 |
|
| 516 |
export default Refinity;
|
| 517 |
|
| 518 |
+
const PreviewPane: React.FC<{ version: Version | null; onBack: ()=>void; onEdit: ()=>void; compareInitially?: boolean }>=({ version, onBack, onEdit, compareInitially })=>{
|
| 519 |
+
const [diffHtml, setDiffHtml] = React.useState<string>('');
|
| 520 |
+
const [showDiff, setShowDiff] = React.useState<boolean>(!!compareInitially);
|
| 521 |
+
React.useEffect(()=>{
|
| 522 |
+
setShowDiff(!!compareInitially);
|
| 523 |
+
},[compareInitially]);
|
| 524 |
if (!version) return (
|
| 525 |
<div>
|
| 526 |
<div className="text-gray-700">No version selected.</div>
|
|
|
|
| 529 |
</div>
|
| 530 |
</div>
|
| 531 |
);
|
| 532 |
+
const doCompare = async ()=>{
|
| 533 |
+
try {
|
| 534 |
+
const base = ((api.defaults as any)?.baseURL as string || '').replace(/\/$/, '');
|
| 535 |
+
// Compare this version with its parent if available
|
| 536 |
+
const prevText = (version as any)?.parentContent || '';
|
| 537 |
+
const resp = await fetch(`${base}/api/refinity/diff`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ prev: prevText, current: version.content || '' }) });
|
| 538 |
+
const data = await resp.json().catch(()=>({}));
|
| 539 |
+
if (!resp.ok) throw new Error(data?.error || 'Diff failed');
|
| 540 |
+
setDiffHtml(String(data?.html || ''));
|
| 541 |
+
setShowDiff(true);
|
| 542 |
+
} catch {}
|
| 543 |
+
};
|
| 544 |
return (
|
| 545 |
<div>
|
| 546 |
<div className="mb-3 text-gray-700 text-sm">Original: {version.originalAuthor} · Revised by: {version.revisedBy || '—'} (v{version.versionNumber})</div>
|
|
|
|
| 549 |
<div className="relative rounded-xl bg-white/10 backdrop-blur-md ring-1 ring-inset ring-white/30 shadow-[inset_0_0.5px_0_rgba(255,255,255,0.5),inset_0_-1px_1.5px_rgba(0,0,0,0.12)] p-6">
|
| 550 |
<div className="pointer-events-none absolute inset-0 rounded-xl opacity-50 [background:linear-gradient(to_bottom,rgba(255,255,255,0.3),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.28),rgba(255,255,255,0)_28%)]" />
|
| 551 |
<div className="pointer-events-none absolute inset-0 rounded-xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-45" />
|
| 552 |
+
{!showDiff && (
|
| 553 |
+
<div className="relative whitespace-pre-wrap text-gray-900 min-h-[220px]">{version.content}</div>
|
| 554 |
+
)}
|
| 555 |
+
{showDiff && (
|
| 556 |
+
<div className="relative prose prose-sm max-w-none text-gray-900" dangerouslySetInnerHTML={{ __html: diffHtml }} />
|
| 557 |
+
)}
|
| 558 |
</div>
|
| 559 |
</div>
|
| 560 |
<div className="mt-4 flex gap-3">
|
| 561 |
<button onClick={onEdit} className="relative overflow-hidden inline-flex items-center justify-center gap-2 px-4 py-2 text-sm font-medium rounded-2xl text-white ring-1 ring-inset ring-white/50 backdrop-blur-md backdrop-brightness-110 backdrop-saturate-150 bg-indigo-600/70 active:translate-y-0.5 transition-all duration-200">Revise</button>
|
| 562 |
<button onClick={onBack} className="relative overflow-hidden inline-flex items-center justify-center gap-2 px-4 py-2 text-sm font-medium rounded-2xl text-black ring-1 ring-inset ring-white/50 backdrop-blur-md bg-white/30 active:translate-y-0.5 transition-all duration-200">Back</button>
|
| 563 |
+
<button onClick={doCompare} className="relative overflow-hidden inline-flex items-center justify-center gap-2 px-4 py-2 text-sm font-medium rounded-2xl text-black ring-1 ring-inset ring-white/50 backdrop-blur-md bg-white/30 active:translate-y-0.5 transition-all duration-200">Compare</button>
|
| 564 |
</div>
|
| 565 |
</div>
|
| 566 |
);
|