using Microsoft.AspNetCore.Mvc;
using PlanTempus.Application.Features.Localization.Services;
namespace PlanTempus.Application.Features.Dashboard.Components;
///
/// ViewComponent for rendering a stat card on the dashboard.
///
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);
}
}
///
/// ViewModel for the StatCard component.
///
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);
}
///
/// Internal data for stat cards (uses localization keys).
///
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; }
}
///
/// Catalog of available stat cards with their data.
///
public static class StatCardCatalog
{
private static readonly Dictionary 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 AllKeys => Cards.Keys;
}