@tinyweb_dev/oe-exam-sdk 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -4
- package/dist/api/contest-rooms.d.ts +13 -0
- package/dist/api/contest-rooms.js +1 -0
- package/dist/api/contest-rooms.types.d.ts +47 -0
- package/dist/api/contest-rooms.types.js +1 -0
- package/dist/api/exam-entry.d.ts +14 -0
- package/dist/api/exam-entry.js +1 -0
- package/dist/api/exam-entry.types.d.ts +93 -0
- package/dist/api/exam-entry.types.js +1 -0
- package/dist/api/exam-questions.d.ts +1 -1
- package/dist/api/exam-questions.js +1 -1
- package/dist/api/exam-questions.types.d.ts +45 -1
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +1 -1
- package/dist/components/exams/CompletionDialog.d.ts +8 -0
- package/dist/components/exams/CompletionDialog.js +1 -0
- package/dist/components/exams/CreateExamInfoForm.d.ts +4 -1
- package/dist/components/exams/CreateExamInfoForm.js +1 -1
- package/dist/components/exams/CreateExamPageContainer.d.ts +3 -0
- package/dist/components/exams/CreateExamPageContainer.js +1 -1
- package/dist/components/exams/ExamCreator.d.ts +9 -3
- package/dist/components/exams/ExamCreator.js +1 -1
- package/dist/components/exams/ExamPartTabs.d.ts +1 -1
- package/dist/components/exams/ExamPartTabs.js +1 -1
- package/dist/components/exams/ExamPreviewDialog.d.ts +20 -0
- package/dist/components/exams/ExamPreviewDialog.js +1 -0
- package/dist/components/exams/ExamQuestionGrid.d.ts +1 -1
- package/dist/components/exams/ExamQuestionGrid.js +1 -1
- package/dist/components/exams/ExamQuestionsPageContainer.d.ts +3 -0
- package/dist/components/exams/ExamQuestionsPageContainer.js +1 -1
- package/dist/components/exams/ExamViewDialog.d.ts +24 -0
- package/dist/components/exams/ExamViewDialog.js +1 -0
- package/dist/components/exams/TemplateSelector.js +1 -1
- package/dist/components/exams/UnsavedChangesDialog.d.ts +8 -0
- package/dist/components/exams/UnsavedChangesDialog.js +1 -0
- package/dist/components/exams/api.d.ts +1 -1
- package/dist/components/exams/create-exam.texts.d.ts +58 -0
- package/dist/components/exams/create-exam.texts.js +1 -0
- package/dist/components/exams/create-exam.validation.js +1 -1
- package/dist/components/exams/entry/EntryRestartDialog.d.ts +12 -0
- package/dist/components/exams/entry/EntryRestartDialog.js +1 -0
- package/dist/components/exams/entry/StudentExamEntryPageContainer.d.ts +31 -0
- package/dist/components/exams/entry/StudentExamEntryPageContainer.js +1 -0
- package/dist/components/exams/entry/exam-entry.states.d.ts +22 -0
- package/dist/components/exams/entry/exam-entry.states.js +1 -0
- package/dist/components/exams/entry/exam-entry.utils.d.ts +16 -0
- package/dist/components/exams/entry/exam-entry.utils.js +1 -0
- package/dist/components/exams/entry/fullscreen-loading.d.ts +5 -0
- package/dist/components/exams/entry/fullscreen-loading.js +1 -0
- package/dist/components/exams/entry/index.d.ts +7 -0
- package/dist/components/exams/entry/index.js +1 -0
- package/dist/components/exams/exam-question-status.d.ts +9 -0
- package/dist/components/exams/exam-question-status.js +1 -0
- package/dist/components/exams/index.d.ts +19 -1
- package/dist/components/exams/index.js +1 -1
- package/dist/components/exams/rooms/StudentContestRoomsPageContainer.d.ts +18 -0
- package/dist/components/exams/rooms/StudentContestRoomsPageContainer.js +1 -0
- package/dist/components/exams/rooms/contest-rooms.utils.d.ts +32 -0
- package/dist/components/exams/rooms/contest-rooms.utils.js +1 -0
- package/dist/components/exams/rooms/index.d.ts +3 -0
- package/dist/components/exams/rooms/index.js +1 -0
- package/dist/components/exams/take/ExamTakingApiContext.d.ts +10 -0
- package/dist/components/exams/take/ExamTakingApiContext.js +1 -0
- package/dist/components/exams/take/ExamTakingPageContainer.d.ts +28 -4
- package/dist/components/exams/take/ExamTakingPageContainer.js +1 -1
- package/dist/components/exams/take/components/QuestionRenderer.d.ts +25 -0
- package/dist/components/exams/take/components/QuestionRenderer.js +1 -0
- package/dist/components/exams/take/components/index.d.ts +10 -0
- package/dist/components/exams/take/components/index.js +1 -0
- package/dist/components/exams/take/components/question-renderers/ArticlesViewer.d.ts +7 -0
- package/dist/components/exams/take/components/question-renderers/ArticlesViewer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversAnswerTheQuestionRenderer.d.ts +22 -0
- package/dist/components/exams/take/components/question-renderers/MoversAnswerTheQuestionRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversChooseAdjectiveRenderer.d.ts +14 -0
- package/dist/components/exams/take/components/question-renderers/MoversChooseAdjectiveRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversChooseBestAnswerRenderer.d.ts +2 -0
- package/dist/components/exams/take/components/question-renderers/MoversChooseBestAnswerRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversColoringRenderer.d.ts +3 -0
- package/dist/components/exams/take/components/question-renderers/MoversColoringRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversFillWordHintRenderer.d.ts +2 -0
- package/dist/components/exams/take/components/question-renderers/MoversFillWordHintRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversGridFillRenderer.d.ts +2 -0
- package/dist/components/exams/take/components/question-renderers/MoversGridFillRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversLabelThePictureRenderer.d.ts +2 -0
- package/dist/components/exams/take/components/question-renderers/MoversLabelThePictureRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversListenAndWriteRenderer.d.ts +21 -0
- package/dist/components/exams/take/components/question-renderers/MoversListenAndWriteRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversMatchByWritingAnswerRenderer.d.ts +19 -0
- package/dist/components/exams/take/components/question-renderers/MoversMatchByWritingAnswerRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversPictureChooseRenderer.d.ts +2 -0
- package/dist/components/exams/take/components/question-renderers/MoversPictureChooseRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversPictureFillBlankChooseRenderer.d.ts +2 -0
- package/dist/components/exams/take/components/question-renderers/MoversPictureFillBlankChooseRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversReadingPassageRenderer.d.ts +2 -0
- package/dist/components/exams/take/components/question-renderers/MoversReadingPassageRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversTrueFalseRenderer.d.ts +20 -0
- package/dist/components/exams/take/components/question-renderers/MoversTrueFalseRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversWordFillParagraphRenderer.d.ts +32 -0
- package/dist/components/exams/take/components/question-renderers/MoversWordFillParagraphRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversWordFillStructuredFormRenderer.d.ts +18 -0
- package/dist/components/exams/take/components/question-renderers/MoversWordFillStructuredFormRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversWordOrderingRenderer.d.ts +19 -0
- package/dist/components/exams/take/components/question-renderers/MoversWordOrderingRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversWriteSentencesRenderer.d.ts +22 -0
- package/dist/components/exams/take/components/question-renderers/MoversWriteSentencesRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/MoversWritingRenderer.d.ts +18 -0
- package/dist/components/exams/take/components/question-renderers/MoversWritingRenderer.js +1 -0
- package/dist/components/exams/take/components/question-renderers/index.d.ts +19 -0
- package/dist/components/exams/take/components/question-renderers/index.js +1 -0
- package/dist/components/exams/take/components/speaking/FindObjectInPicture.module.css +133 -0
- package/dist/components/exams/take/components/speaking/SpeakingAudioPlayer.d.ts +9 -0
- package/dist/components/exams/take/components/speaking/SpeakingAudioPlayer.js +1 -0
- package/dist/components/exams/take/components/speaking/SpeakingCompareImages.module.css +153 -0
- package/dist/components/exams/take/components/speaking/SpeakingContentFrame.d.ts +7 -0
- package/dist/components/exams/take/components/speaking/SpeakingContentFrame.js +1 -0
- package/dist/components/exams/take/components/speaking/SpeakingDragObjects.module.css +238 -0
- package/dist/components/exams/take/components/speaking/SpeakingExamLayout.d.ts +27 -0
- package/dist/components/exams/take/components/speaking/SpeakingExamLayout.js +1 -0
- package/dist/components/exams/take/components/speaking/SpeakingHeader.d.ts +6 -0
- package/dist/components/exams/take/components/speaking/SpeakingHeader.js +1 -0
- package/dist/components/exams/take/components/speaking/SpeakingInfoExchange.module.css +193 -0
- package/dist/components/exams/take/components/speaking/SpeakingInfoExchangeSummerSky.module.css +238 -0
- package/dist/components/exams/take/components/speaking/SpeakingInstructionBar.d.ts +5 -0
- package/dist/components/exams/take/components/speaking/SpeakingInstructionBar.js +1 -0
- package/dist/components/exams/take/components/speaking/SpeakingMicButton.d.ts +14 -0
- package/dist/components/exams/take/components/speaking/SpeakingMicButton.js +1 -0
- package/dist/components/exams/take/components/speaking/SpeakingNavButton.d.ts +7 -0
- package/dist/components/exams/take/components/speaking/SpeakingNavButton.js +1 -0
- package/dist/components/exams/take/components/speaking/SpeakingPartBadge.d.ts +6 -0
- package/dist/components/exams/take/components/speaking/SpeakingPartBadge.js +1 -0
- package/dist/components/exams/take/components/speaking/SpeakingReadDisplayedContent.module.css +115 -0
- package/dist/components/exams/take/components/speaking/SpeakingRecordingPreview.d.ts +11 -0
- package/dist/components/exams/take/components/speaking/SpeakingRecordingPreview.js +1 -0
- package/dist/components/exams/take/components/speaking/SpeakingReportErrorButton.d.ts +1 -0
- package/dist/components/exams/take/components/speaking/SpeakingReportErrorButton.js +1 -0
- package/dist/components/exams/take/components/speaking/SpeakingStoryImages.module.css +231 -0
- package/dist/components/exams/take/components/speaking/SpeakingVideoIntro.d.ts +13 -0
- package/dist/components/exams/take/components/speaking/SpeakingVideoIntro.js +1 -0
- package/dist/components/exams/take/components/speaking/index.d.ts +1 -0
- package/dist/components/exams/take/components/speaking/index.js +1 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseAnswerGroupRenderer.d.ts +16 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseAnswerGroupRenderer.js +1 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseObjectsRenderer.d.ts +16 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingChooseObjectsRenderer.js +1 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingCompareImagesRenderer.d.ts +17 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingCompareImagesRenderer.js +1 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingConversationRenderer.d.ts +16 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingConversationRenderer.js +1 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingCueCardRenderer.d.ts +17 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingCueCardRenderer.js +1 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingDescribeImageRenderer.d.ts +18 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingDescribeImageRenderer.js +1 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingDragObjectsRenderer.d.ts +16 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingDragObjectsRenderer.js +1 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingGNInterviewRenderer.d.ts +16 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingGNInterviewRenderer.js +1 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingInfoExchangeRenderer.d.ts +16 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingInfoExchangeRenderer.js +1 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingListenAndSpeakAnswerRenderer.d.ts +16 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingListenAndSpeakAnswerRenderer.js +1 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingOddOneOutRenderer.d.ts +16 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingOddOneOutRenderer.js +1 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionListRenderer.d.ts +26 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionListRenderer.js +1 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionRenderer.d.ts +32 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingQuestionRenderer.js +1 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingReadDisplayedContentRenderer.d.ts +34 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingReadDisplayedContentRenderer.js +1 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingSpontaneousQARenderer.d.ts +17 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingSpontaneousQARenderer.js +1 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingStoryImagesRenderer.d.ts +17 -0
- package/dist/components/exams/take/components/speaking/renderers/SpeakingStoryImagesRenderer.js +1 -0
- package/dist/components/exams/take/components/speaking/renderers/index.d.ts +13 -0
- package/dist/components/exams/take/components/speaking/renderers/index.js +1 -0
- package/dist/components/exams/take/hooks/index.d.ts +2 -0
- package/dist/components/exams/take/hooks/index.js +1 -0
- package/dist/components/exams/take/hooks/useAnswerAutosave.d.ts +27 -0
- package/dist/components/exams/take/hooks/useAnswerAutosave.js +1 -0
- package/dist/components/exams/take/hooks/useAttemptSubmit.d.ts +29 -0
- package/dist/components/exams/take/hooks/useAttemptSubmit.js +1 -0
- package/dist/components/exams/take/hooks/useAutoSave.d.ts +20 -0
- package/dist/components/exams/take/hooks/useAutoSave.js +1 -0
- package/dist/components/exams/take/hooks/useExamCountdown.d.ts +22 -0
- package/dist/components/exams/take/hooks/useExamCountdown.js +1 -0
- package/dist/components/exams/take/hooks/useExamTimer.d.ts +21 -0
- package/dist/components/exams/take/hooks/useExamTimer.js +1 -0
- package/dist/components/exams/take/hooks/useProctoringCamera.d.ts +19 -0
- package/dist/components/exams/take/hooks/useProctoringCamera.js +1 -0
- package/dist/components/exams/take/hooks/useProctoringSnapshot.d.ts +25 -0
- package/dist/components/exams/take/hooks/useProctoringSnapshot.js +1 -0
- package/dist/components/exams/take/hooks/useSpeakingConversationAudio.d.ts +19 -0
- package/dist/components/exams/take/hooks/useSpeakingConversationAudio.js +1 -0
- package/dist/components/exams/take/hooks/useSpeakingNavigation.d.ts +37 -0
- package/dist/components/exams/take/hooks/useSpeakingNavigation.js +1 -0
- package/dist/components/exams/take/hooks/useSpeakingRecorder.d.ts +45 -5
- package/dist/components/exams/take/hooks/useSpeakingRecorder.js +1 -1
- package/dist/components/exams/take/hooks/useSpeakingRendererSetup.d.ts +39 -0
- package/dist/components/exams/take/hooks/useSpeakingRendererSetup.js +1 -0
- package/dist/components/exams/take/hooks/useToeicAudio.d.ts +17 -0
- package/dist/components/exams/take/hooks/useToeicAudio.js +1 -0
- package/dist/components/exams/take/index.d.ts +9 -1
- package/dist/components/exams/take/index.js +1 -1
- package/dist/components/exams/take/types/speaking-cue-card.types.d.ts +10 -0
- package/dist/components/exams/take/types/speaking-cue-card.types.js +1 -0
- package/dist/components/exams/take/types/speaking.types.d.ts +153 -0
- package/dist/components/exams/take/types/speaking.types.js +1 -0
- package/dist/components/exams/take/types.d.ts +286 -1
- package/dist/components/exams/take/utils/answer-transformers.d.ts +26 -0
- package/dist/components/exams/take/utils/answer-transformers.js +1 -0
- package/dist/components/exams/take/utils/coloring-assignments.d.ts +5 -0
- package/dist/components/exams/take/utils/coloring-assignments.js +1 -0
- package/dist/components/exams/take/utils/question-transformers.d.ts +362 -0
- package/dist/components/exams/take/utils/question-transformers.js +1 -0
- package/dist/components/features/exam-entry/entry-state-cards.d.ts +19 -0
- package/dist/components/features/exam-entry/entry-state-cards.js +1 -0
- package/dist/components/features/exam-entry/index.d.ts +2 -0
- package/dist/components/features/exam-entry/index.js +1 -0
- package/dist/components/features/exam-entry/themed/CambridgeYleWaitingRoom.d.ts +12 -0
- package/dist/components/features/exam-entry/themed/CambridgeYleWaitingRoom.js +1 -0
- package/dist/components/features/exam-entry/themed/ThemedWaitingRoom.d.ts +14 -0
- package/dist/components/features/exam-entry/themed/ThemedWaitingRoom.js +1 -0
- package/dist/components/features/exam-entry/themed/ToeicWaitingRoom.d.ts +16 -0
- package/dist/components/features/exam-entry/themed/ToeicWaitingRoom.js +1 -0
- package/dist/components/features/exam-entry/themed/components/CloseButton.d.ts +9 -0
- package/dist/components/features/exam-entry/themed/components/CloseButton.js +1 -0
- package/dist/components/features/exam-entry/themed/components/ExamInfoPanel.d.ts +13 -0
- package/dist/components/features/exam-entry/themed/components/ExamInfoPanel.js +1 -0
- package/dist/components/features/exam-entry/themed/components/ModeSelector.d.ts +7 -0
- package/dist/components/features/exam-entry/themed/components/ModeSelector.js +1 -0
- package/dist/components/features/exam-entry/themed/components/StartButton.d.ts +11 -0
- package/dist/components/features/exam-entry/themed/components/StartButton.js +1 -0
- package/dist/components/features/exam-entry/themed/components/index.d.ts +4 -0
- package/dist/components/features/exam-entry/themed/components/index.js +1 -0
- package/dist/components/features/exam-entry/themed/index.d.ts +1 -0
- package/dist/components/features/exam-entry/themed/index.js +1 -0
- package/dist/components/results/ResultReviewPageContainer.d.ts +3 -1
- package/dist/components/results/ResultReviewPageContainer.js +1 -1
- package/dist/components/results/hooks/useResultReviewPolling.d.ts +27 -0
- package/dist/components/results/hooks/useResultReviewPolling.js +1 -0
- package/dist/components/results/index.d.ts +3 -0
- package/dist/components/results/index.js +1 -1
- package/dist/components/results/review-status.utils.d.ts +12 -0
- package/dist/components/results/review-status.utils.js +1 -0
- package/dist/components/shared/audio/SpeakingAudioPlayer.d.ts +12 -0
- package/dist/components/shared/audio/SpeakingAudioPlayer.js +1 -0
- package/dist/components/shared/audio/SpeakingAudioPlayer.module.css +115 -0
- package/dist/components/shared/audio/assets/fr-image-part1-border.png +0 -0
- package/dist/components/shared/audio/assets/ic-speaker.webp +0 -0
- package/dist/components/themes/cambridge-yle/CambridgeYleTimer.js +1 -1
- package/dist/components/themes/english-certification/EnglishCertificationAudioPlayer.d.ts +11 -3
- package/dist/components/themes/english-certification/EnglishCertificationAudioPlayer.js +1 -1
- package/dist/components/themes/english-certification/EnglishCertificationQuestionRenderer.d.ts +5 -1
- package/dist/components/themes/english-certification/EnglishCertificationQuestionRenderer.js +1 -1
- package/dist/components/themes/index.d.ts +11 -0
- package/dist/components/themes/index.js +1 -1
- package/dist/components/themes/spaceship/SpaceshipAudioPlayer.d.ts +8 -0
- package/dist/components/themes/spaceship/SpaceshipAudioPlayer.js +1 -0
- package/dist/components/themes/spaceship/SpaceshipLayout.d.ts +2 -0
- package/dist/components/themes/spaceship/SpaceshipLayout.js +1 -0
- package/dist/components/themes/spaceship/assets/images/X-sunset.png +0 -0
- package/dist/components/themes/spaceship/assets/images/X.webp +0 -0
- package/dist/components/themes/spaceship/assets/images/audio-bar.webp +0 -0
- package/dist/components/themes/spaceship/assets/images/background.webp +0 -0
- package/dist/components/themes/spaceship/assets/images/bg_sunset.png +0 -0
- package/dist/components/themes/spaceship/assets/images/big-blue-badge-sunset.png +0 -0
- package/dist/components/themes/spaceship/assets/images/big-blue-badge.png +0 -0
- package/dist/components/themes/spaceship/assets/images/big-blue-badge.webp +0 -0
- package/dist/components/themes/spaceship/assets/images/bingo.webp +0 -0
- package/dist/components/themes/spaceship/assets/images/blue-badge-sunset.png +0 -0
- package/dist/components/themes/spaceship/assets/images/blue-badge.png +0 -0
- package/dist/components/themes/spaceship/assets/images/blue-wrapper-sunset.png +0 -0
- package/dist/components/themes/spaceship/assets/images/blue-wrapper.webp +0 -0
- package/dist/components/themes/spaceship/assets/images/board_red.png +0 -0
- package/dist/components/themes/spaceship/assets/images/button_feedback_vi.png +0 -0
- package/dist/components/themes/spaceship/assets/images/circle-btn-right-sunset.png +0 -0
- package/dist/components/themes/spaceship/assets/images/circle-btn-right.png +0 -0
- package/dist/components/themes/spaceship/assets/images/circle-btn-sunset.png +0 -0
- package/dist/components/themes/spaceship/assets/images/circle-btn.webp +0 -0
- package/dist/components/themes/spaceship/assets/images/focus-vector.webp +0 -0
- package/dist/components/themes/spaceship/assets/images/head-phone_red.png +0 -0
- package/dist/components/themes/spaceship/assets/images/ic-mute-sunset.png +0 -0
- package/dist/components/themes/spaceship/assets/images/ic-mute.png +0 -0
- package/dist/components/themes/spaceship/assets/images/ic-play-sunset.png +0 -0
- package/dist/components/themes/spaceship/assets/images/ic-play-violet.webp +0 -0
- package/dist/components/themes/spaceship/assets/images/ic-play.webp +0 -0
- package/dist/components/themes/spaceship/assets/images/micro.png +0 -0
- package/dist/components/themes/spaceship/assets/images/next-small.webp +0 -0
- package/dist/components/themes/spaceship/assets/images/next-sunset.png +0 -0
- package/dist/components/themes/spaceship/assets/images/next.webp +0 -0
- package/dist/components/themes/spaceship/assets/images/purple-circle.webp +0 -0
- package/dist/components/themes/spaceship/assets/images/question-badge-sunset.png +0 -0
- package/dist/components/themes/spaceship/assets/images/question-badge.webp +0 -0
- package/dist/components/themes/spaceship/assets/images/red-badge-sunset.png +0 -0
- package/dist/components/themes/spaceship/assets/images/red-badge.webp +0 -0
- package/dist/components/themes/spaceship/assets/images/red-wrapper-sunset.png +0 -0
- package/dist/components/themes/spaceship/assets/images/red-wrapper.webp +0 -0
- package/dist/components/themes/spaceship/assets/images/robot-avatar.png +0 -0
- package/dist/components/themes/spaceship/assets/images/sound_red.png +0 -0
- package/dist/components/themes/spaceship/assets/images/student-avatar.png +0 -0
- package/dist/components/themes/spaceship/assets/images/teacher-play-sunset.png +0 -0
- package/dist/components/themes/spaceship/assets/images/teacher-play.webp +0 -0
- package/dist/components/themes/spaceship/assets/images/timer-badge.png +0 -0
- package/dist/components/themes/spaceship/assets/styles/SpaceshipLayout.module.css +347 -0
- package/dist/components/themes/spaceship/assets/styles/SpaceshipWaitingRoom.module.css +395 -0
- package/dist/components/ui/badge.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/index.js +1 -1
- package/dist/shared/lib/stores/examTakingStore.d.ts +54 -0
- package/dist/shared/lib/stores/examTakingStore.js +1 -0
- package/dist/shared/lib/stores/gradingTransientStore.d.ts +23 -0
- package/dist/shared/lib/stores/gradingTransientStore.js +1 -0
- package/dist/shared/lib/themes/config/starters.config.d.ts +3 -0
- package/dist/shared/lib/themes/config/starters.config.js +1 -0
- package/dist/shared/lib/themes/index.d.ts +18 -0
- package/dist/shared/lib/themes/index.js +1 -0
- package/dist/shared/lib/themes/types.d.ts +39 -0
- package/dist/shared/lib/themes/types.js +1 -0
- package/dist/shared/lib/toast.d.ts +19 -0
- package/dist/shared/lib/toast.js +1 -0
- package/dist/shared/lib/utils/question-reverse-transform.d.ts +6 -0
- package/dist/shared/lib/utils/question-reverse-transform.js +1 -0
- package/dist/shared/lib/utils/question-transform-validation.d.ts +6 -0
- package/dist/shared/lib/utils/question-transform-validation.js +1 -0
- package/dist/shared/lib/utils/question-transform.d.ts +6 -2
- package/dist/shared/lib/utils/question-transform.js +1 -1
- package/package.json +19 -4
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Question Transformers - Transform API response to renderer props
|
|
3
|
+
*
|
|
4
|
+
* Maps backend question types to frontend renderer props.
|
|
5
|
+
* Each transformer handles specific question type data structure.
|
|
6
|
+
*/
|
|
7
|
+
import type { FillBlankQuestion, ChooseBestAnswerQuestion, PictureChooseSubQuestion, PictureFillBlankSubQuestion, ReadingPassageQuestion, LabelThePictureLabel, FillWordHintSubQuestion, ColoringHintItem, ColoringRegion } from '../types';
|
|
8
|
+
export type QuestionType = 'FILL_IN_BLANK' | 'WRITE_CORRECT_VERB_FORM' | 'CHOOSE_THE_CORRECT_ANSWER' | 'CHOOSE_CORRECT_ADJECTIVE' | 'WRITE_A_SHORT_LETTER' | 'READ_AND_COLOR_OBJECTS' | 'LOOK_PICTURE_CHOOSE_CORRECT_ANSWER' | 'LOOK_PICTURE_FILL_BLANK_CHOOSE_ANSWER' | 'READ_PASSAGE_AND_ANSWER_QUESTIONS' | 'LABEL_THE_PICTURE' | 'LOOK_PICTURE_FILL_WORD_HINT' | 'FILL_MISSING_WORDS_IN_GRID' | 'IMAGE_OBJECT_MATCHING' | 'ANSWER_THE_QUESTION' | 'TRUE_FALSE' | 'WORD_ORDERING' | 'WORD_FILL_PARAGRAPH' | 'MATCH_BY_WRITING_ANSWER' | 'WRITE_SENTENCES' | 'WORD_FILL_STRUCTURED_FORM' | 'LISTEN_AND_CHOOSE_OBJECTS_IN_SCENE' | 'LISTEN_AND_CHOOSE_FROM_ANSWER_GROUP' | 'LISTEN_AND_DRAG_OBJECTS_INTO_SCENE' | 'LISTEN_AND_SPEAK_ANSWER' | 'LISTEN_AND_SPEAK_COMPARE_IMAGES' | 'LISTEN_AND_SPEAK_WITH_STORY_IMAGES' | 'LISTEN_AND_SPEAK_IMAGE_GROUP' | 'LISTEN_AND_SPEAK_ODD_ONE_OUT' | 'LISTEN_AND_SPEAK_QUESTION_LIST' | 'LISTEN_AND_SPEAK_INFO_EXCHANGE' | 'READ_DISPLAYED_CONTENT' | 'SPEAKING_DESCRIBE_IMAGE' | 'SPONTANEOUS_QA' | 'SPEAKING_CONVERSATION' | 'GN_SPEAKING_INTERVIEW' | 'SPEAKING_CUE_CARD';
|
|
9
|
+
export interface ApiQuestion {
|
|
10
|
+
id: string;
|
|
11
|
+
content: any;
|
|
12
|
+
is_example: boolean;
|
|
13
|
+
total_points: string;
|
|
14
|
+
question_type: QuestionType;
|
|
15
|
+
explanation: string;
|
|
16
|
+
difficult_level: string;
|
|
17
|
+
question_skill_type: string;
|
|
18
|
+
exam_id: string;
|
|
19
|
+
part_id: string;
|
|
20
|
+
part_no: number;
|
|
21
|
+
question_number: number;
|
|
22
|
+
correct_answer?: any;
|
|
23
|
+
audio_url?: string;
|
|
24
|
+
group_id?: string;
|
|
25
|
+
questionGroup?: {
|
|
26
|
+
id: string;
|
|
27
|
+
payload: {
|
|
28
|
+
passage?: string;
|
|
29
|
+
passageTitle?: string;
|
|
30
|
+
passageImageUrl?: string;
|
|
31
|
+
mainImageUrl?: string;
|
|
32
|
+
instructions?: string;
|
|
33
|
+
hintLetters?: string[];
|
|
34
|
+
[key: string]: any;
|
|
35
|
+
};
|
|
36
|
+
} | null;
|
|
37
|
+
}
|
|
38
|
+
export interface QuestionPart {
|
|
39
|
+
partId: string;
|
|
40
|
+
partNo: number;
|
|
41
|
+
questionType: QuestionType;
|
|
42
|
+
questions: ApiQuestion[];
|
|
43
|
+
name?: string;
|
|
44
|
+
instructions?: string;
|
|
45
|
+
audioUrl?: string;
|
|
46
|
+
templateOrder?: number;
|
|
47
|
+
category?: string;
|
|
48
|
+
/** Section-level metadata carried from the template when a part is split by sections. */
|
|
49
|
+
sectionId?: number;
|
|
50
|
+
isGroup?: boolean;
|
|
51
|
+
optionMode?: string;
|
|
52
|
+
optionCount?: number;
|
|
53
|
+
viewMode?: string;
|
|
54
|
+
defaultValue?: string[];
|
|
55
|
+
multipleAnswers?: boolean;
|
|
56
|
+
questionConfig?: string[];
|
|
57
|
+
wordBankConfig?: string[];
|
|
58
|
+
group?: TemplateGroupConfig;
|
|
59
|
+
/** Section list kept whole for IELTS Reading parts (DOCUMENT passage + mixed sub-sections). */
|
|
60
|
+
sections?: TemplateSection[];
|
|
61
|
+
/** Zero-based exam-order start index of this part/section (for question numbering). */
|
|
62
|
+
startIndex?: number;
|
|
63
|
+
endIndex?: number;
|
|
64
|
+
}
|
|
65
|
+
/** Nested template group payload ({ items, config, type }) from the API template. */
|
|
66
|
+
export interface TemplateGroupConfig {
|
|
67
|
+
items?: Array<{
|
|
68
|
+
number: number;
|
|
69
|
+
questionCount: number;
|
|
70
|
+
}>;
|
|
71
|
+
config?: string[];
|
|
72
|
+
type?: string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Section within a template part (for parts with mixed question types)
|
|
76
|
+
* Used in Movers P8 (2 sections) and P11 (3 sections), and IELTS parts
|
|
77
|
+
* whose sections mix question types (e.g. SECTION 2 / Reading passages).
|
|
78
|
+
*/
|
|
79
|
+
export interface TemplateSection {
|
|
80
|
+
name?: string;
|
|
81
|
+
sectionId?: number;
|
|
82
|
+
startIndex: number;
|
|
83
|
+
endIndex: number;
|
|
84
|
+
questionType: QuestionType;
|
|
85
|
+
questionCount: number;
|
|
86
|
+
viewMode?: string;
|
|
87
|
+
instructions?: string;
|
|
88
|
+
isGroup?: boolean;
|
|
89
|
+
optionMode?: string;
|
|
90
|
+
optionCount?: number;
|
|
91
|
+
defaultValue?: string[];
|
|
92
|
+
multipleAnswers?: boolean;
|
|
93
|
+
questionConfig?: string[];
|
|
94
|
+
wordBankConfig?: string[];
|
|
95
|
+
group?: TemplateGroupConfig;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Template part structure from exam.template.parts
|
|
99
|
+
*/
|
|
100
|
+
export interface TemplatePart {
|
|
101
|
+
id: string | number;
|
|
102
|
+
name: string;
|
|
103
|
+
instructions?: string;
|
|
104
|
+
sections?: TemplateSection[];
|
|
105
|
+
audioUrl?: string;
|
|
106
|
+
category?: string;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Group questions by part_id AND questionGroup.id
|
|
110
|
+
* This ensures questions with different passages (different questionGroups)
|
|
111
|
+
* within the same part are properly separated.
|
|
112
|
+
*
|
|
113
|
+
* Handles template sections: parts with `sections` array are split into
|
|
114
|
+
* multiple QuestionPart entries with section-specific questionTypes.
|
|
115
|
+
* Used for Movers P8 (2 sections) and P11 (3 sections).
|
|
116
|
+
*
|
|
117
|
+
* @param questions - API questions to group
|
|
118
|
+
* @param templateParts - Optional template parts with name/instructions metadata
|
|
119
|
+
*/
|
|
120
|
+
export declare function groupQuestionsByPart(questions: ApiQuestion[], templateParts?: TemplatePart[]): QuestionPart[];
|
|
121
|
+
export declare function transformFillInBlank(questions: ApiQuestion[]): {
|
|
122
|
+
questions: FillBlankQuestion[];
|
|
123
|
+
title: string;
|
|
124
|
+
imageUrl?: string;
|
|
125
|
+
audioUrl?: string;
|
|
126
|
+
exampleText?: string;
|
|
127
|
+
exampleHighlight?: string;
|
|
128
|
+
instruction: string;
|
|
129
|
+
showHints?: boolean;
|
|
130
|
+
groupContent?: string;
|
|
131
|
+
groupTitle?: string;
|
|
132
|
+
groupImageUrl?: string;
|
|
133
|
+
};
|
|
134
|
+
export declare function transformWriteCorrectVerbForm(questions: ApiQuestion[]): {
|
|
135
|
+
questions: FillBlankQuestion[];
|
|
136
|
+
title: string;
|
|
137
|
+
instruction: string;
|
|
138
|
+
};
|
|
139
|
+
export declare function transformChooseCorrectAnswer(questions: ApiQuestion[]): {
|
|
140
|
+
questions: ChooseBestAnswerQuestion[];
|
|
141
|
+
example?: import('../types').ChooseBestAnswerExample;
|
|
142
|
+
imageUrl?: string;
|
|
143
|
+
groupImageUrl?: string;
|
|
144
|
+
groupTitle?: string;
|
|
145
|
+
groupContent?: string;
|
|
146
|
+
articles?: Array<{
|
|
147
|
+
name: string;
|
|
148
|
+
content: string;
|
|
149
|
+
imageUrl?: string;
|
|
150
|
+
}>;
|
|
151
|
+
audioUrl?: string;
|
|
152
|
+
instruction: string;
|
|
153
|
+
};
|
|
154
|
+
export interface ChooseAdjectiveOption {
|
|
155
|
+
id: string;
|
|
156
|
+
label: string;
|
|
157
|
+
text: string;
|
|
158
|
+
}
|
|
159
|
+
export interface ChooseAdjectiveQuestion {
|
|
160
|
+
id: string;
|
|
161
|
+
questionNumber: number;
|
|
162
|
+
sentenceBefore: string;
|
|
163
|
+
sentenceAfter: string;
|
|
164
|
+
options: ChooseAdjectiveOption[];
|
|
165
|
+
}
|
|
166
|
+
export declare function transformChooseCorrectAdjective(questions: ApiQuestion[]): {
|
|
167
|
+
questions: ChooseAdjectiveQuestion[];
|
|
168
|
+
instruction: string;
|
|
169
|
+
};
|
|
170
|
+
export declare function transformWriteShortLetter(question: ApiQuestion): {
|
|
171
|
+
prompt: string;
|
|
172
|
+
requirements?: string[];
|
|
173
|
+
minWords?: number;
|
|
174
|
+
maxWords?: number;
|
|
175
|
+
guideImages?: string[];
|
|
176
|
+
};
|
|
177
|
+
export declare function transformColorObjects(questions: ApiQuestion[]): {
|
|
178
|
+
instruction: string;
|
|
179
|
+
instructions?: string[];
|
|
180
|
+
imageUrl: string;
|
|
181
|
+
audioUrl?: string;
|
|
182
|
+
hintItems: ColoringHintItem[];
|
|
183
|
+
regions: ColoringRegion[];
|
|
184
|
+
};
|
|
185
|
+
export declare function transformPictureChoose(questions: ApiQuestion[]): {
|
|
186
|
+
subQuestions: PictureChooseSubQuestion[];
|
|
187
|
+
instruction: string;
|
|
188
|
+
};
|
|
189
|
+
export declare function transformPictureFillBlankChoose(questions: ApiQuestion[]): {
|
|
190
|
+
subQuestions: PictureFillBlankSubQuestion[];
|
|
191
|
+
instruction: string;
|
|
192
|
+
};
|
|
193
|
+
export declare function transformReadingPassage(questions: ApiQuestion[]): {
|
|
194
|
+
passage: string;
|
|
195
|
+
passageTitle?: string;
|
|
196
|
+
passageImageUrl?: string;
|
|
197
|
+
instruction: string;
|
|
198
|
+
questions: ReadingPassageQuestion[];
|
|
199
|
+
};
|
|
200
|
+
export declare function transformLabelPicture(questions: ApiQuestion[]): {
|
|
201
|
+
imageUrl: string;
|
|
202
|
+
wordBank: string[];
|
|
203
|
+
labels: LabelThePictureLabel[];
|
|
204
|
+
instruction: string;
|
|
205
|
+
};
|
|
206
|
+
export declare function transformFillWordHint(questions: ApiQuestion[]): {
|
|
207
|
+
subQuestions: FillWordHintSubQuestion[];
|
|
208
|
+
hintLetters: string[];
|
|
209
|
+
instruction: string;
|
|
210
|
+
};
|
|
211
|
+
export declare function transformGridFill(questions: ApiQuestion[]): {
|
|
212
|
+
grid: (string | null)[][];
|
|
213
|
+
rows: number;
|
|
214
|
+
columns: number;
|
|
215
|
+
instruction: string;
|
|
216
|
+
disabledCells: string[];
|
|
217
|
+
};
|
|
218
|
+
export interface AnswerTheQuestionQuestion {
|
|
219
|
+
id: string;
|
|
220
|
+
questionNumber: number;
|
|
221
|
+
question: string;
|
|
222
|
+
imageUrl?: string;
|
|
223
|
+
prefixText?: string;
|
|
224
|
+
suffixText?: string;
|
|
225
|
+
suggestedAnswers?: string[];
|
|
226
|
+
isExample: boolean;
|
|
227
|
+
exampleAnswer?: string;
|
|
228
|
+
}
|
|
229
|
+
export declare function transformAnswerTheQuestion(questions: ApiQuestion[]): {
|
|
230
|
+
questions: AnswerTheQuestionQuestion[];
|
|
231
|
+
instruction: string;
|
|
232
|
+
imageUrl?: string;
|
|
233
|
+
title?: string;
|
|
234
|
+
groupContent?: string;
|
|
235
|
+
};
|
|
236
|
+
export interface TrueFalseQuestion {
|
|
237
|
+
id: string;
|
|
238
|
+
questionNumber: number;
|
|
239
|
+
question: string;
|
|
240
|
+
imageUrl?: string;
|
|
241
|
+
isExample: boolean;
|
|
242
|
+
exampleCorrectAnswer?: boolean;
|
|
243
|
+
}
|
|
244
|
+
export declare function transformTrueFalse(questions: ApiQuestion[]): {
|
|
245
|
+
questions: TrueFalseQuestion[];
|
|
246
|
+
instruction: string;
|
|
247
|
+
imageUrl?: string;
|
|
248
|
+
groupContent?: string;
|
|
249
|
+
};
|
|
250
|
+
export interface WordOrderingQuestion {
|
|
251
|
+
id: string;
|
|
252
|
+
questionNumber: number;
|
|
253
|
+
words: string[];
|
|
254
|
+
imageUrl?: string;
|
|
255
|
+
isExample: boolean;
|
|
256
|
+
exampleAnswer?: string[];
|
|
257
|
+
}
|
|
258
|
+
export declare function transformWordOrdering(questions: ApiQuestion[]): {
|
|
259
|
+
questions: WordOrderingQuestion[];
|
|
260
|
+
instruction: string;
|
|
261
|
+
};
|
|
262
|
+
export declare function transformWordFillParagraph(questions: ApiQuestion[]): {
|
|
263
|
+
questionId: string;
|
|
264
|
+
paragraph: string;
|
|
265
|
+
title?: string;
|
|
266
|
+
imageUrl?: string;
|
|
267
|
+
wordBank: Array<{
|
|
268
|
+
word: string;
|
|
269
|
+
imageUrl?: string;
|
|
270
|
+
isExample?: boolean;
|
|
271
|
+
}>;
|
|
272
|
+
viewMode: 'WITH_WORD_BANK' | 'WITH_OPTIONS' | 'DEFAULT' | 'EMAIL';
|
|
273
|
+
instruction: string;
|
|
274
|
+
exampleAnswer?: string[];
|
|
275
|
+
emailFrom?: string;
|
|
276
|
+
emailTo?: string;
|
|
277
|
+
};
|
|
278
|
+
export interface MatchByWritingAnswerQuestion {
|
|
279
|
+
id: string;
|
|
280
|
+
questionNumber: number;
|
|
281
|
+
question: string;
|
|
282
|
+
imageUrl?: string;
|
|
283
|
+
isExample: boolean;
|
|
284
|
+
exampleAnswer?: string;
|
|
285
|
+
askerName?: string;
|
|
286
|
+
answererName?: string;
|
|
287
|
+
}
|
|
288
|
+
export interface MatchByWritingAnswerOption {
|
|
289
|
+
answer: string;
|
|
290
|
+
imageUrl: string;
|
|
291
|
+
content?: string;
|
|
292
|
+
}
|
|
293
|
+
export declare function transformMatchByWritingAnswer(questions: ApiQuestion[]): {
|
|
294
|
+
questions: MatchByWritingAnswerQuestion[];
|
|
295
|
+
options: MatchByWritingAnswerOption[];
|
|
296
|
+
instruction: string;
|
|
297
|
+
viewMode: 'DEFAULT' | 'CONVERSATION';
|
|
298
|
+
groupImageUrl?: string;
|
|
299
|
+
askerName?: string;
|
|
300
|
+
answererName?: string;
|
|
301
|
+
};
|
|
302
|
+
export declare function transformWriteSentences(questions: ApiQuestion[]): {
|
|
303
|
+
questions: Array<{
|
|
304
|
+
id: string;
|
|
305
|
+
questionNumber: number;
|
|
306
|
+
}>;
|
|
307
|
+
instruction: string;
|
|
308
|
+
imageUrl?: string;
|
|
309
|
+
title?: string;
|
|
310
|
+
groupContent?: string;
|
|
311
|
+
};
|
|
312
|
+
export interface WordFillStructuredFormQuestion {
|
|
313
|
+
id: string;
|
|
314
|
+
questionNumber: number;
|
|
315
|
+
title: string;
|
|
316
|
+
imageUrl?: string;
|
|
317
|
+
content: string;
|
|
318
|
+
answers: Record<string, string>;
|
|
319
|
+
caseSensitive: boolean;
|
|
320
|
+
}
|
|
321
|
+
export declare function transformWordFillStructuredForm(questions: ApiQuestion[]): {
|
|
322
|
+
questions: WordFillStructuredFormQuestion[];
|
|
323
|
+
instruction: string;
|
|
324
|
+
groupTitle?: string;
|
|
325
|
+
groupContent?: string;
|
|
326
|
+
groupImageUrl?: string;
|
|
327
|
+
audioUrl?: string;
|
|
328
|
+
};
|
|
329
|
+
export interface SceneObjectNode {
|
|
330
|
+
id: string;
|
|
331
|
+
imageUrl: string;
|
|
332
|
+
label: string;
|
|
333
|
+
x: number;
|
|
334
|
+
y: number;
|
|
335
|
+
width: number;
|
|
336
|
+
height: number;
|
|
337
|
+
}
|
|
338
|
+
export declare function transformListenChooseObjects(questions: ApiQuestion[]): {
|
|
339
|
+
audioUrl: string;
|
|
340
|
+
backgroundImageUrl: string;
|
|
341
|
+
objectNodes: SceneObjectNode[];
|
|
342
|
+
correctObjectId: string;
|
|
343
|
+
isBackup: boolean;
|
|
344
|
+
instruction: string;
|
|
345
|
+
};
|
|
346
|
+
export interface ListenSpeakAnswerArrowNode {
|
|
347
|
+
x: number;
|
|
348
|
+
y: number;
|
|
349
|
+
width: number;
|
|
350
|
+
height: number;
|
|
351
|
+
}
|
|
352
|
+
export declare function transformListenSpeakAnswer(questions: ApiQuestion[]): {
|
|
353
|
+
questions: Array<{
|
|
354
|
+
id: string;
|
|
355
|
+
questionNumber: number;
|
|
356
|
+
audioUrl: string;
|
|
357
|
+
arrowNode?: ListenSpeakAnswerArrowNode;
|
|
358
|
+
backgroundImageUrl: string;
|
|
359
|
+
isBackup: boolean;
|
|
360
|
+
}>;
|
|
361
|
+
instruction: string;
|
|
362
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function groupQuestionsByPart(e,t){const n=new Map,o=new Map;for(const t of e){const e=o.get(t.part_id)||[];e.push(t),o.set(t.part_id,e)}for(const[e,r]of o.entries()){const o=[...r].sort((e,t)=>e.question_number-t.question_number),i=o[0];if(!i)continue;const s=t?.find(t=>String(t.id)===String(e)),a=void 0!==s?.id?Number(s.id):void 0,u=s?.name?.match(/\d+/),c=u?parseInt(u[0],10):i.part_no,l=s?.group,m=Boolean(s?.isGroup)&&"DOCUMENT"===l?.type,p=s?.sections??[],d=new Set(p.map(e=>e.questionType).filter(Boolean)),g=p.length>1&&d.size>1;if(m||g){const t=`${e}_part`;n.set(t,{partId:e,partNo:c,questionType:i.question_type,questions:o,name:s?.name,instructions:s?.instructions,audioUrl:s?.audioUrl,templateOrder:a,category:s?.category,isGroup:!0,group:l,sections:s?.sections,startIndex:s?.startIndex,endIndex:s?.endIndex});continue}if(!s?.sections?.length){const t=`${e}_part`;n.set(t,{partId:e,partNo:c,questionType:i.question_type,questions:o,name:s?.name,instructions:s?.instructions,audioUrl:s?.audioUrl,templateOrder:a,category:s?.category,isGroup:s?.isGroup,optionMode:s?.optionMode,optionCount:s?.optionCount,viewMode:s?.viewMode,defaultValue:s?.defaultValue,multipleAnswers:s?.multipleAnswers,questionConfig:s?.questionConfig,wordBankConfig:s?.wordBankConfig,group:s?.group,startIndex:s?.startIndex,endIndex:s?.endIndex});continue}for(const[t,r]of s.sections.entries()){const i=o.filter(e=>{const t=e.question_number-1;return t>=r.startIndex&&t<=r.endIndex});if(!i.length)continue;const u=`${e}_section_${t}`,l=Boolean(r.isGroup||r.group?.type);n.set(u,{partId:e,partNo:c,questionType:r.questionType||i[0].question_type,questions:i,name:s.name,instructions:r.instructions||r.name||s.instructions,audioUrl:s.audioUrl,templateOrder:a,category:s.category,sectionId:r.sectionId,isGroup:l,optionMode:r.optionMode,optionCount:r.optionCount,viewMode:r.viewMode,defaultValue:r.defaultValue,multipleAnswers:r.multipleAnswers,questionConfig:r.questionConfig,wordBankConfig:r.wordBankConfig,group:r.group,startIndex:r.startIndex,endIndex:r.endIndex})}}return Array.from(n.values()).sort((e,t)=>{const n=void 0===e.templateOrder||isNaN(e.templateOrder)?1/0:e.templateOrder,o=void 0===t.templateOrder||isNaN(t.templateOrder)?1/0:t.templateOrder;return n!==o?n-o:(e.questions[0]?.question_number||0)-(t.questions[0]?.question_number||0)})}export function transformFillInBlank(e){const t=e[0],n=t?.content,o=t?.questionGroup?.payload,r=[];for(const t of e){const e=t.content,n=t.is_example||!1,o=e.question||e.blanks?.[0]?.text||"";if([...o.matchAll(/\{(\d+)\}/g)].length>1){const i=o.split("\n").filter(e=>e.trim());for(const o of i){const i=o.match(/\{(\d+)\}/);if(!i)continue;const s=parseInt(i[1],10),a=o.split(/\{\d+\}/),u=a[0]?.trim()||"",c=a[1]?.trim()||"";r.push({id:`${t.id}-blank-${s}`,questionNumber:t.question_number,textBefore:u,textAfter:c,imageUrl:e.imageUrl,hints:e.hints,isExample:n,correctAnswer:n?t.correct_answer?.answers?.[s]:void 0})}}else{const i=o.match(/^(.*?)\{0\}(.*)$/),s=i?i[1].trim():o,a=i?i[2].trim():"";r.push({id:t.id,questionNumber:t.question_number,textBefore:s,textAfter:a,imageUrl:e.imageUrl,hints:e.hints,isExample:n,correctAnswer:n?t.correct_answer?.answers?.[0]:void 0})}}return{questions:r,title:n?.title||o?.title||"FILL IN THE BLANK",imageUrl:n?.imageUrl,audioUrl:n?.audioUrl,exampleText:n?.exampleText,exampleHighlight:n?.exampleHighlight,instruction:n?.instruction||"LISTEN AND WRITE",showHints:n?.showHints,groupContent:o?.content||o?.groupContent,groupTitle:o?.title,groupImageUrl:o?.mainImageUrl||o?.imageUrl}}export function transformWriteCorrectVerbForm(e){const t=e[0],n=t?.content;return{questions:e.map(e=>{const t=e.content,n=t.sentence||"",o=n.match(/^(.*?)\{0\}(.*)$/),r=o?o[1].trim():n,i=o?o[2].trim():"";return{id:e.id,questionNumber:e.question_number,textBefore:r,textAfter:i,verbHint:t.verbHint}}),title:"WRITE THE CORRECT VERB FORM",instruction:n?.instruction||"Write the correct form of the verb in parentheses."}}const e=["A","B","C","D","E","F"];export function transformChooseCorrectAnswer(t){const n=t[0]?.content,o=t[0]?.questionGroup?.payload,r=t.find(e=>e.is_example),i=t.filter(e=>!e.is_example);let s;if(r){const t=r.content,n=(t.options||[]).map((t,n)=>({id:`${r.id}-opt-${n}`,label:e[n]||String(n+1),text:t})),o="number"==typeof r.correct_answer?.answer?r.correct_answer.answer:-1;s={questionNumber:r.question_number,questionText:t.question||"",options:n,correctOptionId:o>=0?n[o]?.id||"":n[0]?.id||"",optionType:t.optionType||"text",imageUrl:t.imageUrl}}return{questions:i.map(t=>{const n=t.content,o=n.optionType||"text",r=(n.options||[]).map((n,o)=>({id:`${t.id}-opt-${o}`,label:e[o]||String(o+1),text:n})),i=t.correct_answer?.answer,s=Array.isArray(i)?i.filter(e=>"number"==typeof e).map(e=>r[e]?.id).filter(e=>Boolean(e)):"number"==typeof i?[r[i]?.id].filter(e=>Boolean(e)):[];return{id:t.id,questionNumber:t.question_number,questionText:n.question||"",options:r,correctOptionId:s[0],correctOptionIds:s,imageUrl:n.imageUrl,optionType:o,multipleAnswers:Boolean(n.multipleAnswers||Array.isArray(i)),explanation:t.explanation}}),example:s,imageUrl:n?.imageUrl,groupImageUrl:o?.mainImageUrl||o?.imageUrl,groupTitle:o?.title,groupContent:o?.content,articles:o?.articles,audioUrl:n?.audioUrl,instruction:n?.instruction||"CHOOSE THE CORRECT ANSWER"}}export function transformChooseCorrectAdjective(t){return{questions:t.map(t=>{const n=t.content,o=n.sentence||"",r=o.match(/^(.*?)\{0\}(.*)$/),i=r?r[1]:o,s=r?r[2]:"";return{id:t.id,questionNumber:t.question_number,sentenceBefore:i,sentenceAfter:s,options:(n.options||[]).map((n,o)=>({id:`${t.id}-opt-${o}`,label:e[o]||String(o+1),text:n}))}}),instruction:"CHOOSE THE CORRECT ADJECTIVE"}}export function transformWriteShortLetter(e){const t=e.content;if(t.instructions?.mainInstruction||t.informations?.length)return{prompt:t.instructions?.mainInstruction||"",requirements:t.informations,minWords:t.minWords,maxWords:t.maxWords,guideImages:t.guideImages};return{prompt:t.contexts?.filter(e=>"text"===e.type).map(e=>e.text).join("\n")||"",minWords:t.minWords,maxWords:t.maxWords,guideImages:t.guideImages}}export function transformColorObjects(e){const t=e[0],n=t?.content,o=n?.colorNodes?.map(e=>({id:e.id,color:e.color,label:e.label}))||n?.hintItems||[],r=n?.regionNodes?.map(e=>({id:e.id,x:e.x,y:e.y,width:e.width,height:e.height,correctHintId:e.linkedColorNodeId}))||n?.regions||[],i=n?.instructions;return{instruction:(i&&i.length>0?i.join(" "):n?.instruction)||"READ AND COLOR THE OBJECTS",instructions:i,imageUrl:n?.backgroundImageUrl||n?.imageUrl||"",audioUrl:n?.audioUrl,hintItems:o,regions:r}}export function transformPictureChoose(t){const n=t[0]?.content;return{subQuestions:t.map(t=>{const n=t.content;return{id:t.id,questionNumber:t.question_number,imageUrl:n.imageUrl||"",questionText:n.questionText,options:(n.options||[]).map((n,o)=>({id:n.id||`${t.id}-opt-${o}`,label:e[o]||String(o+1),text:"string"==typeof n?n:n.text}))}}),instruction:n?.instruction||"LOOK AT THE PICTURE AND CHOOSE THE CORRECT ANSWER"}}export function transformPictureFillBlankChoose(t){const n=t[0]?.content;return{subQuestions:t.map(t=>{const n=t.content;return{id:t.id,questionNumber:t.question_number,imageUrl:n.imageUrl||"",question:n.question||"",options:(n.options||[]).map((n,o)=>({id:n.id||`${t.id}-opt-${o}`,label:e[o]||String(o+1),text:"string"==typeof n?n:n.text}))}}),instruction:n?.instruction||"LOOK AT THE PICTURE, FILL IN THE BLANK AND CHOOSE THE ANSWER"}}export function transformReadingPassage(t){if(function(e){const t=e[0];if(!t)return!1;const n=t.content;return void 0!==n?.question&&!n?.questions&&void 0!==t.questionGroup?.payload?.passage}(t)){const n=t[0],o=n.questionGroup?.payload||{},r=t.map(t=>{const n=t.content;return{id:t.id,questionNumber:t.question_number,questionText:n?.question||"",options:(n?.options||[]).map((n,o)=>({id:`${t.id}-opt-${o}`,label:e[o]||String(o+1),text:"string"==typeof n?n:String(n)}))}});return{passage:o.passage||"",passageTitle:o.passageTitle,passageImageUrl:o.passageImageUrl||o.mainImageUrl,instruction:o.instructions||"READ THE PASSAGE AND ANSWER QUESTIONS",questions:r}}const n=t[0],o=n?.content,r=o?.questions?.map((t,o)=>({id:t.id||`${n.id}-sq-${o}`,questionNumber:o+1,questionText:t.question,options:(t.options||[]).map((o,r)=>({id:`${t.id||n.id}-opt-${r}`,label:e[r]||String(r+1),text:o}))}))||[];return{passage:o?.passage||"",passageTitle:o?.passageTitle,passageImageUrl:o?.passageImageUrl||o?.mainImageUrl,instruction:o?.instructions?.mainInstruction||"READ THE PASSAGE AND ANSWER QUESTIONS",questions:r}}export function transformLabelPicture(e){const t=e[0],n=t?.content;return{imageUrl:n?.imageUrl||"",wordBank:n?.wordBank||[],labels:n?.labels?.map(e=>({id:e.id,number:e.number,isPreFilled:e.isPreFilled||!1,correctAnswer:e.correctAnswer}))||[],instruction:n?.instruction||"LABEL THE PICTURE"}}function t(e){return e&&"string"==typeof e.word&&!e.subQuestions}export function transformFillWordHint(e){const n=e[0],o=n?.content;if(e.length>1&&e.every(e=>t(e.content))){const t=n.questionGroup?.payload?.hintLetters||[];return{subQuestions:e.map(e=>{const t=e.content,n=t.word.replace(/\{\d+\}/,"_");return{id:e.id,questionNumber:e.question_number,imageUrl:t.imageUrl||"",word:n}}),hintLetters:t,instruction:o?.instruction||"LOOK AT THE PICTURE AND FILL IN THE MISSING LETTER"}}if(t(o)){const e=o,t=n.questionGroup?.payload?.hintLetters||[];return{subQuestions:function(e){const t=[],n=e.split(",").map(e=>e.trim());for(const e of n){let n;const o=/\{(\d+)\}/g;for(;null!==(n=o.exec(e));){const o=parseInt(n[1],10),r=e.replace(n[0],"_");t.push({index:o,displayWord:r})}}return t.sort((e,t)=>e.index-t.index),t}(e.word).map(t=>({id:`${n.id}-blank-${t.index}`,questionNumber:n.question_number,imageUrl:e.imageUrl||"",word:t.displayWord,blankIndex:t.index})),hintLetters:t,instruction:e.instruction||"LOOK AT THE PICTURE AND FILL IN THE MISSING LETTER"}}const r=o;return{subQuestions:r?.subQuestions?.map((e,t)=>({id:e.id,questionNumber:n.question_number+t,imageUrl:e.imageUrl||"",word:e.word||""}))||[],hintLetters:r?.hintLetters||n.questionGroup?.payload?.hintLetters||[],instruction:r?.instruction||"LOOK AT THE PICTURE AND FILL IN THE MISSING LETTER"}}export function transformGridFill(e){const t=e[0],n=t?.content;return{grid:n?.grid||[],rows:n?.rows||0,columns:n?.columns||0,instruction:n?.instruction||"FILL IN THE MISSING WORDS",disabledCells:n?.disabledCells||[]}}export function transformAnswerTheQuestion(e){const t=e[0],n=t?.questionGroup?.payload,o=t?.content;return{questions:e.map(e=>{const t=e.content,n=e.is_example||t.isExample||!1;return{id:e.id,questionNumber:e.question_number,question:(t.question||"").replace(/\{\d+\}/g,"______"),imageUrl:t.imageUrl,prefixText:t.prefixText,suffixText:t.suffixText,suggestedAnswers:t.suggestedAnswers,isExample:n,exampleAnswer:n?e.correct_answer?.answer:void 0}}),instruction:"ANSWER THE QUESTION",imageUrl:n?.mainImageUrl||n?.imageUrl||o?.imageUrl,title:o?.title,groupContent:n?.groupContent||o?.groupContent}}export function transformTrueFalse(e){const t=e[0]?.questionGroup?.payload;return{questions:e.map(e=>{const t=e.content,n=e.is_example||t.isExample||!1,o=n&&"boolean"==typeof e.correct_answer?.answer?e.correct_answer.answer:void 0;return{id:e.id,questionNumber:e.question_number,question:t.question||"",imageUrl:t.imageUrl,isExample:n,exampleCorrectAnswer:o}}),instruction:"READ AND CHOOSE TRUE OR FALSE",imageUrl:t?.mainImageUrl||t?.imageUrl,groupContent:t?.content||t?.groupContent}}export function transformWordOrdering(e){return{questions:e.map(e=>{const t=e.content,n=e.is_example||t.isExample||!1,o=Array.isArray(e.correct_answer?.answer)?e.correct_answer.answer:Array.isArray(t.answer)?t.answer:void 0;return{id:e.id,questionNumber:e.question_number,words:t.words||[],imageUrl:t.imageUrl,isExample:n,exampleAnswer:n?o:void 0}}),instruction:"ARRANGE THE LETTERS TO MAKE A WORD"}}export function transformWordFillParagraph(e){const t=e[0],n=t?.questionGroup?.payload,o=t?.content,r=o?.title||n?.title||e.find(e=>e.content?.title)?.content?.title,i=o?.wordBank||[],s=i.map(e=>"string"==typeof e?{word:e}:e),a=o?.viewMode,u=void 0!==o?.wordBank?.[0]?.options;let c;c="EMAIL"===a?"EMAIL":a||!o?.emailFrom&&!o?.emailTo?"DEFAULT"===a?"DEFAULT":"WITH_OPTIONS"===a||u?"WITH_OPTIONS":a||0!==i.length?"WITH_WORD_BANK":"DEFAULT":"EMAIL";const l=o?.emailFrom||o?.metadata?.emailFrom,m=o?.emailTo||o?.metadata?.emailTo;return{questionId:t?.id||"",paragraph:o?.paragraph||"",title:r,imageUrl:o?.imageUrl,wordBank:s,viewMode:c,instruction:"READ AND FILL IN THE BLANKS",exampleAnswer:o?.exampleAnswer,emailFrom:l,emailTo:m}}export function transformMatchByWritingAnswer(e){const t=e[0]?.questionGroup?.payload,n=e.some(e=>!!e.content?.askerName),o=e.map(e=>{const t=e.content,n=e.is_example||t.isExample||!1;return{id:e.id,questionNumber:e.question_number,question:t.question||"",imageUrl:t.imageUrl,isExample:n,exampleAnswer:n?e.correct_answer?.answer:void 0,askerName:t.askerName,answererName:t.answererName}}),r=t?.options?.map(e=>({answer:e.answer,imageUrl:e.imageUrl||"",content:e.content||""}))||[],i=n?e[0]?.content:void 0;return{questions:o,options:r,instruction:"LOOK AND WRITE THE ANSWER",viewMode:n?"CONVERSATION":"DEFAULT",groupImageUrl:t?.groupImageUrl||"",askerName:i?.askerName,answererName:i?.answererName}}export function transformWriteSentences(e){const t=e[0],n=t?.content,o=t?.questionGroup?.payload;return{questions:e.map(e=>({id:e.id,questionNumber:e.question_number})),instruction:n?.instruction||"WRITE SENTENCES ABOUT THE PICTURE",imageUrl:o?.mainImageUrl||o?.imageUrl||n?.imageUrl,title:n?.title,groupContent:o?.groupContent||n?.groupContent}}export function transformWordFillStructuredForm(e){const t=e[0],n=t?.questionGroup?.payload;return{questions:e.map(e=>{const t=e.content,n=e.correct_answer||{};let o=t?.content||"";const r=t?.blocks;return!o&&r?.length&&(o=r.map(e=>(e.heading?`<h3>${e.heading}</h3>`:"")+(e.content||"")).join("")),{id:e.id,questionNumber:e.question_number,title:t?.title||"",imageUrl:t?.imageUrl,content:o,answers:n?.answers||{},caseSensitive:n?.caseSensitive??t?.caseSensitive??!1}}),instruction:n?.instructions||"COMPLETE THE FORM BELOW",groupTitle:n?.title,groupContent:n?.content,groupImageUrl:n?.imageUrl,audioUrl:t?.audio_url||n?.audioUrl}}export function transformListenChooseObjects(e){const t=e[0],n=t?.content,o=t?.questionGroup?.payload||{};return{audioUrl:n?.audioUrl||"",backgroundImageUrl:o.backgroundImageUrl||"",objectNodes:o.objectNodes||[],correctObjectId:t?.correctAnswer?.objectId||t?.correct_answer?.objectId||"",isBackup:n?.isBackup||!1,instruction:"LISTEN AND CHOOSE THE CORRECT OBJECT"}}export function transformListenSpeakAnswer(e){return{questions:e.map(e=>{const t=e.content,n=e.questionGroup?.payload||{};return{id:e.id,questionNumber:e.question_number,audioUrl:t?.audioUrl||"",arrowNode:t?.arrowNode,backgroundImageUrl:n.backgroundImageUrl||n.imageUrl||"",isBackup:t?.isBackup||!1}}),instruction:"LISTEN AND SPEAK YOUR ANSWER"}}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Attempt } from '../../../shared/types/student.types';
|
|
2
|
+
interface BeforeStartCardProps {
|
|
3
|
+
countdown: number;
|
|
4
|
+
formatCountdown: (seconds: number) => string;
|
|
5
|
+
}
|
|
6
|
+
export declare function BeforeStartCard({ countdown, formatCountdown }: BeforeStartCardProps): import("react").JSX.Element;
|
|
7
|
+
interface WithinWindowCardProps {
|
|
8
|
+
autoStartCountdown: number;
|
|
9
|
+
isStarting: boolean;
|
|
10
|
+
showCountdown: boolean;
|
|
11
|
+
onStartClick: () => void;
|
|
12
|
+
}
|
|
13
|
+
export declare function WithinWindowCard({ autoStartCountdown, isStarting, showCountdown, onStartClick, }: WithinWindowCardProps): import("react").JSX.Element;
|
|
14
|
+
export declare function ExpiredCard(): import("react").JSX.Element;
|
|
15
|
+
interface AlreadySubmittedCardProps {
|
|
16
|
+
attempt?: Attempt | null;
|
|
17
|
+
}
|
|
18
|
+
export declare function AlreadySubmittedCard({ attempt }: AlreadySubmittedCardProps): import("react").JSX.Element;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{ROUTES as n}from"../../../shared/constants/routes";import{Clock as r,CheckCircle as i,XCircle as l,Loader2 as a,Play as s,Trophy as c}from"lucide-react";export function BeforeStartCard({countdown:n,formatCountdown:i}){return t("div",{className:"flex flex-col items-center justify-center rounded-2xl bg-black/20 px-6 py-8 text-center ring-1 ring-white/10 backdrop-blur-sm",children:[e(r,{className:"mb-3 h-10 w-10 text-amber-400"}),e("h2",{className:"mb-1 text-xl font-extrabold text-white",children:"Chưa đến giờ thi"}),e("p",{className:"mb-4 text-sm font-medium text-white/80",children:"Bài thi sẽ bắt đầu sau:"}),e("div",{className:"rounded-xl bg-black/30 px-6 py-3 ring-1 ring-white/5",children:e("p",{className:"font-mono text-2xl font-extrabold tracking-wider text-amber-300",children:i(n)})})]})}export function WithinWindowCard({autoStartCountdown:n,isStarting:r,showCountdown:i,onStartClick:l}){return t("div",i?{className:"flex flex-col items-center justify-center rounded-2xl bg-black/20 px-6 py-8 text-center ring-1 ring-white/10 backdrop-blur-sm",children:[e("h2",{className:"mb-4 text-xl font-extrabold text-white",children:"Chuẩn bị vào thi"}),e("div",{className:"flex h-16 w-16 items-center justify-center rounded-full bg-emerald-500/20 ring-2 ring-emerald-400/50",children:e("span",{className:"text-3xl font-extrabold text-emerald-300",children:n})}),t("p",{className:"mt-4 text-sm font-medium text-white/80",children:["Bài thi sẽ tự động bắt đầu sau ",n," giây"]}),r&&t("div",{className:"mt-3 flex items-center gap-2 text-sm font-medium text-emerald-300",children:[e(a,{className:"h-4 w-4 animate-spin"}),e("span",{children:"Đang bắt đầu bài thi..."})]})]}:{className:"flex flex-col items-center justify-center rounded-2xl bg-black/20 px-6 py-8 text-center ring-1 ring-white/10 backdrop-blur-sm",children:[e("h2",{className:"mb-6 text-xl font-extrabold text-white",children:"Sẵn sàng vào thi"}),e("button",{onClick:l,className:"group flex h-20 w-20 cursor-pointer items-center justify-center rounded-full bg-emerald-500 shadow-lg ring-4 ring-emerald-500/30 transition-all duration-200 hover:scale-105 hover:bg-emerald-400 active:scale-95",children:e(s,{className:"h-8 w-8 text-white transition-transform group-hover:scale-110",fill:"white"})}),e("p",{className:"mt-5 text-sm font-medium text-white/80",children:"Nhấn nút trên để bắt đầu bài thi"})]})}export function ExpiredCard(){return t("div",{className:"flex flex-col items-center justify-center rounded-2xl bg-black/20 px-6 py-8 text-center ring-1 ring-white/10 backdrop-blur-sm",children:[e(l,{className:"mb-3 h-10 w-10 text-red-400"}),e("h2",{className:"text-xl font-extrabold text-white",children:"Đã hết thời gian"}),e("p",{className:"mt-2 text-sm font-medium text-white/80",children:"Thời gian làm bài đã kết thúc"})]})}export function AlreadySubmittedCard({attempt:r}){return t("div",{className:"flex flex-col items-center justify-center rounded-2xl bg-black/20 px-6 py-8 text-center ring-1 ring-white/10 backdrop-blur-sm",children:[e(i,{className:"mb-3 h-10 w-10 text-emerald-400"}),e("h2",{className:"mb-4 text-xl font-extrabold text-white",children:"Đã hoàn thành bài thi"}),null!=r?.totalScore&&t("div",{className:"mb-5 flex items-center gap-3 rounded-xl bg-black/30 px-5 py-3 ring-1 ring-white/5",children:[e(c,{className:"h-5 w-5 text-yellow-400"}),e("span",{className:"text-sm font-semibold text-white/90",children:"Điểm số:"}),t("span",{className:"text-xl font-extrabold text-yellow-400",children:[r.totalScore,t("span",{className:"text-sm font-bold text-white/50",children:["/",r.maxScore]})]})]}),r?e("button",{className:"inline-flex cursor-pointer items-center gap-2 rounded-full bg-emerald-600 px-6 py-2.5 text-sm font-bold text-white shadow-lg transition-all duration-200 hover:-translate-y-0.5 hover:bg-emerald-500 active:translate-y-0 active:scale-95",onClick:()=>window.location.href=n.STUDENT.RESULT_DETAIL(r.id),children:"Xem chi tiết kết quả"}):e("p",{className:"text-sm font-medium text-white/80",children:"Phòng thi này không cho phép thi nhiều lần."})]})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{ThemedWaitingRoom}from"./themed";export{BeforeStartCard,WithinWindowCard,ExpiredCard,AlreadySubmittedCard}from"./entry-state-cards";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { StudentRoom } from '../../../../shared/types/student.types';
|
|
2
|
+
interface CambridgeYleWaitingRoomProps {
|
|
3
|
+
room: StudentRoom;
|
|
4
|
+
onStart: () => void;
|
|
5
|
+
isStarting?: boolean;
|
|
6
|
+
showCountdown?: boolean;
|
|
7
|
+
autoStartCountdown?: number;
|
|
8
|
+
closeRedirectUrl?: string;
|
|
9
|
+
onClose?: () => void;
|
|
10
|
+
}
|
|
11
|
+
export declare function CambridgeYleWaitingRoom({ room, onStart, isStarting, showCountdown, autoStartCountdown, closeRedirectUrl, onClose, }: CambridgeYleWaitingRoomProps): import("react").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{useState as n}from"react";import a from"next/image";import{Loader2 as i,FileText as l,Clock as s,Trophy as r,Layers as c,Target as h,HelpCircle as o,ChevronDown as m,X as d}from"lucide-react";import x from"../../../../components/themes/cambridge-yle/assets/images/background-ocean-edu-2.png";import g from"../../../../components/themes/cambridge-yle/assets/images/frame.png";import p from"../../../../components/themes/cambridge-yle/assets/images/bg-title.png";import u from"../../../../components/themes/cambridge-yle/assets/images/close.png";import b from"../../../../components/themes/cambridge-yle/assets/images/rocket.png";const f=[{q:"Bài test này kéo dài bao lâu?",a:"Thời gian làm bài sẽ được hiển thị trên màn hình. Hãy theo dõi đồng hồ để phân bổ thời gian hợp lý."},{q:"Em có cần hoàn thành tất cả câu hỏi không?",a:"Để kết quả phản ánh chính xác nhất năng lực hiện tại, em cố gắng hoàn thành toàn bộ câu hỏi trong thời gian quy định."},{q:"Nếu mất mạng giữa chừng thì sao?",a:"Trong một số trường hợp, hệ thống có thể tự động lưu tiến trình làm bài. Hãy kết nối lại internet sớm nhất có thể. Tuy nhiên để tránh gián đoạn, em nên sử dụng kết nối internet ổn định trong suốt quá trình làm bài."},{q:"Em không nghe được audio thì phải làm sao?",a:"Em hãy kiểm tra loa, tai nghe và âm lượng thiết bị trước. Nếu vẫn gặp lỗi, hãy thử tải lại trang hoặc đổi sang trình duyệt khác để tiếp tục làm bài."},{q:"Trang web bị lag hoặc không tải được câu hỏi?",a:"Em có thể thử làm mới trang, kiểm tra lại kết nối internet hoặc đổi trình duyệt/thiết bị khác. Nếu tình trạng vẫn tiếp diễn, hãy liên hệ trung tâm để được hỗ trợ nhanh nhất."},{q:"Em có thể xem lại đáp án sau khi nộp bài không?",a:"Sau khi nộp bài, sẽ có phiếu kết quả AI chấm điểm trả về, phân tích từng câu hỏi em đã làm."},{q:"Nếu em nộp nhầm thì sao?",a:"Sau khi nộp bài, em sẽ không thể chỉnh sửa câu trả lời. Em có thể liên hệ thầy cô ở trung tâm để hỗ trợ làm lại bài khác."},{q:"Em có được dùng từ điển hoặc tài liệu không?",a:"Để kết quả phản ánh đúng năng lực hiện tại, em nên làm bài trong điều kiện tương tự một bài kiểm tra thực tế và hạn chế sử dụng tài liệu hỗ trợ."},{q:"Em cần chuẩn bị gì trước khi bắt đầu?",a:"Em nên chuẩn bị thiết bị có kết nối internet ổn định, tai nghe (nếu có phần Listening), không gian yên tĩnh và dành đủ thời gian để hoàn thành bài test liên tục."},{q:"Em nên làm gì nếu gặp lỗi hệ thống?",a:"Nếu gặp lỗi trong quá trình làm bài, em hãy chụp lại màn hình lỗi (nếu có) và liên hệ trung tâm để được hỗ trợ xử lý nhanh nhất."}];function w({className:t="",size:n=18}){return e("svg",{width:n,height:n,viewBox:"0 0 24 24",className:t,fill:"currentColor",children:e("path",{d:"M12 0l2.4 9.6L24 12l-9.6 2.4L12 24l-2.4-9.6L0 12l9.6-2.4L12 0z"})})}export function CambridgeYleWaitingRoom({room:i,onStart:b,isStarting:y,showCountdown:k,autoStartCountdown:_,closeRedirectUrl:C,onClose:z}){const j=i.exam?.name||"",q=i.contest?.name||"",S=i.exam?.numberOfParts||1,E=i.exam?.durationMinutes||45,B=i.exam?.totalScore||100,L=i.exam?.passScore||0,[T,W]=n(!1),[O,P]=n(0);return t("div",{className:"fixed inset-0 z-50 flex items-center justify-center overflow-hidden",children:[e("div",{className:"absolute inset-0 scale-105 bg-cover bg-center",style:{backgroundImage:`url(${x.src})`,filter:"blur(2px) brightness(0.8) saturate(0.9)"}}),e("div",{className:"absolute inset-0 bg-gradient-to-b from-blue-950/50 via-blue-900/40 to-blue-950/60"}),e(w,{className:"absolute left-[8%] top-[14%] text-yellow-300 drop-shadow-[0_0_8px_rgba(255,255,150,0.8)]",size:22}),e(w,{className:"absolute right-[10%] top-[10%] text-yellow-200 drop-shadow-[0_0_8px_rgba(255,255,150,0.8)]",size:16}),e(w,{className:"absolute left-[15%] bottom-[18%] text-white/80",size:14}),e(w,{className:"absolute right-[6%] bottom-[24%] text-yellow-300 drop-shadow-[0_0_8px_rgba(255,255,150,0.8)]",size:20}),e(w,{className:"absolute left-[45%] top-[8%] text-white/70",size:12}),e("div",{className:"relative z-10",style:{width:"min(98vw, calc(98vh * 1552 / 672), 1800px)"},children:t("div",{className:"relative aspect-[1552/672] w-full",children:[e(a,{src:g,alt:"",fill:!0,className:"object-contain",priority:!0,unoptimized:!0}),e("div",{className:"absolute left-1/2 top-0 z-20 -translate-x-1/2 -translate-y-1/2",children:t("div",{className:"relative",children:[e(a,{src:p,alt:"",width:320,height:72,className:"drop-shadow-xl",priority:!0,unoptimized:!0}),e("div",{className:"absolute inset-0 flex items-center justify-center px-10 pt-1",title:q,children:e("span",{className:"block truncate text-center text-base font-extrabold uppercase tracking-[0.15em] text-white drop-shadow",children:q})})]})}),e("button",{onClick:()=>{z?z():C&&(window.location.href=C)},className:"absolute right-[7%] top-[-2%] z-30 cursor-pointer transition-transform hover:scale-110 active:scale-95","aria-label":"Close",children:e(a,{src:u,alt:"Close",width:56,height:56,unoptimized:!0})}),e("div",{className:"absolute inset-0 z-10 flex items-stretch overflow-hidden px-[9%] py-[10%]",children:t("div",{className:"flex h-full w-full items-stretch gap-4",children:[t("div",{className:"mx-auto flex w-full max-w-[560px] flex-[0_0_46%] flex-col justify-center gap-1",children:[e("h1",{className:"whitespace-nowrap text-center text-3xl font-black uppercase tracking-wide text-white md:text-4xl lg:text-5xl 2xl:text-6xl",style:{fontWeight:900,margin:"0.2em 0",textShadow:["0 1px 0 #cfe3ff","0 2px 0 #a8c8ee","0 3px 0 #6f9cd4","0 4px 0 #4a7cb8","0 5px 0 #2f5e9c","0 6px 0 #1a4480","0 8px 12px rgba(0,0,0,0.45)","0 0 22px rgba(120,180,255,0.55)"].join(", ")},children:i.name}),e("p",{className:"mt-1 hidden text-center text-sm font-bold text-[#21cffb] md:text-base 2xl:block 2xl:text-lg",children:"Đánh giá năng lực • Xác định lộ trình • Bứt phá tương lai"}),e("p",{className:"mx-auto mt-1 hidden max-w-2xl text-center text-xs text-white/95 md:text-sm 2xl:block",children:"Bài thi giúp bạn biết chính xác trình độ hiện tại và được Ocean Edu tư vấn lộ trình học tập phù hợp nhất."}),t("div",{className:"mt-4 flex items-center justify-center gap-2 2xl:mt-6",children:[e("span",{className:"h-px w-10 bg-white"}),e(w,{className:"text-white",size:12}),e("span",{className:"text-xs font-extrabold uppercase tracking-[0.3em] text-white md:text-sm",children:"Bài thi bao gồm"}),e(w,{className:"text-white",size:12}),e("span",{className:"h-px w-10 bg-white"})]}),t("div",{className:"mt-4 grid grid-cols-3 gap-2.5",children:[e(v,{icon:e(c,{className:"h-6 w-6"}),value:S,label:"Phần thi"}),e(v,{icon:e(s,{className:"h-6 w-6"}),value:E,label:"Phút"}),e(v,{icon:e(r,{className:"h-6 w-6"}),value:B,label:"Thang điểm"})]}),t("div",{className:"mt-4 space-y-2.5",children:[t("div",{className:"flex items-center gap-3 rounded-xl bg-[#0000001c] px-3 py-2.5",children:[e("span",{className:"flex h-9 w-9 flex-none items-center justify-center rounded-full bg-[#00000021] text-white",children:e(l,{className:"h-4 w-4"})}),e("span",{className:"text-sm font-bold text-white md:text-base",children:"Đề thi"}),e("span",{className:"ml-auto truncate text-sm font-bold text-white md:text-base",children:j})]}),L>0&&t("div",{className:"flex items-center gap-3 rounded-xl bg-[#0000001c] px-3 py-2.5",children:[e("span",{className:"flex h-9 w-9 flex-none items-center justify-center rounded-full bg-[#00000021] text-white",children:e(h,{className:"h-4 w-4"})}),e("span",{className:"text-sm font-bold text-white md:text-base",children:"Điểm tối thiểu cần đạt"}),t("span",{className:"ml-auto text-sm font-black text-yellow-300 md:text-lg",children:[L,"/",B]})]})]}),e("div",{className:"mt-5 flex justify-center",children:e(N,{onClick:b,isStarting:y,showCountdown:k,autoStartCountdown:_})})]}),e("div",{className:"relative hidden flex-[0_0_42%] md:block",children:e("div",{className:"absolute left-0 top-[4%] z-20 max-w-[60%]",children:t("div",{className:"relative rounded-2xl bg-white px-3 py-2 text-center text-[11px] font-semibold text-sky-900 shadow-xl ring-2 ring-sky-200 md:text-xs",children:["Cùng mình khám phá trình độ của bạn nhé!",e("span",{className:"absolute -bottom-1.5 right-6 h-3 w-3 rotate-45 bg-white ring-2 ring-sky-200"})]})})})]})})]})}),t("button",{type:"button",onClick:()=>W(!0),"aria-label":"Câu hỏi thường gặp",className:"group fixed bottom-5 right-5 z-40 inline-flex cursor-pointer items-center gap-2 rounded-full bg-gradient-to-b from-cyan-300 via-sky-500 to-sky-700 px-4 py-3 text-sm font-bold text-white shadow-[0_6px_0_0_#0c4a6e,0_10px_22px_rgba(14,165,233,0.45)] ring-2 ring-cyan-200/50 transition-all duration-150 hover:-translate-y-0.5 hover:brightness-110 active:translate-y-1 active:shadow-[0_1px_0_0_#0c4a6e,0_3px_8px_rgba(14,165,233,0.3)]",children:[e(o,{className:"h-5 w-5",strokeWidth:2.5}),e("span",{className:"hidden sm:inline",style:{textShadow:"0 1px 0 rgba(12,74,110,0.5)"},children:"Câu hỏi thường gặp"})]}),T&&t("div",{className:"fixed inset-0 z-[60] flex items-center justify-center p-4",role:"dialog","aria-modal":"true","aria-label":"Câu hỏi thường gặp",children:[e("div",{className:"absolute inset-0 bg-blue-950/70 backdrop-blur-sm",onClick:()=>W(!1)}),t("div",{className:"relative z-10 flex max-h-[85vh] w-full max-w-2xl flex-col overflow-hidden rounded-3xl bg-gradient-to-br from-cyan-300/20 via-white/5 to-white/0 p-px shadow-[0_20px_60px_-15px_rgba(10,75,140,0.7)] backdrop-blur-xl",children:[e("div",{className:"pointer-events-none absolute -left-12 -top-12 h-40 w-40 rounded-full bg-cyan-400/30 blur-3xl"}),e("div",{className:"pointer-events-none absolute -right-12 -bottom-12 h-40 w-40 rounded-full bg-sky-500/25 blur-3xl"}),t("div",{className:"relative flex max-h-[85vh] flex-col overflow-hidden rounded-[calc(1.5rem-1px)] bg-gradient-to-b from-[#0e3d70]/95 via-[#0a4b8c]/95 to-[#0a3866]/95 ring-1 ring-cyan-300/20",children:[t("div",{className:"flex items-center gap-3 px-6 py-5",children:[e("div",{className:"flex h-12 w-12 flex-none items-center justify-center rounded-full bg-gradient-to-br from-cyan-300 to-sky-600 shadow-[0_6px_18px_-4px_rgba(34,211,238,0.6)] ring-4 ring-cyan-300/20",children:e(o,{className:"h-6 w-6 text-white",strokeWidth:2.5})}),t("div",{className:"flex-1",children:[e("h2",{className:"text-lg font-extrabold tracking-tight text-white drop-shadow-md",children:"Câu hỏi thường gặp"}),e("p",{className:"mt-0.5 text-xs font-medium text-cyan-100/70",children:"Những điều cần biết trước khi làm bài"})]}),e("button",{type:"button",onClick:()=>W(!1),"aria-label":"Đóng",className:"flex h-9 w-9 flex-none cursor-pointer items-center justify-center rounded-full bg-white/10 text-white/80 ring-1 ring-white/15 transition-all duration-150 hover:bg-white/20 hover:text-white",children:e(d,{className:"h-5 w-5"})})]}),e("div",{className:"mx-6 h-px bg-gradient-to-r from-transparent via-cyan-300/25 to-transparent"}),e("div",{className:"flex-1 overflow-y-auto px-4 py-4 sm:px-6",children:e("ul",{className:"space-y-2",children:f.map((n,a)=>{const i=O===a;return t("li",{className:"overflow-hidden rounded-2xl ring-1 transition-colors duration-200 "+(i?"bg-white/[0.08] ring-cyan-300/30":"bg-white/[0.04] ring-white/10 hover:bg-white/[0.06]"),children:[t("button",{type:"button",onClick:()=>P(i?null:a),className:"flex w-full cursor-pointer items-center gap-3 px-4 py-3 text-left","aria-expanded":i,children:[e("span",{className:"flex h-7 w-7 flex-none items-center justify-center rounded-full text-xs font-black transition-colors "+(i?"bg-gradient-to-br from-yellow-300 to-orange-500 text-white":"bg-white/10 text-cyan-100"),children:a+1}),e("span",{className:"flex-1 text-sm font-bold text-white",children:n.q}),e(m,{className:"h-5 w-5 flex-none text-cyan-200 transition-transform duration-200 "+(i?"rotate-180":"")})]}),e("div",{className:"grid transition-all duration-200 "+(i?"grid-rows-[1fr] opacity-100":"grid-rows-[0fr] opacity-0"),children:e("div",{className:"overflow-hidden",children:e("p",{className:"px-4 pb-4 pl-14 text-sm leading-relaxed text-cyan-50/90",children:n.a})})})]},a)})})}),e("div",{className:"border-t border-white/10 bg-white/[0.03] px-6 py-3 text-center text-xs text-cyan-100/60",children:"Cần hỗ trợ thêm? Liên hệ trung tâm Ocean Edu để được giải đáp."})]})]})]})]})}function v({icon:n,value:a,label:i}){return t("div",{className:"flex items-center justify-center gap-3 rounded-2xl bg-[#0000001c] px-2 py-4",children:[e("span",{className:"flex h-12 w-12 flex-none items-center justify-center rounded-full bg-[#00bdff1a] text-white",children:n}),t("div",{className:"flex flex-col items-start leading-tight",children:[e("div",{className:"text-2xl font-black text-white md:text-3xl",children:a}),e("div",{className:"text-xs font-bold text-white/90 md:text-sm",children:i})]})]})}function N({onClick:n,isStarting:l,showCountdown:s,autoStartCountdown:r}){return s?e("div",{className:"inline-flex h-14 w-48 items-center justify-center rounded-full bg-yellow-400 text-2xl font-black text-[#1a3a6e]",children:r}):t("button",{onClick:n,disabled:l,className:"group relative mt-5 inline-flex cursor-pointer items-center gap-3 rounded-full bg-gradient-to-b from-[#ffd54a] via-[#ffb733] to-[#ff8a1f] py-2.5 pl-8 pr-10 shadow-[0_6px_0_0_#c46410,0_10px_18px_rgba(0,0,0,0.4)] ring-2 ring-orange-300/60 transition-all duration-150 hover:-translate-y-0.5 hover:brightness-110 hover:shadow-[0_8px_0_0_#c46410,0_14px_22px_rgba(0,0,0,0.45)] active:translate-y-1.5 active:shadow-[0_1px_0_0_#c46410,0_2px_6px_rgba(0,0,0,0.3)] disabled:cursor-not-allowed disabled:opacity-70",children:[l?e(i,{className:"h-7 w-7 animate-spin text-white"}):e(a,{src:b,alt:"",width:36,height:36,unoptimized:!0}),e("span",{className:"text-xl font-black text-white",style:{color:"#685030"},children:"Bắt đầu"})]})}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ThemeConfig } from '../../../../shared/lib/themes';
|
|
2
|
+
import type { StudentRoom } from '../../../../shared/types/student.types';
|
|
3
|
+
interface ThemedWaitingRoomProps {
|
|
4
|
+
room: StudentRoom;
|
|
5
|
+
theme: ThemeConfig;
|
|
6
|
+
onStart: () => void;
|
|
7
|
+
isStarting: boolean;
|
|
8
|
+
showCountdown: boolean;
|
|
9
|
+
autoStartCountdown: number;
|
|
10
|
+
/** Custom redirect URL for close button (default: student exams page) */
|
|
11
|
+
closeRedirectUrl?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function ThemedWaitingRoom({ room, theme, onStart, isStarting, showCountdown, autoStartCountdown, closeRedirectUrl, }: ThemedWaitingRoomProps): import("react").JSX.Element;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import a from"next/image";import{ROUTES as s}from"../../../../shared/constants/routes";import{CloseButton as i,ModeSelector as o,ExamInfoPanel as r,StartButton as n}from"./components";export function ThemedWaitingRoom({room:l,theme:c,onStart:d,isStarting:m,showCountdown:u,autoStartCountdown:h,closeRedirectUrl:p}){const b=l.name,g={parts:l.exam?.numberOfParts||1,duration:l.exam?.durationMinutes||15,maxScore:l.exam?.totalScore||8,passScore:l.exam?.passScore||0,examName:l.exam?.name,contestClassification:l.contest?.classification,level:l.exam?.level},f=c.visuals?.backgroundFilter??"grayscale(1) blur(10px) saturate(0.85) brightness(0.9)",v=c.visuals?.backgroundOverlay??"linear-gradient(to bottom, rgba(0, 0, 0, 0.2), transparent, rgba(0, 0, 0, 0.3))",x=c.visuals?.cardBackground??"radial-gradient(60% 60% at 50% 40%, rgba(184, 229, 157, 0.85) 0%, rgba(115, 213, 133, 0.85) 100%)";return t("div",{className:"fixed inset-0 z-50 flex items-center justify-center overflow-hidden",children:[e("div",{className:"absolute inset-0 scale-110 bg-cover bg-center",style:{backgroundImage:`url(${c.assets.background})`,filter:f}}),e("div",{className:"absolute inset-0",style:{background:v}}),t("div",{className:"relative z-10 w-[88%] max-w-2xl sm:w-[70%] md:w-[50%] lg:w-[42%]",children:[e(i,{imageSrc:c.assets.closeButton,onClick:()=>{"undefined"!=typeof window&&(window.location.href=p||s.STUDENT.CONTESTS_DISCOVER)},className:"absolute -right-3 -top-7 z-30",size:72}),t("div",{className:"absolute left-1/2 top-0 z-10 -translate-x-1/2 -translate-y-1/2",children:[e(a,{src:c.assets.titleBar,alt:"",width:260,height:56,className:"drop-shadow-lg",style:void 0,priority:!0,unoptimized:!0}),e("span",{className:"absolute mt-2.5 inset-0 flex items-center justify-center pb-1 text-sm font-extrabold tracking-wider text-white drop-shadow",children:c.displayName})]}),e("div",{className:"relative overflow-hidden rounded-3xl p-[3px] shadow-2xl",style:{background:"linear-gradient(180deg, #38bdf8 0%, #0ea5e9 35%, #0473f9 70%, #1d4ed8 100%)"},children:e("div",{className:"overflow-hidden rounded-[calc(1.5rem-3px)] ring-1 ring-white/30",children:t("div",{className:"relative p-6 pt-12 md:p-8 md:pt-14 lg:p-10 lg:pt-16",style:{background:x},children:[e("div",{className:"mb-5",children:e(o,{label:b,theme:c})}),e("div",{className:"mb-6",children:e(r,{parts:g.parts,duration:g.duration,maxScore:g.maxScore,passScore:g.passScore,examName:g.examName,contestClassification:g.contestClassification,level:g.level,theme:c})}),e("div",{className:"flex justify-center pb-2",children:e(n,{onClick:d,isLoading:m,showCountdown:u,countdown:h,rocketSrc:c.assets.startIcon,theme:c})}),e("div",{className:"pointer-events-none absolute -bottom-1 -left-1 opacity-60",children:e(a,{src:c.assets.bottomLeft,alt:"",width:80,height:80,unoptimized:!0})}),e("div",{className:"pointer-events-none absolute -bottom-1 -right-1 opacity-60",children:e(a,{src:c.assets.bottomRight,alt:"",width:80,height:80,unoptimized:!0})})]})})})]}),c.assets.feedbackButton&&e("button",{className:"absolute bottom-4 right-0 z-20 transition-transform hover:scale-105","aria-label":"Báo cáo lỗi",children:e(a,{src:c.assets.feedbackButton,alt:"Báo cáo lỗi",width:35,height:100,unoptimized:!0})})]})}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { StudentRoom } from '../../../../shared/types/student.types';
|
|
2
|
+
interface ToeicWaitingRoomProps {
|
|
3
|
+
room: StudentRoom;
|
|
4
|
+
onStart: () => void;
|
|
5
|
+
isStarting: boolean;
|
|
6
|
+
showCountdown: boolean;
|
|
7
|
+
autoStartCountdown: number;
|
|
8
|
+
closeRedirectUrl?: string;
|
|
9
|
+
onClose?: () => void;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Professional waiting room for TOEIC exam entry.
|
|
13
|
+
* Neutral, business-appropriate design (no cartoon elements).
|
|
14
|
+
*/
|
|
15
|
+
export declare function ToeicWaitingRoom({ room, onStart, isStarting, showCountdown, autoStartCountdown, onClose, }: ToeicWaitingRoomProps): import("react").JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as a,Fragment as t}from"react/jsx-runtime";import{Loader2 as s}from"lucide-react";import{Button as l}from"../../../../components/ui/button";export function ToeicWaitingRoom({room:n,onStart:r,isStarting:i,showCountdown:d,autoStartCountdown:c,onClose:m}){return a("div",{className:"fixed inset-0 z-50 flex flex-col items-center justify-center overflow-auto bg-gradient-to-b from-slate-50 to-slate-100 px-4 py-8",children:[a("div",{className:"mb-8 text-center",children:[a("div",{className:"mb-2 inline-flex items-center gap-2 rounded-full border border-blue-200 bg-blue-50 px-4 py-1.5",children:[e("span",{className:"h-2 w-2 rounded-full bg-blue-500"}),e("span",{className:"text-xs font-semibold uppercase tracking-wider text-blue-700",children:"Ocean Edu"})]}),e("h1",{className:"text-2xl font-bold text-gray-900 sm:text-3xl",children:"TOEIC Listening and Reading Test"}),e("p",{className:"mt-2 text-gray-500",children:n.name})]}),a("div",{className:"w-full max-w-lg rounded-2xl border border-gray-200 bg-white p-6 shadow-sm sm:p-8",children:[a("div",{className:"mb-6",children:[e("h2",{className:"mb-4 text-sm font-semibold uppercase tracking-wider text-gray-400",children:"Cấu trúc bài thi"}),a("div",{className:"space-y-3",children:[a("div",{className:"rounded-lg border border-gray-100 bg-gray-50 p-4",children:[a("div",{className:"mb-2 flex items-center justify-between",children:[e("span",{className:"text-sm font-semibold text-gray-700",children:"Listening"}),e("span",{className:"text-xs font-medium text-gray-400",children:"~45 phút"})]}),e("div",{className:"flex flex-wrap gap-1.5",children:["Part 1: Photographs","Part 2: Question-Response","Part 3: Conversations"].map(a=>e("span",{className:"rounded bg-blue-100 px-2 py-0.5 text-xs text-blue-700",children:a},a))}),e("p",{className:"mt-2 text-xs text-gray-500",children:"100 câu hỏi · Nghe và chọn đáp án đúng"})]}),a("div",{className:"rounded-lg border border-gray-100 bg-gray-50 p-4",children:[a("div",{className:"mb-2 flex items-center justify-between",children:[e("span",{className:"text-sm font-semibold text-gray-700",children:"Reading"}),e("span",{className:"text-xs font-medium text-gray-400",children:"~75 phút"})]}),e("div",{className:"flex flex-wrap gap-1.5",children:["Part 5: Incomplete Sentences","Part 6: Text Completion","Part 7: Reading Comprehension"].map(a=>e("span",{className:"rounded bg-green-100 px-2 py-0.5 text-xs text-green-700",children:a},a))}),e("p",{className:"mt-2 text-xs text-gray-500",children:"100 câu hỏi · Đọc hiểu và chọn đáp án đúng"})]})]})]}),a("div",{className:"mb-6 rounded-lg border border-amber-100 bg-amber-50 p-4",children:[e("h3",{className:"mb-2 text-sm font-semibold text-amber-700",children:"Lưu ý quan trọng"}),a("ul",{className:"space-y-1 text-xs text-amber-800",children:[a("li",{className:"flex items-start gap-1.5",children:[e("span",{className:"mt-0.5 h-1.5 w-1.5 shrink-0 rounded-full bg-amber-500"}),"Không thể tạm dừng bài thi sau khi bắt đầu"]}),a("li",{className:"flex items-start gap-1.5",children:[e("span",{className:"mt-0.5 h-1.5 w-1.5 shrink-0 rounded-full bg-amber-500"}),"Không thể quay lại câu trước sau khi chuyển câu"]}),a("li",{className:"flex items-start gap-1.5",children:[e("span",{className:"mt-0.5 h-1.5 w-1.5 shrink-0 rounded-full bg-amber-500"}),"Bài thi sẽ tự động nộp khi hết thời gian 120 phút"]}),a("li",{className:"flex items-start gap-1.5",children:[e("span",{className:"mt-0.5 h-1.5 w-1.5 shrink-0 rounded-full bg-amber-500"}),"Điểm số: Listening (5–495) + Reading (5–495) = Total (10–990)"]})]})]}),e("div",{className:"mb-6 grid grid-cols-3 gap-3",children:[{label:"Tổng câu hỏi",value:"200"},{label:"Thời gian",value:"120 phút"},{label:"Thang điểm",value:"990"}].map(({label:t,value:s})=>a("div",{className:"rounded-lg bg-slate-50 p-3 text-center",children:[e("div",{className:"text-lg font-bold text-gray-900",children:s}),e("div",{className:"text-xs text-gray-400",children:t})]},t))}),e(l,{onClick:r,disabled:i,className:"h-12 w-full rounded-xl bg-blue-600 text-base font-semibold hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-60",children:i?a(t,{children:[e(s,{className:"mr-2 h-4 w-4 animate-spin"}),"Đang khởi tạo..."]}):d?a(t,{children:["Bắt đầu sau ",c,"s..."]}):"Bắt đầu bài thi"})]}),m&&e("button",{onClick:m,className:"mt-6 text-sm text-gray-400 hover:text-gray-600",children:"Quay lại danh sách phòng thi"})]})}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface CloseButtonProps {
|
|
2
|
+
imageSrc: string;
|
|
3
|
+
onClick: () => void;
|
|
4
|
+
className?: string;
|
|
5
|
+
size?: number;
|
|
6
|
+
imageFilter?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function CloseButton({ imageSrc, onClick, className, size, imageFilter }: CloseButtonProps): import("react").JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e}from"react/jsx-runtime";import t from"next/image";export function CloseButton({imageSrc:i,onClick:r,className:a="",size:o=80,imageFilter:s}){return e("button",{onClick:r,className:`cursor-pointer transition-transform hover:scale-105 active:scale-95 ${a}`,"aria-label":"Đóng",children:e(t,{src:i,alt:"Đóng",width:o,height:o,className:"drop-shadow-lg",style:s?{filter:s}:void 0,unoptimized:!0})})}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ThemeConfig } from '../../../../../shared/lib/themes';
|
|
2
|
+
interface ExamInfoPanelProps {
|
|
3
|
+
parts: number;
|
|
4
|
+
duration: number;
|
|
5
|
+
maxScore: number;
|
|
6
|
+
passScore: number;
|
|
7
|
+
examName?: string;
|
|
8
|
+
contestClassification?: string;
|
|
9
|
+
level?: string;
|
|
10
|
+
theme: ThemeConfig;
|
|
11
|
+
}
|
|
12
|
+
export declare function ExamInfoPanel({ parts, duration, maxScore, passScore, examName, level, }: ExamInfoPanelProps): import("react").JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{Clock as l,Trophy as i,Target as n,Layers as a,FileText as r,Sparkles as s}from"lucide-react";const x={A1:{bg:"bg-emerald-100",text:"text-emerald-700",ring:"ring-emerald-300/50"},A2:{bg:"bg-teal-100",text:"text-teal-700",ring:"ring-teal-300/50"},B1:{bg:"bg-blue-100",text:"text-blue-700",ring:"ring-blue-300/50"},B2:{bg:"bg-indigo-100",text:"text-indigo-700",ring:"ring-indigo-300/50"},C1:{bg:"bg-purple-100",text:"text-purple-700",ring:"ring-purple-300/50"},C2:{bg:"bg-rose-100",text:"text-rose-700",ring:"ring-rose-300/50"}};export function ExamInfoPanel({parts:d,duration:o,maxScore:c,passScore:g,examName:m,level:h}){const b=h?x[h]||{bg:"bg-gray-100",text:"text-gray-700",ring:"ring-gray-300/50"}:null;return t("div",{className:"overflow-hidden rounded-2xl bg-[#0473f9] ring-1 ring-white/25",children:[t("div",{className:"relative flex items-center justify-between border-b border-white/15 bg-[#002249]/45 px-5 py-3",children:[e(s,{className:"absolute left-3 top-2 h-3 w-3 text-yellow-300/45"}),e("h2",{className:"text-lg font-extrabold tracking-wide text-white drop-shadow-sm",children:"Chi tiết bài thi"}),h&&b&&e("span",{className:`rounded-full px-3.5 py-1 text-xs font-bold ring-2 ${b.bg} ${b.text} ${b.ring}`,children:h})]}),t("div",{className:"space-y-3 p-4",children:[t("div",{className:"grid grid-cols-3 gap-2.5",children:[t("div",{className:"rounded-xl bg-white/15 px-2 py-3 text-center ring-1 ring-white/20",children:[e(a,{className:"mx-auto mb-1.5 h-5 w-5 text-sky-100"}),e("span",{className:"block text-2xl font-extrabold leading-none text-white",children:d}),e("span",{className:"mt-1 block text-xs font-bold text-sky-100",children:"Phần thi"})]}),t("div",{className:"rounded-xl bg-white/15 px-2 py-3 text-center ring-1 ring-white/20",children:[e(l,{className:"mx-auto mb-1.5 h-5 w-5 text-cyan-100"}),e("span",{className:"block text-2xl font-extrabold leading-none text-white",children:o}),e("span",{className:"mt-1 block text-xs font-bold text-cyan-100",children:"Phút"})]}),t("div",{className:"rounded-xl bg-white/15 px-2 py-3 text-center ring-1 ring-white/20",children:[e(i,{className:"mx-auto mb-1.5 h-5 w-5 text-indigo-100"}),e("span",{className:"block text-2xl font-extrabold leading-none text-white",children:c}),e("span",{className:"mt-1 block text-xs font-bold text-indigo-100",children:"Thang điểm"})]})]}),t("div",{className:"overflow-hidden rounded-xl bg-[#002249]/18 ring-1 ring-white/12",children:[m&&t("div",{className:"flex items-center gap-3 px-3 py-2.5",children:[e(r,{className:"h-4 w-4 shrink-0 text-yellow-300"}),e("span",{className:"text-sm font-bold text-sky-100",children:"Đề thi"}),e("span",{className:"ml-auto text-right text-sm font-extrabold text-white",children:m})]}),m&&e("div",{className:"border-t border-white/10"}),t("div",{className:"flex items-center gap-3 px-3 py-2.5",children:[e(n,{className:"h-4 w-4 shrink-0 text-yellow-300"}),e("span",{className:"text-sm font-bold text-white",children:"Điểm tối thiểu cần đạt"}),t("span",{className:"ml-auto text-base font-extrabold text-yellow-300",children:[g,"/",c]})]})]})]})]})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{User as r}from"lucide-react";export function ModeSelector({label:i}){return e("div",{className:"flex justify-center",children:t("div",{className:"flex items-center gap-3 rounded-2xl bg-white/10 px-6 py-3 ring-1 ring-white/15 backdrop-blur-sm",children:[e("div",{className:"flex h-8 w-8 items-center justify-center rounded-full bg-white/15",children:e(r,{className:"h-4 w-4 text-white/80"})}),e("p",{className:"text-center text-lg font-bold uppercase leading-5 tracking-wider text-white drop-shadow-sm",children:i})]})})}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ThemeConfig } from '../../../../../shared/lib/themes';
|
|
2
|
+
interface StartButtonProps {
|
|
3
|
+
onClick: () => void;
|
|
4
|
+
isLoading: boolean;
|
|
5
|
+
showCountdown: boolean;
|
|
6
|
+
countdown: number;
|
|
7
|
+
rocketSrc: string;
|
|
8
|
+
theme: ThemeConfig;
|
|
9
|
+
}
|
|
10
|
+
export declare function StartButton({ onClick, isLoading, showCountdown, countdown, rocketSrc, }: StartButtonProps): import("react").JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import a from"next/image";import{Loader2 as s}from"lucide-react";export function StartButton({onClick:i,isLoading:l,showCountdown:r,countdown:n,rocketSrc:o}){return r?t("div",{className:"flex flex-col items-center gap-4",children:[t("div",{className:"relative flex h-24 w-24 items-center justify-center",children:[e("div",{className:"absolute inset-0 animate-ping rounded-full bg-sky-400/20"}),e("div",{className:"absolute inset-0 animate-pulse rounded-full bg-blue-500/10"}),e("div",{className:"relative flex h-20 w-20 items-center justify-center rounded-full bg-[#0473f9] shadow-[0_4px_0_0_#1d4ed8]",children:e("span",{className:"text-4xl font-extrabold text-white drop-shadow",children:n})})]}),t("p",{className:"text-sm font-medium text-white/90 drop-shadow",children:["Bài thi sẽ tự động bắt đầu sau ",e("strong",{className:"text-yellow-300",children:n})," giây"]}),l&&t("div",{className:"flex items-center gap-2 rounded-full bg-white/10 px-4 py-1.5 text-white/80 backdrop-blur-sm",children:[e(s,{className:"h-4 w-4 animate-spin"}),e("span",{className:"text-sm",children:"Đang bắt đầu bài thi..."})]})]}):e("div",{className:"relative flex flex-col items-center",children:t("button",{onClick:i,disabled:l,className:"group relative flex cursor-pointer items-center gap-4 rounded-full bg-[#0473f9] px-10 py-4 shadow-[0_5px_0_0_#1d4ed8] transition-all duration-150 hover:brightness-110 active:translate-y-[3px] active:shadow-[0_2px_0_0_#1d4ed8] disabled:cursor-not-allowed disabled:opacity-50",children:[e("div",{className:"relative h-11 w-11 transition-transform duration-300 group-hover:-translate-y-1 group-hover:rotate-[-8deg]",children:e(a,{src:o,alt:"",fill:!0,className:"object-contain drop-shadow",unoptimized:!0})}),e("span",{className:"text-xl font-extrabold tracking-wide text-white drop-shadow-sm",children:"Bắt đầu"}),l&&e(s,{className:"h-5 w-5 animate-spin text-white/80"})]})})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{CloseButton}from"./CloseButton";export{ModeSelector}from"./ModeSelector";export{ExamInfoPanel}from"./ExamInfoPanel";export{StartButton}from"./StartButton";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ThemedWaitingRoom } from './ThemedWaitingRoom';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{ThemedWaitingRoom}from"./ThemedWaitingRoom";
|