- ASP.NET Core 8 REST API server - 12 API endpoints matching EA Synergy protocol - SQLite database with Entity Framework Core - Web admin panel with Bootstrap 5 - User, Catalog, Session, Purchase management - Comprehensive documentation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
202 lines
11 KiB
Plaintext
202 lines
11 KiB
Plaintext
@page
|
|
@model RR3CommunityServer.Pages.CatalogModel
|
|
@{
|
|
ViewData["Title"] = "Catalog Management";
|
|
}
|
|
|
|
<div class="container-fluid mt-4">
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h1>🏪 Catalog Management</h1>
|
|
<p class="text-muted">Manage in-game items and purchases</p>
|
|
</div>
|
|
<div>
|
|
<button class="btn btn-success" data-bs-toggle="modal" data-bs-target="#addItemModal">
|
|
<i class="bi bi-plus-circle"></i> Add New Item
|
|
</button>
|
|
<a href="/admin" class="btn btn-outline-secondary">← Back</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header bg-info text-white">
|
|
<h5 class="mb-0">Catalog Items (@Model.CatalogItems.Count)</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="table-responsive">
|
|
<table class="table table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th>SKU</th>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Price</th>
|
|
<th>Available</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach (var item in Model.CatalogItems)
|
|
{
|
|
<tr>
|
|
<td><code>@item.Sku</code></td>
|
|
<td><strong>@item.Name</strong></td>
|
|
<td>
|
|
<span class="badge bg-secondary">@item.Type</span>
|
|
</td>
|
|
<td>
|
|
@if (item.Price == 0)
|
|
{
|
|
<span class="text-success"><strong>FREE</strong></span>
|
|
}
|
|
else
|
|
{
|
|
<span>@item.Price.ToString("C2")</span>
|
|
}
|
|
</td>
|
|
<td>
|
|
@if (item.Available)
|
|
{
|
|
<span class="badge bg-success">✓ Yes</span>
|
|
}
|
|
else
|
|
{
|
|
<span class="badge bg-danger">✗ No</span>
|
|
}
|
|
</td>
|
|
<td>
|
|
<button class="btn btn-sm btn-primary" data-bs-toggle="modal" data-bs-target="#editModal@(item.Id)">
|
|
<i class="bi bi-pencil"></i> Edit
|
|
</button>
|
|
<form method="post" asp-page-handler="ToggleAvailability" class="d-inline">
|
|
<input type="hidden" name="itemId" value="@item.Id" />
|
|
<button type="submit" class="btn btn-sm btn-@(item.Available ? "warning" : "success")">
|
|
<i class="bi bi-@(item.Available ? "eye-slash" : "eye")"></i> @(item.Available ? "Disable" : "Enable")
|
|
</button>
|
|
</form>
|
|
<form method="post" asp-page-handler="Delete" class="d-inline">
|
|
<input type="hidden" name="itemId" value="@item.Id" />
|
|
<button type="submit" class="btn btn-sm btn-danger" onclick="return confirm('Delete this item?')">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
|
|
<!-- Edit Modal -->
|
|
<div class="modal fade" id="editModal@(item.Id)" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<form method="post" asp-page-handler="Update">
|
|
<div class="modal-header bg-primary text-white">
|
|
<h5 class="modal-title">Edit Item</h5>
|
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<input type="hidden" name="itemId" value="@item.Id" />
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">SKU</label>
|
|
<input type="text" name="sku" value="@item.Sku" class="form-control" required>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">Name</label>
|
|
<input type="text" name="name" value="@item.Name" class="form-control" required>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">Type</label>
|
|
<select name="type" class="form-select" required>
|
|
<option value="car" selected="@(item.Type == "car")">Car</option>
|
|
<option value="upgrade" selected="@(item.Type == "upgrade")">Upgrade</option>
|
|
<option value="currency" selected="@(item.Type == "currency")">Currency</option>
|
|
<option value="consumable" selected="@(item.Type == "consumable")">Consumable</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">Price</label>
|
|
<input type="number" name="price" value="@item.Price" step="0.01" class="form-control" required>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<div class="form-check">
|
|
<input type="checkbox" name="available" checked="@item.Available" class="form-check-input" id="available@(item.Id)">
|
|
<label class="form-check-label" for="available@(item.Id)">Available for purchase</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="submit" class="btn btn-primary">Save Changes</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Add New Item Modal -->
|
|
<div class="modal fade" id="addItemModal" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<form method="post" asp-page-handler="Add">
|
|
<div class="modal-header bg-success text-white">
|
|
<h5 class="modal-title">Add New Item</h5>
|
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="mb-3">
|
|
<label class="form-label">SKU</label>
|
|
<input type="text" name="sku" class="form-control" placeholder="com.ea.rr3.car.porsche911" required>
|
|
<small class="text-muted">Unique identifier (e.g., com.ea.rr3.car.name)</small>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">Name</label>
|
|
<input type="text" name="name" class="form-control" placeholder="Porsche 911 GT3" required>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">Type</label>
|
|
<select name="type" class="form-select" required>
|
|
<option value="car">Car</option>
|
|
<option value="upgrade">Upgrade</option>
|
|
<option value="currency">Currency</option>
|
|
<option value="consumable">Consumable</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">Price</label>
|
|
<input type="number" name="price" step="0.01" value="0.00" class="form-control" required>
|
|
<small class="text-muted">Set to 0 for free items</small>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<div class="form-check">
|
|
<input type="checkbox" name="available" checked class="form-check-input" id="availableNew">
|
|
<label class="form-check-label" for="availableNew">Available for purchase</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="submit" class="btn btn-success">Add Item</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|