feat(frontend+backend): add theming to the blazor frontend

This commit is contained in:
2025-09-04 22:16:04 -04:00
parent 133efdddea
commit 0768e4816d
30 changed files with 1544 additions and 686 deletions

View File

@@ -5,90 +5,71 @@
<PageTitle>NimbusFlow Dashboard</PageTitle>
<h1>NimbusFlow Dashboard</h1>
<h1 class="nimbus-page-title">
<i class="bi bi-speedometer2 me-3"></i>NimbusFlow Dashboard
</h1>
<div class="row">
<div class="row g-4">
<div class="col-md-3">
<div class="card text-white bg-primary mb-3">
<div class="card-header">Active Members</div>
<div class="card-body">
<h4 class="card-title">@activeMemberCount</h4>
<div class="card nimbus-dashboard-card card-members mb-3">
<div class="card-header d-flex align-items-center">
<i class="bi bi-people-fill me-2"></i>
Active Members
</div>
<div class="card-body text-center">
<h2 class="card-title mb-0">@activeMemberCount</h2>
<small class="opacity-75">Currently Active</small>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-white bg-success mb-3">
<div class="card-header">Pending Schedules</div>
<div class="card-body">
<h4 class="card-title">@pendingScheduleCount</h4>
<div class="card nimbus-dashboard-card card-schedules mb-3">
<div class="card-header d-flex align-items-center">
<i class="bi bi-calendar-event-fill me-2"></i>
Pending Schedules
</div>
<div class="card-body text-center">
<h2 class="card-title mb-0">@pendingScheduleCount</h2>
<small class="opacity-75">Awaiting Response</small>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-white bg-warning mb-3">
<div class="card-header">Upcoming Services</div>
<div class="card-body">
<h4 class="card-title">@upcomingServiceCount</h4>
<div class="card nimbus-dashboard-card card-services mb-3">
<div class="card-header d-flex align-items-center">
<i class="bi bi-calendar-plus-fill me-2"></i>
Upcoming Services
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-white bg-info mb-3">
<div class="card-header">Total Classifications</div>
<div class="card-body">
<h4 class="card-title">@classificationCount</h4>
<div class="card-body text-center">
<h2 class="card-title mb-0">@upcomingServiceCount</h2>
<small class="opacity-75">This Week</small>
</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5>Recent Schedules</h5>
</div>
<div class="card-body">
@if (recentSchedules.Any())
{
<div class="list-group">
@foreach (var schedule in recentSchedules.Take(5))
{
<div class="list-group-item">
<div class="d-flex w-100 justify-content-between">
<h6 class="mb-1">@($"{schedule.Member?.FullName}")</h6>
<small class="badge @GetStatusBadgeClass(schedule.Status)">@schedule.Status</small>
</div>
<p class="mb-1">Service: @schedule.Service?.ServiceDate.ToString("MMM dd, yyyy")</p>
<small>Scheduled: @schedule.ScheduledAt.ToString("MMM dd, yyyy HH:mm")</small>
</div>
}
</div>
}
else
{
<p class="text-muted">No recent schedules found.</p>
}
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5>Quick Actions</h5>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<a href="/schedules/create" class="btn btn-primary">Schedule Next Member</a>
<a href="/members/create" class="btn btn-success">Add New Member</a>
<a href="/services/create" class="btn btn-warning">Create New Service</a>
<a href="/schedules" class="btn btn-info">View All Schedules</a>
</div>
</div>
<div class="row mt-5">
<div class="col-md-12">
<div class="nimbus-quick-actions">
<h5><i class="bi bi-lightning-charge me-2"></i>Quick Actions</h5>
<a href="/schedules/schedule-next" class="btn btn-nimbus-primary me-3 mb-2">
<i class="bi bi-calendar-plus-fill me-2"></i>Schedule Next Member
</a>
<a href="/members" class="btn btn-success me-3 mb-2">
<i class="bi bi-person-plus-fill me-2"></i>Add New Member
</a>
<a href="/services" class="btn btn-outline-warning me-3 mb-2">
<i class="bi bi-gear-wide-connected me-2"></i>Create New Service
</a>
<a href="/schedules" class="btn btn-outline-secondary me-3 mb-2">
<i class="bi bi-list-check me-2"></i>View All Schedules
</a>
</div>
</div>
</div>
@@ -97,8 +78,6 @@
private int activeMemberCount = 0;
private int pendingScheduleCount = 0;
private int upcomingServiceCount = 0;
private int classificationCount = 0;
private List<Schedule> recentSchedules = new();
protected override async Task OnInitializedAsync()
{
@@ -109,14 +88,11 @@
activeMemberCount = members.Count(m => m.IsActive == 1);
var schedules = await ApiService.GetSchedulesAsync();
recentSchedules = schedules.OrderByDescending(s => s.ScheduledAt).ToList();
pendingScheduleCount = schedules.Count(s => s.Status == "pending");
var services = await ApiService.GetServicesAsync();
upcomingServiceCount = services.Count(s => s.ServiceDate >= DateTime.Today);
var classifications = await ApiService.GetClassificationsAsync();
classificationCount = classifications.Count;
}
catch (Exception ex)
{
@@ -124,15 +100,4 @@
Console.WriteLine($"Error loading dashboard data: {ex.Message}");
}
}
private string GetStatusBadgeClass(string status)
{
return status switch
{
"pending" => "bg-warning",
"accepted" => "bg-success",
"declined" => "bg-danger",
_ => "bg-secondary"
};
}
}