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
84 lines
3.5 KiB
C#
84 lines
3.5 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
using PlanTempus.Application.Features.Localization.Services;
|
|
|
|
namespace PlanTempus.Application.Features.Customers.Components;
|
|
|
|
public class CustomerDetailHeaderViewComponent : ViewComponent
|
|
{
|
|
private readonly ILocalizationService _localization;
|
|
|
|
public CustomerDetailHeaderViewComponent(ILocalizationService localization)
|
|
{
|
|
_localization = localization;
|
|
}
|
|
|
|
public IViewComponentResult Invoke(string customerId)
|
|
{
|
|
var customer = CustomerDetailCatalog.Get(customerId);
|
|
var header = customer.Header;
|
|
var contact = customer.Contact;
|
|
|
|
// Format customer since date
|
|
var customerSince = DateTime.TryParse(header.CustomerSince, out var date)
|
|
? date.ToString("MMMM yyyy", new System.Globalization.CultureInfo("da-DK"))
|
|
: header.CustomerSince;
|
|
|
|
var model = new CustomerDetailHeaderViewModel
|
|
{
|
|
Initials = header.Initials,
|
|
Name = header.Name,
|
|
Tags = header.Tags.Select(t => new CustomerTagViewModel
|
|
{
|
|
Text = t.ToUpper(),
|
|
CssClass = t.ToLowerInvariant()
|
|
}).ToList(),
|
|
BookingAllowed = header.BookingAllowed,
|
|
Phone = contact.Phone,
|
|
PhoneHref = $"tel:{contact.Phone.Replace(" ", "")}",
|
|
Email = contact.Email,
|
|
EmailHref = $"mailto:{contact.Email}",
|
|
CustomerSinceText = $"Kunde siden {customerSince}",
|
|
FactVisits = header.Facts.Visits.ToString(),
|
|
FactVisitsLabel = _localization.Get("customers.detail.visits"),
|
|
FactInterval = header.Facts.AvgIntervalDays.ToString(),
|
|
FactIntervalLabel = _localization.Get("customers.detail.interval"),
|
|
FactHairdresser = header.Facts.PreferredHairdresser,
|
|
FactHairdresserLabel = _localization.Get("customers.detail.preferredHairdresser"),
|
|
FactRevenue = $"{header.Facts.TotalRevenue:N0} kr".Replace(",", "."),
|
|
FactRevenueLabel = _localization.Get("customers.detail.totalRevenue"),
|
|
BookingAllowedText = _localization.Get("customers.detail.bookingAllowed"),
|
|
BookingBlockedText = _localization.Get("customers.detail.bookingBlocked")
|
|
};
|
|
|
|
return View(model);
|
|
}
|
|
}
|
|
|
|
public class CustomerDetailHeaderViewModel
|
|
{
|
|
public required string Initials { get; init; }
|
|
public required string Name { get; init; }
|
|
public List<CustomerTagViewModel> Tags { get; init; } = new();
|
|
public bool BookingAllowed { get; init; }
|
|
public required string Phone { get; init; }
|
|
public required string PhoneHref { get; init; }
|
|
public required string Email { get; init; }
|
|
public required string EmailHref { get; init; }
|
|
public required string CustomerSinceText { get; init; }
|
|
public required string FactVisits { get; init; }
|
|
public required string FactVisitsLabel { get; init; }
|
|
public required string FactInterval { get; init; }
|
|
public required string FactIntervalLabel { get; init; }
|
|
public required string FactHairdresser { get; init; }
|
|
public required string FactHairdresserLabel { get; init; }
|
|
public required string FactRevenue { get; init; }
|
|
public required string FactRevenueLabel { get; init; }
|
|
public required string BookingAllowedText { get; init; }
|
|
public required string BookingBlockedText { get; init; }
|
|
}
|
|
|
|
public class CustomerTagViewModel
|
|
{
|
|
public required string Text { get; init; }
|
|
public required string CssClass { get; init; }
|
|
}
|