Adds comprehensive service detail views and localization
Implements new service detail tabs for prices, duration, and rules Extends localization support for Danish and English translations Adds dynamic view components for managing service-specific configurations Introduces flexible pricing, duration, and booking rule management Enhances service management with granular configuration options
This commit is contained in:
parent
e9f3639c7c
commit
5e3811347c
11 changed files with 1018 additions and 13 deletions
|
|
@ -0,0 +1,173 @@
|
|||
@model PlanTempus.Application.Features.Services.Components.ServiceDetailRulesViewModel
|
||||
|
||||
<swp-detail-grid>
|
||||
<swp-card>
|
||||
<swp-section-label>@Model.LabelBookingRules</swp-section-label>
|
||||
<swp-edit-section>
|
||||
<swp-edit-row>
|
||||
<swp-edit-label>@Model.LabelMinNotice</swp-edit-label>
|
||||
<swp-select data-value="@Model.MinNotice">
|
||||
<button type="button" aria-expanded="false">
|
||||
<swp-select-value>@GetNoticeLabel(Model.MinNotice)</swp-select-value>
|
||||
<i class="ph ph-caret-down"></i>
|
||||
</button>
|
||||
<swp-select-dropdown>
|
||||
<swp-select-option data-value="0" class="@(Model.MinNotice == "0" ? "selected" : "")">Ingen</swp-select-option>
|
||||
<swp-select-option data-value="2" class="@(Model.MinNotice == "2" ? "selected" : "")">2 timer</swp-select-option>
|
||||
<swp-select-option data-value="4" class="@(Model.MinNotice == "4" ? "selected" : "")">4 timer</swp-select-option>
|
||||
<swp-select-option data-value="24" class="@(Model.MinNotice == "24" ? "selected" : "")">24 timer</swp-select-option>
|
||||
<swp-select-option data-value="48" class="@(Model.MinNotice == "48" ? "selected" : "")">48 timer</swp-select-option>
|
||||
<swp-select-option data-value="168" class="@(Model.MinNotice == "168" ? "selected" : "")">1 uge</swp-select-option>
|
||||
</swp-select-dropdown>
|
||||
</swp-select>
|
||||
</swp-edit-row>
|
||||
<swp-edit-row>
|
||||
<swp-edit-label>@Model.LabelMaxAdvanceBooking</swp-edit-label>
|
||||
<swp-select data-value="@Model.MaxAdvanceBooking">
|
||||
<button type="button" aria-expanded="false">
|
||||
<swp-select-value>@GetAdvanceBookingLabel(Model.MaxAdvanceBooking)</swp-select-value>
|
||||
<i class="ph ph-caret-down"></i>
|
||||
</button>
|
||||
<swp-select-dropdown>
|
||||
<swp-select-option data-value="1" class="@(Model.MaxAdvanceBooking == "1" ? "selected" : "")">1 måned</swp-select-option>
|
||||
<swp-select-option data-value="2" class="@(Model.MaxAdvanceBooking == "2" ? "selected" : "")">2 måneder</swp-select-option>
|
||||
<swp-select-option data-value="3" class="@(Model.MaxAdvanceBooking == "3" ? "selected" : "")">3 måneder</swp-select-option>
|
||||
<swp-select-option data-value="6" class="@(Model.MaxAdvanceBooking == "6" ? "selected" : "")">6 måneder</swp-select-option>
|
||||
<swp-select-option data-value="12" class="@(Model.MaxAdvanceBooking == "12" ? "selected" : "")">1 år</swp-select-option>
|
||||
</swp-select-dropdown>
|
||||
</swp-select>
|
||||
</swp-edit-row>
|
||||
<swp-edit-row>
|
||||
<swp-edit-label>@Model.LabelCancellationDeadline</swp-edit-label>
|
||||
<swp-select data-value="@Model.CancellationDeadline">
|
||||
<button type="button" aria-expanded="false">
|
||||
<swp-select-value>@GetNoticeLabel(Model.CancellationDeadline)</swp-select-value>
|
||||
<i class="ph ph-caret-down"></i>
|
||||
</button>
|
||||
<swp-select-dropdown>
|
||||
<swp-select-option data-value="0" class="@(Model.CancellationDeadline == "0" ? "selected" : "")">Ingen</swp-select-option>
|
||||
<swp-select-option data-value="2" class="@(Model.CancellationDeadline == "2" ? "selected" : "")">2 timer</swp-select-option>
|
||||
<swp-select-option data-value="4" class="@(Model.CancellationDeadline == "4" ? "selected" : "")">4 timer</swp-select-option>
|
||||
<swp-select-option data-value="24" class="@(Model.CancellationDeadline == "24" ? "selected" : "")">24 timer</swp-select-option>
|
||||
<swp-select-option data-value="48" class="@(Model.CancellationDeadline == "48" ? "selected" : "")">48 timer</swp-select-option>
|
||||
</swp-select-dropdown>
|
||||
</swp-select>
|
||||
</swp-edit-row>
|
||||
<swp-edit-row>
|
||||
<swp-edit-label>@Model.LabelNoShowFee</swp-edit-label>
|
||||
<swp-select data-value="@Model.NoShowFee">
|
||||
<button type="button" aria-expanded="false">
|
||||
<swp-select-value>@GetNoShowFeeLabel(Model.NoShowFee)</swp-select-value>
|
||||
<i class="ph ph-caret-down"></i>
|
||||
</button>
|
||||
<swp-select-dropdown>
|
||||
<swp-select-option data-value="0" class="@(Model.NoShowFee == "0" ? "selected" : "")">Intet</swp-select-option>
|
||||
<swp-select-option data-value="25" class="@(Model.NoShowFee == "25" ? "selected" : "")">25% af pris</swp-select-option>
|
||||
<swp-select-option data-value="50" class="@(Model.NoShowFee == "50" ? "selected" : "")">50% af pris</swp-select-option>
|
||||
<swp-select-option data-value="100" class="@(Model.NoShowFee == "100" ? "selected" : "")">Fuld pris</swp-select-option>
|
||||
<swp-select-option data-value="fixed" class="@(Model.NoShowFee == "fixed" ? "selected" : "")">Fast beløb</swp-select-option>
|
||||
</swp-select-dropdown>
|
||||
</swp-select>
|
||||
</swp-edit-row>
|
||||
</swp-edit-section>
|
||||
</swp-card>
|
||||
|
||||
<swp-card>
|
||||
<swp-section-label>@Model.LabelRequirements</swp-section-label>
|
||||
<swp-toggle-row>
|
||||
<div>
|
||||
<swp-toggle-label>@Model.LabelRequiresConsultation</swp-toggle-label>
|
||||
<swp-toggle-description>@Model.LabelRequiresConsultationDesc</swp-toggle-description>
|
||||
</div>
|
||||
<swp-toggle-slider data-value="@(Model.RequiresConsultation ? "yes" : "no")">
|
||||
<swp-toggle-option>@Model.ToggleYes</swp-toggle-option>
|
||||
<swp-toggle-option>@Model.ToggleNo</swp-toggle-option>
|
||||
</swp-toggle-slider>
|
||||
</swp-toggle-row>
|
||||
<swp-toggle-row>
|
||||
<div>
|
||||
<swp-toggle-label>@Model.LabelRequiresPatchTest</swp-toggle-label>
|
||||
<swp-toggle-description>@Model.LabelRequiresPatchTestDesc</swp-toggle-description>
|
||||
</div>
|
||||
<swp-toggle-slider data-value="@(Model.RequiresPatchTest ? "yes" : "no")">
|
||||
<swp-toggle-option>@Model.ToggleYes</swp-toggle-option>
|
||||
<swp-toggle-option>@Model.ToggleNo</swp-toggle-option>
|
||||
</swp-toggle-slider>
|
||||
</swp-toggle-row>
|
||||
<swp-toggle-row>
|
||||
<div>
|
||||
<swp-toggle-label>@Model.LabelAgeRestriction</swp-toggle-label>
|
||||
<swp-toggle-description>@Model.LabelAgeRestrictionDesc</swp-toggle-description>
|
||||
</div>
|
||||
<swp-toggle-slider data-value="@(Model.AgeRestriction ? "yes" : "no")">
|
||||
<swp-toggle-option>@Model.ToggleYes</swp-toggle-option>
|
||||
<swp-toggle-option>@Model.ToggleNo</swp-toggle-option>
|
||||
</swp-toggle-slider>
|
||||
</swp-toggle-row>
|
||||
</swp-card>
|
||||
</swp-detail-grid>
|
||||
|
||||
<swp-card>
|
||||
<swp-section-label>@Model.LabelOnlineBookingSettings</swp-section-label>
|
||||
<swp-toggle-row>
|
||||
<swp-toggle-label>@Model.LabelShowInOnlineBooking</swp-toggle-label>
|
||||
<swp-toggle-slider data-value="@(Model.ShowInOnlineBooking ? "yes" : "no")">
|
||||
<swp-toggle-option>@Model.ToggleYes</swp-toggle-option>
|
||||
<swp-toggle-option>@Model.ToggleNo</swp-toggle-option>
|
||||
</swp-toggle-slider>
|
||||
</swp-toggle-row>
|
||||
<swp-toggle-row>
|
||||
<swp-toggle-label>@Model.LabelAllowEmployeeSelection</swp-toggle-label>
|
||||
<swp-toggle-slider data-value="@(Model.AllowEmployeeSelection ? "yes" : "no")">
|
||||
<swp-toggle-option>@Model.ToggleYes</swp-toggle-option>
|
||||
<swp-toggle-option>@Model.ToggleNo</swp-toggle-option>
|
||||
</swp-toggle-slider>
|
||||
</swp-toggle-row>
|
||||
<swp-toggle-row>
|
||||
<swp-toggle-label>@Model.LabelShowPrice</swp-toggle-label>
|
||||
<swp-toggle-slider data-value="@(Model.ShowPrice ? "yes" : "no")">
|
||||
<swp-toggle-option>@Model.ToggleYes</swp-toggle-option>
|
||||
<swp-toggle-option>@Model.ToggleNo</swp-toggle-option>
|
||||
</swp-toggle-slider>
|
||||
</swp-toggle-row>
|
||||
<swp-toggle-row>
|
||||
<swp-toggle-label>@Model.LabelShowDuration</swp-toggle-label>
|
||||
<swp-toggle-slider data-value="@(Model.ShowDuration ? "yes" : "no")">
|
||||
<swp-toggle-option>@Model.ToggleYes</swp-toggle-option>
|
||||
<swp-toggle-option>@Model.ToggleNo</swp-toggle-option>
|
||||
</swp-toggle-slider>
|
||||
</swp-toggle-row>
|
||||
</swp-card>
|
||||
|
||||
@functions {
|
||||
string GetNoticeLabel(string hours)
|
||||
{
|
||||
return hours switch
|
||||
{
|
||||
"0" => "Ingen",
|
||||
"168" => "1 uge",
|
||||
_ => $"{hours} timer"
|
||||
};
|
||||
}
|
||||
|
||||
string GetAdvanceBookingLabel(string months)
|
||||
{
|
||||
return months switch
|
||||
{
|
||||
"1" => "1 måned",
|
||||
"12" => "1 år",
|
||||
_ => $"{months} måneder"
|
||||
};
|
||||
}
|
||||
|
||||
string GetNoShowFeeLabel(string fee)
|
||||
{
|
||||
return fee switch
|
||||
{
|
||||
"0" => "Intet",
|
||||
"100" => "Fuld pris",
|
||||
"fixed" => "Fast beløb",
|
||||
_ => $"{fee}% af pris"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using PlanTempus.Application.Features.Localization.Services;
|
||||
|
||||
namespace PlanTempus.Application.Features.Services.Components;
|
||||
|
||||
public class ServiceDetailRulesViewComponent : ViewComponent
|
||||
{
|
||||
private readonly ILocalizationService _localization;
|
||||
|
||||
public ServiceDetailRulesViewComponent(ILocalizationService localization)
|
||||
{
|
||||
_localization = localization;
|
||||
}
|
||||
|
||||
public IViewComponentResult Invoke(string key)
|
||||
{
|
||||
var service = ServiceDetailCatalog.Get(key);
|
||||
|
||||
var model = new ServiceDetailRulesViewModel
|
||||
{
|
||||
// Data
|
||||
MinNotice = service.MinNotice,
|
||||
MaxAdvanceBooking = service.MaxAdvanceBooking,
|
||||
CancellationDeadline = service.CancellationDeadline,
|
||||
NoShowFee = service.NoShowFee,
|
||||
RequiresConsultation = service.RequiresConsultation,
|
||||
RequiresPatchTest = service.RequiresPatchTest,
|
||||
AgeRestriction = service.AgeRestriction,
|
||||
ShowInOnlineBooking = service.ShowInOnlineBookingRules,
|
||||
AllowEmployeeSelection = service.AllowEmployeeSelection,
|
||||
ShowPrice = service.ShowPrice,
|
||||
ShowDuration = service.ShowDuration,
|
||||
|
||||
// Labels - Booking rules
|
||||
LabelBookingRules = _localization.Get("services.detail.rules.bookingRules"),
|
||||
LabelMinNotice = _localization.Get("services.detail.rules.minNotice"),
|
||||
LabelMaxAdvanceBooking = _localization.Get("services.detail.rules.maxAdvanceBooking"),
|
||||
LabelCancellationDeadline = _localization.Get("services.detail.rules.cancellationDeadline"),
|
||||
LabelNoShowFee = _localization.Get("services.detail.rules.noShowFee"),
|
||||
|
||||
// Labels - Requirements
|
||||
LabelRequirements = _localization.Get("services.detail.rules.requirements"),
|
||||
LabelRequiresConsultation = _localization.Get("services.detail.rules.requiresConsultation"),
|
||||
LabelRequiresConsultationDesc = _localization.Get("services.detail.rules.requiresConsultationDesc"),
|
||||
LabelRequiresPatchTest = _localization.Get("services.detail.rules.requiresPatchTest"),
|
||||
LabelRequiresPatchTestDesc = _localization.Get("services.detail.rules.requiresPatchTestDesc"),
|
||||
LabelAgeRestriction = _localization.Get("services.detail.rules.ageRestriction"),
|
||||
LabelAgeRestrictionDesc = _localization.Get("services.detail.rules.ageRestrictionDesc"),
|
||||
|
||||
// Labels - Online booking settings
|
||||
LabelOnlineBookingSettings = _localization.Get("services.detail.rules.onlineBookingSettings"),
|
||||
LabelShowInOnlineBooking = _localization.Get("services.detail.rules.showInOnlineBooking"),
|
||||
LabelAllowEmployeeSelection = _localization.Get("services.detail.rules.allowEmployeeSelection"),
|
||||
LabelShowPrice = _localization.Get("services.detail.rules.showPrice"),
|
||||
LabelShowDuration = _localization.Get("services.detail.rules.showDuration"),
|
||||
|
||||
// Toggle labels
|
||||
ToggleYes = _localization.Get("common.yes"),
|
||||
ToggleNo = _localization.Get("common.no")
|
||||
};
|
||||
|
||||
return View(model);
|
||||
}
|
||||
}
|
||||
|
||||
public class ServiceDetailRulesViewModel
|
||||
{
|
||||
// Data - Booking rules
|
||||
public required string MinNotice { get; init; }
|
||||
public required string MaxAdvanceBooking { get; init; }
|
||||
public required string CancellationDeadline { get; init; }
|
||||
public required string NoShowFee { get; init; }
|
||||
|
||||
// Data - Requirements
|
||||
public bool RequiresConsultation { get; init; }
|
||||
public bool RequiresPatchTest { get; init; }
|
||||
public bool AgeRestriction { get; init; }
|
||||
|
||||
// Data - Online booking settings
|
||||
public bool ShowInOnlineBooking { get; init; }
|
||||
public bool AllowEmployeeSelection { get; init; }
|
||||
public bool ShowPrice { get; init; }
|
||||
public bool ShowDuration { get; init; }
|
||||
|
||||
// Labels - Booking rules
|
||||
public required string LabelBookingRules { get; init; }
|
||||
public required string LabelMinNotice { get; init; }
|
||||
public required string LabelMaxAdvanceBooking { get; init; }
|
||||
public required string LabelCancellationDeadline { get; init; }
|
||||
public required string LabelNoShowFee { get; init; }
|
||||
|
||||
// Labels - Requirements
|
||||
public required string LabelRequirements { get; init; }
|
||||
public required string LabelRequiresConsultation { get; init; }
|
||||
public required string LabelRequiresConsultationDesc { get; init; }
|
||||
public required string LabelRequiresPatchTest { get; init; }
|
||||
public required string LabelRequiresPatchTestDesc { get; init; }
|
||||
public required string LabelAgeRestriction { get; init; }
|
||||
public required string LabelAgeRestrictionDesc { get; init; }
|
||||
|
||||
// Labels - Online booking settings
|
||||
public required string LabelOnlineBookingSettings { get; init; }
|
||||
public required string LabelShowInOnlineBooking { get; init; }
|
||||
public required string LabelAllowEmployeeSelection { get; init; }
|
||||
public required string LabelShowPrice { get; init; }
|
||||
public required string LabelShowDuration { get; init; }
|
||||
|
||||
// Toggle labels
|
||||
public required string ToggleYes { get; init; }
|
||||
public required string ToggleNo { get; init; }
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue