Adds comprehensive customers list and management components
Introduces customer-related view components for table and row display Implements mock data loading and customer list rendering Adds localization support for customer-related text Enhances UI with detailed customer information and interactions
This commit is contained in:
parent
cd7acaf490
commit
6ef001e35f
11 changed files with 869 additions and 675 deletions
|
|
@ -0,0 +1,11 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace PlanTempus.Application.Features.Customers.Components;
|
||||
|
||||
public class CustomerRowViewComponent : ViewComponent
|
||||
{
|
||||
public IViewComponentResult Invoke(CustomerItemViewModel customer)
|
||||
{
|
||||
return View(customer);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
@model PlanTempus.Application.Features.Customers.Components.CustomerItemViewModel
|
||||
|
||||
<swp-data-table-row data-name="@Model.FullName" data-visits="@Model.Visits" data-href="/kunder/@Model.Id">
|
||||
<swp-data-table-cell>
|
||||
<swp-avatar class="@Model.AvatarColor">@Model.Initials</swp-avatar>
|
||||
<swp-quick-view-btn data-drawer-trigger="customer-drawer">
|
||||
<i class="ph ph-sidebar"></i>
|
||||
</swp-quick-view-btn>
|
||||
<span>@Model.FullName</span>
|
||||
</swp-data-table-cell>
|
||||
<swp-data-table-cell>@Model.Phone</swp-data-table-cell>
|
||||
<swp-data-table-cell>@Model.Email</swp-data-table-cell>
|
||||
<swp-data-table-cell>@Model.Visits</swp-data-table-cell>
|
||||
<swp-data-table-cell>@Model.LastVisit</swp-data-table-cell>
|
||||
<swp-data-table-cell>@Model.PreferredHairdresser</swp-data-table-cell>
|
||||
<swp-data-table-cell>@Model.CreatedAt</swp-data-table-cell>
|
||||
<swp-data-table-cell>
|
||||
@foreach (var tag in Model.Tags)
|
||||
{
|
||||
<swp-tag class="@tag">@GetTagLabel(tag)</swp-tag>
|
||||
}
|
||||
</swp-data-table-cell>
|
||||
</swp-data-table-row>
|
||||
|
||||
@functions {
|
||||
string GetTagLabel(string tag)
|
||||
{
|
||||
return tag switch
|
||||
{
|
||||
"vip" => "VIP",
|
||||
"ny" => "Ny",
|
||||
"allergi" => "Allergi",
|
||||
"sensitiv" => "Sensitiv",
|
||||
"stamkunde" => "Stamkunde",
|
||||
_ => tag
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using PlanTempus.Application.Features.Localization.Services;
|
||||
|
||||
namespace PlanTempus.Application.Features.Customers.Components;
|
||||
|
||||
public class CustomerTableViewComponent : ViewComponent
|
||||
{
|
||||
private readonly ILocalizationService _localization;
|
||||
private readonly IWebHostEnvironment _env;
|
||||
|
||||
public CustomerTableViewComponent(ILocalizationService localization, IWebHostEnvironment env)
|
||||
{
|
||||
_localization = localization;
|
||||
_env = env;
|
||||
}
|
||||
|
||||
public IViewComponentResult Invoke()
|
||||
{
|
||||
var data = LoadCustomerData();
|
||||
var model = new CustomerTableViewModel
|
||||
{
|
||||
SearchPlaceholder = _localization.Get("customers.searchPlaceholder"),
|
||||
ExportButtonText = _localization.Get("customers.export"),
|
||||
CreateButtonText = _localization.Get("customers.create"),
|
||||
ColumnName = _localization.Get("customers.column.name"),
|
||||
ColumnPhone = _localization.Get("customers.column.phone"),
|
||||
ColumnEmail = _localization.Get("customers.column.email"),
|
||||
ColumnVisits = _localization.Get("customers.column.visits"),
|
||||
ColumnLastVisit = _localization.Get("customers.column.lastVisit"),
|
||||
ColumnHairdresser = _localization.Get("customers.column.hairdresser"),
|
||||
ColumnCreated = _localization.Get("customers.column.created"),
|
||||
ColumnTags = _localization.Get("customers.column.tags"),
|
||||
EmptySearchText = _localization.Get("customers.emptySearch"),
|
||||
Customers = data.Customers
|
||||
.OrderBy(c => c.FirstName)
|
||||
.ThenBy(c => c.LastName)
|
||||
.Select(c => new CustomerItemViewModel
|
||||
{
|
||||
Id = c.Id,
|
||||
FullName = $"{c.FirstName} {c.LastName}",
|
||||
Initials = c.Initials,
|
||||
Phone = c.Phone,
|
||||
Email = c.Email,
|
||||
Visits = c.Visits,
|
||||
LastVisit = FormatLastVisit(c.LastVisit),
|
||||
PreferredHairdresser = c.PreferredHairdresser,
|
||||
CreatedAt = FormatCreatedAt(c.CreatedAt),
|
||||
Tags = c.Tags,
|
||||
AvatarColor = c.AvatarColor
|
||||
})
|
||||
.ToList()
|
||||
};
|
||||
|
||||
return View(model);
|
||||
}
|
||||
|
||||
private CustomerMockData LoadCustomerData()
|
||||
{
|
||||
var jsonPath = Path.Combine(_env.ContentRootPath, "Features", "Customers", "Data", "customersMock.json");
|
||||
var json = System.IO.File.ReadAllText(jsonPath);
|
||||
return JsonSerializer.Deserialize<CustomerMockData>(json, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
}) ?? new CustomerMockData();
|
||||
}
|
||||
|
||||
private static string FormatLastVisit(string dateStr)
|
||||
{
|
||||
if (DateTime.TryParse(dateStr, out var date))
|
||||
{
|
||||
return date.ToString("d. MMM", new CultureInfo("da-DK")).TrimEnd('.');
|
||||
}
|
||||
return dateStr;
|
||||
}
|
||||
|
||||
private static string FormatCreatedAt(string dateStr)
|
||||
{
|
||||
if (DateTime.TryParse(dateStr, out var date))
|
||||
{
|
||||
return date.ToString("MMM yyyy", new CultureInfo("da-DK"));
|
||||
}
|
||||
return dateStr;
|
||||
}
|
||||
}
|
||||
|
||||
public class CustomerTableViewModel
|
||||
{
|
||||
public required string SearchPlaceholder { get; init; }
|
||||
public required string ExportButtonText { get; init; }
|
||||
public required string CreateButtonText { get; init; }
|
||||
public required string ColumnName { get; init; }
|
||||
public required string ColumnPhone { get; init; }
|
||||
public required string ColumnEmail { get; init; }
|
||||
public required string ColumnVisits { get; init; }
|
||||
public required string ColumnLastVisit { get; init; }
|
||||
public required string ColumnHairdresser { get; init; }
|
||||
public required string ColumnCreated { get; init; }
|
||||
public required string ColumnTags { get; init; }
|
||||
public required string EmptySearchText { get; init; }
|
||||
public required IReadOnlyList<CustomerItemViewModel> Customers { get; init; }
|
||||
}
|
||||
|
||||
public class CustomerItemViewModel
|
||||
{
|
||||
public required string Id { get; init; }
|
||||
public required string FullName { get; init; }
|
||||
public required string Initials { get; init; }
|
||||
public required string Phone { get; init; }
|
||||
public required string Email { get; init; }
|
||||
public int Visits { get; init; }
|
||||
public required string LastVisit { get; init; }
|
||||
public required string PreferredHairdresser { get; init; }
|
||||
public required string CreatedAt { get; init; }
|
||||
public required IReadOnlyList<string> Tags { get; init; }
|
||||
public string? AvatarColor { get; init; }
|
||||
}
|
||||
|
||||
internal class CustomerMockData
|
||||
{
|
||||
public List<CustomerData> Customers { get; set; } = new();
|
||||
}
|
||||
|
||||
internal class CustomerData
|
||||
{
|
||||
public string Id { get; set; } = "";
|
||||
public string FirstName { get; set; } = "";
|
||||
public string LastName { get; set; } = "";
|
||||
public string Initials { get; set; } = "";
|
||||
public string Phone { get; set; } = "";
|
||||
public string Email { get; set; } = "";
|
||||
public int Visits { get; set; }
|
||||
public string LastVisit { get; set; } = "";
|
||||
public string PreferredHairdresser { get; set; } = "";
|
||||
public string CreatedAt { get; set; } = "";
|
||||
public List<string> Tags { get; set; } = new();
|
||||
public string? AvatarColor { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
@model PlanTempus.Application.Features.Customers.Components.CustomerTableViewModel
|
||||
|
||||
<swp-action-bar>
|
||||
<swp-search-input>
|
||||
<i class="ph ph-magnifying-glass"></i>
|
||||
<input type="text" id="searchInput" placeholder="@Model.SearchPlaceholder" />
|
||||
</swp-search-input>
|
||||
<swp-btn-group>
|
||||
<swp-btn class="secondary">
|
||||
<i class="ph ph-export"></i>
|
||||
<span>@Model.ExportButtonText</span>
|
||||
</swp-btn>
|
||||
<swp-btn class="primary">
|
||||
<i class="ph ph-plus"></i>
|
||||
<span>@Model.CreateButtonText</span>
|
||||
</swp-btn>
|
||||
</swp-btn-group>
|
||||
</swp-action-bar>
|
||||
|
||||
<swp-card class="customers-list">
|
||||
<swp-data-table>
|
||||
<swp-data-table-header>
|
||||
<swp-data-table-cell>@Model.ColumnName</swp-data-table-cell>
|
||||
<swp-data-table-cell>@Model.ColumnPhone</swp-data-table-cell>
|
||||
<swp-data-table-cell>@Model.ColumnEmail</swp-data-table-cell>
|
||||
<swp-data-table-cell>@Model.ColumnVisits</swp-data-table-cell>
|
||||
<swp-data-table-cell>@Model.ColumnLastVisit</swp-data-table-cell>
|
||||
<swp-data-table-cell>@Model.ColumnHairdresser</swp-data-table-cell>
|
||||
<swp-data-table-cell>@Model.ColumnCreated</swp-data-table-cell>
|
||||
<swp-data-table-cell>@Model.ColumnTags</swp-data-table-cell>
|
||||
</swp-data-table-header>
|
||||
@foreach (var customer in Model.Customers)
|
||||
{
|
||||
@await Component.InvokeAsync("CustomerRow", customer)
|
||||
}
|
||||
</swp-data-table>
|
||||
|
||||
<swp-empty-state id="emptyState" style="display: none;">
|
||||
<i class="ph ph-users"></i>
|
||||
<span>@Model.EmptySearchText</span>
|
||||
</swp-empty-state>
|
||||
</swp-card>
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
{
|
||||
"customers": [
|
||||
{
|
||||
"id": "anna-jensen",
|
||||
"firstName": "Anna",
|
||||
"lastName": "Jensen",
|
||||
"initials": "AJ",
|
||||
"phone": "+45 22 33 44 55",
|
||||
"email": "anna.j@hotmail.dk",
|
||||
"visits": 6,
|
||||
"lastVisit": "2025-11-15",
|
||||
"preferredHairdresser": "Nina K.",
|
||||
"createdAt": "2024-09-01",
|
||||
"tags": [],
|
||||
"avatarColor": null
|
||||
},
|
||||
{
|
||||
"id": "camilla-holm",
|
||||
"firstName": "Camilla",
|
||||
"lastName": "Holm",
|
||||
"initials": "CH",
|
||||
"phone": "+45 66 77 88 99",
|
||||
"email": "camilla.h@outlook.dk",
|
||||
"visits": 25,
|
||||
"lastVisit": "2025-10-28",
|
||||
"preferredHairdresser": "Emma L.",
|
||||
"createdAt": "2022-12-01",
|
||||
"tags": ["vip"],
|
||||
"avatarColor": null
|
||||
},
|
||||
{
|
||||
"id": "emma-larsen",
|
||||
"firstName": "Emma",
|
||||
"lastName": "Larsen",
|
||||
"initials": "EL",
|
||||
"phone": "+45 12 34 56 78",
|
||||
"email": "emma.l@gmail.com",
|
||||
"visits": 8,
|
||||
"lastVisit": "2025-12-05",
|
||||
"preferredHairdresser": "Nina K.",
|
||||
"createdAt": "2024-06-01",
|
||||
"tags": [],
|
||||
"avatarColor": null
|
||||
},
|
||||
{
|
||||
"id": "freja-christensen",
|
||||
"firstName": "Freja",
|
||||
"lastName": "Christensen",
|
||||
"initials": "FC",
|
||||
"phone": "+45 55 66 77 88",
|
||||
"email": "freja.c@outlook.dk",
|
||||
"visits": 31,
|
||||
"lastVisit": "2025-11-20",
|
||||
"preferredHairdresser": "Emma L.",
|
||||
"createdAt": "2022-08-01",
|
||||
"tags": ["vip", "allergi"],
|
||||
"avatarColor": null
|
||||
},
|
||||
{
|
||||
"id": "ida-andersen",
|
||||
"firstName": "Ida",
|
||||
"lastName": "Andersen",
|
||||
"initials": "IA",
|
||||
"phone": "+45 11 22 33 44",
|
||||
"email": "ida@firma.dk",
|
||||
"visits": 3,
|
||||
"lastVisit": "2025-11-28",
|
||||
"preferredHairdresser": "Sofie M.",
|
||||
"createdAt": "2025-10-01",
|
||||
"tags": ["ny"],
|
||||
"avatarColor": null
|
||||
},
|
||||
{
|
||||
"id": "katrine-berg",
|
||||
"firstName": "Katrine",
|
||||
"lastName": "Berg",
|
||||
"initials": "KB",
|
||||
"phone": "+45 55 66 77 88",
|
||||
"email": "katrine.b@firma.dk",
|
||||
"visits": 12,
|
||||
"lastVisit": "2025-11-01",
|
||||
"preferredHairdresser": "Nina K.",
|
||||
"createdAt": "2024-04-01",
|
||||
"tags": [],
|
||||
"avatarColor": null
|
||||
},
|
||||
{
|
||||
"id": "line-frost",
|
||||
"firstName": "Line",
|
||||
"lastName": "Frost",
|
||||
"initials": "LF",
|
||||
"phone": "+45 88 99 00 11",
|
||||
"email": "line.f@mail.dk",
|
||||
"visits": 9,
|
||||
"lastVisit": "2025-10-15",
|
||||
"preferredHairdresser": "Nina K.",
|
||||
"createdAt": "2024-05-01",
|
||||
"tags": ["sensitiv"],
|
||||
"avatarColor": null
|
||||
},
|
||||
{
|
||||
"id": "louise-hansen",
|
||||
"firstName": "Louise",
|
||||
"lastName": "Hansen",
|
||||
"initials": "LH",
|
||||
"phone": "+45 33 44 55 66",
|
||||
"email": "louise.h@gmail.com",
|
||||
"visits": 18,
|
||||
"lastVisit": "2025-11-10",
|
||||
"preferredHairdresser": "Emma L.",
|
||||
"createdAt": "2023-02-01",
|
||||
"tags": ["stamkunde"],
|
||||
"avatarColor": "purple"
|
||||
},
|
||||
{
|
||||
"id": "maja-petersen",
|
||||
"firstName": "Maja",
|
||||
"lastName": "Petersen",
|
||||
"initials": "MP",
|
||||
"phone": "+45 98 76 54 32",
|
||||
"email": "maja.p@mail.dk",
|
||||
"visits": 22,
|
||||
"lastVisit": "2025-12-01",
|
||||
"preferredHairdresser": "Emma L.",
|
||||
"createdAt": "2023-01-01",
|
||||
"tags": ["stamkunde"],
|
||||
"avatarColor": "blue"
|
||||
},
|
||||
{
|
||||
"id": "maria-olsen",
|
||||
"firstName": "Maria",
|
||||
"lastName": "Olsen",
|
||||
"initials": "MO",
|
||||
"phone": "+45 44 55 66 77",
|
||||
"email": "maria.o@mail.dk",
|
||||
"visits": 2,
|
||||
"lastVisit": "2025-11-05",
|
||||
"preferredHairdresser": "Sofie M.",
|
||||
"createdAt": "2025-11-01",
|
||||
"tags": ["ny"],
|
||||
"avatarColor": "amber"
|
||||
},
|
||||
{
|
||||
"id": "rikke-skov",
|
||||
"firstName": "Rikke",
|
||||
"lastName": "Skov",
|
||||
"initials": "RS",
|
||||
"phone": "+45 77 88 99 00",
|
||||
"email": "rikke.s@gmail.com",
|
||||
"visits": 4,
|
||||
"lastVisit": "2025-10-20",
|
||||
"preferredHairdresser": "Sofie M.",
|
||||
"createdAt": "2025-08-01",
|
||||
"tags": [],
|
||||
"avatarColor": null
|
||||
},
|
||||
{
|
||||
"id": "sofie-nielsen",
|
||||
"firstName": "Sofie",
|
||||
"lastName": "Nielsen",
|
||||
"initials": "SN",
|
||||
"phone": "+45 23 45 67 89",
|
||||
"email": "sofie@email.dk",
|
||||
"visits": 14,
|
||||
"lastVisit": "2025-12-09",
|
||||
"preferredHairdresser": "Emma L.",
|
||||
"createdAt": "2024-03-01",
|
||||
"tags": ["vip"],
|
||||
"avatarColor": null
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -31,288 +31,7 @@
|
|||
</swp-sticky-header>
|
||||
|
||||
<swp-page-container>
|
||||
<swp-action-bar>
|
||||
<swp-search-input>
|
||||
<i class="ph ph-magnifying-glass"></i>
|
||||
<input type="text" id="searchInput" placeholder="Søg kunde (navn, telefon, email...)" />
|
||||
</swp-search-input>
|
||||
<swp-btn-group>
|
||||
<swp-btn class="secondary">
|
||||
<i class="ph ph-export"></i>
|
||||
<span localize="customers.export">Eksporter</span>
|
||||
</swp-btn>
|
||||
<swp-btn class="primary">
|
||||
<i class="ph ph-plus"></i>
|
||||
<span localize="customers.create">Ny kunde</span>
|
||||
</swp-btn>
|
||||
</swp-btn-group>
|
||||
</swp-action-bar>
|
||||
|
||||
<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>
|
||||
<swp-data-table-cell localize="customers.column.visits">Besøg</swp-data-table-cell>
|
||||
<swp-data-table-cell localize="customers.column.lastVisit">Sidste</swp-data-table-cell>
|
||||
<swp-data-table-cell localize="customers.column.hairdresser">Frisør</swp-data-table-cell>
|
||||
<swp-data-table-cell localize="customers.column.created">Oprettet</swp-data-table-cell>
|
||||
<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-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>
|
||||
</swp-data-table-cell>
|
||||
<swp-data-table-cell>+45 22 33 44 55</swp-data-table-cell>
|
||||
<swp-data-table-cell>anna.j@hotmail.dk</swp-data-table-cell>
|
||||
<swp-data-table-cell>6</swp-data-table-cell>
|
||||
<swp-data-table-cell>15. nov</swp-data-table-cell>
|
||||
<swp-data-table-cell>Nina K.</swp-data-table-cell>
|
||||
<swp-data-table-cell>Sep 2024</swp-data-table-cell>
|
||||
<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-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>
|
||||
</swp-data-table-cell>
|
||||
<swp-data-table-cell>+45 66 77 88 99</swp-data-table-cell>
|
||||
<swp-data-table-cell>camilla.h@outlook.dk</swp-data-table-cell>
|
||||
<swp-data-table-cell>25</swp-data-table-cell>
|
||||
<swp-data-table-cell>28. okt</swp-data-table-cell>
|
||||
<swp-data-table-cell>Emma L.</swp-data-table-cell>
|
||||
<swp-data-table-cell>Dec 2022</swp-data-table-cell>
|
||||
<swp-data-table-cell>
|
||||
<swp-tag class="vip">VIP</swp-tag>
|
||||
</swp-data-table-cell>
|
||||
</swp-data-table-row>
|
||||
|
||||
<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>
|
||||
</swp-data-table-cell>
|
||||
<swp-data-table-cell>+45 12 34 56 78</swp-data-table-cell>
|
||||
<swp-data-table-cell>emma.l@gmail.com</swp-data-table-cell>
|
||||
<swp-data-table-cell>8</swp-data-table-cell>
|
||||
<swp-data-table-cell>5. dec</swp-data-table-cell>
|
||||
<swp-data-table-cell>Nina K.</swp-data-table-cell>
|
||||
<swp-data-table-cell>Jun 2024</swp-data-table-cell>
|
||||
<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-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>
|
||||
</swp-data-table-cell>
|
||||
<swp-data-table-cell>+45 55 66 77 88</swp-data-table-cell>
|
||||
<swp-data-table-cell>freja.c@outlook.dk</swp-data-table-cell>
|
||||
<swp-data-table-cell>31</swp-data-table-cell>
|
||||
<swp-data-table-cell>20. nov</swp-data-table-cell>
|
||||
<swp-data-table-cell>Emma L.</swp-data-table-cell>
|
||||
<swp-data-table-cell>Aug 2022</swp-data-table-cell>
|
||||
<swp-data-table-cell>
|
||||
<swp-tag class="vip">VIP</swp-tag>
|
||||
<swp-tag class="allergi">Allergi</swp-tag>
|
||||
</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-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>
|
||||
</swp-data-table-cell>
|
||||
<swp-data-table-cell>+45 11 22 33 44</swp-data-table-cell>
|
||||
<swp-data-table-cell>ida@firma.dk</swp-data-table-cell>
|
||||
<swp-data-table-cell>3</swp-data-table-cell>
|
||||
<swp-data-table-cell>28. nov</swp-data-table-cell>
|
||||
<swp-data-table-cell>Sofie M.</swp-data-table-cell>
|
||||
<swp-data-table-cell>Okt 2025</swp-data-table-cell>
|
||||
<swp-data-table-cell>
|
||||
<swp-tag class="ny">Ny</swp-tag>
|
||||
</swp-data-table-cell>
|
||||
</swp-data-table-row>
|
||||
|
||||
<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>
|
||||
</swp-data-table-cell>
|
||||
<swp-data-table-cell>+45 55 66 77 88</swp-data-table-cell>
|
||||
<swp-data-table-cell>katrine.b@firma.dk</swp-data-table-cell>
|
||||
<swp-data-table-cell>12</swp-data-table-cell>
|
||||
<swp-data-table-cell>1. nov</swp-data-table-cell>
|
||||
<swp-data-table-cell>Nina K.</swp-data-table-cell>
|
||||
<swp-data-table-cell>Apr 2024</swp-data-table-cell>
|
||||
<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-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>
|
||||
</swp-data-table-cell>
|
||||
<swp-data-table-cell>+45 88 99 00 11</swp-data-table-cell>
|
||||
<swp-data-table-cell>line.f@mail.dk</swp-data-table-cell>
|
||||
<swp-data-table-cell>9</swp-data-table-cell>
|
||||
<swp-data-table-cell>15. okt</swp-data-table-cell>
|
||||
<swp-data-table-cell>Nina K.</swp-data-table-cell>
|
||||
<swp-data-table-cell>Maj 2024</swp-data-table-cell>
|
||||
<swp-data-table-cell>
|
||||
<swp-tag class="sensitiv">Sensitiv</swp-tag>
|
||||
</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-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>
|
||||
</swp-data-table-cell>
|
||||
<swp-data-table-cell>+45 33 44 55 66</swp-data-table-cell>
|
||||
<swp-data-table-cell>louise.h@gmail.com</swp-data-table-cell>
|
||||
<swp-data-table-cell>18</swp-data-table-cell>
|
||||
<swp-data-table-cell>10. nov</swp-data-table-cell>
|
||||
<swp-data-table-cell>Emma L.</swp-data-table-cell>
|
||||
<swp-data-table-cell>Feb 2023</swp-data-table-cell>
|
||||
<swp-data-table-cell>
|
||||
<swp-tag class="stamkunde">Stamkunde</swp-tag>
|
||||
</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-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>
|
||||
</swp-data-table-cell>
|
||||
<swp-data-table-cell>+45 98 76 54 32</swp-data-table-cell>
|
||||
<swp-data-table-cell>maja.p@mail.dk</swp-data-table-cell>
|
||||
<swp-data-table-cell>22</swp-data-table-cell>
|
||||
<swp-data-table-cell>1. dec</swp-data-table-cell>
|
||||
<swp-data-table-cell>Emma L.</swp-data-table-cell>
|
||||
<swp-data-table-cell>Jan 2023</swp-data-table-cell>
|
||||
<swp-data-table-cell>
|
||||
<swp-tag class="stamkunde">Stamkunde</swp-tag>
|
||||
</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-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>
|
||||
</swp-data-table-cell>
|
||||
<swp-data-table-cell>+45 44 55 66 77</swp-data-table-cell>
|
||||
<swp-data-table-cell>maria.o@mail.dk</swp-data-table-cell>
|
||||
<swp-data-table-cell>2</swp-data-table-cell>
|
||||
<swp-data-table-cell>5. nov</swp-data-table-cell>
|
||||
<swp-data-table-cell>Sofie M.</swp-data-table-cell>
|
||||
<swp-data-table-cell>Nov 2025</swp-data-table-cell>
|
||||
<swp-data-table-cell>
|
||||
<swp-tag class="ny">Ny</swp-tag>
|
||||
</swp-data-table-cell>
|
||||
</swp-data-table-row>
|
||||
|
||||
<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>
|
||||
</swp-data-table-cell>
|
||||
<swp-data-table-cell>+45 77 88 99 00</swp-data-table-cell>
|
||||
<swp-data-table-cell>rikke.s@gmail.com</swp-data-table-cell>
|
||||
<swp-data-table-cell>4</swp-data-table-cell>
|
||||
<swp-data-table-cell>20. okt</swp-data-table-cell>
|
||||
<swp-data-table-cell>Sofie M.</swp-data-table-cell>
|
||||
<swp-data-table-cell>Aug 2025</swp-data-table-cell>
|
||||
<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-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>
|
||||
</swp-data-table-cell>
|
||||
<swp-data-table-cell>+45 23 45 67 89</swp-data-table-cell>
|
||||
<swp-data-table-cell>sofie@email.dk</swp-data-table-cell>
|
||||
<swp-data-table-cell>14</swp-data-table-cell>
|
||||
<swp-data-table-cell>9. dec</swp-data-table-cell>
|
||||
<swp-data-table-cell>Emma L.</swp-data-table-cell>
|
||||
<swp-data-table-cell>Mar 2024</swp-data-table-cell>
|
||||
<swp-data-table-cell>
|
||||
<swp-tag class="vip">VIP</swp-tag>
|
||||
</swp-data-table-cell>
|
||||
</swp-data-table-row>
|
||||
</swp-data-table>
|
||||
|
||||
<swp-empty-state id="emptyState" style="display: none;">
|
||||
<i class="ph ph-users"></i>
|
||||
<span localize="customers.emptySearch">Ingen kunder matcher din søgning</span>
|
||||
</swp-empty-state>
|
||||
</swp-card>
|
||||
@await Component.InvokeAsync("CustomerTable")
|
||||
</swp-page-container>
|
||||
|
||||
<!-- Customer Drawer -->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue