/* eslint-disable @next/next/no-img-element */ import { SpeakingExercise } from "@/interfaces/exam"; import { CommonProps } from "."; import { Fragment, useEffect, useState } from "react"; import Button from "../Low/Button"; import dynamic from "next/dynamic"; import axios from "axios"; import { speakingReverseMarking } from "@/utils/score"; import { Tab } from "@headlessui/react"; import clsx from "clsx"; import Modal from "../Modal"; import { BsQuestionCircleFill } from "react-icons/bs"; import ReactDiffViewer, { DiffMethod } from "react-diff-viewer"; const Waveform = dynamic(() => import("../Waveform"), { ssr: false }); export default function Speaking({ id, type, title, video_url, text, prompts, userSolutions, onNext, onBack }: SpeakingExercise & CommonProps) { const [solutionURL, setSolutionURL] = useState(); const [showDiff, setShowDiff] = useState(false); useEffect(() => { if (userSolutions && userSolutions.length > 0 && userSolutions[0].solution) { const solution = userSolutions[0].solution; if (solution.startsWith("https://")) return setSolutionURL(solution); axios.post(`/api/speaking`, { path: userSolutions[0].solution }, { responseType: "arraybuffer" }).then(({ data }) => { const blob = new Blob([data], { type: "audio/wav" }); const url = URL.createObjectURL(blob); setSolutionURL(url); }); } }, [userSolutions]); const tooltips: { [key: string]: string } = { "Grammatical Range and Accuracy": "Assesses the variety and correctness of grammatical structures used. A higher score indicates a wide range of complex and accurate grammar; a lower score suggests the need for more basic grammar practice.", "Fluency and Coherence": "Evaluates smoothness and logical flow of speech. A higher score means natural, effortless speech and clear idea progression; a lower score indicates frequent pauses and difficulty in maintaining coherence.", "Pronunciation": "Measures clarity and accuracy of spoken words. A higher score reflects clear, well-articulated speech with correct intonation; a lower score shows challenges in being understood.", "Lexical Resource": "Looks at the range and appropriateness of vocabulary. A higher score demonstrates a rich and precise vocabulary; a lower score suggests limited vocabulary usage and appropriateness.", }; return ( <> setShowDiff(false)}> <> {userSolutions && userSolutions.length > 0 && userSolutions[0].evaluation?.transcript_1 && userSolutions[0].evaluation?.fixed_text_1 && (
Transcript Recommended Improvements
)}
{title} {!video_url && ( {text.split("\\n").map((line, index) => ( {line}
))}
)}
{video_url && (
)} {prompts && prompts.length > 0 && (
You should talk about the following things:
{prompts.map((x, index) => (
  • {x}
  • ))}
    )}
    {solutionURL && } {userSolutions && userSolutions.length > 0 && userSolutions[0].evaluation?.transcript_1 && userSolutions[0].evaluation?.fixed_text_1 && ( )}
    {userSolutions && userSolutions.length > 0 && userSolutions[0].evaluation && typeof userSolutions[0].evaluation !== "string" && (
    {Object.keys(userSolutions[0].evaluation!.task_response).map((key, index) => { const taskResponse = userSolutions[0].evaluation!.task_response[key]; const grade: number = typeof taskResponse === "number" ? taskResponse : taskResponse.grade; return (
    {key}: Level {grade}
    ); })}
    {userSolutions[0].evaluation && (userSolutions[0].evaluation.perfect_answer || userSolutions[0].evaluation.perfect_answer_1) ? ( clsx( "w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-ielts-speaking/80", "ring-white ring-opacity-60 ring-offset-2 ring-offset-ielts-speaking focus:outline-none focus:ring-2", "transition duration-300 ease-in-out", selected ? "bg-white shadow" : "text-blue-100 hover:bg-white/[0.12] hover:text-ielts-speaking", ) }> General Feedback clsx( "w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-ielts-speaking/80", "ring-white ring-opacity-60 ring-offset-2 ring-offset-ielts-speaking focus:outline-none focus:ring-2", "transition duration-300 ease-in-out", selected ? "bg-white shadow" : "text-blue-100 hover:bg-white/[0.12] hover:text-ielts-speaking", ) }> Evaluation clsx( "w-full rounded-lg py-2.5 text-sm font-medium leading-5 text-ielts-speaking/80", "ring-white ring-opacity-60 ring-offset-2 ring-offset-ielts-speaking focus:outline-none focus:ring-2", "transition duration-300 ease-in-out", selected ? "bg-white shadow" : "text-blue-100 hover:bg-white/[0.12] hover:text-ielts-speaking", ) }> Recommended Answer {/* General Feedback */}
    {Object.keys(userSolutions[0].evaluation!.task_response).map((key) => { const taskResponse = userSolutions[0].evaluation!.task_response[key]; const grade: number = typeof taskResponse === "number" ? taskResponse : taskResponse.grade; return (
    {key}: Level {grade}
    {typeof taskResponse !== "number" && {taskResponse.comment}}
    ); })}
    {/* Evaluation */} {userSolutions[0].evaluation!.comment} {/* Recommended Answer */} {userSolutions[0].evaluation!.perfect_answer && userSolutions[0].evaluation!.perfect_answer.replaceAll(/\s{2,}/g, "\n\n")} {userSolutions[0].evaluation!.perfect_answer_1 && userSolutions[0].evaluation!.perfect_answer_1.replaceAll(/\s{2,}/g, "\n\n")}
    ) : (
    {userSolutions[0].evaluation!.comment}
    )}
    )}
    ); }