< Summary

Information
Class: Chronicis.Client.ViewModels.GettingStartedViewModel
Assembly: Chronicis.Client
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Client/ViewModels/GettingStartedViewModel.cs
Line coverage
100%
Covered lines: 25
Uncovered lines: 0
Coverable lines: 25
Total lines: 127
Line coverage: 100%
Branch coverage
100%
Covered branches: 8
Total branches: 8
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_CurrentStep()100%11100%
set_CurrentStep(...)100%11100%
get_IsCompleting()100%11100%
set_IsCompleting(...)100%11100%
get_IsReturningUser()100%11100%
set_IsReturningUser(...)100%11100%
.ctor(...)100%11100%
NextStep()100%22100%
PreviousStep()100%22100%
GoToStep(...)100%44100%

File(s)

/home/runner/work/chronicis/chronicis/src/Chronicis.Client/ViewModels/GettingStartedViewModel.cs

#LineLine coverage
 1using Chronicis.Client.Abstractions;
 2using Chronicis.Client.Services;
 3using Chronicis.Shared.Extensions;
 4
 5namespace Chronicis.Client.ViewModels;
 6
 7/// <summary>
 8/// ViewModel for the Getting Started / onboarding wizard.
 9/// Owns step navigation state and the async completion flow.
 10/// </summary>
 11public sealed class GettingStartedViewModel : ViewModelBase
 12{
 13    /// <summary>Total number of wizard steps.</summary>
 14    public const int TotalSteps = 4;
 15
 16    private readonly IUserApiService _userApi;
 17    private readonly IAppNavigator _navigator;
 18    private readonly IUserNotifier _notifier;
 19    private readonly ILogger<GettingStartedViewModel> _logger;
 20
 21    private int _currentStep = 0;
 22    private bool _isCompleting = false;
 23    private bool _isReturningUser = false;
 24
 25    /// <summary>Zero-based index of the currently displayed step (0 – <see cref="TotalSteps"/> − 1).</summary>
 26    public int CurrentStep
 27    {
 28928        get => _currentStep;
 1529        private set => SetField(ref _currentStep, value);
 30    }
 31
 32    /// <summary>Whether the completion async operation is in-flight.</summary>
 33    public bool IsCompleting
 34    {
 2535        get => _isCompleting;
 1036        private set => SetField(ref _isCompleting, value);
 37    }
 38
 39    /// <summary>
 40    /// Whether the user has previously completed onboarding.
 41    /// Affects button labels and skip-to-end behaviour.
 42    /// </summary>
 43    public bool IsReturningUser
 44    {
 3845        get => _isReturningUser;
 1446        private set => SetField(ref _isReturningUser, value);
 47    }
 48
 3149    public GettingStartedViewModel(
 3150        IUserApiService userApi,
 3151        IAppNavigator navigator,
 3152        IUserNotifier notifier,
 3153        ILogger<GettingStartedViewModel> logger)
 54    {
 3155        _userApi = userApi;
 3156        _navigator = navigator;
 3157        _notifier = notifier;
 3158        _logger = logger;
 3159    }
 60
 61    /// <summary>
 62    /// Loads the user profile to determine whether this is a returning user.
 63    /// Call from <c>OnInitializedAsync</c>.
 64    /// </summary>
 65    public async Task InitializeAsync()
 66    {
 67        var profile = await _userApi.GetUserProfileAsync();
 68        IsReturningUser = profile?.HasCompletedOnboarding == true;
 69    }
 70
 71    /// <summary>Advances to the next step, clamped at the last step.</summary>
 72    public void NextStep()
 73    {
 574        if (CurrentStep < TotalSteps - 1)
 475            CurrentStep++;
 576    }
 77
 78    /// <summary>Returns to the previous step, clamped at step 0.</summary>
 79    public void PreviousStep()
 80    {
 281        if (CurrentStep > 0)
 182            CurrentStep--;
 283    }
 84
 85    /// <summary>Jumps directly to <paramref name="step"/> if it is within bounds.</summary>
 86    public void GoToStep(int step)
 87    {
 1388        if (step >= 0 && step < TotalSteps)
 1089            CurrentStep = step;
 1390    }
 91
 92    /// <summary>
 93    /// Completes onboarding (or, for returning users, simply navigates back to the dashboard).
 94    /// Marks the user's profile as having completed onboarding before navigating.
 95    /// </summary>
 96    public async Task CompleteOnboardingAsync()
 97    {
 98        if (IsReturningUser)
 99        {
 100            _navigator.NavigateTo("/dashboard");
 101            return;
 102        }
 103
 104        IsCompleting = true;
 105        try
 106        {
 107            var success = await _userApi.CompleteOnboardingAsync();
 108            if (success)
 109            {
 110                _navigator.NavigateTo("/dashboard", replace: true);
 111            }
 112            else
 113            {
 114                _notifier.Error("Failed to complete setup. Please try again.");
 115            }
 116        }
 117        catch (Exception ex)
 118        {
 119            _logger.LogErrorSanitized(ex, "Error completing onboarding");
 120            _notifier.Error("An error occurred. Please try again.");
 121        }
 122        finally
 123        {
 124            IsCompleting = false;
 125        }
 126    }
 127}