b46269bfc0
Build and Push Docker Image / build-and-push (push) Successful in 19s
- Show current admins in RegistryAdmin using new RegistryAdminDisplayModel and backend support - Improve RegistryMetadataService: better normalization, Amazon-specific extraction for images/prices, and URL normalization - Use normalized product URLs and improved metadata logic in RegistryAdmin - Add error handling for Blazored.TextEditor interop issues - Switch healthchecks in portainer-stack.yml to process checks (pidof) - Remove appsettings.Development.json contents from source control - Add RegistryAdminDisplayModel and NormalizedUrl to models
192 lines
7.8 KiB
Plaintext
192 lines
7.8 KiB
Plaintext
@page "/registry/{RegistryId:guid}/admin"
|
|
@rendermode InteractiveServer
|
|
|
|
@using Blazored.TextEditor
|
|
|
|
<PageTitle>Registry Admin</PageTitle>
|
|
|
|
@if (!IsAuthorized)
|
|
{
|
|
<p>Access denied.</p>
|
|
}
|
|
else
|
|
{
|
|
<h1>Registry Admin</h1>
|
|
|
|
@if (!IsSmtpConfigured)
|
|
{
|
|
<div class="alert alert-warning" role="alert">
|
|
SMTP is not configured. Email features (identity emails and admin invite emails) are disabled. Configure the Smtp section in appsettings or user secrets.
|
|
</div>
|
|
}
|
|
|
|
<section class="mb-4">
|
|
<h2>Current admins</h2>
|
|
@if (Admins.Count == 0)
|
|
{
|
|
<p>No admins assigned yet.</p>
|
|
}
|
|
else
|
|
{
|
|
<ul>
|
|
@foreach (var admin in Admins)
|
|
{
|
|
<li>@admin.DisplayName</li>
|
|
}
|
|
</ul>
|
|
}
|
|
</section>
|
|
|
|
<section class="mb-4">
|
|
<h2>Settings</h2>
|
|
<EditForm Model="SettingsModel" OnValidSubmit="SaveSettingsAsync" FormName="registry-settings-form">
|
|
<div class="row g-3">
|
|
<div class="col-md-4">
|
|
<label class="form-label">Baby name</label>
|
|
<InputText class="form-control" @bind-Value="SettingsModel.BabyName" />
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="form-label">Birth date</label>
|
|
<InputDate class="form-control" @bind-Value="SettingsModel.BirthDate" />
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label class="form-label">Currency</label>
|
|
<InputText class="form-control" @bind-Value="SettingsModel.CurrencyCode" />
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="form-label">Theme</label>
|
|
<InputSelect class="form-select" @bind-Value="SettingsModel.ThemeKey">
|
|
<option value="default">Default</option>
|
|
<option value="soft">Soft</option>
|
|
<option value="modern">Modern</option>
|
|
</InputSelect>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-3">
|
|
<label class="form-label">Shipping address</label>
|
|
<InputTextArea class="form-control" @bind-Value="SettingsModel.ShippingAddress" rows="3" />
|
|
</div>
|
|
|
|
<div class="mt-3">
|
|
<label class="form-label">Top content</label>
|
|
<BlazoredTextEditor @ref="TextEditor" Placeholder="Welcome text" Theme="snow" />
|
|
</div>
|
|
|
|
<div class="row g-3 mt-2">
|
|
<div class="col-md-4">
|
|
<label class="form-label">Bank account name</label>
|
|
<InputText class="form-control" @bind-Value="SettingsModel.BankAccountDisplayName" />
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label">IBAN</label>
|
|
<InputText class="form-control" @bind-Value="SettingsModel.BankAccountIban" />
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label">BIC</label>
|
|
<InputText class="form-control" @bind-Value="SettingsModel.BankAccountBic" />
|
|
</div>
|
|
</div>
|
|
|
|
<button class="btn btn-primary mt-3" type="submit">Save settings</button>
|
|
</EditForm>
|
|
</section>
|
|
|
|
<section class="mb-4">
|
|
<h2>Invite admin</h2>
|
|
<div class="row g-2">
|
|
<div class="col-md-8">
|
|
<InputText class="form-control" @bind-Value="InviteEmail" placeholder="optional email" />
|
|
</div>
|
|
<div class="col-md-4">
|
|
<button class="btn btn-outline-primary w-100" @onclick="CreateInviteAsync">Create invite</button>
|
|
</div>
|
|
</div>
|
|
@if (!string.IsNullOrWhiteSpace(InviteLink))
|
|
{
|
|
<p class="mt-2">Invite link: <a href="@InviteLink">@InviteLink</a></p>
|
|
}
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Add or edit item</h2>
|
|
<EditForm Model="ItemModel" OnValidSubmit="SaveItemAsync" FormName="registry-item-form">
|
|
<div class="row g-3">
|
|
<div class="col-md-6">
|
|
<label class="form-label">Name</label>
|
|
<InputText class="form-control" @bind-Value="ItemModel.Name" />
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Product URL</label>
|
|
<div class="input-group">
|
|
<InputText class="form-control" @bind-Value="ItemModel.ProductUrl" />
|
|
<button type="button" class="btn btn-outline-secondary" @onclick="FetchMetadataAsync">Auto fetch</button>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Picture URL</label>
|
|
<InputText class="form-control" @bind-Value="ItemModel.PictureUrl" />
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Description</label>
|
|
<InputTextArea class="form-control" @bind-Value="ItemModel.Description" rows="2" />
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label class="form-label">Price</label>
|
|
<InputNumber class="form-control" @bind-Value="ItemModel.PriceAmount" />
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label class="form-label">Currency</label>
|
|
<InputText class="form-control" @bind-Value="ItemModel.CurrencyCode" />
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label class="form-label">Desired qty</label>
|
|
<InputNumber class="form-control" @bind-Value="ItemModel.DesiredQuantity" />
|
|
</div>
|
|
<div class="col-md-3 d-flex align-items-center gap-2">
|
|
<InputCheckbox @bind-Value="ItemModel.ParticipationAllowed" />
|
|
<label>Participation</label>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="form-label">Participation target</label>
|
|
<InputNumber class="form-control" @bind-Value="ItemModel.ParticipationTargetAmount" />
|
|
</div>
|
|
<div class="col-md-3 d-flex align-items-center gap-2">
|
|
<InputCheckbox @bind-Value="ItemModel.CanBeSecondHand" />
|
|
<label>Second hand allowed</label>
|
|
</div>
|
|
<div class="col-md-3 d-flex align-items-center gap-2">
|
|
<InputCheckbox @bind-Value="ItemModel.IsGiven" />
|
|
<label>Given</label>
|
|
</div>
|
|
</div>
|
|
<button class="btn btn-primary mt-3" type="submit">Save item</button>
|
|
</EditForm>
|
|
|
|
<table class="table table-striped mt-4">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Desired Qty</th>
|
|
<th>Participation</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach (var item in Items)
|
|
{
|
|
<tr>
|
|
<td>@item.Name</td>
|
|
<td>@item.DesiredQuantity</td>
|
|
<td>@(item.ParticipationAllowed ? "Yes" : "No")</td>
|
|
<td>
|
|
<button class="btn btn-sm btn-outline-secondary me-2" @onclick="() => EditItem(item)">Edit</button>
|
|
<button class="btn btn-sm btn-outline-danger" @onclick="() => DeleteItemAsync(item.Id)">Delete</button>
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</section>
|
|
}
|