Skip to content

Commit 8047acf

Browse files
committed
Quiz feedback integrated in responses flow
1 parent 8b0ba78 commit 8047acf

3 files changed

Lines changed: 206 additions & 6 deletions

File tree

src/app/expo-quiz-2025/expo-quiz-2025.component.css

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,12 +339,126 @@ header p {
339339
background: linear-gradient(45deg, #48bb78, #38a169);
340340
border-color: #2f855a;
341341
color: white;
342+
animation: correctPulse 0.6s ease;
342343
}
343344

344345
.option.incorrect {
345346
background: linear-gradient(45deg, #fc8181, #e53e3e);
346347
border-color: #c53030;
347348
color: white;
349+
animation: incorrectShake 0.6s ease;
350+
}
351+
352+
.option.disabled {
353+
cursor: not-allowed;
354+
opacity: 0.7;
355+
}
356+
357+
.option.disabled:hover {
358+
transform: none;
359+
box-shadow: none;
360+
}
361+
362+
.correct-indicator {
363+
display: block;
364+
font-size: 0.85rem;
365+
margin-top: 8px;
366+
font-weight: bold;
367+
opacity: 0.9;
368+
}
369+
370+
/* Feedback Message Styles */
371+
.feedback-message {
372+
margin-top: 20px;
373+
padding: 20px;
374+
border-radius: 15px;
375+
font-size: 1.4rem;
376+
font-weight: bold;
377+
text-align: center;
378+
animation: fadeInUp 0.5s ease;
379+
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
380+
}
381+
382+
.feedback-message.correct-feedback {
383+
background: linear-gradient(45deg, #48bb78, #38a169);
384+
color: white;
385+
border: 3px solid #2f855a;
386+
}
387+
388+
.feedback-message.incorrect-feedback {
389+
background: linear-gradient(45deg, #fc8181, #e53e3e);
390+
color: white;
391+
border: 3px solid #c53030;
392+
}
393+
394+
/* Explanation Box Styles */
395+
.explanation-box {
396+
margin-top: 20px;
397+
padding: 20px;
398+
border-radius: 15px;
399+
background: linear-gradient(45deg, #ebf8ff, #bee3f8);
400+
border: 3px solid #4299e1;
401+
animation: fadeInUp 0.6s ease;
402+
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
403+
}
404+
405+
.explanation-header {
406+
font-size: 1.2rem;
407+
font-weight: bold;
408+
color: #2c5282;
409+
margin-bottom: 10px;
410+
display: flex;
411+
align-items: center;
412+
gap: 8px;
413+
}
414+
415+
.explanation-text {
416+
font-size: 1.05rem;
417+
line-height: 1.6;
418+
color: #2d3748;
419+
font-style: italic;
420+
}
421+
422+
/* Animations */
423+
@keyframes correctPulse {
424+
0% {
425+
transform: scale(1);
426+
}
427+
25% {
428+
transform: scale(1.05);
429+
}
430+
50% {
431+
transform: scale(1);
432+
}
433+
75% {
434+
transform: scale(1.03);
435+
}
436+
100% {
437+
transform: scale(1);
438+
}
439+
}
440+
441+
@keyframes incorrectShake {
442+
0%, 100% {
443+
transform: translateX(0);
444+
}
445+
10%, 30%, 50%, 70%, 90% {
446+
transform: translateX(-10px);
447+
}
448+
20%, 40%, 60%, 80% {
449+
transform: translateX(10px);
450+
}
451+
}
452+
453+
@keyframes fadeInUp {
454+
from {
455+
opacity: 0;
456+
transform: translateY(20px);
457+
}
458+
to {
459+
opacity: 1;
460+
transform: translateY(0);
461+
}
348462
}
349463

350464
/* Quiz Controls */
@@ -499,6 +613,26 @@ header p {
499613
gap: 15px;
500614
border: 2px solid #48bb78;
501615
text-align: center;
616+
animation: successFlash 1.5s ease;
617+
}
618+
619+
@keyframes successFlash {
620+
0%, 100% {
621+
box-shadow: 0 0 0 0 rgba(72, 187, 120, 0);
622+
transform: scale(1);
623+
}
624+
25% {
625+
box-shadow: 0 0 20px 10px rgba(72, 187, 120, 0.5);
626+
transform: scale(1.02);
627+
}
628+
50% {
629+
box-shadow: 0 0 30px 15px rgba(72, 187, 120, 0.3);
630+
transform: scale(1);
631+
}
632+
75% {
633+
box-shadow: 0 0 20px 10px rgba(72, 187, 120, 0.5);
634+
transform: scale(1.02);
635+
}
502636
}
503637

504638
.score-submitted-section h3 {

src/app/expo-quiz-2025/expo-quiz-2025.component.html

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,27 @@ <h3>Question {{ currentQuestion + 1 }} of 5</h3>
5151
*ngFor="let option of getCurrentQuestion().options; let i = index"
5252
class="option"
5353
[class.selected]="selectedAnswer === i"
54+
[class.correct]="showFeedback && (selectedAnswer === i && isAnswerCorrect || !isAnswerCorrect && i === currentCorrectAnswer)"
55+
[class.incorrect]="showFeedback && selectedAnswer === i && !isAnswerCorrect"
56+
[class.disabled]="showFeedback"
5457
(click)="selectAnswer(i)">
5558
{{ getOptionLetter(i) }}) {{ option }}
59+
<span *ngIf="showFeedback && !isAnswerCorrect && i === currentCorrectAnswer" class="correct-indicator">✓ Correct Answer</span>
5660
</button>
5761
</div>
62+
63+
<!-- Feedback Message -->
64+
<div class="feedback-message" *ngIf="showFeedback"
65+
[class.correct-feedback]="isAnswerCorrect"
66+
[class.incorrect-feedback]="!isAnswerCorrect">
67+
{{ feedbackMessage }}
68+
</div>
69+
70+
<!-- Explanation -->
71+
<div class="explanation-box" *ngIf="showFeedback">
72+
<div class="explanation-header">💡 Explanation</div>
73+
<div class="explanation-text">{{ getCurrentQuestion().explanation }}</div>
74+
</div>
5875
</div>
5976
</div>
6077
<div class="quiz-controls">
@@ -95,10 +112,27 @@ <h3>Question {{ currentQuestion + 1 }} of 5</h3>
95112
*ngFor="let option of getCurrentQuestion().options; let i = index"
96113
class="option"
97114
[class.selected]="selectedAnswer === i"
115+
[class.correct]="showFeedback && (selectedAnswer === i && isAnswerCorrect || !isAnswerCorrect && i === currentCorrectAnswer)"
116+
[class.incorrect]="showFeedback && selectedAnswer === i && !isAnswerCorrect"
117+
[class.disabled]="showFeedback"
98118
(click)="selectAnswer(i)">
99119
{{ getOptionLetter(i) }}) {{ option }}
120+
<span *ngIf="showFeedback && !isAnswerCorrect && i === currentCorrectAnswer" class="correct-indicator">✓ Correct Answer</span>
100121
</button>
101122
</div>
123+
124+
<!-- Feedback Message -->
125+
<div class="feedback-message" *ngIf="showFeedback"
126+
[class.correct-feedback]="isAnswerCorrect"
127+
[class.incorrect-feedback]="!isAnswerCorrect">
128+
{{ feedbackMessage }}
129+
</div>
130+
131+
<!-- Explanation -->
132+
<div class="explanation-box" *ngIf="showFeedback">
133+
<div class="explanation-header">💡 Explanation</div>
134+
<div class="explanation-text">{{ getCurrentQuestion().explanation }}</div>
135+
</div>
102136
</div>
103137
</div>
104138
<div class="quiz-controls">

src/app/expo-quiz-2025/expo-quiz-2025.component.ts

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ export class ExpoQuiz2025Component implements OnInit, OnDestroy {
159159
showResultsModal: boolean = false;
160160
showLeaderboardModal: boolean = false;
161161

162+
// Feedback state
163+
showFeedback: boolean = false;
164+
isAnswerCorrect: boolean = false;
165+
feedbackMessage: string = '';
166+
currentCorrectAnswer: number | null = null;
167+
162168
// Modal data
163169
incorrectAnswers: any[] = [];
164170
playerName: string = '';
@@ -262,10 +268,34 @@ export class ExpoQuiz2025Component implements OnInit, OnDestroy {
262268

263269
private resetQuizState(): void {
264270
this.selectedAnswer = null;
271+
this.showFeedback = false;
272+
this.isAnswerCorrect = false;
273+
this.feedbackMessage = '';
274+
this.currentCorrectAnswer = null;
265275
}
266276

267277
selectAnswer(answerIndex: number): void {
278+
// Don't allow changing answer while feedback is showing
279+
if (this.showFeedback) return;
280+
268281
this.selectedAnswer = answerIndex;
282+
283+
// Check if answer is correct
284+
const correctAnswer = this.quizData[this.currentQuiz!].questions[this.currentQuestion].correct;
285+
this.currentCorrectAnswer = correctAnswer;
286+
this.isAnswerCorrect = (answerIndex === correctAnswer);
287+
288+
// Set feedback message
289+
if (this.isAnswerCorrect) {
290+
const messages = ['🎉 Correct!', '✨ Well done!', '🌟 Excellent!', '👏 Great job!', '💯 Perfect!'];
291+
this.feedbackMessage = messages[Math.floor(Math.random() * messages.length)];
292+
} else {
293+
const messages = ['❌ Incorrect', '🤔 Not quite', '💭 Try again next time', '📚 Keep learning'];
294+
this.feedbackMessage = messages[Math.floor(Math.random() * messages.length)];
295+
}
296+
297+
// Show feedback
298+
this.showFeedback = true;
269299
}
270300

271301
nextQuestion(): void {
@@ -283,6 +313,10 @@ export class ExpoQuiz2025Component implements OnInit, OnDestroy {
283313
// Move to next question
284314
this.currentQuestion++;
285315
this.selectedAnswer = null;
316+
this.showFeedback = false;
317+
this.isAnswerCorrect = false;
318+
this.feedbackMessage = '';
319+
this.currentCorrectAnswer = null;
286320
}
287321

288322
finishQuiz(): void {
@@ -297,8 +331,8 @@ export class ExpoQuiz2025Component implements OnInit, OnDestroy {
297331
this.score++;
298332
}
299333

300-
// Show answers modal first
301-
this.showAnswers();
334+
// Go directly to results, skip the answers modal
335+
this.showResults();
302336
}
303337

304338
private showAnswers(): void {
@@ -414,12 +448,10 @@ export class ExpoQuiz2025Component implements OnInit, OnDestroy {
414448

415449
// Mark name as submitted and clear input
416450
this.nameSubmitted = true;
417-
const playerName = this.playerName.trim();
418451
this.playerName = '';
419452

420-
// Show success message
421-
const quizName = this.currentQuiz === 'food' ? 'Global Food Quiz' : 'SNOMED CT International Quiz';
422-
alert(`Great job, ${playerName}! Your score has been added to the ${quizName} leaderboard!`);
453+
// Trigger flash animation by adding/removing class
454+
// The leaderboard will update with real-time data and the new entry will flash
423455
} catch (error) {
424456
console.error('Error adding to leaderboard:', error);
425457
alert('Sorry, there was an error saving your score. Please try again.');

0 commit comments

Comments
 (0)