timed revision
All checks were successful
Mindforge API Build and Deploy / Build Mindforge API Image (push) Successful in 3m58s
Mindforge API Build and Deploy / Deploy Mindforge API (internal) (push) Successful in 37s
Mindforge Web Build and Deploy (internal) / Build Mindforge Web Image (push) Successful in 5m19s
Mindforge Web Build and Deploy (internal) / Deploy Mindforge Web (internal) (push) Successful in 11s

This commit is contained in:
2026-06-01 19:08:48 -03:00
parent b80d28f671
commit f03bcc40e3
14 changed files with 1138 additions and 14 deletions

View File

@@ -24,6 +24,17 @@ function difficultyLabel(difficulty: string) {
return difficulty === 'Hard' ? 'Dificil' : 'Facil';
}
function shuffleCards(cards: FlashcardCard[]) {
const shuffled = [...cards];
for (let i = shuffled.length - 1; i > 0; i--) {
const randomIndex = Math.floor(Math.random() * (i + 1));
[shuffled[i], shuffled[randomIndex]] = [shuffled[randomIndex], shuffled[i]];
}
return shuffled;
}
export function FlashcardReviewComponent() {
const [libraries, setLibraries] = useState<FlashcardLibrarySummary[]>([]);
const [selectedLibraryIds, setSelectedLibraryIds] = useState<number[]>([]);
@@ -33,6 +44,7 @@ export function FlashcardReviewComponent() {
const [sessionCards, setSessionCards] = useState<FlashcardCard[]>([]);
const [currentIndex, setCurrentIndex] = useState(0);
const [showAnswer, setShowAnswer] = useState(false);
const [submittingAnswer, setSubmittingAnswer] = useState(false);
useEffect(() => {
let cancelled = false;
@@ -97,7 +109,7 @@ export function FlashcardReviewComponent() {
libraryIds: selectedLibraryIds,
});
setSessionCards(response.cards);
setSessionCards(shuffleCards(response.cards));
setCurrentIndex(0);
setShowAnswer(false);
} catch (err: any) {
@@ -111,6 +123,7 @@ export function FlashcardReviewComponent() {
setSessionCards([]);
setCurrentIndex(0);
setShowAnswer(false);
setSubmittingAnswer(false);
};
const goToPrevious = () => {
@@ -121,12 +134,32 @@ export function FlashcardReviewComponent() {
setShowAnswer(false);
};
const goToNext = () => {
if (currentIndex >= sessionCards.length - 1) {
const registerReviewAnswer = async (correct: boolean) => {
if (!currentCard) {
return;
}
setCurrentIndex(currentIndex + 1);
setShowAnswer(false);
setSubmittingAnswer(true);
setError(null);
try {
await MindforgeApiService.recordFlashcardReviewAnswer({
cardId: currentCard.id,
correct,
});
if (currentIndex >= sessionCards.length - 1) {
endSession();
return;
}
setCurrentIndex(currentIndex + 1);
setShowAnswer(false);
} catch (err: any) {
setError(err?.message || 'Falha ao registrar resposta da revisao.');
} finally {
setSubmittingAnswer(false);
}
};
return (
@@ -206,7 +239,7 @@ export function FlashcardReviewComponent() {
</article>
<div className="review-session-actions">
<Button variant="secondary" onClick={goToPrevious} disabled={currentIndex === 0}>
<Button variant="secondary" onClick={goToPrevious} disabled={currentIndex === 0 || submittingAnswer}>
Anterior
</Button>
@@ -217,9 +250,14 @@ export function FlashcardReviewComponent() {
)}
{showAnswer && (
<Button variant="primary" onClick={goToNext} disabled={currentIndex >= sessionCards.length - 1}>
Proximo
</Button>
<>
<Button variant="primary" onClick={() => registerReviewAnswer(true)} disabled={submittingAnswer}>
Acertei
</Button>
<Button variant="secondary" onClick={() => registerReviewAnswer(false)} disabled={submittingAnswer}>
Errei
</Button>
</>
)}
<Button variant="secondary" onClick={endSession}>