ExamIndex.tsx 3.4 KB

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