Implements localization for dashboard, cash register, account, and profile sections Adds localization keys for various UI elements, improving internationalization support Refactors view components to use ILocalizationService for dynamic text rendering Prepares ground for multi-language support with translation-ready markup
121 lines
3.8 KiB
C#
121 lines
3.8 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
using PlanTempus.Application.Features.Localization.Services;
|
|
|
|
namespace PlanTempus.Application.Features.Dashboard.Components;
|
|
|
|
/// <summary>
|
|
/// ViewComponent for rendering a stat card on the dashboard.
|
|
/// </summary>
|
|
public class StatCardViewComponent : ViewComponent
|
|
{
|
|
private readonly ILocalizationService _localization;
|
|
|
|
public StatCardViewComponent(ILocalizationService localization)
|
|
{
|
|
_localization = localization;
|
|
}
|
|
|
|
public IViewComponentResult Invoke(string key)
|
|
{
|
|
var model = StatCardCatalog.Get(key, _localization);
|
|
return View(model);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// ViewModel for the StatCard component.
|
|
/// </summary>
|
|
public class StatCardViewModel
|
|
{
|
|
public required string Key { get; init; }
|
|
public required string Value { get; init; }
|
|
public required string Label { get; init; }
|
|
public string? TrendText { get; init; }
|
|
public string? TrendIcon { get; init; }
|
|
public string? TrendDirection { get; init; }
|
|
public string? Variant { get; init; }
|
|
public bool HasTrend => !string.IsNullOrEmpty(TrendText);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Internal data for stat cards (uses localization keys).
|
|
/// </summary>
|
|
internal class StatCardData
|
|
{
|
|
public required string Key { get; init; }
|
|
public required string Value { get; init; }
|
|
public required string LabelKey { get; init; }
|
|
public string? TrendTextKey { get; init; }
|
|
public string? TrendIcon { get; init; }
|
|
public string? TrendDirection { get; init; }
|
|
public string? Variant { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Catalog of available stat cards with their data.
|
|
/// </summary>
|
|
public static class StatCardCatalog
|
|
{
|
|
private static readonly Dictionary<string, StatCardData> Cards = new()
|
|
{
|
|
["bookings-today"] = new StatCardData
|
|
{
|
|
Key = "bookings-today",
|
|
Value = "12",
|
|
LabelKey = "dashboard.stats.bookingsToday",
|
|
TrendTextKey = "dashboard.stats.bookingsTrend",
|
|
TrendIcon = "ph-check-circle",
|
|
TrendDirection = "up",
|
|
Variant = "highlight"
|
|
},
|
|
["expected-revenue"] = new StatCardData
|
|
{
|
|
Key = "expected-revenue",
|
|
Value = "8.450 kr",
|
|
LabelKey = "dashboard.stats.expectedRevenue",
|
|
TrendTextKey = "dashboard.stats.revenueTrend",
|
|
TrendIcon = "ph-trend-up",
|
|
TrendDirection = "up",
|
|
Variant = "success"
|
|
},
|
|
["occupancy-rate"] = new StatCardData
|
|
{
|
|
Key = "occupancy-rate",
|
|
Value = "78%",
|
|
LabelKey = "dashboard.stats.occupancyRate",
|
|
TrendTextKey = "dashboard.stats.occupancyTrend",
|
|
TrendIcon = "ph-trend-up",
|
|
TrendDirection = "up",
|
|
Variant = null
|
|
},
|
|
["needs-attention"] = new StatCardData
|
|
{
|
|
Key = "needs-attention",
|
|
Value = "4",
|
|
LabelKey = "dashboard.stats.needsAttention",
|
|
TrendTextKey = null,
|
|
TrendIcon = null,
|
|
TrendDirection = null,
|
|
Variant = "warning"
|
|
}
|
|
};
|
|
|
|
public static StatCardViewModel Get(string key, ILocalizationService localization)
|
|
{
|
|
if (!Cards.TryGetValue(key, out var card))
|
|
throw new KeyNotFoundException($"StatCard with key '{key}' not found");
|
|
|
|
return new StatCardViewModel
|
|
{
|
|
Key = card.Key,
|
|
Value = card.Value,
|
|
Label = localization.Get(card.LabelKey),
|
|
TrendText = card.TrendTextKey != null ? localization.Get(card.TrendTextKey) : null,
|
|
TrendIcon = card.TrendIcon,
|
|
TrendDirection = card.TrendDirection,
|
|
Variant = card.Variant
|
|
};
|
|
}
|
|
|
|
public static IEnumerable<string> AllKeys => Cards.Keys;
|
|
}
|