Initial commit: NexusArchitect Professional Workstation Overhaul
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
@using MediatR
|
||||
@using NexusReader.Application.Queries.Quiz
|
||||
@using NexusReader.Application.Commands.Quiz
|
||||
@using NexusReader.Application.Abstractions.Services
|
||||
@inject IMediator Mediator
|
||||
@inject IPlatformService PlatformService
|
||||
|
||||
<div class="knowledge-check">
|
||||
<div class="quiz-header">
|
||||
<span class="header-title">Sprawdzian Wiedzy</span>
|
||||
<button class="expand-btn">⌵</button>
|
||||
</div>
|
||||
|
||||
@if (_isLoading)
|
||||
{
|
||||
<div class="loading-state">Pobieranie pytań...</div>
|
||||
}
|
||||
else if (_quiz != null)
|
||||
{
|
||||
<div class="quiz-body">
|
||||
@foreach (var question in _quiz.Questions)
|
||||
{
|
||||
<div class="question-container">
|
||||
<p class="question-text">@question.Question</p>
|
||||
|
||||
<div class="options-list">
|
||||
@for (int i = 0; i < question.Options.Count; i++)
|
||||
{
|
||||
var index = i;
|
||||
var letter = (char)('A' + i);
|
||||
<button class="option-item @GetOptionClass(question, index)"
|
||||
@onclick="() => SelectOptionAsync(question, index)"
|
||||
disabled="@_states.ContainsKey(question)">
|
||||
<span class="option-letter">@letter)</span>
|
||||
<span class="option-text">@question.Options[index]</span>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="quiz-footer">
|
||||
<button class="submit-btn" disabled="@(!AllQuestionsAnswered())">Wyślij</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
@code {
|
||||
[Parameter] public string ContextBlockId { get; set; } = string.Empty;
|
||||
|
||||
private bool _isLoading = true;
|
||||
private QuizDto? _quiz;
|
||||
|
||||
private Dictionary<QuizQuestionDto, (int SelectedIndex, bool IsCorrect)> _states = new();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
_isLoading = true;
|
||||
var query = new GetQuizQuestionsQuery(ContextBlockId);
|
||||
var result = await Mediator.Send(query);
|
||||
|
||||
if (result.IsSuccess)
|
||||
_quiz = result.Value;
|
||||
|
||||
_isLoading = false;
|
||||
}
|
||||
|
||||
private async Task SelectOptionAsync(QuizQuestionDto question, int index)
|
||||
{
|
||||
if (_states.ContainsKey(question)) return;
|
||||
|
||||
// Haptic feedback
|
||||
await PlatformService.VibrateAsync(40);
|
||||
|
||||
var cmd = new SubmitAnswerCommand(index, question.CorrectIndex);
|
||||
var res = await Mediator.Send(cmd);
|
||||
|
||||
_states[question] = (index, res.IsSuccess);
|
||||
|
||||
if (res.IsSuccess)
|
||||
await PlatformService.VibrateSuccessAsync();
|
||||
else
|
||||
await PlatformService.VibrateErrorAsync();
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private bool AllQuestionsAnswered()
|
||||
{
|
||||
return _quiz != null && _states.Count == _quiz.Questions.Count;
|
||||
}
|
||||
|
||||
|
||||
private string GetBlockClass(QuizQuestionDto question)
|
||||
{
|
||||
if (!_states.TryGetValue(question, out var state)) return "";
|
||||
return state.IsCorrect ? "state-correct" : "state-incorrect";
|
||||
}
|
||||
|
||||
private string GetOptionClass(QuizQuestionDto question, int index)
|
||||
{
|
||||
if (!_states.TryGetValue(question, out var state)) return "";
|
||||
|
||||
if (state.SelectedIndex == index)
|
||||
return state.IsCorrect ? "option-correct" : "option-incorrect";
|
||||
|
||||
if (state.IsCorrect == false && question.CorrectIndex == index)
|
||||
return "option-revealed-correct";
|
||||
|
||||
return "option-faded";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user