dvc890 commited on
Commit
4dfa63d
·
verified ·
1 Parent(s): 2ab052a

Update pages/GameRandom.tsx

Browse files
Files changed (1) hide show
  1. pages/GameRandom.tsx +20 -12
pages/GameRandom.tsx CHANGED
@@ -32,7 +32,7 @@ export const GameRandom: React.FC = () => {
32
  const [rewardType, setRewardType] = useState<'DRAW_COUNT' | 'ITEM' | 'ACHIEVEMENT'>('DRAW_COUNT');
33
  const [rewardId, setRewardId] = useState(''); // Achievement ID or Item Name
34
  const [rewardCount, setRewardCount] = useState(1);
35
- const [enableReward, setEnableReward] = useState(true);
36
 
37
  const timerRef = useRef<any>(null);
38
  const speedRef = useRef<number>(50);
@@ -48,7 +48,7 @@ export const GameRandom: React.FC = () => {
48
  // Clear picked IDs when mode changes to avoid ID confusion
49
  useEffect(() => {
50
  setPickedIds(new Set());
51
- }, [mode]);
52
 
53
  const loadData = async () => {
54
  if (!homeroomClass) return setLoading(false);
@@ -92,7 +92,7 @@ export const GameRandom: React.FC = () => {
92
  baseList = baseList.filter(s => !excludedStudentIds.has(s._id || String(s.id)));
93
  }
94
 
95
- // NEW: Filter out previously picked if mode is on
96
  if (avoidRepeat) {
97
  baseList = baseList.filter(item => !pickedIds.has(mode === 'TEAM' ? item.id : (item._id || String(item.id))));
98
  }
@@ -104,7 +104,11 @@ export const GameRandom: React.FC = () => {
104
  const list = getTargetList();
105
  if (list.length === 0) {
106
  if (avoidRepeat && pickedIds.size > 0) {
107
- return alert('本轮所有候选对象已全部点完!请点击上方“重置记录”重新开始。');
 
 
 
 
108
  }
109
  return alert('当前范围内没有可选对象');
110
  }
@@ -156,8 +160,9 @@ export const GameRandom: React.FC = () => {
156
  setIsRunning(false);
157
  };
158
 
159
- const handleGrantReward = async () => {
160
- if (!selectedResult || !enableReward) {
 
161
  setShowResultModal(false);
162
  return;
163
  }
@@ -200,7 +205,7 @@ export const GameRandom: React.FC = () => {
200
  }
201
  });
202
  await Promise.all(promises);
203
- alert(`已发放奖励给 ${targets.length} 名学生!`);
204
  } catch (e) {
205
  console.error(e);
206
  alert('发放失败');
@@ -227,6 +232,7 @@ export const GameRandom: React.FC = () => {
227
  {isFullscreen ? <Minimize size={20}/> : <Maximize size={20}/>}
228
  <span className="text-xs font-bold hidden sm:inline">{isFullscreen ? '退出全屏' : '全屏模式'}</span>
229
  </button>
 
230
  {/* Header Config */}
231
  <div className="bg-white p-4 shadow-sm border-b border-gray-200 z-10 flex flex-wrap gap-4 items-center justify-between shrink-0 pr-36">
232
  <div className="flex flex-wrap gap-4 items-center">
@@ -247,15 +253,15 @@ export const GameRandom: React.FC = () => {
247
 
248
  {/* Avoid Repeat Logic */}
249
  <div className={`flex items-center gap-2 px-3 py-2 rounded-lg border transition-colors ${avoidRepeat ? 'bg-indigo-50 border-indigo-200' : 'bg-gray-50 border-gray-200'}`}>
250
- <div className="flex items-center gap-2">
251
  <input type="checkbox" id="avoidRepeat" checked={avoidRepeat} onChange={e => setAvoidRepeat(e.target.checked)} className="w-4 h-4 text-indigo-600 rounded focus:ring-indigo-500 cursor-pointer"/>
252
- <label htmlFor="avoidRepeat" className={`text-sm font-bold cursor-pointer ${avoidRepeat ? 'text-indigo-700' : 'text-gray-600'}`}>不重复</label>
253
  </div>
254
  {avoidRepeat && pickedIds.size > 0 && (
255
  <>
256
  <div className="w-px h-4 bg-indigo-200 mx-1"></div>
257
  <span className="text-xs text-indigo-500 font-mono">已点{pickedIds.size}</span>
258
- <button onClick={() => setPickedIds(new Set())} className="text-indigo-400 hover:text-indigo-700 p-1 rounded-full hover:bg-indigo-100" title="重置记录">
259
  <RotateCcw size={14}/>
260
  </button>
261
  </>
@@ -290,6 +296,7 @@ export const GameRandom: React.FC = () => {
290
  </div>
291
  </div>
292
  </div>
 
293
  {/* Grid Area */}
294
  <div className="flex-1 overflow-y-auto p-6 custom-scrollbar bg-slate-50">
295
  <div className={`grid gap-4 transition-all pb-24 ${mode==='STUDENT' ? (isFullscreen ? 'grid-cols-6 sm:grid-cols-8 md:grid-cols-10 lg:grid-cols-12' : 'grid-cols-4 sm:grid-cols-6 md:grid-cols-8 lg:grid-cols-10') : 'grid-cols-2 md:grid-cols-3 lg:grid-cols-4'}`}>
@@ -325,6 +332,7 @@ export const GameRandom: React.FC = () => {
325
  })}
326
  </div>
327
  </div>
 
328
  {/* Start Button */}
329
  <div className="absolute bottom-0 left-0 right-0 p-6 flex justify-center bg-white/90 backdrop-blur-sm border-t border-gray-200 z-10 shadow-[0_-4px_10px_-1px_rgba(0,0,0,0.1)]">
330
  <button
@@ -389,12 +397,12 @@ export const GameRandom: React.FC = () => {
389
  {/* @ts-ignore */}
390
  <div className="text-gray-400 mb-8">{mode==='STUDENT' ? `座号: ${selectedResult.seatNo || '-'}` : `${selectedResult.members.length} 位成员`}</div>
391
  <div className="grid grid-cols-2 gap-4 mb-4">
392
- <button onClick={() => { setEnableReward(true); handleGrantReward(); }} className="bg-green-500 hover:bg-green-600 text-white py-4 rounded-2xl font-bold text-lg flex flex-col items-center justify-center shadow-md transition-transform hover:-translate-y-1">
393
  <CheckCircle size={32} className="mb-1"/>
394
  回答正确
395
  <span className="text-xs font-normal opacity-80 mt-1">发放奖励</span>
396
  </button>
397
- <button onClick={() => { setEnableReward(false); handleGrantReward(); }} className="bg-gray-100 hover:bg-gray-200 text-gray-600 py-4 rounded-2xl font-bold text-lg flex flex-col items-center justify-center shadow-sm transition-transform hover:-translate-y-1">
398
  <XCircle size={32} className="mb-1"/>
399
  回答错误
400
  <span className="text-xs font-normal opacity-80 mt-1">无奖励</span>
 
32
  const [rewardType, setRewardType] = useState<'DRAW_COUNT' | 'ITEM' | 'ACHIEVEMENT'>('DRAW_COUNT');
33
  const [rewardId, setRewardId] = useState(''); // Achievement ID or Item Name
34
  const [rewardCount, setRewardCount] = useState(1);
35
+ // Removed explicit enableReward state dependency for immediate actions to avoid async bugs
36
 
37
  const timerRef = useRef<any>(null);
38
  const speedRef = useRef<number>(50);
 
48
  // Clear picked IDs when mode changes to avoid ID confusion
49
  useEffect(() => {
50
  setPickedIds(new Set());
51
+ }, [mode, scopeTeamId]);
52
 
53
  const loadData = async () => {
54
  if (!homeroomClass) return setLoading(false);
 
92
  baseList = baseList.filter(s => !excludedStudentIds.has(s._id || String(s.id)));
93
  }
94
 
95
+ // Filter out previously picked if mode is on
96
  if (avoidRepeat) {
97
  baseList = baseList.filter(item => !pickedIds.has(mode === 'TEAM' ? item.id : (item._id || String(item.id))));
98
  }
 
104
  const list = getTargetList();
105
  if (list.length === 0) {
106
  if (avoidRepeat && pickedIds.size > 0) {
107
+ if (confirm('本轮所有候选对象已全部点完!是否重置记录并重新开始?')) {
108
+ setPickedIds(new Set());
109
+ // Logic to restart immediately after reset could go here, but let's just reset first
110
+ }
111
+ return;
112
  }
113
  return alert('当前范围内没有可选对象');
114
  }
 
160
  setIsRunning(false);
161
  };
162
 
163
+ // Fixed: Pass `shouldReward` directly to avoid async state issues
164
+ const handleGrantReward = async (shouldReward: boolean) => {
165
+ if (!selectedResult || !shouldReward) {
166
  setShowResultModal(false);
167
  return;
168
  }
 
205
  }
206
  });
207
  await Promise.all(promises);
208
+ // Optional: Show success toast
209
  } catch (e) {
210
  console.error(e);
211
  alert('发放失败');
 
232
  {isFullscreen ? <Minimize size={20}/> : <Maximize size={20}/>}
233
  <span className="text-xs font-bold hidden sm:inline">{isFullscreen ? '退出全屏' : '全屏模式'}</span>
234
  </button>
235
+
236
  {/* Header Config */}
237
  <div className="bg-white p-4 shadow-sm border-b border-gray-200 z-10 flex flex-wrap gap-4 items-center justify-between shrink-0 pr-36">
238
  <div className="flex flex-wrap gap-4 items-center">
 
253
 
254
  {/* Avoid Repeat Logic */}
255
  <div className={`flex items-center gap-2 px-3 py-2 rounded-lg border transition-colors ${avoidRepeat ? 'bg-indigo-50 border-indigo-200' : 'bg-gray-50 border-gray-200'}`}>
256
+ <div className="flex items-center gap-2" title="开启后,已点过的学生/小组不会再次被选中">
257
  <input type="checkbox" id="avoidRepeat" checked={avoidRepeat} onChange={e => setAvoidRepeat(e.target.checked)} className="w-4 h-4 text-indigo-600 rounded focus:ring-indigo-500 cursor-pointer"/>
258
+ <label htmlFor="avoidRepeat" className={`text-sm font-bold cursor-pointer select-none ${avoidRepeat ? 'text-indigo-700' : 'text-gray-600'}`}>不重复</label>
259
  </div>
260
  {avoidRepeat && pickedIds.size > 0 && (
261
  <>
262
  <div className="w-px h-4 bg-indigo-200 mx-1"></div>
263
  <span className="text-xs text-indigo-500 font-mono">已点{pickedIds.size}</span>
264
+ <button onClick={() => setPickedIds(new Set())} className="text-indigo-400 hover:text-indigo-700 p-1 rounded-full hover:bg-indigo-100 transition-colors" title="重置记录">
265
  <RotateCcw size={14}/>
266
  </button>
267
  </>
 
296
  </div>
297
  </div>
298
  </div>
299
+
300
  {/* Grid Area */}
301
  <div className="flex-1 overflow-y-auto p-6 custom-scrollbar bg-slate-50">
302
  <div className={`grid gap-4 transition-all pb-24 ${mode==='STUDENT' ? (isFullscreen ? 'grid-cols-6 sm:grid-cols-8 md:grid-cols-10 lg:grid-cols-12' : 'grid-cols-4 sm:grid-cols-6 md:grid-cols-8 lg:grid-cols-10') : 'grid-cols-2 md:grid-cols-3 lg:grid-cols-4'}`}>
 
332
  })}
333
  </div>
334
  </div>
335
+
336
  {/* Start Button */}
337
  <div className="absolute bottom-0 left-0 right-0 p-6 flex justify-center bg-white/90 backdrop-blur-sm border-t border-gray-200 z-10 shadow-[0_-4px_10px_-1px_rgba(0,0,0,0.1)]">
338
  <button
 
397
  {/* @ts-ignore */}
398
  <div className="text-gray-400 mb-8">{mode==='STUDENT' ? `座号: ${selectedResult.seatNo || '-'}` : `${selectedResult.members.length} 位成员`}</div>
399
  <div className="grid grid-cols-2 gap-4 mb-4">
400
+ <button onClick={() => handleGrantReward(true)} className="bg-green-500 hover:bg-green-600 text-white py-4 rounded-2xl font-bold text-lg flex flex-col items-center justify-center shadow-md transition-transform hover:-translate-y-1">
401
  <CheckCircle size={32} className="mb-1"/>
402
  回答正确
403
  <span className="text-xs font-normal opacity-80 mt-1">发放奖励</span>
404
  </button>
405
+ <button onClick={() => handleGrantReward(false)} className="bg-gray-100 hover:bg-gray-200 text-gray-600 py-4 rounded-2xl font-bold text-lg flex flex-col items-center justify-center shadow-sm transition-transform hover:-translate-y-1">
406
  <XCircle size={32} className="mb-1"/>
407
  回答错误
408
  <span className="text-xs font-normal opacity-80 mt-1">无奖励</span>