|
|
<div class="app-container"> |
|
|
<div *ngIf="isLoading" class="loading-overlay"> |
|
|
<span class="loader"></span> |
|
|
</div> |
|
|
|
|
|
<app-header [title]="'Grammar Questions'"></app-header> |
|
|
|
|
|
<img src="assets/images/grammar-bg.png" alt="Chat Background" class="grammar-bg" /> |
|
|
|
|
|
<div class="header-section"> |
|
|
<div class="input-section"> |
|
|
|
|
|
<div class="input-wrapper"> |
|
|
<input [(ngModel)]="topic" |
|
|
(input)="onTopicChange()" |
|
|
[readonly]="isTopicLocked" |
|
|
placeholder="Enter a Topic..." |
|
|
class="input-box topic-input" |
|
|
(focus)="showSuggestions = true" |
|
|
(click)="showSuggestions = true" |
|
|
(blur)="hideSuggestions()" /> |
|
|
|
|
|
|
|
|
<div *ngIf="showSuggestions && !isDropdownDisabled" class="suggestions-container"> |
|
|
<div class="suggestions-list"> |
|
|
<div *ngFor="let suggestion of hardcodedTopics" |
|
|
(click)="selectTopic(suggestion)" |
|
|
class="suggestion-item"> |
|
|
{{ suggestion }} |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<app-button [disabled]="isGenerateDisabled" (click)="generateQuestions()">π Generate</app-button> |
|
|
<app-button [disabled]="!topic || isResetDisabled" (click)="resetTopic()">Reset</app-button> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div *ngIf="isQuestionsGenerated" class="difficulty-container"> |
|
|
<div class="progress-bar-fill" [style.width]="getProgressWidth()"></div> |
|
|
<div class="level-dots"> |
|
|
<div *ngFor="let level of difficultyLevels" |
|
|
class="level-dot" |
|
|
[class.active]="activateLevelDot && currentDifficulty === level"> |
|
|
<div class="level-tooltip" *ngIf="showLevelTooltip && currentDifficulty === level"> |
|
|
{{ level | titlecase }} |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div *ngIf="error" class="error-popup"> |
|
|
<div class="error-popup-content"> |
|
|
<p>{{ error }}</p> |
|
|
<app-button class="close-popup-btn" (click)="closeErrorPopup()">Close</app-button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div *ngIf="!isAllLevelsCompleted" class="full-content"> |
|
|
<div class="questions-container" *ngIf="questions.length > 0"> |
|
|
<div class="quesHintbtn"> |
|
|
<h2 class="section-title">π Questions</h2> |
|
|
</div> |
|
|
|
|
|
<ul class="questions-list"> |
|
|
<li *ngFor="let question of questions" class="question-item"> |
|
|
<div class="question-wrapper"> |
|
|
<div class="question-text-wrapper"> |
|
|
|
|
|
|
|
|
<span class="question-text" *ngFor="let part of question.parts; let i = index"> |
|
|
{{ part }} |
|
|
|
|
|
|
|
|
<span class="answer-slot" *ngIf="i < question.parts.length - 1"> |
|
|
<input [(ngModel)]="userAnswers[question.index]" |
|
|
[readonly]="isValidationInProgress || readonlyAnswers[question.index]" |
|
|
placeholder="" |
|
|
class="answer-input" |
|
|
pattern="[A-Za-z]*" |
|
|
(input)="onInput($event, question.index); onAnswerChange(question.index)" |
|
|
[ngClass]="{ |
|
|
'correct-answer': answerStatuses[question.index] === 'correct', |
|
|
'wrong-answer': answerStatuses[question.index] === 'incorrect' |
|
|
}" /> |
|
|
</span> |
|
|
|
|
|
</span> |
|
|
</div> |
|
|
</div> |
|
|
</li> |
|
|
</ul> |
|
|
|
|
|
|
|
|
<ng-container *ngIf="isFirstAttemptDone && hints?.length"> |
|
|
<div class="hint-anchor" (click)="$event.stopPropagation()"> |
|
|
<button type="button" class="hint-toggle-btn" |
|
|
aria-haspopup="dialog" |
|
|
[attr.aria-expanded]="isHintMenuVisible ? 'true' : 'false'" |
|
|
aria-controls="hintsPanel" |
|
|
(click)="toggleHintMenu()"> |
|
|
π‘ |
|
|
</button> |
|
|
|
|
|
<section *ngIf="isHintMenuVisible" |
|
|
id="hintsPanel" |
|
|
class="hint-popover" |
|
|
role="dialog" |
|
|
aria-modal="true" |
|
|
aria-label="Hints" |
|
|
(click)="$event.stopPropagation()"> |
|
|
|
|
|
<button type="button" |
|
|
class="user-guide-close-icon" |
|
|
aria-label="Close hints" |
|
|
(click)="closeHints()"> |
|
|
Γ |
|
|
</button> |
|
|
|
|
|
<h3 class="hint-title">Hints</h3> |
|
|
|
|
|
<ul class="hint-list" role="list"> |
|
|
<ng-container *ngFor="let hint of hints; let i = index"> |
|
|
<li *ngIf="hint && hint.trim() !== ''" |
|
|
class="hint-item"> |
|
|
<strong>Hint for Question {{ i + 1 }}:</strong> {{ hint }} |
|
|
</li> |
|
|
</ng-container> |
|
|
</ul> |
|
|
</section> |
|
|
</div> |
|
|
|
|
|
<div *ngIf="isHintMenuVisible" class="hint-backdrop" (click)="closeHints()"></div> |
|
|
</ng-container> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="submit-container" |
|
|
*ngIf="isQuestionsGenerated && !isAllLevelsCompleted"> |
|
|
<app-button [disabled]="!areAllAnswersFilled() || isChecked" |
|
|
(click)="checkAllAnswers()"> |
|
|
Validate Answers |
|
|
</app-button> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div *ngIf="showGlobalCountdown" |
|
|
class="global-countdown-overlay" |
|
|
role="status" |
|
|
aria-live="assertive"> |
|
|
|
|
|
<div class="overlay-card"> |
|
|
<div class="ring"> |
|
|
<svg class="ring-svg" viewBox="0 0 220 220" aria-hidden="true"> |
|
|
<circle class="ring-track" cx="110" cy="110" r="90"></circle> |
|
|
<circle class="ring-progress" |
|
|
cx="110" cy="110" r="90" |
|
|
[attr.stroke-dasharray]="ringCircumference" |
|
|
[attr.stroke-dashoffset]="ringDashoffset"></circle> |
|
|
</svg> |
|
|
<div class="ring-number">{{ globalCountdown }}</div> |
|
|
</div> |
|
|
|
|
|
<div class="caption-pill"> |
|
|
{{ overlayCaption }} {{ globalCountdown }}s |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div *ngIf="isAllLevelsCompleted" class="congratulation-message"> |
|
|
<h2>π Congratulations! You have completed all levels! π</h2> |
|
|
<p>Ready to start over and improve even more?</p> |
|
|
<app-button (click)="stopConfettiAndReset()">Start Over</app-button> |
|
|
</div> |
|
|
</div> |
|
|
|