Files
nimbusflow/frontend/Components/Pages/Members.razor

181 lines
7.0 KiB
Plaintext

@page "/members"
@using NimbusFlow.Frontend.Services
@using NimbusFlow.Frontend.Models
@inject IApiService ApiService
@inject NavigationManager Navigation
@inject IJSRuntime JSRuntime
<PageTitle>Members</PageTitle>
<div class="d-flex justify-content-between align-items-center mb-4">
<h1>Members</h1>
<a href="/members/create" class="btn btn-primary">
<i class="bi bi-plus-circle"></i> Add Member
</a>
</div>
@if (loading)
{
<div class="text-center">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
}
else if (members.Any())
{
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Name</th>
<th>Classification</th>
<th>Email</th>
<th>Phone</th>
<th>Status</th>
<th>Last Accepted</th>
<th>Decline Streak</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (var member in filteredMembers)
{
<tr>
<td>
<strong>@member.FullName</strong>
</td>
<td>
<span class="badge bg-secondary">@member.ClassificationName</span>
</td>
<td>@member.Email</td>
<td>@member.PhoneNumber</td>
<td>
@if (member.IsActive == 1)
{
<span class="badge bg-success">Active</span>
}
else
{
<span class="badge bg-danger">Inactive</span>
}
</td>
<td>
@if (member.LastAcceptedAt.HasValue)
{
@member.LastAcceptedAt.Value.ToString("MMM dd, yyyy")
}
else
{
<span class="text-muted">Never</span>
}
</td>
<td>
@if (member.DeclineStreak > 0)
{
<span class="badge bg-warning">@member.DeclineStreak</span>
}
else
{
<span class="text-muted">0</span>
}
</td>
<td>
<div class="btn-group" role="group">
<a href="/members/@member.MemberId" class="btn btn-sm btn-outline-primary">View</a>
<a href="/members/@member.MemberId/edit" class="btn btn-sm btn-outline-warning">Edit</a>
<button class="btn btn-sm btn-outline-danger" @onclick="() => ConfirmDelete(member)">Delete</button>
</div>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-md-12">
<div class="d-flex justify-content-between align-items-center">
<small class="text-muted">
Showing @filteredMembers.Count() of @members.Count members
</small>
<div class="form-check">
<input class="form-check-input" type="checkbox" @bind="showInactiveMembers" id="showInactive">
<label class="form-check-label" for="showInactive">
Show inactive members
</label>
</div>
</div>
</div>
</div>
}
else
{
<div class="text-center">
<div class="alert alert-info">
<h4>No Members Found</h4>
<p>There are currently no members in the system.</p>
<a href="/members/create" class="btn btn-primary">Add Your First Member</a>
</div>
</div>
}
@code {
private List<Member> members = new();
private bool loading = true;
private bool showInactiveMembers = false;
private IEnumerable<Member> filteredMembers =>
showInactiveMembers ? members : members.Where(m => m.IsActive == 1);
protected override async Task OnInitializedAsync()
{
await LoadMembers();
}
private async Task LoadMembers()
{
try
{
loading = true;
members = await ApiService.GetMembersAsync();
}
catch (Exception ex)
{
// Handle error (could show toast notification)
Console.WriteLine($"Error loading members: {ex.Message}");
}
finally
{
loading = false;
}
}
private async Task ConfirmDelete(Member member)
{
var confirmed = await JSRuntime.InvokeAsync<bool>("confirm", $"Are you sure you want to delete {member.FullName}?");
if (confirmed)
{
try
{
var success = await ApiService.DeleteMemberAsync(member.MemberId);
if (success)
{
await LoadMembers(); // Refresh the list
}
}
catch (Exception ex)
{
Console.WriteLine($"Error deleting member: {ex.Message}");
}
}
}
}