linguabot commited on
Commit
dc5580a
·
verified ·
1 Parent(s): cad77ca

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. client/src/components/Refinity.tsx +84 -2
client/src/components/Refinity.tsx CHANGED
@@ -26,7 +26,7 @@ const mockTasks: Task[] = [
26
 
27
  const Refinity: React.FC = () => {
28
  const [stage, setStage] = React.useState<Stage>('task');
29
- const [tasks] = React.useState<Task[]>(mockTasks);
30
  const [selectedTaskId, setSelectedTaskId] = React.useState<string>(mockTasks[0]?.id || '');
31
  const [versions, setVersions] = React.useState<Version[]>([]);
32
  const [currentVersionId, setCurrentVersionId] = React.useState<string | null>(null);
@@ -42,6 +42,14 @@ const Refinity: React.FC = () => {
42
 
43
  // File upload (.docx placeholder)
44
  const [uploading, setUploading] = React.useState(false);
 
 
 
 
 
 
 
 
45
 
46
  const task = React.useMemo(() => tasks.find(t => t.id === selectedTaskId) || tasks[0], [tasks, selectedTaskId]);
47
  const taskVersions = React.useMemo(() => versions.filter(v => v.taskId === (task?.id || '')), [versions, task?.id]);
@@ -78,6 +86,34 @@ const Refinity: React.FC = () => {
78
  }
79
  };
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  const assignRandom = () => {
82
  const pool = taskVersions.filter(v => (v.originalAuthor !== username && v.revisedBy !== username));
83
  if (!pool.length) return;
@@ -135,7 +171,15 @@ const Refinity: React.FC = () => {
135
  </div>
136
  <div className="md:col-span-2">
137
  <label className="block text-sm text-gray-700 mb-1">Upload .doc or .docx translation</label>
138
- <input type="file" accept=".doc,.docx" onChange={(e)=>{ const f=e.target.files?.[0]; if(f) uploadDocx(f); }} className="block w-full text-gray-800 file:px-4 file:py-2 file:rounded-2xl file:ring-1 file:ring-inset file:ring-white/50 file:backdrop-blur-md file:backdrop-brightness-110 file:backdrop-saturate-150 file:bg-indigo-600/70 file:text-white hover:file:opacity-95 disabled:file:bg-gray-400" disabled={uploading} />
 
 
 
 
 
 
 
 
139
  </div>
140
  </div>
141
 
@@ -150,7 +194,45 @@ const Refinity: React.FC = () => {
150
  <div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
151
  <span className="relative z-10">Choose Manually</span>
152
  </button>
 
 
 
 
 
153
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  </div>
155
  )}
156
 
 
26
 
27
  const Refinity: React.FC = () => {
28
  const [stage, setStage] = React.useState<Stage>('task');
29
+ const [tasks, setTasks] = React.useState<Task[]>(mockTasks);
30
  const [selectedTaskId, setSelectedTaskId] = React.useState<string>(mockTasks[0]?.id || '');
31
  const [versions, setVersions] = React.useState<Version[]>([]);
32
  const [currentVersionId, setCurrentVersionId] = React.useState<string | null>(null);
 
42
 
43
  // File upload (.docx placeholder)
44
  const [uploading, setUploading] = React.useState(false);
45
+ const fileInputRef = React.useRef<HTMLInputElement | null>(null);
46
+
47
+ // Add Task UI state
48
+ const [showAddTask, setShowAddTask] = React.useState<boolean>(false);
49
+ const [newTaskTitle, setNewTaskTitle] = React.useState<string>('');
50
+ const [newTaskSource, setNewTaskSource] = React.useState<string>('');
51
+ const addTaskFileRef = React.useRef<HTMLInputElement | null>(null);
52
+ const [addingSourceUploading, setAddingSourceUploading] = React.useState<boolean>(false);
53
 
54
  const task = React.useMemo(() => tasks.find(t => t.id === selectedTaskId) || tasks[0], [tasks, selectedTaskId]);
55
  const taskVersions = React.useMemo(() => versions.filter(v => v.taskId === (task?.id || '')), [versions, task?.id]);
 
86
  }
87
  };
88
 
89
+ const uploadSourceDoc = async (file: File) => {
90
+ setAddingSourceUploading(true);
91
+ try {
92
+ const base = ((api.defaults as any)?.baseURL as string || '').replace(/\/$/, '');
93
+ const form = new FormData();
94
+ form.append('file', file);
95
+ const resp = await fetch(`${base}/api/refinity/parse`, { method: 'POST', body: form });
96
+ const data = await resp.json().catch(()=>({}));
97
+ if (!resp.ok) throw new Error(data?.error || 'Failed to parse document');
98
+ setNewTaskSource(String(data?.text || ''));
99
+ } finally {
100
+ setAddingSourceUploading(false);
101
+ }
102
+ };
103
+
104
+ const saveNewTask = () => {
105
+ const title = newTaskTitle.trim();
106
+ const src = newTaskSource.trim();
107
+ if (!title || !src) return;
108
+ const id = `t_${Date.now()}`;
109
+ const t: Task = { id, title, sourceText: src };
110
+ setTasks(prev => [...prev, t]);
111
+ setSelectedTaskId(id);
112
+ setShowAddTask(false);
113
+ setNewTaskTitle('');
114
+ setNewTaskSource('');
115
+ };
116
+
117
  const assignRandom = () => {
118
  const pool = taskVersions.filter(v => (v.originalAuthor !== username && v.revisedBy !== username));
119
  if (!pool.length) return;
 
171
  </div>
172
  <div className="md:col-span-2">
173
  <label className="block text-sm text-gray-700 mb-1">Upload .doc or .docx translation</label>
174
+ <div className="flex items-center gap-3">
175
+ <input ref={fileInputRef} type="file" accept=".doc,.docx" onChange={(e)=>{ const f=e.target.files?.[0]; if(f) uploadDocx(f); if(fileInputRef.current) fileInputRef.current.value=''; }} className="hidden" />
176
+ <button type="button" onClick={()=>fileInputRef.current?.click()} className="relative overflow-hidden inline-flex items-center justify-center gap-2 px-3 py-1.5 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">
177
+ <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%)]" />
178
+ <div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
179
+ <span className="relative z-10">Choose file</span>
180
+ </button>
181
+ {uploading && <span className="text-sm text-gray-600">Uploading…</span>}
182
+ </div>
183
  </div>
184
  </div>
185
 
 
194
  <div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
195
  <span className="relative z-10">Choose Manually</span>
196
  </button>
197
+ <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">
198
+ <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%)]" />
199
+ <div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
200
+ <span className="relative z-10">New Task</span>
201
+ </button>
202
  </div>
203
+
204
+ {showAddTask && (
205
+ <div className="mt-6 relative rounded-xl">
206
+ <div className="absolute inset-0 rounded-xl bg-gradient-to-r from-indigo-200/45 via-indigo-100/40 to-indigo-300/45" />
207
+ <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-4">
208
+ <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%)]" />
209
+ <div className="pointer-events-none absolute inset-0 rounded-xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-45" />
210
+ <div className="relative grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
211
+ <div>
212
+ <label className="block text-sm text-gray-700 mb-1">Title</label>
213
+ <input value={newTaskTitle} onChange={(e)=>setNewTaskTitle(e.target.value)} className="w-full px-3 py-2 rounded-lg bg-white/50 backdrop-blur border border-ui-border text-gray-900 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" />
214
+ </div>
215
+ <div className="md:col-span-2">
216
+ <label className="block text-sm text-gray-700 mb-1">Source Text</label>
217
+ <textarea value={newTaskSource} onChange={(e)=>setNewTaskSource(e.target.value)} rows={4} className="w-full px-4 py-3 border border-ui-border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 bg-white" placeholder="Paste source text here…" />
218
+ <div className="mt-2 flex items-center gap-3">
219
+ <input ref={addTaskFileRef} type="file" accept=".doc,.docx" onChange={(e)=>{ const f=e.target.files?.[0]; if(f) uploadSourceDoc(f); if(addTaskFileRef.current) addTaskFileRef.current.value=''; }} className="hidden" />
220
+ <button type="button" onClick={()=>addTaskFileRef.current?.click()} className="relative overflow-hidden inline-flex items-center justify-center gap-2 px-3 py-1.5 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">
221
+ <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%)]" />
222
+ <div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
223
+ <span className="relative z-10">Choose source file</span>
224
+ </button>
225
+ {addingSourceUploading && <span className="text-sm text-gray-600">Parsing…</span>}
226
+ </div>
227
+ </div>
228
+ </div>
229
+ <div className="relative mt-4 flex gap-3">
230
+ <button onClick={saveNewTask} 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">Save Task</button>
231
+ <button onClick={()=>{ setShowAddTask(false); setNewTaskTitle(''); setNewTaskSource(''); }} 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">Cancel</button>
232
+ </div>
233
+ </div>
234
+ </div>
235
+ )}
236
  </div>
237
  )}
238