2026-01-11 18:18:36 +01:00
|
|
|
using Microsoft.AspNetCore.Mvc;
|
2026-01-12 15:42:18 +01:00
|
|
|
using PlanTempus.Application.Features.Localization.Services;
|
2026-01-11 18:18:36 +01:00
|
|
|
|
|
|
|
|
namespace PlanTempus.Application.Features.Dashboard.Components;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// ViewComponent for rendering a quick stat item in the sidebar.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class QuickStatViewComponent : ViewComponent
|
|
|
|
|
{
|
2026-01-12 15:42:18 +01:00
|
|
|
private readonly ILocalizationService _localization;
|
|
|
|
|
|
|
|
|
|
public QuickStatViewComponent(ILocalizationService localization)
|
|
|
|
|
{
|
|
|
|
|
_localization = localization;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-11 18:18:36 +01:00
|
|
|
public IViewComponentResult Invoke(string key)
|
|
|
|
|
{
|
2026-01-12 15:42:18 +01:00
|
|
|
var model = QuickStatCatalog.Get(key, _localization);
|
2026-01-11 18:18:36 +01:00
|
|
|
return View(model);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// ViewModel for the QuickStat component.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class QuickStatViewModel
|
|
|
|
|
{
|
|
|
|
|
public required string Key { get; init; }
|
|
|
|
|
public required string Value { get; init; }
|
|
|
|
|
public required string Label { get; init; }
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-12 15:42:18 +01:00
|
|
|
internal class QuickStatData
|
|
|
|
|
{
|
|
|
|
|
public required string Key { get; init; }
|
|
|
|
|
public required string Value { get; init; }
|
|
|
|
|
public required string LabelKey { get; init; }
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-11 18:18:36 +01:00
|
|
|
/// <summary>
|
|
|
|
|
/// Catalog of available quick stats with their data.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static class QuickStatCatalog
|
|
|
|
|
{
|
2026-01-12 15:42:18 +01:00
|
|
|
private static readonly Dictionary<string, QuickStatData> Stats = new()
|
2026-01-11 18:18:36 +01:00
|
|
|
{
|
2026-01-12 15:42:18 +01:00
|
|
|
["bookings-week"] = new QuickStatData
|
2026-01-11 18:18:36 +01:00
|
|
|
{
|
|
|
|
|
Key = "bookings-week",
|
|
|
|
|
Value = "47",
|
2026-01-12 15:42:18 +01:00
|
|
|
LabelKey = "dashboard.quickStats.bookings"
|
2026-01-11 18:18:36 +01:00
|
|
|
},
|
2026-01-12 15:42:18 +01:00
|
|
|
["revenue-week"] = new QuickStatData
|
2026-01-11 18:18:36 +01:00
|
|
|
{
|
|
|
|
|
Key = "revenue-week",
|
|
|
|
|
Value = "38.200 kr",
|
2026-01-12 15:42:18 +01:00
|
|
|
LabelKey = "dashboard.quickStats.revenue"
|
2026-01-11 18:18:36 +01:00
|
|
|
},
|
2026-01-12 15:42:18 +01:00
|
|
|
["new-customers"] = new QuickStatData
|
2026-01-11 18:18:36 +01:00
|
|
|
{
|
|
|
|
|
Key = "new-customers",
|
|
|
|
|
Value = "8",
|
2026-01-12 15:42:18 +01:00
|
|
|
LabelKey = "dashboard.quickStats.newCustomers"
|
2026-01-11 18:18:36 +01:00
|
|
|
},
|
2026-01-12 15:42:18 +01:00
|
|
|
["avg-occupancy"] = new QuickStatData
|
2026-01-11 18:18:36 +01:00
|
|
|
{
|
|
|
|
|
Key = "avg-occupancy",
|
|
|
|
|
Value = "72%",
|
2026-01-12 15:42:18 +01:00
|
|
|
LabelKey = "dashboard.quickStats.avgOccupancy"
|
2026-01-11 18:18:36 +01:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2026-01-12 15:42:18 +01:00
|
|
|
public static QuickStatViewModel Get(string key, ILocalizationService localization)
|
2026-01-11 18:18:36 +01:00
|
|
|
{
|
2026-01-12 15:42:18 +01:00
|
|
|
if (!Stats.TryGetValue(key, out var stat))
|
|
|
|
|
throw new KeyNotFoundException($"QuickStat with key '{key}' not found");
|
2026-01-11 18:18:36 +01:00
|
|
|
|
2026-01-12 15:42:18 +01:00
|
|
|
return new QuickStatViewModel
|
|
|
|
|
{
|
|
|
|
|
Key = stat.Key,
|
|
|
|
|
Value = stat.Value,
|
|
|
|
|
Label = localization.Get(stat.LabelKey)
|
|
|
|
|
};
|
2026-01-11 18:18:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static IEnumerable<string> AllKeys => Stats.Keys;
|
|
|
|
|
}
|