linguabot commited on
Commit
c31b5fd
·
verified ·
1 Parent(s): 21191f7

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. client/src/components/Refinity.tsx +42 -67
client/src/components/Refinity.tsx CHANGED
@@ -1,5 +1,10 @@
1
  import React from 'react';
2
  import { motion, AnimatePresence } from 'framer-motion';
 
 
 
 
 
3
  import { api } from '../services/api';
4
 
5
  type Stage = 'task' | 'flow' | 'preview' | 'editor';
@@ -233,15 +238,8 @@ const Refinity: React.FC = () => {
233
 
234
  return (
235
  <div className="relative">
236
- {/* Indigo-tinted gradient underlay */}
237
- <div className="absolute inset-0 rounded-xl bg-gradient-to-r from-indigo-200/45 via-indigo-100/40 to-indigo-300/45" />
238
- {/* Glass card container */}
239
- <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)]">
240
- <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%)]" />
241
- <div className="pointer-events-none absolute inset-0 rounded-xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-45" />
242
- <div className="pointer-events-none absolute inset-0 rounded-xl" style={{ background: 'radial-gradient(120% 120% at 50% 55%, rgba(0,0,0,0.03), rgba(0,0,0,0) 60%)' }} />
243
- <div className="pointer-events-none absolute inset-0 rounded-xl bg-indigo-500/10 mix-blend-overlay opacity-30" />
244
- <div className="relative p-6">
245
  {/* Stage 1: Task Creation / Selection */}
246
  {stage === 'task' && (
247
  <div>
@@ -351,13 +349,13 @@ const Refinity: React.FC = () => {
351
  </div>
352
  )}
353
 
354
- {/* Stage 2: Version Flow - Framer Motion 3-card deck */}
355
  {stage === 'flow' && (
356
  <div>
357
  <div className="flex items-center justify-between mb-4">
358
  <div>
359
  <h3 className="text-xl font-semibold text-black">Version Flow — {task?.title}</h3>
360
- <div className="text-gray-700 text-sm">Use arrows or click cards. Center card is active.</div>
361
  </div>
362
  <div className="flex gap-2">
363
  <button onClick={()=>setStage('task')} 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">
@@ -367,62 +365,40 @@ const Refinity: React.FC = () => {
367
  </button>
368
  </div>
369
  </div>
370
-
371
- <div className="relative h-[420px]">
372
- <button aria-label="Previous" onClick={()=> setFlowIndex(i => Math.max(i-1, 0))} className="absolute left-2 top-1/2 -translate-y-1/2 z-10 px-2 py-1 rounded-2xl bg-white/50 ring-1 ring-white/50 backdrop-blur-md text-sm">‹</button>
373
- <button aria-label="Next" onClick={()=> setFlowIndex(i => Math.min(i+1, Math.max(taskVersions.length-1, 0)))} className="absolute right-2 top-1/2 -translate-y-1/2 z-10 px-2 py-1 rounded-2xl bg-white/50 ring-1 ring-white/50 backdrop-blur-md text-sm">›</button>
374
-
375
- {(() => {
376
- const n = taskVersions.length;
377
- if (n === 0) return (
378
- <div className="h-full grid place-items-center text-gray-600">No versions yet.</div>
379
- );
380
- const center = Math.min(Math.max(flowIndex, 0), n - 1);
381
- const ids: Array<{ pos: 'left'|'center'|'right'; idx: number }> = [];
382
- if (center - 1 >= 0) ids.push({ pos: 'left', idx: center - 1 });
383
- ids.push({ pos: 'center', idx: center });
384
- if (center + 1 < n) ids.push({ pos: 'right', idx: center + 1 });
385
-
386
- const variants = {
387
- left: { x: '-32%', scale: 0.98, rotate: 0, opacity: 0.98, zIndex: 10 },
388
- center: { x: '-50%', scale: 1.0, rotate: 0, opacity: 1, zIndex: 20 },
389
- right: { x: '-68%', scale: 0.98, rotate: 0, opacity: 0.98, zIndex: 10 }
390
- } as const;
391
-
392
- return (
393
- <AnimatePresence initial={false}>
394
- {ids.map(({ pos, idx }) => {
395
- const v = taskVersions[idx];
396
- const snippet = (v.content || '').slice(0, 220) + ((v.content || '').length > 220 ? '…' : '');
397
- const isCenter = pos === 'center';
398
- return (
399
- <motion.div
400
- key={v.id}
401
- className="absolute top-0 left-1/2 w-[560px]"
402
- initial={variants[pos]}
403
- animate={variants[pos]}
404
- exit={variants[pos]}
405
- transition={{ type: 'spring', stiffness: 300, damping: 28 }}
406
- onClick={() => { if (!isCenter) setFlowIndex(idx); }}
407
- >
408
- <div className="relative rounded-xl p-5 bg-white ring-1 ring-gray-200 shadow-lg text-base">
409
- <div className="text-gray-800 text-sm mb-2">Original: {v.originalAuthor}</div>
410
- <div className="text-gray-600 text-xs mb-3">Revised by: {v.revisedBy ? `${v.revisedBy} (v${v.versionNumber})` : `— (v${v.versionNumber})`}</div>
411
- <div className="text-gray-900 whitespace-pre-wrap break-words leading-relaxed">{snippet}</div>
412
- {isCenter && (
413
- <div className="mt-4 flex gap-3">
414
- <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">Full Text</button>
415
- <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">Revise</button>
416
- <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>
417
- </div>
418
- )}
419
  </div>
420
- </motion.div>
421
- );
422
- })}
423
- </AnimatePresence>
424
- );
425
- })()}
426
  </div>
427
  </div>
428
  )}
@@ -449,7 +425,6 @@ const Refinity: React.FC = () => {
449
  nextVersionNumber={((versions.filter(v=>v.taskId===(task?.id||'')).slice(-1)[0]?.versionNumber) || 0) + 1}
450
  />
451
  )}
452
- </div>
453
  </div>
454
  </div>
455
  );
 
1
  import React from 'react';
2
  import { motion, AnimatePresence } from 'framer-motion';
3
+ import { Swiper as SwiperRoot, SwiperSlide } from 'swiper/react';
4
+ import { EffectCoverflow, Navigation, A11y } from 'swiper/modules';
5
+ import 'swiper/css';
6
+ import 'swiper/css/effect-coverflow';
7
+ import 'swiper/css/navigation';
8
  import { api } from '../services/api';
9
 
10
  type Stage = 'task' | 'flow' | 'preview' | 'editor';
 
238
 
239
  return (
240
  <div className="relative">
241
+ {/* Clean container (no purple gradient) */}
242
+ <div className="relative rounded-xl p-6 bg-transparent">
 
 
 
 
 
 
 
243
  {/* Stage 1: Task Creation / Selection */}
244
  {stage === 'task' && (
245
  <div>
 
349
  </div>
350
  )}
351
 
352
+ {/* Stage 2: Version Flow - Swiper Coverflow */}
353
  {stage === 'flow' && (
354
  <div>
355
  <div className="flex items-center justify-between mb-4">
356
  <div>
357
  <h3 className="text-xl font-semibold text-black">Version Flow — {task?.title}</h3>
358
+ <div className="text-gray-700 text-sm">Swipe/click to browse. Center slide is active.</div>
359
  </div>
360
  <div className="flex gap-2">
361
  <button onClick={()=>setStage('task')} 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">
 
365
  </button>
366
  </div>
367
  </div>
368
+ <div className="relative">
369
+ <SwiperRoot
370
+ modules={[EffectCoverflow, Navigation, A11y]}
371
+ effect="coverflow"
372
+ onSlideChange={(s)=> setFlowIndex(s.activeIndex)}
373
+ onAfterInit={(s)=> setFlowIndex(s.activeIndex)}
374
+ navigation
375
+ centeredSlides
376
+ slidesPerView={1.2}
377
+ spaceBetween={24}
378
+ coverflowEffect={{ rotate: 0, stretch: 40, depth: 80, modifier: 1, slideShadows: false }}
379
+ className="!px-8"
380
+ >
381
+ {taskVersions.map((v, idx) => {
382
+ const snippet = (v.content || '').slice(0, 220) + ((v.content || '').length > 220 ? '…' : '');
383
+ const isCenter = idx === flowIndex;
384
+ return (
385
+ <SwiperSlide key={v.id} style={{ width: 560 }}>
386
+ <div className="relative rounded-xl p-5 bg-white ring-1 ring-gray-200 shadow-lg text-base">
387
+ <div className="text-gray-800 text-sm mb-2">Original: {v.originalAuthor}</div>
388
+ <div className="text-gray-600 text-xs mb-3">Revised by: {v.revisedBy ? `${v.revisedBy} (v${v.versionNumber})` : `— (v${v.versionNumber})`}</div>
389
+ <div className="text-gray-900 whitespace-pre-wrap break-words leading-relaxed">{snippet}</div>
390
+ {isCenter && (
391
+ <div className="mt-4 flex gap-3">
392
+ <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">Full Text</button>
393
+ <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">Revise</button>
394
+ <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>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
395
  </div>
396
+ )}
397
+ </div>
398
+ </SwiperSlide>
399
+ );
400
+ })}
401
+ </SwiperRoot>
402
  </div>
403
  </div>
404
  )}
 
425
  nextVersionNumber={((versions.filter(v=>v.taskId===(task?.id||'')).slice(-1)[0]?.versionNumber) || 0) + 1}
426
  />
427
  )}
 
428
  </div>
429
  </div>
430
  );