Refactor admin dashboard and standardize UI shells
TaxBaik CI/CD / build-and-deploy (push) Successful in 2m46s

This commit is contained in:
2026-07-07 23:16:31 +09:00
parent fc655e20c1
commit 08347a4e20
35 changed files with 625 additions and 230 deletions
@@ -18,7 +18,7 @@ public class ValidateSitemapEndpoint : EndpointWithoutRequest
public override void Configure()
{
Get("/api/admin/validate/sitemap");
Roles("admin");
Policies("AdminOnly");
}
public override async Task HandleAsync(CancellationToken ct)
@@ -40,7 +40,7 @@ public class ValidateRssEndpoint : EndpointWithoutRequest
public override void Configure()
{
Get("/api/admin/validate/rss");
Roles("admin");
Policies("AdminOnly");
}
public override async Task HandleAsync(CancellationToken ct)
@@ -62,7 +62,7 @@ public class ValidateConsistencyEndpoint : EndpointWithoutRequest
public override void Configure()
{
Get("/api/admin/validate/consistency");
Roles("admin");
Policies("AdminOnly");
}
public override async Task HandleAsync(CancellationToken ct)
@@ -15,7 +15,7 @@ public class GetMonthlyStatsEndpoint : Endpoint<MonthlyStatsQuery, MonthlyStatsR
public override void Configure()
{
Get("/api/admin-dashboard/monthly-stats");
Policies("Bearer");
Policies("AdminOnly");
}
public override async Task HandleAsync(MonthlyStatsQuery request, CancellationToken ct)
@@ -15,7 +15,7 @@ public class GetRecentInquiriesEndpoint : Endpoint<RecentInquiriesQuery, RecentI
public override void Configure()
{
Get("/api/admin-dashboard/recent-inquiries");
Policies("Bearer");
Policies("AdminOnly");
}
public override async Task HandleAsync(RecentInquiriesQuery request, CancellationToken ct)
@@ -15,7 +15,7 @@ public class GetSummaryEndpoint : EndpointWithoutRequest<AdminDashboardSummaryRe
public override void Configure()
{
Get("/api/admin-dashboard/summary");
Policies("Bearer");
Policies("AdminOnly");
}
public override async Task HandleAsync(CancellationToken ct)
@@ -15,7 +15,7 @@ public class GetUpcomingFilingsEndpoint : Endpoint<UpcomingFilingsQuery, Upcomin
public override void Configure()
{
Get("/api/admin-dashboard/upcoming-filings");
Policies("Bearer");
Policies("AdminOnly");
}
public override async Task HandleAsync(UpcomingFilingsQuery request, CancellationToken ct)
+4
View File
@@ -69,6 +69,10 @@ builder.Services.AddAuthorization(opts =>
opts.AddPolicy("Bearer", new Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.Build());
opts.AddPolicy("AdminOnly", new Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.RequireRole("Admin")
.Build());
});
builder.Services.AddProblemDetails();
builder.Services.AddHealthChecks();
+2 -1
View File
@@ -173,7 +173,8 @@ public class AuthService
{
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
new Claim(ClaimTypes.Name, user.Username),
new Claim("username", user.Username)
new Claim("username", user.Username),
new Claim(ClaimTypes.Role, "Admin")
};
var accessToken = new JwtSecurityToken(
+144
View File
@@ -497,6 +497,9 @@ textarea:focus-visible {
border-right: 1px solid var(--border-color);
display: flex;
flex-direction: column;
position: sticky;
top: 0;
height: 100vh;
}
.admin-drawer-brand {
@@ -539,6 +542,23 @@ textarea:focus-visible {
font-size: 0.78rem;
}
.admin-nav .mud-nav-link .mud-stack {
width: 100%;
gap: 8px;
}
.admin-nav-badge {
margin-left: auto;
height: 18px;
font-size: 0.65rem;
}
.admin-body {
display: flex;
min-height: 0;
flex: 1;
}
.admin-nav .mud-nav-group-header {
min-height: 32px;
font-size: 0.78rem;
@@ -618,6 +638,130 @@ textarea:focus-visible {
width: 100%;
}
.admin-dashboard-grid {
margin-top: 0;
}
.admin-stats-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 12px;
}
.admin-stat {
padding: 14px;
border: 1px solid var(--border-color-light);
border-radius: var(--radius-lg);
background: linear-gradient(180deg, #fff 0%, #f8fbff 100%);
}
.admin-stat-label {
display: block;
margin-bottom: 4px;
color: var(--text-secondary);
font-size: 0.75rem;
}
.admin-stat-value {
font-size: 1.25rem;
font-weight: 700;
color: var(--text-primary);
}
.admin-chart {
margin-top: 14px;
padding: 14px;
border: 1px solid var(--border-color-light);
border-radius: var(--radius-lg);
background: #fff;
}
.admin-chart-header {
display: flex;
justify-content: space-between;
gap: 12px;
margin-bottom: 12px;
font-size: 0.8rem;
color: var(--text-secondary);
}
.admin-chart-bars {
display: flex;
flex-direction: column;
gap: 10px;
}
.admin-chart-row {
display: grid;
grid-template-columns: 56px 1fr 28px;
gap: 10px;
align-items: center;
font-size: 0.75rem;
}
.admin-chart-track {
height: 10px;
background: var(--bg-tertiary);
border-radius: var(--radius-full);
overflow: hidden;
}
.admin-chart-fill {
height: 100%;
border-radius: inherit;
}
.admin-quick-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 12px;
}
.admin-quick-card {
display: flex;
align-items: center;
gap: 12px;
padding: 14px;
border: 1px solid var(--border-color-light);
border-radius: var(--radius-lg);
cursor: pointer;
transition: transform var(--transition-base), box-shadow var(--transition-base), border-color var(--transition-base);
background: linear-gradient(180deg, #fff 0%, #f8fbff 100%);
}
.admin-quick-card:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-md);
border-color: var(--border-color-strong);
}
.admin-quick-card .mud-icon-root {
color: var(--primary-color);
}
.admin-note-list {
display: grid;
gap: 10px;
color: var(--text-secondary);
font-size: 0.8rem;
}
.admin-note-list div {
padding-left: 14px;
position: relative;
}
.admin-note-list div::before {
content: '';
position: absolute;
left: 0;
top: 0.55em;
width: 6px;
height: 6px;
border-radius: 9999px;
background: var(--primary-color);
}
/* ============================================================================
Dashboard Page Styles
============================================================================ */