Add localization support and UI enhancements
Build and Push Docker Image / build-and-push (push) Successful in 27s
Build and Push Docker Image / build-and-push (push) Successful in 27s
Introduced centralized RESX localization with hierarchical keys for multi-language support. Added resource files for English, French, Dutch (Belgium), and pseudo-localization. Replaced hardcoded strings in Razor components with localized string references. Added a `PreferredCulture` property to `ApplicationUser` with a migration to store user-specific culture preferences. Implemented `LocalizationService` to manage supported cultures and user preferences. Added a language picker in `TopBar.razor` and configured `RequestLocalizationOptions` for culture detection. Localized registry-related components and error messages. Enhanced UI elements to dynamically display localized content. Added pseudo-localization to identify hardcoded strings during development.
This commit is contained in:
@@ -2,23 +2,23 @@
|
||||
|
||||
@using BirthList.Web.Features.Registries
|
||||
|
||||
<PageTitle>Birth Registry</PageTitle>
|
||||
<PageTitle>@L["Home.PageTitle"]</PageTitle>
|
||||
|
||||
<h1>Welcome to Gift List</h1>
|
||||
<h1>@L["Home.Welcome"]</h1>
|
||||
|
||||
<AuthorizeView>
|
||||
<Authorized Context="authState">
|
||||
<div class="registry-sections">
|
||||
<div class="mb-4">
|
||||
<div class="section-header">
|
||||
<h2>Registries you manage</h2>
|
||||
<h2>@L["Home.ManagedRegistries"]</h2>
|
||||
<button class="btn btn-primary btn-sm" @onclick="() => ShowCreateForm = !ShowCreateForm">
|
||||
<span class="bi bi-plus"></span> Create new
|
||||
<span class="bi bi-plus"></span> @L["Home.CreateNew"]
|
||||
</button>
|
||||
</div>
|
||||
@if (MyRegistries.Count == 0)
|
||||
{
|
||||
<p class="text-muted">No registries yet.</p>
|
||||
<p class="text-muted">@L["Home.NoRegistries"]</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -28,8 +28,8 @@
|
||||
<div class="registry-card">
|
||||
<h3>@registry.Title</h3>
|
||||
<div class="registry-actions">
|
||||
<a href="/registry/@registry.PublicLinkCode" class="btn btn-outline-primary btn-sm">View</a>
|
||||
<a href="/registry/@registry.Id/admin" class="btn btn-outline-secondary btn-sm">Manage</a>
|
||||
<a href="/registry/@registry.PublicLinkCode" class="btn btn-outline-primary btn-sm">@L["Home.View"]</a>
|
||||
<a href="/registry/@registry.Id/admin" class="btn btn-outline-secondary btn-sm">@L["Home.Manage"]</a>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@@ -38,10 +38,10 @@
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<h2>Visited registries</h2>
|
||||
<h2>@L["Home.VisitedRegistries"]</h2>
|
||||
@if (VisitedRegistries.Count == 0)
|
||||
{
|
||||
<p class="text-muted">No visited registries yet.</p>
|
||||
<p class="text-muted">@L["Home.NoVisitedRegistries"]</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -51,7 +51,7 @@
|
||||
<div class="registry-card">
|
||||
<h3>@registry.Title</h3>
|
||||
<div class="registry-actions">
|
||||
<a href="/registry/@registry.PublicLinkCode" class="btn btn-outline-primary btn-sm">View</a>
|
||||
<a href="/registry/@registry.PublicLinkCode" class="btn btn-outline-primary btn-sm">@L["Home.View"]</a>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@@ -65,30 +65,30 @@
|
||||
<div class="create-registry-modal-overlay" @onclick="() => ShowCreateForm = false">
|
||||
<div class="create-registry-modal" @onclick:stopPropagation="true">
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">Create new registry</h3>
|
||||
<h3 class="modal-title">@L["Home.CreateRegistryTitle"]</h3>
|
||||
<button type="button" class="btn-close" @onclick="() => ShowCreateForm = false"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<EditForm Model="Model" OnValidSubmit="CreateRegistryAsync" Context="formContext" FormName="create-registry-form">
|
||||
<DataAnnotationsValidator />
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Title</label>
|
||||
<label class="form-label">@L["Home.Title"]</label>
|
||||
<InputText class="form-control" @bind-Value="Model.Title" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Type</label>
|
||||
<label class="form-label">@L["Home.Type"]</label>
|
||||
<InputSelect class="form-select" @bind-Value="Model.RegistryType">
|
||||
<option value="@BirthList.Domain.Entities.RegistryType.Birth">Birth</option>
|
||||
<option value="@BirthList.Domain.Entities.RegistryType.Wedding">Wedding</option>
|
||||
<option value="@BirthList.Domain.Entities.RegistryType.Birthday">Birthday</option>
|
||||
<option value="@BirthList.Domain.Entities.RegistryType.Birth">@L["Home.RegistryType.Birth"]</option>
|
||||
<option value="@BirthList.Domain.Entities.RegistryType.Wedding">@L["Home.RegistryType.Wedding"]</option>
|
||||
<option value="@BirthList.Domain.Entities.RegistryType.Birthday">@L["Home.RegistryType.Birthday"]</option>
|
||||
</InputSelect>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Theme</label>
|
||||
<label class="form-label">@L["Home.Theme"]</label>
|
||||
<InputSelect class="form-select" @bind-Value="Model.ThemeKey">
|
||||
<option value="default">Default</option>
|
||||
<option value="soft">Soft</option>
|
||||
<option value="modern">Modern</option>
|
||||
<option value="default">@L["Home.Theme.Default"]</option>
|
||||
<option value="soft">@L["Home.Theme.Soft"]</option>
|
||||
<option value="modern">@L["Home.Theme.Modern"]</option>
|
||||
</InputSelect>
|
||||
</div>
|
||||
@if (!string.IsNullOrWhiteSpace(ErrorMessage))
|
||||
@@ -96,8 +96,8 @@
|
||||
<div class="alert alert-danger mb-3">@ErrorMessage</div>
|
||||
}
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary" @onclick="() => ShowCreateForm = false">Cancel</button>
|
||||
<button class="btn btn-primary" type="submit">Create</button>
|
||||
<button type="button" class="btn btn-outline-secondary" @onclick="() => ShowCreateForm = false">@L["Common.Cancel"]</button>
|
||||
<button class="btn btn-primary" type="submit">@L["Home.CreateNew"]</button>
|
||||
</div>
|
||||
</EditForm>
|
||||
</div>
|
||||
@@ -107,7 +107,9 @@
|
||||
</Authorized>
|
||||
<NotAuthorized>
|
||||
<div class="alert alert-info mt-4">
|
||||
<p>Please <a href="Account/Login">log in</a> to create and manage registries.</p>
|
||||
<p>
|
||||
@L["Home.LoginPromptPrefix"]<a href="Account/Login">@L["Home.LoginPromptLinkText"]</a>@L["Home.LoginPromptSuffix"]
|
||||
</p>
|
||||
</div>
|
||||
</NotAuthorized>
|
||||
</AuthorizeView>
|
||||
@@ -136,13 +138,13 @@
|
||||
var userId = await RegistryUserContext.GetUserIdAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
if (string.IsNullOrWhiteSpace(userId))
|
||||
{
|
||||
ErrorMessage = "You must be logged in to create a registry.";
|
||||
ErrorMessage = L["Home.MustBeLoggedIn"];
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(Model.Title))
|
||||
{
|
||||
ErrorMessage = "Title is required.";
|
||||
ErrorMessage = L["Home.TitleRequired"];
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user