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,110 @@
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using PlanTempus.Application.Features.Localization.Services;
namespace PlanTempus.Application.Features.Services.Components;
public class ServiceTableViewComponent : ViewComponent
{
private readonly ILocalizationService _localization;
private readonly IWebHostEnvironment _env;
public ServiceTableViewComponent(ILocalizationService localization, IWebHostEnvironment env)
{
_localization = localization;
_env = env;
}
public IViewComponentResult Invoke(string key)
{
var data = LoadServiceData();
var model = new ServiceTableViewModel
{
Key = key,
SearchPlaceholder = _localization.Get("services.searchPlaceholder"),
CreateButtonText = _localization.Get("services.createService"),
ColumnService = _localization.Get("services.table.service"),
ColumnDuration = _localization.Get("services.table.duration"),
ColumnPrice = _localization.Get("services.table.price"),
Categories = data.Categories
.OrderBy(c => c.SortOrder)
.Select(c => new ServiceCategoryViewModel
{
Id = c.Id,
Name = c.Name,
Services = data.Services
.Where(s => s.CategoryId == c.Id)
.Select(s => new ServiceItemViewModel
{
Id = s.Id,
Name = s.Name,
Duration = s.Duration,
Price = s.Price
})
.ToList()
})
.Where(c => c.Services.Any())
.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 ServiceTableViewModel
{
public required string Key { get; init; }
public required string SearchPlaceholder { get; init; }
public required string CreateButtonText { get; init; }
public required string ColumnService { get; init; }
public required string ColumnDuration { get; init; }
public required string ColumnPrice { get; init; }
public required IReadOnlyList<ServiceCategoryViewModel> Categories { get; init; }
}
public class ServiceCategoryViewModel
{
public required string Id { get; init; }
public required string Name { get; init; }
public required IReadOnlyList<ServiceItemViewModel> Services { get; init; }
}
public class ServiceItemViewModel
{
public required string Id { get; init; }
public required string Name { get; init; }
public int Duration { get; init; }
public decimal Price { get; init; }
}
internal class ServiceMockData
{
public List<ServiceCategoryData> Categories { get; set; } = new();
public List<ServiceData> Services { get; set; } = new();
}
internal class ServiceCategoryData
{
public string Id { get; set; } = "";
public string Name { get; set; } = "";
public int SortOrder { get; set; }
}
internal class ServiceData
{
public string Id { get; set; } = "";
public string CategoryId { get; set; } = "";
public string Name { get; set; } = "";
public int Duration { get; set; }
public decimal Price { get; set; }
}