1- import { type FC , useState } from "react" ;
1+ import { type FC , useState , useEffect } from "react" ;
22import { useForm , FieldValues } from "react-hook-form" ;
33import { Question } from "./types" ;
44import Image from "next/image" ;
@@ -24,6 +24,9 @@ const QuizForm: FC<Props> = ({
2424} ) => {
2525 const { register, handleSubmit, reset, watch } = useForm ( ) ;
2626 const [ showCorrectAnswer , setShowCorrectAnswer ] = useState < boolean > ( false ) ;
27+ const [ isThinking , setIsThinking ] = useState < boolean > ( false ) ;
28+ const [ ollamaAvailable , setOllamaAvailable ] = useState < boolean > ( false ) ;
29+ const [ explanation , setExplanation ] = useState < string | null > ( null ) ;
2730 const [ lastIndex , setLastIndex ] = useState < number > ( 1 ) ;
2831 const [ canGoBack , setCanGoBack ] = useState < boolean > ( false ) ;
2932 const [ savedAnswers , setSavedAnswers ] = useState < {
@@ -34,6 +37,21 @@ const QuizForm: FC<Props> = ({
3437 alt : string ;
3538 } | null > ( null ) ;
3639
40+ useEffect ( ( ) => {
41+ const checkOllamaStatus = async ( ) => {
42+ try {
43+ const response = await fetch ( "http://localhost:11434" ) ;
44+ if ( response . ok ) {
45+ setOllamaAvailable ( true ) ;
46+ }
47+ } catch ( error ) {
48+ console . error ( "Error checking server status:" , error ) ;
49+ }
50+ } ;
51+
52+ checkOllamaStatus ( ) ;
53+ } , [ ] ) ;
54+
3755 const onSubmit = ( data : FieldValues ) => {
3856 setSavedAnswers ( ( prev ) => ( {
3957 ...prev ,
@@ -53,10 +71,46 @@ const QuizForm: FC<Props> = ({
5371 }
5472 } ;
5573
74+ const explainCorrectAnswer = async ( ) => {
75+ try {
76+ const prompt = `${ question } Explain why these answers are correct: ${ options
77+ . filter ( ( o ) => o . isAnswer == true )
78+ . map ( ( o ) => o . text ) } `;
79+
80+ const response = await fetch ( "http://localhost:11434/api/generate" , {
81+ method : "POST" ,
82+ headers : {
83+ "Content-Type" : "application/json" ,
84+ } ,
85+ body : JSON . stringify ( {
86+ model : "mistral" ,
87+ prompt : prompt ,
88+ stream : false ,
89+ } ) ,
90+ } ) ;
91+
92+ if ( ! response . ok ) {
93+ throw new Error ( `HTTP error! Status: ${ response . status } ` ) ;
94+ }
95+
96+ const responseData = await response . json ( ) ;
97+
98+ if ( responseData && "response" in responseData ) {
99+ setExplanation ( responseData . response ) ;
100+ } else {
101+ console . error ( "Response does not contain explanation:" , responseData ) ;
102+ }
103+ } catch ( error ) {
104+ console . error ( "Error fetching explanation:" , error ) ;
105+ } finally {
106+ setIsThinking ( false ) ;
107+ }
108+ } ;
109+
56110 if ( isLoading ) return < p > Loading...</ p > ;
57111 //Error Handling for loading issues
58112 if ( ! questionSet ) return < p > Loading questions failed</ p > ;
59-
113+
60114 const { question, options, images } = questionSet ! ;
61115 const watchInput = watch ( `options.${ currentQuestionIndex } ` ) ;
62116
@@ -201,6 +255,9 @@ const QuizForm: FC<Props> = ({
201255 </ li >
202256 ) ) }
203257 </ ul >
258+ { explanation && (
259+ < p className = "text-white md:px-12 mb-16 select-none" > { explanation } </ p >
260+ ) }
204261 < div className = "flex justify-center flex-col sm:flex-row" >
205262 < Button
206263 type = "submit"
@@ -210,13 +267,30 @@ const QuizForm: FC<Props> = ({
210267 >
211268 Reveal Answer
212269 </ Button >
270+ { ollamaAvailable && (
271+ < Button
272+ type = "button"
273+ intent = "secondary"
274+ size = "medium"
275+ disabled = { isThinking }
276+ onClick = { ( ) => {
277+ setShowCorrectAnswer ( true ) ;
278+ setIsThinking ( true ) ;
279+ explainCorrectAnswer ( ) ;
280+ reset ( ) ;
281+ } }
282+ >
283+ { isThinking ? "Thinking..." : "Explain" }
284+ </ Button >
285+ ) }
213286 < Button
214287 type = "button"
215288 intent = "primary"
216289 size = "medium"
217290 disabled = { currentQuestionIndex < lastIndex }
218291 onClick = { ( ) => {
219292 setShowCorrectAnswer ( false ) ;
293+ setExplanation ( null ) ;
220294 setSavedAnswers ( ( prev ) => ( {
221295 ...prev ,
222296 [ currentQuestionIndex ] : watchInput ,
0 commit comments