linguabot commited on
Commit
7a5ce86
·
verified ·
1 Parent(s): c44adbb

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. client/src/pages/TutorialTasks.tsx +22 -5
client/src/pages/TutorialTasks.tsx CHANGED
@@ -73,6 +73,23 @@ const TutorialTasks: React.FC = () => {
73
  const cardRefs = useRef<{[key: string]: HTMLDivElement | null}>({});
74
  const [listLockedHeight, setListLockedHeight] = useState<number | null>(null);
75
  const listRef = useRef<HTMLDivElement | null>(null);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
  // Move a task up or down by normalizing positions for the current visible list (weeks 4–6 only)
78
  const moveTask = async (taskId: string, direction: 'up' | 'down') => {
@@ -1665,7 +1682,7 @@ const TutorialTasks: React.FC = () => {
1665
  </div>
1666
  )}
1667
 
1668
- <div ref={listRef} style={listLockedHeight ? { height: listLockedHeight } : undefined}>
1669
  {tutorialTasks.length === 0 && !addingTask ? (
1670
  <div className="text-center py-12">
1671
  <DocumentTextIcon className="h-12 w-12 text-gray-400 mx-auto mb-4" />
@@ -1896,7 +1913,7 @@ const TutorialTasks: React.FC = () => {
1896
  <select
1897
  value={selectedGroups[task._id] || ''}
1898
  onFocus={() => { lockListHeight(); lockCardHeight(task._id); }}
1899
- onChange={(e) => { lockListHeight(); lockCardHeight(task._id); setSelectedGroups({ ...selectedGroups, [task._id]: parseInt(e.target.value) }); }}
1900
  onBlur={() => { unlockCardHeight(task._id); unlockListHeight(); }}
1901
  className="w-40 px-2 py-1 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 bg-white text-xs"
1902
  >
@@ -1913,8 +1930,8 @@ const TutorialTasks: React.FC = () => {
1913
  id={`tutorial-translation-${task._id}`}
1914
  value={translationText[task._id] || ''}
1915
  onFocus={() => { lockListHeight(); lockCardHeight(task._id); }}
1916
- onInput={() => { lockListHeight(); lockCardHeight(task._id); }}
1917
- onChange={(e) => setTranslationText({ ...translationText, [task._id]: e.target.value })}
1918
  onBlur={() => { unlockCardHeight(task._id); unlockListHeight(); }}
1919
  className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 bg-white"
1920
  style={{ height: sourceHeights[task._id] ? `${sourceHeights[task._id]}px` : 'auto' }}
@@ -1922,7 +1939,7 @@ const TutorialTasks: React.FC = () => {
1922
  placeholder="Enter your group's translation here..."
1923
  />
1924
  <div className="flex justify-end mt-2">
1925
- <button onClick={() => { lockListHeight(); lockCardHeight(task._id); handleSubmitTranslation(task._id).finally(() => setTimeout(() => { unlockCardHeight(task._id); unlockListHeight(); }, 300)); }} disabled={submitting[task._id]} className="btn-primary disabled:bg-gray-400 text-white px-4 py-2 rounded-lg text-sm">{submitting[task._id] ? 'Submitting...' : 'Submit Translation'}</button>
1926
  </div>
1927
  </div>
1928
  )}
 
73
  const cardRefs = useRef<{[key: string]: HTMLDivElement | null}>({});
74
  const [listLockedHeight, setListLockedHeight] = useState<number | null>(null);
75
  const listRef = useRef<HTMLDivElement | null>(null);
76
+ const withPreservedScroll = useRef<(fn: () => void) => void>();
77
+
78
+ // Initialize scroll preservation helper once
79
+ useEffect(() => {
80
+ withPreservedScroll.current = (fn: () => void) => {
81
+ try {
82
+ const y = window.scrollY;
83
+ fn();
84
+ // Restore immediately after next paint
85
+ requestAnimationFrame(() => {
86
+ window.scrollTo(0, y);
87
+ });
88
+ } catch {
89
+ fn();
90
+ }
91
+ };
92
+ }, []);
93
 
94
  // Move a task up or down by normalizing positions for the current visible list (weeks 4–6 only)
95
  const moveTask = async (taskId: string, direction: 'up' | 'down') => {
 
1682
  </div>
1683
  )}
1684
 
1685
+ <div ref={listRef} style={listLockedHeight ? { minHeight: listLockedHeight } : undefined}>
1686
  {tutorialTasks.length === 0 && !addingTask ? (
1687
  <div className="text-center py-12">
1688
  <DocumentTextIcon className="h-12 w-12 text-gray-400 mx-auto mb-4" />
 
1913
  <select
1914
  value={selectedGroups[task._id] || ''}
1915
  onFocus={() => { lockListHeight(); lockCardHeight(task._id); }}
1916
+ onChange={(e) => { lockListHeight(); lockCardHeight(task._id); (withPreservedScroll.current || ((fn)=>fn()))(() => setSelectedGroups({ ...selectedGroups, [task._id]: parseInt(e.target.value) })); }}
1917
  onBlur={() => { unlockCardHeight(task._id); unlockListHeight(); }}
1918
  className="w-40 px-2 py-1 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 bg-white text-xs"
1919
  >
 
1930
  id={`tutorial-translation-${task._id}`}
1931
  value={translationText[task._id] || ''}
1932
  onFocus={() => { lockListHeight(); lockCardHeight(task._id); }}
1933
+ onInput={(e) => { lockListHeight(); lockCardHeight(task._id); (withPreservedScroll.current || ((fn)=>fn()))(() => setTranslationText({ ...translationText, [task._id]: (e.target as HTMLTextAreaElement).value })); }}
1934
+ onChange={(e) => (withPreservedScroll.current || ((fn)=>fn()))(() => setTranslationText({ ...translationText, [task._id]: e.target.value }))}
1935
  onBlur={() => { unlockCardHeight(task._id); unlockListHeight(); }}
1936
  className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 bg-white"
1937
  style={{ height: sourceHeights[task._id] ? `${sourceHeights[task._id]}px` : 'auto' }}
 
1939
  placeholder="Enter your group's translation here..."
1940
  />
1941
  <div className="flex justify-end mt-2">
1942
+ <button onClick={() => { lockListHeight(); lockCardHeight(task._id); (withPreservedScroll.current || ((fn)=>fn()))(() => {}); handleSubmitTranslation(task._id).finally(() => setTimeout(() => { unlockCardHeight(task._id); unlockListHeight(); }, 300)); }} disabled={submitting[task._id]} className="btn-primary disabled:bg-gray-400 text-white px-4 py-2 rounded-lg text-sm">{submitting[task._id] ? 'Submitting...' : 'Submit Translation'}</button>
1943
  </div>
1944
  </div>
1945
  )}