Add services feature with mock data and components

Introduces comprehensive services management module with:
- Dynamic service and category tables
- Localization support for services section
- Mock data for services and categories
- Responsive UI components for services listing
- Menu navigation and styling updates

Enhances application's service management capabilities
This commit is contained in:
Janus C. H. Knudsen 2026-01-15 23:29:26 +01:00
parent 408e590922
commit 4cf30e1f27
20 changed files with 951 additions and 0 deletions

View file

@ -0,0 +1,68 @@
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using PlanTempus.Application.Features.Localization.Services;
namespace PlanTempus.Application.Features.Services.Components;
public class CategoryTableViewComponent : ViewComponent
{
private readonly ILocalizationService _localization;
private readonly IWebHostEnvironment _env;
public CategoryTableViewComponent(ILocalizationService localization, IWebHostEnvironment env)
{
_localization = localization;
_env = env;
}
public IViewComponentResult Invoke(string key)
{
var data = LoadServiceData();
var model = new CategoryTableViewModel
{
Key = key,
CreateButtonText = _localization.Get("services.createCategory"),
ColumnCategory = _localization.Get("services.table.category"),
ColumnServiceCount = _localization.Get("services.table.serviceCount"),
Categories = data.Categories
.OrderBy(c => c.SortOrder)
.Select(c => new CategoryItemViewModel
{
Id = c.Id,
Name = c.Name,
SortOrder = c.SortOrder,
ServiceCount = data.Services.Count(s => s.CategoryId == c.Id)
})
.ToList()
};
return View(model);
}
private ServiceMockData LoadServiceData()
{
var jsonPath = Path.Combine(_env.ContentRootPath, "Features", "Services", "Data", "servicesMock.json");
var json = System.IO.File.ReadAllText(jsonPath);
return JsonSerializer.Deserialize<ServiceMockData>(json, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
}) ?? new ServiceMockData();
}
}
public class CategoryTableViewModel
{
public required string Key { get; init; }
public required string CreateButtonText { get; init; }
public required string ColumnCategory { get; init; }
public required string ColumnServiceCount { get; init; }
public required IReadOnlyList<CategoryItemViewModel> Categories { get; init; }
}
public class CategoryItemViewModel
{
public required string Id { get; init; }
public required string Name { get; init; }
public int SortOrder { get; init; }
public int ServiceCount { get; init; }
}

View file

@ -0,0 +1,31 @@
@model PlanTempus.Application.Features.Services.Components.CategoryTableViewModel
<swp-services-header>
<div></div>
<swp-btn class="primary">
<i class="ph ph-plus"></i>
@Model.CreateButtonText
</swp-btn>
</swp-services-header>
<swp-card class="categories-list">
<swp-data-table>
<swp-data-table-header>
<swp-data-table-cell>@Model.ColumnCategory</swp-data-table-cell>
<swp-data-table-cell>@Model.ColumnServiceCount</swp-data-table-cell>
<swp-data-table-cell></swp-data-table-cell>
</swp-data-table-header>
@foreach (var category in Model.Categories)
{
<swp-data-table-row data-category-detail="@category.Id">
<swp-data-table-cell>@category.Name</swp-data-table-cell>
<swp-data-table-cell>@category.ServiceCount</swp-data-table-cell>
<swp-data-table-cell>
<swp-row-toggle>
<i class="ph ph-caret-right"></i>
</swp-row-toggle>
</swp-data-table-cell>
</swp-data-table-row>
}
</swp-data-table>
</swp-card>