Enhances customer list and detail views

Improves customer page UI with interactive elements:
- Adds quick view sidebar button for each customer row
- Implements row-level navigation to customer details
- Corrects Danish spelling and typography
- Refactors data table layout for better usability

Modernizes customer interaction by enabling direct page navigation and quick information access
This commit is contained in:
Janus C. H. Knudsen 2026-01-20 21:32:03 +01:00
parent 6b0a84a07e
commit cd7acaf490
5 changed files with 291 additions and 178 deletions

View file

@ -54,11 +54,11 @@
</swp-fact-inline>
<swp-fact-inline>
<swp-fact-inline-value>Emma L.</swp-fact-inline-value>
<swp-fact-inline-label>foretrukken frisor</swp-fact-inline-label>
<swp-fact-inline-label>foretrukken frisør</swp-fact-inline-label>
</swp-fact-inline>
<swp-fact-inline>
<swp-fact-inline-value>12.450 kr</swp-fact-inline-value>
<swp-fact-inline-label>total omsaetning</swp-fact-inline-label>
<swp-fact-inline-label>total omsætning</swp-fact-inline-label>
</swp-fact-inline>
</swp-fact-boxes-inline>
</swp-customer-detail-info>
@ -205,7 +205,7 @@
</swp-card-header>
<swp-profile-boxes>
<swp-profile-box>
<swp-profile-box-label localize="customers.detail.preferredHairdresser">Foretrukken frisor</swp-profile-box-label>
<swp-profile-box-label localize="customers.detail.preferredHairdresser">Foretrukken frisør</swp-profile-box-label>
<swp-profile-box-value>Emma L.</swp-profile-box-value>
</swp-profile-box>
<swp-profile-box>
@ -213,8 +213,8 @@
<swp-profile-box-value>Tirsdag/Torsdag</swp-profile-box-value>
</swp-profile-box>
<swp-profile-box class="full-width">
<swp-profile-box-label localize="customers.detail.specialRequests">Specielle onsker</swp-profile-box-label>
<swp-profile-box-value>Foretraekker kold tone, ikke for mork</swp-profile-box-value>
<swp-profile-box-label localize="customers.detail.specialRequests">Specielle ønsker</swp-profile-box-label>
<swp-profile-box-value>Foretraekker kold tone, ikke for mørk</swp-profile-box-value>
</swp-profile-box>
</swp-profile-boxes>
</swp-card>

View file

@ -51,6 +51,7 @@
<swp-card class="customers-list">
<swp-data-table>
<swp-data-table-header>
<swp-data-table-cell></swp-data-table-cell>
<swp-data-table-cell localize="customers.column.name">Navn</swp-data-table-cell>
<swp-data-table-cell localize="customers.column.phone">Telefon</swp-data-table-cell>
<swp-data-table-cell localize="customers.column.email">Email</swp-data-table-cell>
@ -61,7 +62,12 @@
<swp-data-table-cell localize="customers.column.tags">Tags</swp-data-table-cell>
</swp-data-table-header>
<swp-data-table-row data-name="Anna Jensen" data-visits="6" data-created="2024-09" data-drawer-trigger="customer-drawer">
<swp-data-table-row data-name="Anna Jensen" data-visits="6" data-created="2024-09" data-href="/kunder/anna-jensen">
<swp-data-table-cell class="quick-view">
<swp-quick-view-btn data-drawer-trigger="customer-drawer">
<i class="ph ph-sidebar"></i>
</swp-quick-view-btn>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-avatar>AJ</swp-avatar>
<span>Anna Jensen</span>
@ -75,7 +81,12 @@
<swp-data-table-cell></swp-data-table-cell>
</swp-data-table-row>
<swp-data-table-row data-name="Camilla Holm" data-visits="25" data-created="2022-12" data-tags="vip" data-drawer-trigger="customer-drawer">
<swp-data-table-row data-name="Camilla Holm" data-visits="25" data-created="2022-12" data-tags="vip" data-href="/kunder/camilla-holm">
<swp-data-table-cell class="quick-view">
<swp-quick-view-btn data-drawer-trigger="customer-drawer">
<i class="ph ph-sidebar"></i>
</swp-quick-view-btn>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-avatar>CH</swp-avatar>
<span>Camilla Holm</span>
@ -91,7 +102,12 @@
</swp-data-table-cell>
</swp-data-table-row>
<swp-data-table-row data-name="Emma Larsen" data-visits="8" data-created="2024-06" data-drawer-trigger="customer-drawer">
<swp-data-table-row data-name="Emma Larsen" data-visits="8" data-created="2024-06" data-href="/kunder/emma-larsen">
<swp-data-table-cell class="quick-view">
<swp-quick-view-btn data-drawer-trigger="customer-drawer">
<i class="ph ph-sidebar"></i>
</swp-quick-view-btn>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-avatar>EL</swp-avatar>
<span>Emma Larsen</span>
@ -105,7 +121,12 @@
<swp-data-table-cell></swp-data-table-cell>
</swp-data-table-row>
<swp-data-table-row data-name="Freja Christensen" data-visits="31" data-created="2022-08" data-tags="vip,allergi" data-drawer-trigger="customer-drawer">
<swp-data-table-row data-name="Freja Christensen" data-visits="31" data-created="2022-08" data-tags="vip,allergi" data-href="/kunder/freja-christensen">
<swp-data-table-cell class="quick-view">
<swp-quick-view-btn data-drawer-trigger="customer-drawer">
<i class="ph ph-sidebar"></i>
</swp-quick-view-btn>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-avatar>FC</swp-avatar>
<span>Freja Christensen</span>
@ -122,7 +143,12 @@
</swp-data-table-cell>
</swp-data-table-row>
<swp-data-table-row data-name="Ida Andersen" data-visits="3" data-created="2025-10" data-tags="ny" data-drawer-trigger="customer-drawer">
<swp-data-table-row data-name="Ida Andersen" data-visits="3" data-created="2025-10" data-tags="ny" data-href="/kunder/ida-andersen">
<swp-data-table-cell class="quick-view">
<swp-quick-view-btn data-drawer-trigger="customer-drawer">
<i class="ph ph-sidebar"></i>
</swp-quick-view-btn>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-avatar>IA</swp-avatar>
<span>Ida Andersen</span>
@ -138,7 +164,12 @@
</swp-data-table-cell>
</swp-data-table-row>
<swp-data-table-row data-name="Katrine Berg" data-visits="12" data-created="2024-04" data-drawer-trigger="customer-drawer">
<swp-data-table-row data-name="Katrine Berg" data-visits="12" data-created="2024-04" data-href="/kunder/katrine-berg">
<swp-data-table-cell class="quick-view">
<swp-quick-view-btn data-drawer-trigger="customer-drawer">
<i class="ph ph-sidebar"></i>
</swp-quick-view-btn>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-avatar>KB</swp-avatar>
<span>Katrine Berg</span>
@ -152,7 +183,12 @@
<swp-data-table-cell></swp-data-table-cell>
</swp-data-table-row>
<swp-data-table-row data-name="Line Frost" data-visits="9" data-created="2024-05" data-tags="sensitiv" data-drawer-trigger="customer-drawer">
<swp-data-table-row data-name="Line Frost" data-visits="9" data-created="2024-05" data-tags="sensitiv" data-href="/kunder/line-frost">
<swp-data-table-cell class="quick-view">
<swp-quick-view-btn data-drawer-trigger="customer-drawer">
<i class="ph ph-sidebar"></i>
</swp-quick-view-btn>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-avatar>LF</swp-avatar>
<span>Line Frost</span>
@ -168,7 +204,12 @@
</swp-data-table-cell>
</swp-data-table-row>
<swp-data-table-row data-name="Louise Hansen" data-visits="18" data-created="2023-02" data-tags="stamkunde" data-drawer-trigger="customer-drawer">
<swp-data-table-row data-name="Louise Hansen" data-visits="18" data-created="2023-02" data-tags="stamkunde" data-href="/kunder/louise-hansen">
<swp-data-table-cell class="quick-view">
<swp-quick-view-btn data-drawer-trigger="customer-drawer">
<i class="ph ph-sidebar"></i>
</swp-quick-view-btn>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-avatar class="purple">LH</swp-avatar>
<span>Louise Hansen</span>
@ -184,7 +225,12 @@
</swp-data-table-cell>
</swp-data-table-row>
<swp-data-table-row data-name="Maja Petersen" data-visits="22" data-created="2023-01" data-tags="stamkunde" data-drawer-trigger="customer-drawer">
<swp-data-table-row data-name="Maja Petersen" data-visits="22" data-created="2023-01" data-tags="stamkunde" data-href="/kunder/maja-petersen">
<swp-data-table-cell class="quick-view">
<swp-quick-view-btn data-drawer-trigger="customer-drawer">
<i class="ph ph-sidebar"></i>
</swp-quick-view-btn>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-avatar class="blue">MP</swp-avatar>
<span>Maja Petersen</span>
@ -200,7 +246,12 @@
</swp-data-table-cell>
</swp-data-table-row>
<swp-data-table-row data-name="Maria Olsen" data-visits="2" data-created="2025-11" data-tags="ny" data-drawer-trigger="customer-drawer">
<swp-data-table-row data-name="Maria Olsen" data-visits="2" data-created="2025-11" data-tags="ny" data-href="/kunder/maria-olsen">
<swp-data-table-cell class="quick-view">
<swp-quick-view-btn data-drawer-trigger="customer-drawer">
<i class="ph ph-sidebar"></i>
</swp-quick-view-btn>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-avatar class="amber">MO</swp-avatar>
<span>Maria Olsen</span>
@ -216,7 +267,12 @@
</swp-data-table-cell>
</swp-data-table-row>
<swp-data-table-row data-name="Rikke Skov" data-visits="4" data-created="2025-08" data-drawer-trigger="customer-drawer">
<swp-data-table-row data-name="Rikke Skov" data-visits="4" data-created="2025-08" data-href="/kunder/rikke-skov">
<swp-data-table-cell class="quick-view">
<swp-quick-view-btn data-drawer-trigger="customer-drawer">
<i class="ph ph-sidebar"></i>
</swp-quick-view-btn>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-avatar>RS</swp-avatar>
<span>Rikke Skov</span>
@ -230,7 +286,12 @@
<swp-data-table-cell></swp-data-table-cell>
</swp-data-table-row>
<swp-data-table-row data-name="Sofie Nielsen" data-visits="14" data-created="2024-03" data-tags="vip" data-drawer-trigger="customer-drawer">
<swp-data-table-row data-name="Sofie Nielsen" data-visits="14" data-created="2024-03" data-tags="vip" data-href="/kunder/sofie-nielsen">
<swp-data-table-cell class="quick-view">
<swp-quick-view-btn data-drawer-trigger="customer-drawer">
<i class="ph ph-sidebar"></i>
</swp-quick-view-btn>
</swp-data-table-cell>
<swp-data-table-cell>
<swp-avatar>SN</swp-avatar>
<span>Sofie Nielsen</span>
@ -419,13 +480,30 @@
@section Scripts {
<script>
// Update detail link when drawer opens
document.querySelectorAll('[data-drawer-trigger="customer-drawer"]').forEach(row => {
row.addEventListener('click', () => {
// Row click - navigate to detail page
document.querySelectorAll('swp-data-table-row[data-href]').forEach(row => {
row.addEventListener('click', (e) => {
// Don't navigate if clicking the quick-view button
if (e.target.closest('swp-quick-view-btn')) {
return;
}
const href = row.dataset.href;
if (href) {
window.location.href = href;
}
});
});
// Quick-view button click - update drawer data before it opens
// Note: The drawer opening is handled by the global drawer system via data-drawer-trigger
document.querySelectorAll('swp-quick-view-btn[data-drawer-trigger="customer-drawer"]').forEach(btn => {
btn.addEventListener('click', (e) => {
// Don't stop propagation - let the event bubble up to the drawer system
const row = btn.closest('swp-data-table-row');
const drawer = document.getElementById('customer-drawer');
const detailLink = document.getElementById('openFullDetailLink');
// Generate a customer ID from the row data (in real app, use actual ID)
// Get customer data from row
const customerName = row.dataset.name || 'unknown';
const customerId = customerName.toLowerCase().replace(/\s+/g, '-');

View file

@ -1,150 +1,156 @@
@model PlanTempus.Application.Features.Services.Components.ServiceDetailRulesViewModel
<swp-detail-grid>
<swp-card>
<swp-card-header>
<swp-card-title>@Model.LabelBookingRules</swp-card-title>
</swp-card-header>
<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>
<!-- Column 1 -->
<swp-card-column>
<swp-card>
<swp-card-header>
<swp-card-title>@Model.LabelBookingRules</swp-card-title>
</swp-card-header>
<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-card-header>
<swp-card-title>@Model.LabelRequirements</swp-card-title>
</swp-card-header>
<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-card>
<swp-card-header>
<swp-card-title>@Model.LabelOnlineBookingSettings</swp-card-title>
</swp-card-header>
<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>
</swp-card-column>
<!-- Column 2 -->
<swp-card-column>
<swp-card>
<swp-card-header>
<swp-card-title>@Model.LabelRequirements</swp-card-title>
</swp-card-header>
<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-card-column>
</swp-detail-grid>
<swp-card>
<swp-card-header>
<swp-card-title>@Model.LabelOnlineBookingSettings</swp-card-title>
</swp-card-header>
<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)
{

View file

@ -568,7 +568,7 @@ swp-card-title {
display: flex;
align-items: center;
gap: var(--spacing-3);
font-size: var(--font-size-md);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-semibold);
text-transform: uppercase;
color: var(--color-text);

View file

@ -18,9 +18,9 @@ swp-card.customers-list {
overflow: hidden;
}
/* Table columns: Navn(1fr) | Tlf(120px) | Email(180px) | Besøg(70px) | Sidste(90px) | Frisør(100px) | Oprettet(90px) | Tags(140px) */
/* Table columns: QuickView(40px) | Navn(1fr) | Tlf(120px) | Email(180px) | Besøg(70px) | Sidste(90px) | Frisør(100px) | Oprettet(90px) | Tags(140px) */
swp-card.customers-list swp-data-table {
grid-template-columns: minmax(200px, 1fr) 120px 180px 70px 90px 100px 90px 140px;
grid-template-columns: 40px minmax(200px, 1fr) 120px 180px 70px 90px 100px 90px 140px;
}
swp-card.customers-list swp-data-table-header,
@ -41,32 +41,61 @@ swp-card.customers-list swp-data-table-cell {
padding: var(--spacing-5) 0;
}
/* Name cell with avatar */
/* Quick-view cell (first column) */
swp-card.customers-list swp-data-table-cell:first-child {
display: flex;
align-items: center;
justify-content: center;
}
/* Name cell with avatar (second column) */
swp-card.customers-list swp-data-table-cell:nth-child(2) {
display: flex;
align-items: center;
gap: var(--spacing-4);
}
/* Mono font for visits column */
swp-card.customers-list swp-data-table-row swp-data-table-cell:nth-child(4) {
/* Mono font for visits column (fifth column) */
swp-card.customers-list swp-data-table-row swp-data-table-cell:nth-child(5) {
font-family: var(--font-mono);
text-align: center;
}
/* Muted text for email and created columns */
swp-card.customers-list swp-data-table-row swp-data-table-cell:nth-child(3),
swp-card.customers-list swp-data-table-row swp-data-table-cell:nth-child(7) {
/* Muted text for email and created columns (4th and 8th) */
swp-card.customers-list swp-data-table-row swp-data-table-cell:nth-child(4),
swp-card.customers-list swp-data-table-row swp-data-table-cell:nth-child(8) {
color: var(--color-text-secondary);
}
/* Tags cell */
/* Tags cell (last column) */
swp-card.customers-list swp-data-table-cell:last-child {
display: flex;
gap: var(--spacing-2);
flex-wrap: wrap;
}
/* Quick-view button */
swp-quick-view-btn {
display: flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border-radius: var(--radius-md);
color: var(--color-text-tertiary);
cursor: pointer;
transition: all var(--transition-fast);
}
swp-quick-view-btn:hover {
background: var(--bg-teal-subtle);
color: var(--color-teal);
}
swp-quick-view-btn i {
font-size: var(--font-size-lg);
}
/* ===========================================
CUSTOMER DRAWER
Reuses: swp-drawer-* (drawers.css), swp-section-label (components.css),
@ -1207,20 +1236,20 @@ swp-giftcard-balance {
}
swp-giftcard-balance strong {
color: var(--color-text);
font-weight: var(--font-weight-semibold);
font-family: var(--font-mono);
color: var(--color-teal);
}
swp-giftcard-expires {
font-size: var(--font-size-xs);
font-size: var(--font-size-sm);
color: var(--color-text-tertiary);
}
/* Progress Bar */
swp-progress-bar {
height: 6px;
height: 8px;
background: var(--color-border);
border-radius: var(--radius-full);
border-radius: var(--radius-sm);
overflow: hidden;
}
@ -1348,7 +1377,7 @@ swp-activity-content {
}
swp-activity-title {
font-size: var(--font-size-sm);
font-size: var(--font-size-md);
color: var(--color-text);
display: flex;
align-items: center;