@page "/storefronts" @rendermode InteractiveServer Storefronts

Storefronts

Manage storefronts and their items.

@if (loading) {
} else if (!string.IsNullOrEmpty(error)) {
@error
} else if (storefronts == null || storefronts.Count == 0) {
No storefronts found.
} else { @foreach (var store in storefronts) {
@store.Name Type: @store.StorefrontType | Items: @(store.Items?.Count ?? 0)
@if (store.Items != null && store.Items.Count > 0) {
@foreach (var item in store.Items) { }
ID PurchasableItemId Type Featured Prices Gift Drops Actions
@item.Id @item.PurchasableItemId @item.Type @(item.IsFeatured ? "Yes" : "No") @if (item.Prices != null && item.Prices.Count > 0) { @foreach (var p in item.Prices) {
Type @p.CurrencyType: @p.Price
} }
@(item.GiftDrops?.Count ?? 0)
} else {

No items in this storefront.

}
} @if (showEditModal) { } } @code { private bool loading = true; private string? error; private List? storefronts; private bool showEditModal; private bool savingItem; private string? modalMessage; private StorefrontItem editingItem = new(); private int editingStorefrontId; private int editPurchasableItemId; private int editType; private bool editIsFeatured; private string? editNewUntil; private int editCurrencyType; private int editPrice; protected override async Task OnInitializedAsync() { await LoadStorefronts(); } private async Task LoadStorefronts() { loading = true; error = null; try { storefronts = await Http.GetFromJsonAsync>("/admin/api/storefronts"); } catch (Exception ex) { error = $"Failed to load storefronts: {ex.Message}"; } finally { loading = false; } } private void EditItem(int storefrontId, StorefrontItem item) { editingStorefrontId = storefrontId; editingItem = item; editPurchasableItemId = item.PurchasableItemId; editType = item.Type; editIsFeatured = item.IsFeatured; editNewUntil = item.NewUntil?.ToString("o"); editCurrencyType = item.Prices?.FirstOrDefault()?.CurrencyType ?? 0; editPrice = item.Prices?.FirstOrDefault()?.Price ?? 0; modalMessage = null; showEditModal = true; } private void StartCreateItem(int storefrontId) { editingStorefrontId = storefrontId; editingItem = new StorefrontItem { StorefrontId = storefrontId }; editPurchasableItemId = 0; editType = 0; editIsFeatured = false; editNewUntil = null; editCurrencyType = 0; editPrice = 0; modalMessage = null; showEditModal = true; } private void CloseModal() { showEditModal = false; modalMessage = null; } private async Task SaveItem() { savingItem = true; modalMessage = null; try { if (editingItem.Id == 0) { var payload = new { purchasableItemId = editPurchasableItemId, type = editType, isFeatured = editIsFeatured, newUntil = editNewUntil, price = editPrice, currencyType = editCurrencyType }; var response = await Http.PostAsJsonAsync($"/admin/api/storefronts/{editingStorefrontId}/items", payload); response.EnsureSuccessStatusCode(); modalMessage = "Item created!"; } else { var payload = new { purchasableItemId = editPurchasableItemId, type = editType, isFeatured = editIsFeatured, newUntil = string.IsNullOrEmpty(editNewUntil) ? null : editNewUntil, prices = new[] { new { currencyType = editCurrencyType, price = editPrice } } }; var response = await Http.PutAsJsonAsync($"/admin/api/storefronts/items/{editingItem.Id}", payload); response.EnsureSuccessStatusCode(); modalMessage = "Item updated!"; } await LoadStorefronts(); } catch (Exception ex) { modalMessage = $"Error: {ex.Message}"; } finally { savingItem = false; } } private async Task DeleteItem(int storefrontId, int itemId) { var confirmed = await JSRuntime.InvokeAsync("confirm", "Delete this item?"); if (!confirmed) return; try { var response = await Http.DeleteAsync($"/admin/api/storefronts/items/{itemId}"); response.EnsureSuccessStatusCode(); await LoadStorefronts(); } catch (Exception ex) { error = $"Failed to delete: {ex.Message}"; } } [Inject] private IJSRuntime JSRuntime { get; set; } = default!; [Inject] private HttpClient Http { get; set; } = default!; }