diff --git a/Aaru.Server/Components/Admin/AdminNavMenu.razor b/Aaru.Server/Components/Admin/AdminNavMenu.razor
index 50f70b87..26028b87 100644
--- a/Aaru.Server/Components/Admin/AdminNavMenu.razor
+++ b/Aaru.Server/Components/Admin/AdminNavMenu.razor
@@ -26,6 +26,9 @@
Partitions
+
+ USB Products
+
Versions
diff --git a/Aaru.Server/Components/Admin/Pages/Usb/Products/List.razor b/Aaru.Server/Components/Admin/Pages/Usb/Products/List.razor
new file mode 100644
index 00000000..dfca1cf1
--- /dev/null
+++ b/Aaru.Server/Components/Admin/Pages/Usb/Products/List.razor
@@ -0,0 +1,51 @@
+@page "/admin/usb/products"
+@attribute [Authorize]
+@layout AdminLayout
+@rendermode InteractiveServer
+
+@inject Microsoft.EntityFrameworkCore.IDbContextFactory DbContextFactory
+
+USB products
+
+@if(!_initialized)
+{
+
+
Loading...
+
+
+ return;
+}
+
+
+
+
+
+ |
+ @DisplayNameHelper.GetDisplayName(typeof(UsbProductModel), nameof(UsbProductModel.VendorName))
+ |
+
+ @DisplayNameHelper.GetDisplayName(typeof(UsbProductModel), nameof(UsbProductModel.ProductName))
+ |
+
+ @DisplayNameHelper.GetDisplayName(typeof(UsbProductModel), nameof(UsbProductModel.ProductId))
+ |
+
+
+
+ @foreach(UsbProductModel item in _items)
+ {
+
+ |
+ @item.VendorName
+ |
+
+ @item.ProductName
+ |
+
+ @item.ProductId
+ |
+
+ }
+
+
+
\ No newline at end of file
diff --git a/Aaru.Server/Components/Admin/Pages/Usb/Products/List.razor.cs b/Aaru.Server/Components/Admin/Pages/Usb/Products/List.razor.cs
new file mode 100644
index 00000000..ecd8ee18
--- /dev/null
+++ b/Aaru.Server/Components/Admin/Pages/Usb/Products/List.razor.cs
@@ -0,0 +1,39 @@
+using Aaru.Server.Database.Models;
+using Microsoft.EntityFrameworkCore;
+using DbContext = Aaru.Server.Database.DbContext;
+
+namespace Aaru.Server.Components.Admin.Pages.Usb.Products;
+
+public partial class List
+{
+ bool _initialized;
+
+ List _items;
+
+ ///
+ protected override async Task OnInitializedAsync()
+ {
+ await base.OnInitializedAsync();
+
+ StateHasChanged();
+
+ await using DbContext ctx = await DbContextFactory.CreateDbContextAsync();
+
+ _items = await ctx.UsbProducts.Include(static u => u.Vendor)
+ .OrderBy(static p => p.Vendor.Vendor)
+ .ThenBy(static p => p.Product)
+ .ThenBy(static p => p.ProductId)
+ .Select(static p => new UsbProductModel
+ {
+ ProductId = p.ProductId,
+ ProductName = p.Product,
+ VendorId = p.Vendor.Id,
+ VendorName = p.Vendor.Vendor
+ })
+ .ToListAsync();
+
+ _initialized = true;
+
+ StateHasChanged();
+ }
+}
\ No newline at end of file