ExamIndex.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import React, { useState, useCallback, useEffect } from 'react';
  2. import { useQuery } from '@tanstack/react-query';
  3. import { useNavigate, useSearchParams } from "react-router";
  4. import dayjs from 'dayjs';
  5. import { message } from 'antd';
  6. import { ClassroomDataAPI } from '../../api/classroom_data.ts';
  7. import { ClassroomStatus } from '../../../share/types_stock.ts';
  8. // 昵称输入页面
  9. function ExamIndex() {
  10. const [nickname, setNickname] = useState('');
  11. const navigate = useNavigate();
  12. const [searchParams] = useSearchParams();
  13. const classroom = searchParams.get('classroom');
  14. const { data: classroomData, isLoading } = useQuery({
  15. queryKey: ['classroom', classroom],
  16. queryFn: async () => {
  17. if (!classroom) return null;
  18. const response = await ClassroomDataAPI.getClassroomDatas({ classroom_no: classroom });
  19. if (!response.data?.length) {
  20. message.error('获取教室数据失败');
  21. return null;
  22. }
  23. return response.data[0] || null;
  24. },
  25. enabled: !!classroom
  26. });
  27. useEffect(() => {
  28. if (classroomData && classroomData.status !== ClassroomStatus.OPEN) {
  29. message.error('该教室已关闭');
  30. }
  31. }, [classroomData]);
  32. const handleJoinTraining = useCallback(() => {
  33. if (!nickname.trim()) {
  34. message.error('请输入昵称');
  35. return;
  36. }
  37. if (!classroom) {
  38. message.error('教室号不能为空');
  39. return;
  40. }
  41. if (!classroomData) {
  42. message.error('教室不存在');
  43. return;
  44. }
  45. if (classroomData.status !== ClassroomStatus.OPEN) {
  46. message.error('该教室已关闭');
  47. return;
  48. }
  49. // 将昵称和教室号作为参数传递到答题页
  50. navigate(`/mobile/exam/card?nickname=${encodeURIComponent(nickname)}&classroom=${classroom}`);
  51. }, [nickname, navigate, classroom, classroomData]);
  52. if (isLoading) {
  53. return <div className="flex items-center justify-center min-h-screen">加载中...</div>;
  54. }
  55. return (
  56. <div className="flex flex-col items-center justify-center min-h-screen bg-gray-100">
  57. <div className="w-full max-w-md space-y-8">
  58. <div className="text-center">
  59. <h2 className="text-3xl font-bold text-gray-900">股票训练答题卡系统</h2>
  60. <p className="mt-2 text-gray-600">
  61. {classroom ? `教室号: ${classroom}` : '请输入昵称开始答题'}
  62. </p>
  63. {classroomData && (
  64. <div className="mt-2 text-sm text-gray-500">
  65. <p>训练日期: {dayjs(classroomData.training_date).format('YYYY-MM-DD')}</p>
  66. <p>代码: {classroomData.code}</p>
  67. </div>
  68. )}
  69. </div>
  70. <div className="mt-8">
  71. <input
  72. type="text"
  73. value={nickname}
  74. onChange={(e) => setNickname(e.target.value)}
  75. placeholder="请输入昵称"
  76. className="w-full px-4 py-3 text-lg border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
  77. />
  78. </div>
  79. <button
  80. onClick={handleJoinTraining}
  81. disabled={!classroomData || classroomData.status !== ClassroomStatus.OPEN}
  82. className={`w-full px-8 py-3 text-lg font-medium text-white rounded-lg focus:outline-none focus:ring-2 focus:ring-offset-2 transition-colors ${
  83. !classroomData || classroomData.status !== ClassroomStatus.OPEN
  84. ? 'bg-gray-400 cursor-not-allowed'
  85. : 'bg-blue-500 hover:bg-blue-600 focus:ring-blue-500'
  86. }`}
  87. >
  88. 开始答题
  89. </button>
  90. </div>
  91. </div>
  92. );
  93. }
  94. export default ExamIndex;