Upload folder using huggingface_hub
Browse files
client/src/components/Refinity.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
import React from 'react';
|
| 2 |
import { api } from '../services/api';
|
| 3 |
|
| 4 |
-
type Stage = 'task' | 'flow' | 'editor';
|
| 5 |
|
| 6 |
type Version = {
|
| 7 |
id: string;
|
|
@@ -30,6 +30,7 @@ const Refinity: React.FC = () => {
|
|
| 30 |
const [selectedTaskId, setSelectedTaskId] = React.useState<string>('');
|
| 31 |
const [versions, setVersions] = React.useState<Version[]>([]);
|
| 32 |
const [currentVersionId, setCurrentVersionId] = React.useState<string | null>(null);
|
|
|
|
| 33 |
const [username] = React.useState<string>(() => {
|
| 34 |
try {
|
| 35 |
const u = localStorage.getItem('user');
|
|
@@ -261,13 +262,13 @@ const Refinity: React.FC = () => {
|
|
| 261 |
<button onClick={assignRandom} 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">
|
| 262 |
<div className="pointer-events-none absolute inset-0 rounded-2xl opacity-60 [background:linear-gradient(to_bottom,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%)]" />
|
| 263 |
<div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
|
| 264 |
-
<span className="relative z-10">
|
| 265 |
</button>
|
| 266 |
{taskVersions.length > 0 && (
|
| 267 |
<button onClick={()=>setStage('flow')} 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">
|
| 268 |
<div className="pointer-events-none absolute inset-0 rounded-2xl opacity-60 [background:linear-gradient(to_bottom,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%)]" />
|
| 269 |
<div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
|
| 270 |
-
<span className="relative z-10">
|
| 271 |
</button>
|
| 272 |
)}
|
| 273 |
<button onClick={()=>setShowAddTask(v=>!v)} 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">
|
|
@@ -337,25 +338,20 @@ const Refinity: React.FC = () => {
|
|
| 337 |
const scale = isCenter ? 1.0 : Math.max(0.8, 1 - sideOffset * 0.08);
|
| 338 |
const rotate = isCenter ? 0 : (idx < focusedIndex ? -12 : 12);
|
| 339 |
const opacity = isCenter ? 1 : Math.max(0.35, 1 - sideOffset * 0.2);
|
|
|
|
| 340 |
return (
|
| 341 |
<div key={v.id} className="transition-transform duration-300"
|
| 342 |
style={{ transform: `scale(${scale}) rotateY(${rotate}deg)`, opacity }}>
|
| 343 |
-
<div className="relative w-[520px] rounded-xl p-5 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)]"
|
| 344 |
-
onClick={()=>setCurrentVersionId(v.id)}>
|
| 345 |
<div className="text-gray-800 text-sm mb-2">Original: {v.originalAuthor}</div>
|
| 346 |
<div className="text-gray-600 text-xs mb-3">Revised by: {v.revisedBy ? `${v.revisedBy} (v${v.versionNumber})` : `— (v${v.versionNumber})`}</div>
|
| 347 |
-
<div className="text-gray-900 whitespace-pre-wrap break-words min-h-[
|
| 348 |
{isCenter && (
|
| 349 |
<div className="mt-4 flex gap-3">
|
| 350 |
-
<button 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">
|
| 351 |
<div className="pointer-events-none absolute inset-0 rounded-2xl opacity-60 [background:linear-gradient(to_bottom,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%)]" />
|
| 352 |
<div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
|
| 353 |
-
<span className="relative z-10">
|
| 354 |
-
</button>
|
| 355 |
-
<button 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">
|
| 356 |
-
<div className="pointer-events-none absolute inset-0 rounded-2xl opacity-60 [background:linear-gradient(to_bottom,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%)]" />
|
| 357 |
-
<div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
|
| 358 |
-
<span className="relative z-10">Comment</span>
|
| 359 |
</button>
|
| 360 |
<button onClick={()=>selectManual(v.id)} className="relative overflow-hidden inline-flex items-center justify-center gap-2 px-3 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">
|
| 361 |
<div className="pointer-events-none absolute inset-0 rounded-2xl opacity-60 [background:linear-gradient(to_bottom,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%)]" />
|
|
@@ -373,6 +369,15 @@ const Refinity: React.FC = () => {
|
|
| 373 |
</div>
|
| 374 |
)}
|
| 375 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 376 |
{/* Stage 3: Editor */}
|
| 377 |
{stage === 'editor' && (
|
| 378 |
<EditorPane
|
|
@@ -472,4 +477,32 @@ const EditorPane: React.FC<{ source: string; initialTranslation: string; onBack:
|
|
| 472 |
|
| 473 |
export default Refinity;
|
| 474 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 475 |
|
|
|
|
| 1 |
import React from 'react';
|
| 2 |
import { api } from '../services/api';
|
| 3 |
|
| 4 |
+
type Stage = 'task' | 'flow' | 'preview' | 'editor';
|
| 5 |
|
| 6 |
type Version = {
|
| 7 |
id: string;
|
|
|
|
| 30 |
const [selectedTaskId, setSelectedTaskId] = React.useState<string>('');
|
| 31 |
const [versions, setVersions] = React.useState<Version[]>([]);
|
| 32 |
const [currentVersionId, setCurrentVersionId] = React.useState<string | null>(null);
|
| 33 |
+
const [previewVersionId, setPreviewVersionId] = React.useState<string | null>(null);
|
| 34 |
const [username] = React.useState<string>(() => {
|
| 35 |
try {
|
| 36 |
const u = localStorage.getItem('user');
|
|
|
|
| 262 |
<button onClick={assignRandom} 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">
|
| 263 |
<div className="pointer-events-none absolute inset-0 rounded-2xl opacity-60 [background:linear-gradient(to_bottom,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%)]" />
|
| 264 |
<div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
|
| 265 |
+
<span className="relative z-10">Random Mode</span>
|
| 266 |
</button>
|
| 267 |
{taskVersions.length > 0 && (
|
| 268 |
<button onClick={()=>setStage('flow')} 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">
|
| 269 |
<div className="pointer-events-none absolute inset-0 rounded-2xl opacity-60 [background:linear-gradient(to_bottom,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%)]" />
|
| 270 |
<div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
|
| 271 |
+
<span className="relative z-10">Manual Selection</span>
|
| 272 |
</button>
|
| 273 |
)}
|
| 274 |
<button onClick={()=>setShowAddTask(v=>!v)} 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">
|
|
|
|
| 338 |
const scale = isCenter ? 1.0 : Math.max(0.8, 1 - sideOffset * 0.08);
|
| 339 |
const rotate = isCenter ? 0 : (idx < focusedIndex ? -12 : 12);
|
| 340 |
const opacity = isCenter ? 1 : Math.max(0.35, 1 - sideOffset * 0.2);
|
| 341 |
+
const snippet = (v.content || '').slice(0, 160) + ((v.content || '').length > 160 ? '…' : '');
|
| 342 |
return (
|
| 343 |
<div key={v.id} className="transition-transform duration-300"
|
| 344 |
style={{ transform: `scale(${scale}) rotateY(${rotate}deg)`, opacity }}>
|
| 345 |
+
<div className="relative w-[520px] rounded-xl p-5 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)]">
|
|
|
|
| 346 |
<div className="text-gray-800 text-sm mb-2">Original: {v.originalAuthor}</div>
|
| 347 |
<div className="text-gray-600 text-xs mb-3">Revised by: {v.revisedBy ? `${v.revisedBy} (v${v.versionNumber})` : `— (v${v.versionNumber})`}</div>
|
| 348 |
+
<div className="text-gray-900 whitespace-pre-wrap break-words min-h-[100px]">{snippet}</div>
|
| 349 |
{isCenter && (
|
| 350 |
<div className="mt-4 flex gap-3">
|
| 351 |
+
<button onClick={()=>{ setPreviewVersionId(v.id); 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">
|
| 352 |
<div className="pointer-events-none absolute inset-0 rounded-2xl opacity-60 [background:linear-gradient(to_bottom,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%)]" />
|
| 353 |
<div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
|
| 354 |
+
<span className="relative z-10">Preview</span>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 355 |
</button>
|
| 356 |
<button onClick={()=>selectManual(v.id)} className="relative overflow-hidden inline-flex items-center justify-center gap-2 px-3 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">
|
| 357 |
<div className="pointer-events-none absolute inset-0 rounded-2xl opacity-60 [background:linear-gradient(to_bottom,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%)]" />
|
|
|
|
| 369 |
</div>
|
| 370 |
)}
|
| 371 |
|
| 372 |
+
{/* Stage: Preview full text */}
|
| 373 |
+
{stage === 'preview' && (
|
| 374 |
+
<PreviewPane
|
| 375 |
+
version={taskVersions.find(v => v.id === previewVersionId) || null}
|
| 376 |
+
onBack={()=>setStage('flow')}
|
| 377 |
+
onEdit={()=>{ if (previewVersionId) { setCurrentVersionId(previewVersionId); setStage('editor'); } }}
|
| 378 |
+
/>
|
| 379 |
+
)}
|
| 380 |
+
|
| 381 |
{/* Stage 3: Editor */}
|
| 382 |
{stage === 'editor' && (
|
| 383 |
<EditorPane
|
|
|
|
| 477 |
|
| 478 |
export default Refinity;
|
| 479 |
|
| 480 |
+
const PreviewPane: React.FC<{ version: Version | null; onBack: ()=>void; onEdit: ()=>void }>=({ version, onBack, onEdit })=>{
|
| 481 |
+
if (!version) return (
|
| 482 |
+
<div>
|
| 483 |
+
<div className="text-gray-700">No version selected.</div>
|
| 484 |
+
<div className="mt-3">
|
| 485 |
+
<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>
|
| 486 |
+
</div>
|
| 487 |
+
</div>
|
| 488 |
+
);
|
| 489 |
+
return (
|
| 490 |
+
<div>
|
| 491 |
+
<div className="mb-3 text-gray-700 text-sm">Original: {version.originalAuthor} · Revised by: {version.revisedBy || '—'} (v{version.versionNumber})</div>
|
| 492 |
+
<div className="relative rounded-xl">
|
| 493 |
+
<div className="absolute inset-0 rounded-xl bg-gradient-to-r from-indigo-200/45 via-indigo-100/40 to-indigo-300/45" />
|
| 494 |
+
<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">
|
| 495 |
+
<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%)]" />
|
| 496 |
+
<div className="pointer-events-none absolute inset-0 rounded-xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-45" />
|
| 497 |
+
<div className="relative whitespace-pre-wrap text-gray-900 min-h-[220px]">{version.content}</div>
|
| 498 |
+
</div>
|
| 499 |
+
</div>
|
| 500 |
+
<div className="mt-4 flex gap-3">
|
| 501 |
+
<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">Edit</button>
|
| 502 |
+
<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>
|
| 503 |
+
</div>
|
| 504 |
+
</div>
|
| 505 |
+
);
|
| 506 |
+
};
|
| 507 |
+
|
| 508 |
|