linguabot commited on
Commit
b3f2315
·
verified ·
1 Parent(s): 3ab9dea

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. client/src/components/Refinity.tsx +36 -18
client/src/components/Refinity.tsx CHANGED
@@ -53,6 +53,7 @@ const Refinity: React.FC = () => {
53
  const [addingSourceUploading, setAddingSourceUploading] = React.useState<boolean>(false);
54
  const [taskMenuOpen, setTaskMenuOpen] = React.useState<boolean>(false);
55
  const [pastedTranslation, setPastedTranslation] = React.useState<string>('');
 
56
 
57
  const task = React.useMemo(() => tasks.find(t => t.id === selectedTaskId) || tasks[0], [tasks, selectedTaskId]);
58
  const taskVersions = React.useMemo(() => versions.filter(v => v.taskId === (task?.id || '')), [versions, task?.id]);
@@ -150,7 +151,7 @@ const Refinity: React.FC = () => {
150
 
151
  const assignRandom = () => {
152
  const pool = taskVersions.filter(v => (v.originalAuthor !== username && v.revisedBy !== username));
153
- if (!pool.length) return;
154
  const pick = pool[Math.floor(Math.random() * pool.length)];
155
  setCurrentVersionId(pick.id);
156
  setStage('editor');
@@ -177,21 +178,37 @@ const Refinity: React.FC = () => {
177
  setStage('editor');
178
  };
179
 
180
- const handleSaveRevision = (newContent: string) => {
181
  const parent = taskVersions.find(v => v.id === currentVersionId);
182
- const nextVersionNumber = (taskVersions[taskVersions.length - 1]?.versionNumber || 0) + 1;
183
- const v: Version = {
184
- id: `v_${Date.now()}`,
185
- taskId: task?.id || 't1',
186
- originalAuthor: parent?.originalAuthor || username,
187
- revisedBy: username,
188
- versionNumber: nextVersionNumber,
189
- content: newContent,
190
- parentVersionId: parent?.id,
191
- };
192
- setVersions(prev => [...prev, v]);
193
- setCurrentVersionId(v.id);
194
- setStage('flow');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  };
196
 
197
  return (
@@ -258,8 +275,8 @@ const Refinity: React.FC = () => {
258
  </div>
259
  </div>
260
 
261
- <div className="mt-8 flex gap-3">
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>
@@ -276,6 +293,7 @@ const Refinity: React.FC = () => {
276
  <div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
277
  <span className="relative z-10">New Task</span>
278
  </button>
 
279
  </div>
280
 
281
  {showAddTask && (
@@ -351,7 +369,7 @@ const Refinity: React.FC = () => {
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%)]" />
 
53
  const [addingSourceUploading, setAddingSourceUploading] = React.useState<boolean>(false);
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]);
 
151
 
152
  const assignRandom = () => {
153
  const pool = taskVersions.filter(v => (v.originalAuthor !== username && v.revisedBy !== username));
154
+ if (!pool.length) { setTaskStageNote('No eligible translations to revise yet. Try Manual Selection or add a translation.'); return; }
155
  const pick = pool[Math.floor(Math.random() * pool.length)];
156
  setCurrentVersionId(pick.id);
157
  setStage('editor');
 
178
  setStage('editor');
179
  };
180
 
181
+ const handleSaveRevision = async (newContent: string) => {
182
  const parent = taskVersions.find(v => v.id === currentVersionId);
183
+ try {
184
+ const base = ((api.defaults as any)?.baseURL as string || '').replace(/\/$/, '');
185
+ const resp = await fetch(`${base}/api/refinity/tasks/${encodeURIComponent(task?.id || '')}/versions`, {
186
+ method: 'POST',
187
+ headers: { 'Content-Type': 'application/json' },
188
+ body: JSON.stringify({
189
+ originalAuthor: parent?.originalAuthor || username,
190
+ revisedBy: username,
191
+ content: newContent,
192
+ parentVersionId: parent?.id,
193
+ })
194
+ });
195
+ const saved = await resp.json().catch(()=>({}));
196
+ if (!resp.ok) throw new Error(saved?.error || 'Save failed');
197
+ const v: Version = {
198
+ id: saved._id,
199
+ taskId: saved.taskId,
200
+ originalAuthor: saved.originalAuthor,
201
+ revisedBy: saved.revisedBy,
202
+ versionNumber: saved.versionNumber,
203
+ content: saved.content,
204
+ parentVersionId: saved.parentVersionId,
205
+ };
206
+ setVersions(prev => [...prev, v]);
207
+ setCurrentVersionId(v.id);
208
+ setStage('flow');
209
+ } catch {
210
+ // no-op; keep user in editor if needed
211
+ }
212
  };
213
 
214
  return (
 
275
  </div>
276
  </div>
277
 
278
+ <div className="mt-8 flex gap-3 items-center flex-wrap">
279
+ <button onClick={assignRandom} disabled={!taskVersions.some(v=>v.originalAuthor!==username && v.revisedBy!==username)} 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 disabled:bg-gray-400 active:translate-y-0.5 transition-all duration-200">
280
  <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%)]" />
281
  <div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
282
  <span className="relative z-10">Random Mode</span>
 
293
  <div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
294
  <span className="relative z-10">New Task</span>
295
  </button>
296
+ {taskStageNote && <span className="text-sm text-gray-600 ml-2">{taskStageNote}</span>}
297
  </div>
298
 
299
  {showAddTask && (
 
369
  <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">
370
  <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%)]" />
371
  <div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
372
+ <span className="relative z-10">Full Text</span>
373
  </button>
374
  <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">
375
  <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%)]" />