< Summary

Information
Class: Chronicis.Client.Pages.Cosmos
Assembly: Chronicis.Client
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Client/Pages/Cosmos.razor
Line coverage
100%
Covered lines: 10
Uncovered lines: 0
Coverable lines: 10
Total lines: 270
Line coverage: 100%
Branch coverage
100%
Covered branches: 6
Total branches: 6
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
BuildRenderTree(...)100%66100%
OnVmPropertyChanged(...)100%11100%
Dispose()100%11100%

File(s)

/home/runner/work/chronicis/chronicis/src/Chronicis.Client/Pages/Cosmos.razor

#LineLine coverage
 1@page "/articosmoscle/{*Path}"
 2@attribute [Authorize]
 3@inject CosmosViewModel VM
 4@inject ITreeStateService TreeStateService
 5@implements IDisposable
 6
 7@code {
 8    private readonly ILogger<Cosmos> _logger;
 9
 10    // Direct constructor injection
 1011    public Cosmos(ILogger<Cosmos> logger)
 12    {
 1013        _logger = logger;
 1014    }
 15}
 16
 3417@if (TreeStateService.SelectedArticleId.HasValue && TreeStateService.SelectedArticleId.Value != Guid.Empty)
 18{
 19    <ArticleDetail />
 20}
 21else
 22{
 23    <div class="chronicis-welcome-page">
 24        <!-- Hero Section -->
 25        <MudPaper Elevation="0" Class="chronicis-hero pa-8 mb-6" Style="background: linear-gradient(135deg, rgba(31, 42,
 26            <div class="text-center">
 27                <div style="font-size: 4rem; margin-bottom: 16px;">📖✨</div>
 28                <MudText Typo="Typo.h2" Class="mb-3" Style="font-family: 'Spellweaver Display', serif; color: #C4AF8E;">
 29                    Your Chronicle Awaits
 30                </MudText>
 31                <MudText Typo="Typo.h6" Class="mb-4" Style="opacity: 0.9; max-width: 600px; margin: 0 auto;">
 32                    Every great campaign deserves a legendary chronicle. Organize your world, track your story, and neve
 33                </MudText>
 34                <MudButton Variant="Variant.Filled"
 35                           Color="Color.Primary"
 36                           Size="Size.Large"
 37                           StartIcon="@Icons.Material.Filled.Add"
 38                           OnClick="VM.CreateFirstArticleAsync"
 39                           Class="mt-2">
 40                    Start Your First Article
 41                </MudButton>
 42            </div>
 43        </MudPaper>
 44
 45        <!-- Stats Cards -->
 3346        @if (VM.Stats != null)
 47        {
 48            <MudGrid Class="mb-6">
 49                <MudItem xs="12" sm="6" md="3">
 50                    <MudPaper Elevation="2" Class="pa-4 text-center chronicis-stat-card">
 51                        <div style="font-size: 2.5rem; color: #C4AF8E;">📚</div>
 52                        <MudText Typo="Typo.h4" Class="mt-2">@VM.Stats.TotalArticles</MudText>
 53                        <MudText Typo="Typo.body2" Color="Color.Secondary">Total Articles</MudText>
 54                    </MudPaper>
 55                </MudItem>
 56                <MudItem xs="12" sm="6" md="3">
 57                    <MudPaper Elevation="2" Class="pa-4 text-center chronicis-stat-card">
 58                        <div style="font-size: 2.5rem; color: #C4AF8E;">🗂️</div>
 59                        <MudText Typo="Typo.h4" Class="mt-2">@VM.Stats.RootArticles</MudText>
 60                        <MudText Typo="Typo.body2" Color="Color.Secondary">Top-Level Topics</MudText>
 61                    </MudPaper>
 62                </MudItem>
 63                <MudItem xs="12" sm="6" md="3">
 64                    <MudPaper Elevation="2" Class="pa-4 text-center chronicis-stat-card">
 65                        <div style="font-size: 2.5rem; color: #C4AF8E;">✍️</div>
 66                        <MudText Typo="Typo.h4" Class="mt-2">@VM.Stats.RecentlyModified</MudText>
 67                        <MudText Typo="Typo.body2" Color="Color.Secondary">Edited This Week</MudText>
 68                    </MudPaper>
 69                </MudItem>
 70                <MudItem xs="12" sm="6" md="3">
 71                    <MudPaper Elevation="2" Class="pa-4 text-center chronicis-stat-card">
 72                        <div style="font-size: 2.5rem; color: #C4AF8E;">🎲</div>
 73                        <MudText Typo="Typo.h4" Class="mt-2">@VM.Stats.DaysSinceStart</MudText>
 74                        <MudText Typo="Typo.body2" Color="Color.Secondary">Days Chronicling</MudText>
 75                    </MudPaper>
 76                </MudItem>
 77            </MudGrid>
 78        }
 79
 80        <!-- Main Content Grid -->
 81        <MudGrid>
 82            <!-- Recent Articles -->
 83            <MudItem xs="12" md="8">
 84                <MudPaper Elevation="2" Class="pa-6">
 85                    <div class="d-flex align-center justify-space-between mb-4">
 86                        <MudText Typo="Typo.h5" Style="color: #C4AF8E;">
 87                            📜 Recent Articles
 88                        </MudText>
 89                        @if (VM.RecentArticles?.Any() ?? false)
 90                        {
 91                            <MudButton Variant="Variant.Text"
 92                                       Color="Color.Primary"
 93                                       Size="Size.Small">
 94                                View All
 95                            </MudButton>
 96                        }
 97                    </div>
 98
 99                    @if (VM.IsLoadingRecent)
 100                    {
 101                        <div class="text-center py-4">
 102                            <MudProgressCircular Color="Color.Primary" Size="Size.Small" Indeterminate="true" />
 103                        </div>
 104                    }
 105                    else if (VM.RecentArticles?.Any() ?? false)
 106                    {
 107                        <MudList T="string">
 108                            @foreach (var article in VM.RecentArticles)
 109                            {
 110                                <MudListItem T="string" OnClick="@(() => VM.NavigateToArticleAsync(article.Id))">
 111                                    <div class="d-flex align-center">
 112                                        <MudIcon Icon="@(string.IsNullOrEmpty(article.IconEmoji) ? Icons.Material.Filled
 113                                                 Color="Color.Primary"
 114                                                 Class="mr-3" />
 115                                        <div style="flex: 1;">
 116                                            <MudText Typo="Typo.body1">
 117                                                @(string.IsNullOrEmpty(article.Title) ? "(Untitled)" : article.Title)
 118                                            </MudText>
 119                                            <MudText Typo="Typo.caption" Color="Color.Secondary">
 120                                                Modified @CosmosViewModel.FormatRelativeTime(article.ModifiedAt ?? artic
 121                                            </MudText>
 122                                        </div>
 123                                        <MudIcon Icon="@Icons.Material.Filled.ChevronRight" Size="Size.Small" />
 124                                    </div>
 125                                </MudListItem>
 126                                <MudDivider />
 127                            }
 128                        </MudList>
 129                    }
 130                    else
 131                    {
 132                        <div class="text-center py-6" style="opacity: 0.6;">
 133                            <div style="font-size: 3rem; margin-bottom: 12px;">📝</div>
 134                            <MudText Typo="Typo.body1" Color="Color.Secondary">
 135                                No articles yet. Start building your chronicle!
 136                            </MudText>
 137                        </div>
 138                    }
 139                </MudPaper>
 140            </MudItem>
 141
 142            <!-- Quick Actions & Tips -->
 143            <MudItem xs="12" md="4">
 144                <!-- Quick Actions -->
 145                <MudPaper Elevation="2" Class="pa-6 mb-4">
 146                    <MudText Typo="Typo.h6" Class="mb-3" Style="color: #C4AF8E;">
 147                        ⚡ Quick Actions
 148                    </MudText>
 149                    <MudStack Spacing="2">
 150                        <MudButton Variant="Variant.Outlined"
 151                                   Color="Color.Primary"
 152                                   FullWidth="true"
 153                                   StartIcon="@Icons.Material.Filled.PersonAdd"
 154                                   OnClick="@(() => VM.CreateArticleWithTitleAsync("New Character"))">
 155                            Create Character
 156                        </MudButton>
 157                        <MudButton Variant="Variant.Outlined"
 158                                   Color="Color.Primary"
 159                                   FullWidth="true"
 160                                   StartIcon="@Icons.Material.Filled.Place"
 161                                   OnClick="@(() => VM.CreateArticleWithTitleAsync("New Location"))">
 162                            Add Location
 163                        </MudButton>
 164                        <MudButton Variant="Variant.Outlined"
 165                                   Color="Color.Primary"
 166                                   FullWidth="true"
 167                                   StartIcon="@Icons.Material.Filled.CalendarToday"
 168                                   OnClick="@(() => VM.CreateArticleWithTitleAsync("Session Notes"))">
 169                            Session Notes
 170                        </MudButton>
 171                        <MudButton Variant="Variant.Outlined"
 172                                   Color="Color.Primary"
 173                                   FullWidth="true"
 174                                   StartIcon="@Icons.Material.Filled.AutoStories"
 175                                   OnClick="@(() => VM.CreateArticleWithTitleAsync("Lore Entry"))">
 176                            Lore Entry
 177                        </MudButton>
 178                    </MudStack>
 179                </MudPaper>
 180
 181                <!-- Tips Card -->
 182                <MudPaper Elevation="2" Class="pa-6" Style="background: linear-gradient(135deg, rgba(196, 175, 142, 0.1)
 183                    <MudText Typo="Typo.h6" Class="mb-3" Style="color: #C4AF8E;">
 184                        💡 Pro Tips
 185                    </MudText>
 186                    <MudStack Spacing="3">
 187                        <div>
 188                            <MudText Typo="Typo.body2" Class="mb-1">
 189                                <strong>Search Tree:</strong>
 190                            </MudText>
 191                            <MudText Typo="Typo.caption" Color="Color.Secondary">
 192                                Use the search box in the sidebar to filter articles by title
 193                            </MudText>
 194                        </div>
 195                        <MudDivider />
 196                        <div>
 197                            <MudText Typo="Typo.body2" Class="mb-1">
 198                                <strong>Organize with Hierarchy:</strong>
 199                            </MudText>
 200                            <MudText Typo="Typo.caption" Color="Color.Secondary">
 201                                Use the three-dot menu to add child articles and build your knowledge tree
 202                            </MudText>
 203                        </div>
 204                        <MudDivider />
 205                        <div>
 206                            <MudText Typo="Typo.body2" Class="mb-1">
 207                                <strong>Auto-Save:</strong>
 208                            </MudText>
 209                            <MudText Typo="Typo.caption" Color="Color.Secondary">
 210                                Your work saves automatically as you type—no need to click Save!
 211                            </MudText>
 212                        </div>
 213                    </MudStack>
 214                </MudPaper>
 215            </MudItem>
 216        </MudGrid>
 217
 218        <!-- Inspirational Quote Footer -->
 219        <MudPaper Elevation="0" Class="pa-6 mt-6 text-center chronicis-quote-footer" Style="background: rgba(196, 175, 1
 220            @if (VM.LoadingQuote)
 221            {
 222                <MudProgressCircular Color="Color.Primary" Size="Size.Small" Indeterminate="true" />
 223            }
 224            else if (VM.Quote != null)
 225            {
 226                <MudText Typo="Typo.body1" Style="font-style: italic; color: #3A4750;">
 227                    "@VM.Quote.Content"
 228                </MudText>
 229                <MudText Typo="Typo.caption" Color="Color.Secondary" Class="mt-2">
 230                    — @VM.Quote.Author
 231                </MudText>
 232                <MudTooltip Text="Get a new quote">
 233                    <MudIconButton Icon="@Icons.Material.Filled.Refresh"
 234                                   Size="Size.Small"
 235                                   Color="Color.Primary"
 236                                   OnClick="VM.LoadNewQuoteAsync"
 237                                   Class="mt-2"
 238                                   Style="opacity: 0.6;" />
 239                </MudTooltip>
 240            }
 241        </MudPaper>
 242    </div>
 243}
 244
 245@code {
 246    [Parameter]
 247    public string? Path { get; set; }
 248
 249    protected override async Task OnInitializedAsync()
 250    {
 251        VM.PropertyChanged += OnVmPropertyChanged;
 252        await VM.InitializeAsync(Path);
 253    }
 254
 255    protected override async Task OnParametersSetAsync()
 256    {
 257        await VM.OnParametersSetAsync(Path);
 258    }
 259
 260    private void OnVmPropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
 261    {
 48262        InvokeAsync(StateHasChanged);
 48263    }
 264
 265    public void Dispose()
 266    {
 10267        VM.PropertyChanged -= OnVmPropertyChanged;
 10268        VM.Dispose();
 10269    }
 270}