Test
This commit is contained in:
@@ -0,0 +1,604 @@
|
||||
@page "/user-decks"
|
||||
@implements IDisposable
|
||||
@using System.Text.Json
|
||||
|
||||
<PageTitle>User Decks Management - Chrono DB</PageTitle>
|
||||
|
||||
<div class="d-flex align-items-center justify-content-between mb-4">
|
||||
<div>
|
||||
<h2 class="fw-bold mb-1 text-white">User Decks Database (`UserDeck`)</h2>
|
||||
<p class="text-secondary mb-0">Browse, add, edit, and delete deck builds with native JSONB collection mappings.</p>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<button class="btn btn-chrono-secondary" @onclick="LoadDecksAsync">
|
||||
<i class="bi bi-arrow-clockwise"></i> Refresh
|
||||
</button>
|
||||
<button class="btn btn-chrono-primary" @onclick="OpenAddModal">
|
||||
<i class="bi bi-plus-lg"></i> Create New Deck
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (!string.IsNullOrEmpty(alertMessage))
|
||||
{
|
||||
<div class="alert @(alertIsSuccess ? "alert-success" : "alert-danger") alert-dismissible fade show" role="alert">
|
||||
<i class="bi @(alertIsSuccess ? "bi-check-circle-fill" : "bi-exclamation-triangle-fill") me-2"></i>
|
||||
@alertMessage
|
||||
<button type="button" class="btn-close" @onclick="() => alertMessage = null"></button>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="chrono-card">
|
||||
<div class="d-flex align-items-center justify-content-between mb-3 gap-3">
|
||||
<div class="input-group" style="max-width: 400px;">
|
||||
<span class="input-group-text bg-dark border-secondary text-secondary"><i class="bi bi-search"></i></span>
|
||||
<input type="text" class="form-control form-control-chrono" placeholder="Search decks by name, season, or notes..."
|
||||
@bind="searchTerm" @bind:event="oninput" @bind:after="FilterDecks" />
|
||||
@if (!string.IsNullOrEmpty(searchTerm))
|
||||
{
|
||||
<button class="btn btn-outline-secondary" @onclick="ClearSearch"><i class="bi bi-x-lg"></i></button>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="text-secondary small">
|
||||
Showing @decks.Count deck(s)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (isLoading)
|
||||
{
|
||||
<div class="text-center py-5 text-secondary">
|
||||
<div class="spinner-border text-primary mb-2" role="status"></div>
|
||||
<div>Loading decks from database...</div>
|
||||
</div>
|
||||
}
|
||||
else if (!decks.Any())
|
||||
{
|
||||
<div class="text-center py-5 text-secondary">
|
||||
<i class="bi bi-collection fs-1 d-block mb-2"></i>
|
||||
<h5>No User Decks Found</h5>
|
||||
<p class="small">No decks were found matching your search.</p>
|
||||
<div class="d-flex justify-content-center gap-2 mt-3">
|
||||
<button class="btn btn-chrono-primary" @onclick="OpenAddModal">
|
||||
<i class="bi bi-plus-lg"></i> Create First Deck
|
||||
</button>
|
||||
<button class="btn btn-chrono-secondary" @onclick="SeedSampleDecksAsync">
|
||||
<i class="bi bi-box-arrow-in-down"></i> Seed Sample Decks
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="table-responsive">
|
||||
<table class="chrono-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Deck Name</th>
|
||||
<th style="width: 120px;">Season</th>
|
||||
<th style="width: 130px;">Cards (JSONB)</th>
|
||||
<th style="width: 110px;">Divers</th>
|
||||
<th>Notes</th>
|
||||
<th style="width: 150px;">Updated (UTC)</th>
|
||||
<th style="width: 170px;" class="text-end">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var deck in decks)
|
||||
{
|
||||
var totalCards = deck.Cards?.Count ?? 0;
|
||||
var uniqueCards = deck.Cards?.Distinct().Count() ?? 0;
|
||||
var diverCount = deck.Divers?.Count ?? 0;
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<div class="fw-bold text-white">@deck.Name</div>
|
||||
<div class="text-secondary" style="font-size: 0.75rem;">ID: @deck.Id</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge bg-secondary">@(string.IsNullOrEmpty(deck.Season) ? "General" : deck.Season)</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge bg-primary" title="@($"{uniqueCards} unique card type(s)")">
|
||||
<i class="bi bi-stack me-1"></i> @totalCards cards
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge @(diverCount > 0 ? "bg-purple" : "bg-dark border border-secondary text-secondary")">
|
||||
<i class="bi bi-person-fill me-1"></i> @diverCount
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="text-secondary text-truncate" style="max-width: 220px;" title="@deck.Notes">
|
||||
@(string.IsNullOrEmpty(deck.Notes) ? "-" : deck.Notes)
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="small text-secondary">
|
||||
@deck.UpdatedAt.ToString("yyyy-MM-dd HH:mm")
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button class="btn btn-chrono-secondary" @onclick="() => OpenViewModal(deck)" title="View JSON & Breakdown">
|
||||
<i class="bi bi-eye-fill"></i>
|
||||
</button>
|
||||
<button class="btn btn-chrono-secondary" @onclick="() => OpenEditModal(deck)" title="Edit Deck">
|
||||
<i class="bi bi-pencil-fill"></i>
|
||||
</button>
|
||||
<button class="btn btn-chrono-danger" @onclick="() => OpenDeleteModal(deck)" title="Delete Deck">
|
||||
<i class="bi bi-trash3-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<!-- Add / Edit Modal -->
|
||||
@if (showModal)
|
||||
{
|
||||
<div class="modal-backdrop-custom">
|
||||
<div class="modal-dialog-custom" style="max-width: 750px;">
|
||||
<div class="modal-header-custom">
|
||||
<h5 class="modal-title-custom">
|
||||
<i class="bi @(isEditing ? "bi-pencil-square" : "bi-plus-circle") text-primary me-2"></i>
|
||||
@(isEditing ? "Edit User Deck" : "Create New User Deck")
|
||||
</h5>
|
||||
<button type="button" class="btn-close btn-close-white" @onclick="CloseModal"></button>
|
||||
</div>
|
||||
<div class="modal-body-custom">
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="col-md-8">
|
||||
<label class="form-label text-secondary small fw-bold">DECK NAME</label>
|
||||
<input type="text" class="form-control form-control-chrono" placeholder="Enter deck name..."
|
||||
@bind="currentDeck.Name" />
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-secondary small fw-bold">SEASON</label>
|
||||
<input type="text" class="form-control form-control-chrono" placeholder="e.g. Season 1, Tournament"
|
||||
@bind="currentDeck.Season" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label text-secondary small fw-bold">DECK STRATEGY & NOTES</label>
|
||||
<textarea class="form-control form-control-chrono" rows="2"
|
||||
placeholder="Notes about curve, combos, sideboarding..."
|
||||
@bind="currentDeck.Notes"></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Cards (JSONB Collection) Section -->
|
||||
<div class="chrono-card mb-3 p-3">
|
||||
<div class="d-flex align-items-center justify-content-between mb-2">
|
||||
<span class="fw-bold text-white small">
|
||||
<i class="bi bi-stack text-primary me-1"></i>
|
||||
DECK CARDS (@(currentDeck.Cards?.Count ?? 0) Total)
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Add Card Form -->
|
||||
<div class="row g-2 mb-3">
|
||||
<div class="col-md-7">
|
||||
<input type="text" class="form-control form-control-chrono form-control-sm"
|
||||
list="deckCardSuggestions" placeholder="Card name..." @bind="newCardName" />
|
||||
<datalist id="deckCardSuggestions">
|
||||
@foreach (var c in allCardNames.Take(50))
|
||||
{
|
||||
<option value="@c" />
|
||||
}
|
||||
</datalist>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<select class="form-select form-select-chrono form-select-sm" @bind="newCardCount">
|
||||
<option value="1">x1</option>
|
||||
<option value="2">x2</option>
|
||||
<option value="3">x3</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<button type="button" class="btn btn-sm btn-chrono-secondary w-100" @onclick="AddCardToDeck">
|
||||
<i class="bi bi-plus-circle"></i> Add Card
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Current Cards List (Grouped for display) -->
|
||||
@if (currentDeck.Cards == null || !currentDeck.Cards.Any())
|
||||
{
|
||||
<div class="text-secondary small fst-italic p-2 bg-dark rounded border border-secondary border-opacity-25">
|
||||
No cards added yet. Use the selector above to add cards to this deck.
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="d-flex flex-wrap gap-2" style="max-height: 160px; overflow-y: auto;">
|
||||
@foreach (var group in currentDeck.Cards.GroupBy(c => c))
|
||||
{
|
||||
var cardName = group.Key;
|
||||
var count = group.Count();
|
||||
<div class="badge bg-dark border border-secondary p-2 d-flex align-items-center gap-2">
|
||||
<span class="text-white">@cardName</span>
|
||||
<span class="badge bg-primary">x@count</span>
|
||||
<button type="button" class="btn btn-sm p-0 text-secondary" title="Remove one" @onclick="() => RemoveOneCardFromDeck(cardName)">
|
||||
<i class="bi bi-dash"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-sm p-0 text-danger" title="Remove all" @onclick="() => RemoveAllCardsFromDeck(cardName)">
|
||||
<i class="bi bi-x-circle-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<!-- Divers (JSONB Collection) Section -->
|
||||
<div class="chrono-card mb-0 p-3">
|
||||
<div class="d-flex align-items-center justify-content-between mb-2">
|
||||
<span class="fw-bold text-white small">
|
||||
<i class="bi bi-person-fill text-purple me-1"></i>
|
||||
DIVERS / AGENTS (@(currentDeck.Divers?.Count ?? 0))
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="row g-2 mb-3">
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control form-control-chrono form-control-sm"
|
||||
list="diverSuggestions" placeholder="Agent / Diver name..." @bind="newDiverName" />
|
||||
<datalist id="diverSuggestions">
|
||||
@foreach (var c in agentCardNames.Take(40))
|
||||
{
|
||||
<option value="@c" />
|
||||
}
|
||||
</datalist>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<button type="button" class="btn btn-sm btn-chrono-secondary w-100" @onclick="AddDiverToDeck">
|
||||
<i class="bi bi-plus-circle"></i> Add Diver
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (currentDeck.Divers == null || !currentDeck.Divers.Any())
|
||||
{
|
||||
<div class="text-secondary small fst-italic p-2 bg-dark rounded border border-secondary border-opacity-25">
|
||||
No divers specified for this deck.
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
@foreach (var diver in currentDeck.Divers)
|
||||
{
|
||||
<div class="badge bg-dark border border-purple p-2 d-flex align-items-center gap-2">
|
||||
<span class="text-purple">@diver</span>
|
||||
<button type="button" class="btn btn-sm p-0 text-danger" @onclick="() => RemoveDiverFromDeck(diver)">
|
||||
<i class="bi bi-x-circle-fill"></i>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer-custom">
|
||||
<button type="button" class="btn btn-chrono-secondary" @onclick="CloseModal">Cancel</button>
|
||||
<button type="button" class="btn btn-chrono-primary" @onclick="SaveDeckAsync" disabled="@isSaving">
|
||||
@(isSaving ? "Saving..." : "Save Deck")
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- View JSON & Breakdown Modal -->
|
||||
@if (showViewModal && viewedDeck != null)
|
||||
{
|
||||
<div class="modal-backdrop-custom">
|
||||
<div class="modal-dialog-custom" style="max-width: 650px;">
|
||||
<div class="modal-header-custom">
|
||||
<h5 class="modal-title-custom">
|
||||
<i class="bi bi-file-earmark-code text-primary me-2"></i>
|
||||
Deck Inspection: @viewedDeck.Name
|
||||
</h5>
|
||||
<button type="button" class="btn-close btn-close-white" @onclick="() => showViewModal = false"></button>
|
||||
</div>
|
||||
<div class="modal-body-custom">
|
||||
<div class="mb-3">
|
||||
<h6 class="text-secondary small fw-bold mb-2">RAW JSON DATABASE RECORD</h6>
|
||||
<pre class="code-block" style="max-height: 250px;">@GetFormattedDeckJson(viewedDeck)</pre>
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<h6 class="text-secondary small fw-bold mb-2">CARDS BREAKDOWN</h6>
|
||||
<div class="row g-2">
|
||||
@foreach (var group in (viewedDeck.Cards ?? []).GroupBy(c => c))
|
||||
{
|
||||
<div class="col-md-6">
|
||||
<div class="p-2 rounded bg-dark border border-secondary d-flex align-items-center justify-content-between">
|
||||
<span class="text-white small">@group.Key</span>
|
||||
<span class="badge bg-primary">x@group.Count()</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer-custom">
|
||||
<button type="button" class="btn btn-chrono-secondary" @onclick="() => showViewModal = false">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Delete Confirmation Modal -->
|
||||
@if (showDeleteModal && deckToDelete != null)
|
||||
{
|
||||
<div class="modal-backdrop-custom">
|
||||
<div class="modal-dialog-custom" style="max-width: 450px;">
|
||||
<div class="modal-header-custom">
|
||||
<h5 class="modal-title-custom text-danger">
|
||||
<i class="bi bi-exclamation-triangle-fill me-2"></i>
|
||||
Confirm Delete Deck
|
||||
</h5>
|
||||
<button type="button" class="btn-close btn-close-white" @onclick="() => showDeleteModal = false"></button>
|
||||
</div>
|
||||
<div class="modal-body-custom">
|
||||
<p class="text-white mb-2">Are you sure you want to delete deck:</p>
|
||||
<div class="p-2 rounded bg-dark border border-secondary fw-bold text-primary mb-3">
|
||||
@deckToDelete.Name
|
||||
</div>
|
||||
<p class="text-secondary small mb-0">This will remove the deck record and its JSONB associations from the database.</p>
|
||||
</div>
|
||||
<div class="modal-footer-custom">
|
||||
<button type="button" class="btn btn-chrono-secondary" @onclick="() => showDeleteModal = false">Cancel</button>
|
||||
<button type="button" class="btn btn-chrono-danger" @onclick="ConfirmDeleteAsync" disabled="@isSaving">
|
||||
@(isSaving ? "Deleting..." : "Delete Deck")
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@code {
|
||||
private List<UserDeck> decks = [];
|
||||
private List<string> allCardNames = [];
|
||||
private List<string> agentCardNames = [];
|
||||
private string searchTerm = "";
|
||||
private bool isLoading = true;
|
||||
private bool isSaving = false;
|
||||
private string? alertMessage;
|
||||
private bool alertIsSuccess;
|
||||
|
||||
private bool showModal;
|
||||
private bool isEditing;
|
||||
private UserDeck currentDeck = new();
|
||||
private string newCardName = "";
|
||||
private int newCardCount = 1;
|
||||
private string newDiverName = "";
|
||||
|
||||
private bool showViewModal;
|
||||
private UserDeck? viewedDeck;
|
||||
|
||||
private bool showDeleteModal;
|
||||
private UserDeck? deckToDelete;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
ConfigService.OnConfigurationChanged += HandleConfigChanged;
|
||||
|
||||
try
|
||||
{
|
||||
allCardNames = CardDatabase.Cards
|
||||
.Select(c => c.Name)
|
||||
.Where(n => !string.IsNullOrWhiteSpace(n))
|
||||
.Distinct()
|
||||
.OrderBy(n => n)
|
||||
.ToList();
|
||||
|
||||
agentCardNames = CardDatabase.Cards
|
||||
.Where(c => c.IsAgent)
|
||||
.Select(c => c.Name)
|
||||
.Where(n => !string.IsNullOrWhiteSpace(n))
|
||||
.Distinct()
|
||||
.OrderBy(n => n)
|
||||
.ToList();
|
||||
}
|
||||
catch
|
||||
{
|
||||
allCardNames = [];
|
||||
agentCardNames = [];
|
||||
}
|
||||
|
||||
await LoadDecksAsync();
|
||||
}
|
||||
|
||||
private void HandleConfigChanged()
|
||||
{
|
||||
_ = LoadDecksAsync();
|
||||
}
|
||||
|
||||
private async Task LoadDecksAsync()
|
||||
{
|
||||
isLoading = true;
|
||||
try
|
||||
{
|
||||
decks = await DbService.GetUserDecksAsync(searchTerm);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
alertIsSuccess = false;
|
||||
alertMessage = "Error loading user decks: " + ex.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
isLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task FilterDecks()
|
||||
{
|
||||
decks = await DbService.GetUserDecksAsync(searchTerm);
|
||||
}
|
||||
|
||||
private async Task ClearSearch()
|
||||
{
|
||||
searchTerm = "";
|
||||
await LoadDecksAsync();
|
||||
}
|
||||
|
||||
private void OpenAddModal()
|
||||
{
|
||||
isEditing = false;
|
||||
currentDeck = new UserDeck
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Name = "",
|
||||
Season = "Season 1",
|
||||
UpdatedAt = DateTime.UtcNow,
|
||||
Cards = new List<string>(),
|
||||
Divers = new List<string>()
|
||||
};
|
||||
newCardName = "";
|
||||
newCardCount = 1;
|
||||
newDiverName = "";
|
||||
showModal = true;
|
||||
}
|
||||
|
||||
private void OpenEditModal(UserDeck deck)
|
||||
{
|
||||
isEditing = true;
|
||||
currentDeck = new UserDeck
|
||||
{
|
||||
Id = deck.Id,
|
||||
Name = deck.Name,
|
||||
Season = deck.Season,
|
||||
Notes = deck.Notes,
|
||||
UpdatedAt = deck.UpdatedAt,
|
||||
Cards = deck.Cards?.ToList() ?? new(),
|
||||
Divers = deck.Divers?.ToList() ?? new()
|
||||
};
|
||||
newCardName = "";
|
||||
newCardCount = 1;
|
||||
newDiverName = "";
|
||||
showModal = true;
|
||||
}
|
||||
|
||||
private void CloseModal()
|
||||
{
|
||||
showModal = false;
|
||||
}
|
||||
|
||||
private void AddCardToDeck()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(newCardName)) return;
|
||||
|
||||
currentDeck.Cards ??= new List<string>();
|
||||
for (int i = 0; i < newCardCount; i++)
|
||||
{
|
||||
currentDeck.Cards.Add(newCardName.Trim());
|
||||
}
|
||||
newCardName = "";
|
||||
newCardCount = 1;
|
||||
}
|
||||
|
||||
private void RemoveOneCardFromDeck(string cardName)
|
||||
{
|
||||
currentDeck.Cards?.Remove(cardName);
|
||||
}
|
||||
|
||||
private void RemoveAllCardsFromDeck(string cardName)
|
||||
{
|
||||
currentDeck.Cards?.RemoveAll(c => c == cardName);
|
||||
}
|
||||
|
||||
private void AddDiverToDeck()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(newDiverName)) return;
|
||||
|
||||
currentDeck.Divers ??= new List<string>();
|
||||
if (!currentDeck.Divers.Contains(newDiverName.Trim(), StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
currentDeck.Divers.Add(newDiverName.Trim());
|
||||
}
|
||||
newDiverName = "";
|
||||
}
|
||||
|
||||
private void RemoveDiverFromDeck(string diver)
|
||||
{
|
||||
currentDeck.Divers?.Remove(diver);
|
||||
}
|
||||
|
||||
private async Task SaveDeckAsync()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(currentDeck.Name))
|
||||
{
|
||||
alertIsSuccess = false;
|
||||
alertMessage = "Deck name cannot be empty.";
|
||||
return;
|
||||
}
|
||||
|
||||
isSaving = true;
|
||||
var result = await DbService.SaveUserDeckAsync(currentDeck, !isEditing);
|
||||
isSaving = false;
|
||||
|
||||
alertIsSuccess = result.Success;
|
||||
alertMessage = result.Message;
|
||||
|
||||
if (result.Success)
|
||||
{
|
||||
showModal = false;
|
||||
await LoadDecksAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenViewModal(UserDeck deck)
|
||||
{
|
||||
viewedDeck = deck;
|
||||
showViewModal = true;
|
||||
}
|
||||
|
||||
private string GetFormattedDeckJson(UserDeck deck)
|
||||
{
|
||||
return JsonSerializer.Serialize(deck, new JsonSerializerOptions { WriteIndented = true });
|
||||
}
|
||||
|
||||
private void OpenDeleteModal(UserDeck deck)
|
||||
{
|
||||
deckToDelete = deck;
|
||||
showDeleteModal = true;
|
||||
}
|
||||
|
||||
private async Task ConfirmDeleteAsync()
|
||||
{
|
||||
if (deckToDelete == null) return;
|
||||
|
||||
isSaving = true;
|
||||
var result = await DbService.DeleteUserDeckAsync(deckToDelete.Id);
|
||||
isSaving = false;
|
||||
|
||||
alertIsSuccess = result.Success;
|
||||
alertMessage = result.Message;
|
||||
showDeleteModal = false;
|
||||
deckToDelete = null;
|
||||
|
||||
await LoadDecksAsync();
|
||||
}
|
||||
|
||||
private async Task SeedSampleDecksAsync()
|
||||
{
|
||||
var result = await DbService.SeedSampleDataAsync();
|
||||
alertIsSuccess = result.Success;
|
||||
alertMessage = result.Message;
|
||||
await LoadDecksAsync();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ConfigService.OnConfigurationChanged -= HandleConfigChanged;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user