Implements full customer detail page with multiple feature-rich components including overview, economy, statistics, journal, appointments, giftcards, and activity sections Creates reusable ViewComponents for different customer detail aspects with robust data modeling and presentation logic
106 lines
3.7 KiB
C#
106 lines
3.7 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
using PlanTempus.Application.Features.Localization.Services;
|
|
|
|
namespace PlanTempus.Application.Features.Customers.Components;
|
|
|
|
public class CustomerDetailJournalViewComponent : ViewComponent
|
|
{
|
|
private readonly ILocalizationService _localization;
|
|
|
|
public CustomerDetailJournalViewComponent(ILocalizationService localization)
|
|
{
|
|
_localization = localization;
|
|
}
|
|
|
|
public IViewComponentResult Invoke(string customerId)
|
|
{
|
|
var customer = CustomerDetailCatalog.Get(customerId);
|
|
|
|
// Group entries by type
|
|
var notes = customer.Journal.Where(j => j.Type == "note").ToList();
|
|
var colorFormulas = customer.Journal.Where(j => j.Type == "colorFormula").ToList();
|
|
var analyses = customer.Journal.Where(j => j.Type == "analysis").ToList();
|
|
|
|
var model = new CustomerDetailJournalViewModel
|
|
{
|
|
AllCount = customer.Journal.Count,
|
|
NotesCount = notes.Count,
|
|
ColorFormulasCount = colorFormulas.Count,
|
|
AnalysesCount = analyses.Count,
|
|
Notes = notes.Select(MapEntry).ToList(),
|
|
ColorFormulas = colorFormulas.Select(MapEntry).ToList(),
|
|
Analyses = analyses.Select(MapEntry).ToList(),
|
|
NotesTitle = "Noter",
|
|
ColorFormulasTitle = "Farveformler",
|
|
AnalysesTitle = "Analyser",
|
|
AddNoteText = "+ Tilføj note",
|
|
AddColorFormulaText = "+ Tilføj",
|
|
AddAnalysisText = "+ Tilføj"
|
|
};
|
|
|
|
return View(model);
|
|
}
|
|
|
|
private JournalEntryViewModel MapEntry(CustomerJournalEntry entry)
|
|
{
|
|
// Format the date (e.g., "2025-12-09" -> "9. dec 2025")
|
|
var formattedDate = entry.Date;
|
|
if (DateTime.TryParse(entry.Date, out var date))
|
|
{
|
|
formattedDate = date.ToString("d. MMM yyyy", new System.Globalization.CultureInfo("da-DK"));
|
|
}
|
|
|
|
return new JournalEntryViewModel
|
|
{
|
|
Id = entry.Id,
|
|
Type = entry.Type,
|
|
Tag = entry.Tag,
|
|
Subtags = entry.Subtags,
|
|
Text = entry.Text,
|
|
FormattedDate = $"{formattedDate} - Af: {entry.Author}",
|
|
Author = entry.Author,
|
|
TypeClass = GetTypeClass(entry.Tag)
|
|
};
|
|
}
|
|
|
|
private string GetTypeClass(string tag)
|
|
{
|
|
return tag.ToLowerInvariant() switch
|
|
{
|
|
"note" => "note",
|
|
"advarsel" => "advarsel",
|
|
"farveformel" => "farveformel",
|
|
"haranalyse" or "analyse" => "analyse",
|
|
_ => "note"
|
|
};
|
|
}
|
|
}
|
|
|
|
public class CustomerDetailJournalViewModel
|
|
{
|
|
public int AllCount { get; init; }
|
|
public int NotesCount { get; init; }
|
|
public int ColorFormulasCount { get; init; }
|
|
public int AnalysesCount { get; init; }
|
|
public List<JournalEntryViewModel> Notes { get; init; } = new();
|
|
public List<JournalEntryViewModel> ColorFormulas { get; init; } = new();
|
|
public List<JournalEntryViewModel> Analyses { get; init; } = new();
|
|
public required string NotesTitle { get; init; }
|
|
public required string ColorFormulasTitle { get; init; }
|
|
public required string AnalysesTitle { get; init; }
|
|
public required string AddNoteText { get; init; }
|
|
public required string AddColorFormulaText { get; init; }
|
|
public required string AddAnalysisText { get; init; }
|
|
}
|
|
|
|
public class JournalEntryViewModel
|
|
{
|
|
public required string Id { get; init; }
|
|
public required string Type { get; init; }
|
|
public required string Tag { get; init; }
|
|
public List<string> Subtags { get; init; } = new();
|
|
public required string Text { get; init; }
|
|
public required string FormattedDate { get; init; }
|
|
public required string Author { get; init; }
|
|
public required string TypeClass { get; init; }
|
|
}
|