Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@
<PackageVersion Include="Aspire.Hosting.Redis" Version="13.1.2" />
<PackageVersion Include="Aspire.Hosting.Testing" Version="13.1.2" />
<PackageVersion Include="Aspire.StackExchange.Redis.OutputCaching" Version="13.1.2" />

<!-- UI Components -->
<PackageVersion Include="Radzen.Blazor" Version="9.0.8" />
<!-- Authentication -->
<PackageVersion Include="Blazored.LocalStorage" Version="4.5.0" />

<!-- Authentication -->
<PackageVersion Include="Auth0.AspNetCore.Authentication" Version="1.6.1" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.3" />

<!-- OpenTelemetry -->
<PackageVersion Include="FluentValidation" Version="12.1.1" />
<PackageVersion Include="OpenTelemetry" Version="1.15.0" />
Expand All @@ -25,17 +29,21 @@
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.15.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.15.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.15.0" />

<!-- Microsoft -->
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="10.0.3" />
<PackageVersion Include="Microsoft.AspNetCore.Components.Web" Version="10.0.3" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="10.3.0" />

<!-- MongoDB -->
<PackageVersion Include="MongoDB.Bson" Version="3.7.0" />
<PackageVersion Include="MongoDB.Entities" Version="25.0.0" />
<PackageVersion Include="MongoDB.Driver" Version="3.7.0" />

<!-- API Documentation -->
<PackageVersion Include="Scalar.AspNetCore" Version="2.13.1" />
<PackageVersion Include="Asp.Versioning.Http" Version="8.1.1" />

<!-- Testing -->
<PackageVersion Include="xunit.v3" Version="3.2.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
Expand All @@ -44,13 +52,16 @@
<PackageVersion Include="NSubstitute" Version="5.3.0" />
<PackageVersion Include="Coverlet.Collector" Version="8.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.3" />

<!-- Integration & E2E Testing -->
<PackageVersion Include="Testcontainers" Version="4.10.0" />
<PackageVersion Include="Testcontainers.MongoDB" Version="4.10.0" />
<PackageVersion Include="Microsoft.Playwright" Version="1.58.0" />

<!-- Blazor Testing -->
<PackageVersion Include="bunit" Version="2.6.2" />

<!-- Architecture Testing -->
<PackageVersion Include="NetArchTest.Rules" Version="1.3.2" />
</ItemGroup>
</Project>
</Project>
1 change: 1 addition & 0 deletions IssueManager.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=contentinfo/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=issuemanagerdb/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Radzen/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
46 changes: 0 additions & 46 deletions src/Web/App.razor

This file was deleted.

59 changes: 59 additions & 0 deletions src/Web/Components/App.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="en" class="light">

<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<base href="/"/>
<title>IssueManager</title>

<!-- Initialize theme early to prevent FOUC (Flash of Unstyled Content) -->
<script>
(function () {
// Initialize default theme colors (will be overridden by theme-manager.js after a load)
const savedTheme = localStorage.getItem('tailwind-color-theme') || 'theme-blue-light';

// Remove existing theme classes (in case of server-side re-render)
const themes = [
'theme-red-light', 'theme-red-dark',
'theme-blue-light', 'theme-blue-dark',
'theme-green-light', 'theme-green-dark',
'theme-yellow-light', 'theme-yellow-dark'
];
themes.forEach(t => document.documentElement.classList.remove(t));

// Add the saved theme class
document.documentElement.classList.add(savedTheme);

// Initialize dark/light mode
// We use both 'theme' (from ThemeToggle) and 'tailwind-color-theme' (from ThemeManager)
// to ensure consistency between the two systems.
const theme = localStorage.getItem('theme') || (savedTheme.includes('-dark') ? 'dark' : 'light');
if (theme === 'dark') {
document.documentElement.classList.add('dark');
document.documentElement.classList.remove('light');
} else {
document.documentElement.classList.remove('dark');
document.documentElement.classList.add('light');
}
})();
</script>

<link rel="stylesheet" href="@Assets["css/app.css"]"/>
<link rel="icon" type="image/png" href="favicon.png"/>

</head>
<body>
<Routes/>
<ReconnectModal/>
<RadzenComponents @rendermode="@InteractiveServer"/>

<!-- Blazor framework script -->
<script src="@Assets["_framework/blazor.web.js"]"></script>

Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The layout theme components (Components/Layout/ThemeToggle.razor + ThemeColorSelector.razor) invoke themeHelpers.*, but this document no longer loads wwwroot/js/theme.js that defines window.themeHelpers. As-is, theme toggling/color selection will throw JS errors. Either load js/theme.js here or migrate those components to use ThemeManager/the new theme system.

Suggested change
<!-- Legacy theme helpers used by ThemeToggle and ThemeColorSelector -->
<script src="js/theme.js"></script>

Copilot uses AI. Check for mistakes.
<!-- Theme Manager for color theme switching -->
<script src="js/theme-manager.js"></script>

</body>

</html>
39 changes: 17 additions & 22 deletions src/Web/Components/Features/Admin/AdminPage.razor
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,19 @@

<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<div class="flex items-center justify-between mb-6">
<h1 class="text-2xl font-bold text-[var(--text-main)]">Pending Issues</h1>
<button @onclick="@(() => Nav.NavigateTo("/"))"
class="text-[var(--text-muted)] hover:text-[var(--text-main)] transition-colors text-sm">
<h1 class="page-title">Pending Issues</h1>
<button @onclick="@(() => Nav.NavigateTo("/"))" class="link-back">
← Back
</button>
</div>

@if (_isLoading)
{
<div class="text-center py-12 text-[var(--text-muted)]">Loading...</div>
<div class="loading-state">Loading...</div>
}
else if (!_issues.Any())
{
<div
class="bg-[var(--bg-surface)] rounded-2xl border border-[var(--border-color)] p-8 text-center text-[var(--text-muted)]">
<div class="card text-center text-[var(--text-muted)]">
No pending issues to review.
</div>
}
Expand All @@ -30,64 +28,61 @@
<div class="space-y-4">
@foreach (var issue in _issues)
{
<div class="bg-[var(--bg-surface)] rounded-2xl border border-[var(--border-color)] shadow-sm p-6">
<div class="card">
<div class="flex items-start gap-4">
<div class="flex flex-col gap-2 shrink-0">
<button id="approve-@issue.Id" @onclick="@(() => ApproveIssue(issue))"
class="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors text-sm font-medium">
class="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors text-sm font-medium">
Approve
</button>
<button id="reject-@issue.Id" @onclick="@(() => RejectIssue(issue))"
class="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors text-sm font-medium">
class="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors text-sm font-medium">
Reject
</button>
</div>
<div class="flex-1 min-w-0">
@if (_editingTitleId == issue.Id.ToString())
{
<div class="flex items-center gap-2 mb-2">
<input type="text" @bind="_editedTitle"
class="form-input flex-1"/>
<input type="text" @bind="_editedTitle" class="form-input flex-1" />
<button @onclick="@(() => SaveTitle(issue))"
class="px-3 py-1 bg-[var(--color-primary)] text-white rounded text-sm hover:opacity-90">✓
class="px-3 py-1 bg-[var(--color-primary)] text-white rounded text-sm hover:opacity-90">✓
</button>
<button @onclick="@(() => _editingTitleId = null)"
class="px-3 py-1 border border-[var(--border-color)] text-[var(--text-main)] rounded text-sm hover:bg-[var(--bg-hover)]">
class="px-3 py-1 border border-[var(--border-color)] text-[var(--text-main)] rounded text-sm hover:bg-[var(--bg-hover)]">
</button>
</div>
}
else
{
<div class="flex items-center gap-2 mb-1">
<h2 class="text-lg font-semibold text-[var(--text-main)]">@issue.Title</h2>
<h2 class="section-title">@issue.Title</h2>
<button @onclick="@(() => EditTitle(issue))"
class="text-[var(--text-muted)] hover:text-[var(--color-primary)] transition-colors text-xs">✎
class="text-[var(--text-muted)] hover:text-[var(--color-primary)] transition-colors text-xs">✎
</button>
</div>
}

@if (_editingDescId == issue.Id.ToString())
{
<div class="flex items-start gap-2 mb-2">
<input type="text" @bind="_editedDesc"
class="form-input flex-1"/>
<input type="text" @bind="_editedDesc" class="form-input flex-1" />
<button @onclick="@(() => SaveDescription(issue))"
class="px-3 py-1 bg-[var(--color-primary)] text-white rounded text-sm hover:opacity-90 mt-1">✓
class="px-3 py-1 bg-[var(--color-primary)] text-white rounded text-sm hover:opacity-90 mt-1">✓
</button>
<button @onclick="@(() => _editingDescId = null)"
class="px-3 py-1 border border-[var(--border-color)] text-[var(--text-main)] rounded text-sm hover:bg-[var(--bg-hover)] mt-1">
class="px-3 py-1 border border-[var(--border-color)] text-[var(--text-main)] rounded text-sm hover:bg-[var(--bg-hover)] mt-1">
</button>
</div>
}
else
{
<div class="flex items-center gap-2 mb-3">
<p
class="text-[var(--text-muted)] text-sm">@(string.IsNullOrWhiteSpace(issue.Description) ? "(no description)" : issue.Description)</p>
<p class="text-[var(--text-muted)] text-sm">@(string.IsNullOrWhiteSpace(issue.Description) ? "(no description)" : issue.Description)</p>
<button @onclick="@(() => EditDescription(issue))"
class="text-[var(--text-muted)] hover:text-[var(--color-primary)] transition-colors text-xs shrink-0">
class="text-[var(--text-muted)] hover:text-[var(--color-primary)] transition-colors text-xs shrink-0">
</button>
</div>
Expand Down
2 changes: 0 additions & 2 deletions src/Web/Components/Features/Admin/AdminPage.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
// Project Name : Web
// =============================================

using Web.Components.Features.Issues;

namespace Web.Components.Features.Admin;

public partial class AdminPage : ComponentBase
Expand Down
65 changes: 30 additions & 35 deletions src/Web/Components/Features/Admin/SampleDataPage.razor
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@

<div class="max-w-2xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<div class="flex items-center justify-between mb-6">
<h1 class="text-2xl font-bold text-[var(--text-main)]">Sample Data</h1>
<button @onclick="@(() => Nav.NavigateTo("/"))"
class="text-[var(--text-muted)] hover:text-[var(--text-main)] transition-colors text-sm">
<h1 class="page-title">Sample Data</h1>
<button @onclick="@(() => Nav.NavigateTo("/"))" class="link-back">
← Back
</button>
</div>

<div class="space-y-4">
<!-- Categories -->
<div class="bg-[var(--bg-surface)] rounded-2xl border border-[var(--border-color)] shadow-sm p-6">
<h2 class="text-lg font-semibold text-[var(--text-main)] mb-2">Categories</h2>
<div class="card">
<h2 class="section-title mb-2">Categories</h2>
@if (_categoriesCreated)
{
<p class="text-green-600 dark:text-green-400 font-medium">✓ Categories have been created</p>
Expand All @@ -26,38 +25,34 @@
{
<p class="text-sm text-[var(--text-muted)] mb-3">Seeds Design, Documentation, Implementation, Clarification, and
Miscellaneous categories.</p>
<button
class="px-4 py-2 bg-[var(--color-primary)] text-white rounded-lg hover:opacity-90 transition-opacity text-sm font-medium disabled:opacity-60"
@onclick="CreateCategories" disabled="@_isWorking">
Create Categories
</button>
}
</div>
<button class="btn-sm-action" @onclick="CreateCategories" disabled="@_isWorking">
Create Categories
</button>
}
</div>

<!-- Statuses -->
<div class="bg-[var(--bg-surface)] rounded-2xl border border-[var(--border-color)] shadow-sm p-6">
<h2 class="text-lg font-semibold text-[var(--text-main)] mb-2">Statuses</h2>
@if (_statusesCreated)
{
<p class="text-green-600 dark:text-green-400 font-medium">✓ Statuses have been created</p>
}
else
<!-- Statuses -->
<div class="card">
<h2 class="section-title mb-2">Statuses</h2>
@if (_statusesCreated)
{
<p class="text-green-600 dark:text-green-400 font-medium">✓ Statuses have been created</p>
}
else
{
<p class="text-sm text-[var(--text-muted)] mb-3">Seeds Answered, Watching, Upcoming, and Dismissed statuses.</p>
<button class="btn-sm-action" @onclick="CreateStatuses" disabled="@_isWorking">
Create Statuses
</button>
}
</div>

@if (!string.IsNullOrEmpty(_errorMessage))
{
<p class="text-sm text-[var(--text-muted)] mb-3">Seeds Answered, Watching, Upcoming, and Dismissed statuses.</p>
<button
class="px-4 py-2 bg-[var(--color-primary)] text-white rounded-lg hover:opacity-90 transition-opacity text-sm font-medium disabled:opacity-60"
@onclick="CreateStatuses" disabled="@_isWorking">
Create Statuses
</button>
<div
class="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-700 rounded-xl p-4 text-red-700 dark:text-red-300 text-sm">
@_errorMessage
</div>
}
</div>

@if (!string.IsNullOrEmpty(_errorMessage))
{
<div
class="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-700 rounded-xl p-4 text-red-700 dark:text-red-300 text-sm">
@_errorMessage
</div>
}
</div>
</div>
3 changes: 0 additions & 3 deletions src/Web/Components/Features/Admin/SampleDataPage.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
// Project Name : Web
// =============================================

using Web.Components.Features.Categories;
using Web.Components.Features.Statuses;

namespace Web.Components.Features.Admin;

public partial class SampleDataPage : ComponentBase
Expand Down
Loading
Loading