Explicação do Componente 📚
O componente MultiplaEscolha gerencia uma pergunta de múltipla escolha em um ambiente React. Ele permite ao usuário selecionar uma resposta e verificar se está correta, enviando a resposta para um backend via requisição POST.
Gerenciamento do Estado 🧠
Usamos o useState para gerenciar dois estados principais: o índice da opção selecionada (selectedOptionIndex
) e se a resposta está correta (isCorrect
).
Código de Gerenciamento de Estado:
const [selectedOptionIndex, setSelectedOptionIndex] = useState(null)
const [isCorrect, setIsCorrect] = useState(null)
- selectedOptionIndex: Armazena o índice da opção selecionada pelo usuário.
- isCorrect: Armazena se a resposta do usuário é correta ou incorreta (true ou false).
Função de Clique na Opção 🔘
A função handleOptionClick é chamada quando o usuário clica em uma das opções de resposta. Ela envia uma requisição ao backend para verificar se a resposta está correta.
Código da Função handleOptionClick
:
const handleOptionClick = async (index) => {
setSelectedOptionIndex(index)
try {
const response = await fetch('/api/verificar-resposta', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
perguntaId: data.id,
respostaIndex: index,
}),
})
const result = await response.json()
if (result.isCorrect) {
setIsCorrect(true)
} else {
setIsCorrect(false)
}
} catch (error) {
console.error('Erro ao verificar a resposta:', error)
}
}
- setSelectedOptionIndex(index): Atualiza o índice da opção selecionada.
- fetch: Envia uma requisição POST com os dados da pergunta e da opção selecionada.
- setIsCorrect(true/false): Atualiza o estado de isCorrect dependendo da resposta recebida do backend.
Gerando a Letra da Opção 🔠
A função getOptionLetter converte o índice da opção para uma letra, seguindo a convenção A, B, C, etc.
Código da Função getOptionLetter
:
const getOptionLetter = (index) => String.fromCharCode(65 + index)
- String.fromCharCode(65 + index): Converte o índice numérico para a letra correspondente (A para 0, B para 1, C para 2, etc.).
Exibição do Formulário de Pergunta e Opções 🔍
A renderização do formulário é feita com um div que contém a pergunta e as opções. Cada opção é exibida como um botão, que pode ser selecionado. O estilo do botão muda dependendo de a resposta estar correta ou incorreta.
Código da Renderização:
<div className="my-6 p-4 border rounded-lg">
<div className="mb-4">
<RichTextContent content={data.pergunta} />
</div>
<div className="space-y-2">
{data.alternativa.map((opcao, index) => (
<button
key={index}
onClick={() => handleOptionClick(index)}
className={cn(
'w-full text-left p-3 border rounded-md',
selectedOptionIndex === index && isCorrect === true
? 'bg-green-100 border-green-500'
: selectedOptionIndex === index && isCorrect === false
? 'bg-red-100 border-red-500'
: 'bg-white dark:bg-gray-800',
)}
>
<span className="font-bold mr-2">{getOptionLetter(index)}.</span>
{opcao.textoAlternativa}
</button>
))}
</div>
{isCorrect !== null && (
<p className="mt-4">
{isCorrect ? 'Resposta correta!' : 'Resposta incorreta. Tente novamente.'}
</p>
)}
</div>
- RichTextContent: Exibe o conteúdo da pergunta, possivelmente com formatação rica.
- Alternativas: Cada opção é mapeada e exibida como um botão. Se a opção for selecionada, seu estilo é alterado com base na correção da resposta.
- Feedback: Exibe um texto com a mensagem "Resposta correta!" ou "Resposta incorreta", dependendo do estado de
isCorrect
.
Código Completo 🖥️
import { useState } from 'react'
import { cn } from '@/lib/utils'
import RichTextContent from '@/components/RichTextContent'
export default function MultiplaEscolha({ data }) {
const [selectedOptionIndex, setSelectedOptionIndex] = useState(null)
const [isCorrect, setIsCorrect] = useState(null)
const handleOptionClick = async (index) => {
setSelectedOptionIndex(index)
try {
const response = await fetch('/api/verificar-resposta', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
perguntaId: data.id,
respostaIndex: index,
}),
})
const result = await response.json()
if (result.isCorrect) {
setIsCorrect(true)
} else {
setIsCorrect(false)
}
} catch (error) {
console.error('Erro ao verificar a resposta:', error)
}
}
const getOptionLetter = (index) => String.fromCharCode(65 + index)
return (
<div className="my-6 p-4 border rounded-lg">
<div className="mb-4">
<RichTextContent content={data.pergunta} />
</div>
<div className="space-y-2">
{data.alternativa.map((opcao, index) => (
<button
key={index}
onClick={() => handleOptionClick(index)}
className={cn(
'w-full text-left p-3 border rounded-md',
selectedOptionIndex === index && isCorrect === true
? 'bg-green-100 border-green-500'
: selectedOptionIndex === index && isCorrect === false
? 'bg-red-100 border-red-500'
: 'bg-white dark:bg-gray-800',
)}
>
<span className="font-bold mr-2">{getOptionLetter(index)}.</span>
{opcao.textoAlternativa}
</button>
))}
</div>
{isCorrect !== null && (
<p className="mt-4">
{isCorrect ? 'Resposta correta!' : 'Resposta incorreta. Tente novamente.'}
</p>
)}
</div>
)
}