Adds customer details drawer to customers list page

Enhances customer management with interactive drawer
Introduces detailed customer profile view with metadata
Implements search functionality and dynamic drawer population

Improves user experience for customer information exploration
This commit is contained in:
Janus C. H. Knudsen 2026-01-19 18:27:59 +01:00
parent 65ad9aacdf
commit 0a431c8db4
8 changed files with 694 additions and 15 deletions

View file

@ -1039,6 +1039,8 @@ swp-form-input {
[data-drawer] swp-section-label {
margin-bottom: 12px;
padding-bottom: 0;
border-bottom: none;
}
[data-drawer] swp-data-section {
@ -1179,7 +1181,7 @@ swp-status-indicator {
&[data-active="false"] {
background: var(--bg-red-medium);
color: var(--color-red);
border: 1px solid var(--bg-red-border);
border: 1px solid var(--border-red);
}
.icon {

View file

@ -4,7 +4,7 @@
* Feature-specific styling only.
* Reuses:
* - swp-sticky-header, swp-header-content, swp-page-container (page.css)
* - swp-stats-row, swp-stat-card (stats.css)
* - swp-stats-row, swp-stat-card, swp-quick-stats (stats.css)
* - swp-action-bar, swp-search-input (components.css, services.css)
* - swp-data-table, swp-avatar, swp-tag, swp-empty-state (components.css)
* - swp-btn (components.css)
@ -66,3 +66,274 @@ swp-card.customers-list swp-data-table-cell:last-child {
gap: var(--spacing-2);
flex-wrap: wrap;
}
/* ===========================================
CUSTOMER DRAWER
Reuses: swp-drawer-* (drawers.css), swp-section-label (components.css),
swp-edit-section/row (components.css), swp-toggle-row/slider (controls.css)
=========================================== */
/* Customer Header */
swp-customer-header {
display: flex;
gap: var(--spacing-6);
padding-bottom: var(--spacing-6);
border-bottom: 1px solid var(--color-border);
margin-bottom: var(--spacing-6);
}
swp-customer-avatar-large {
width: 80px;
height: 80px;
border-radius: var(--radius-full);
background: var(--color-teal);
color: white;
font-size: var(--font-size-3xl);
font-weight: var(--font-weight-semibold);
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
swp-customer-header-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
gap: var(--spacing-3);
}
swp-customer-header-top {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: var(--spacing-4);
}
swp-customer-header-left {
display: flex;
flex-direction: column;
gap: var(--spacing-1);
}
swp-customer-header-name {
font-size: var(--font-size-xl);
font-weight: var(--font-weight-semibold);
color: var(--color-text);
}
swp-customer-since {
font-size: var(--font-size-sm);
color: var(--color-text-secondary);
}
swp-customer-header-contact {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: var(--spacing-2);
font-size: var(--font-size-sm);
a {
color: var(--color-teal);
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
swp-customer-tags {
display: flex;
gap: var(--spacing-2);
margin-top: var(--spacing-1);
}
/* Marketing Section */
swp-marketing-section {
display: flex;
flex-direction: column;
gap: var(--spacing-3);
swp-toggle-row,
swp-toggle-row:last-child {
padding: var(--spacing-4);
background: var(--color-background-alt);
border-radius: var(--radius-md);
border: 1px solid var(--color-border);
}
}
/* Profile Boxes (2x2 grid) */
swp-profile-boxes {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--spacing-4);
}
swp-profile-box {
display: flex;
flex-direction: column;
gap: var(--spacing-2);
padding: var(--spacing-4);
background: var(--color-background-alt);
border-radius: var(--radius-md);
border: 1px solid var(--color-border);
&.warning {
background: var(--bg-red-subtle);
border: 1px solid var(--border-red);
swp-profile-box-label {
color: var(--color-red);
}
}
}
swp-profile-box-label {
font-size: var(--font-size-xs);
font-weight: var(--font-weight-medium);
color: var(--color-text-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
}
swp-profile-box-value {
font-size: var(--font-size-base);
color: var(--color-text);
}
/* Chart Section */
swp-chart-section {
display: flex;
flex-direction: column;
gap: var(--spacing-4);
margin-top: var(--spacing-6);
padding-top: var(--spacing-6);
border-top: 1px solid var(--color-border);
}
swp-chart-header {
display: flex;
justify-content: space-between;
align-items: center;
}
swp-chart-legend {
display: flex;
gap: var(--spacing-5);
}
swp-chart-legend-item {
display: flex;
align-items: center;
gap: var(--spacing-2);
font-size: var(--font-size-sm);
color: var(--color-text-secondary);
}
swp-chart-legend-dot {
width: 10px;
height: 10px;
border-radius: var(--radius-full);
&.services {
background: var(--color-teal);
}
&.products {
background: var(--color-blue);
}
}
swp-chart-container {
width: 100%;
height: 180px;
background: var(--color-background-alt);
border-radius: var(--radius-md);
}
/* Notes Section */
swp-notes-section {
display: flex;
flex-direction: column;
gap: var(--spacing-4);
margin-top: var(--spacing-6);
padding-top: var(--spacing-6);
border-top: 1px solid var(--color-border);
}
swp-note-item {
display: flex;
flex-direction: column;
gap: var(--spacing-2);
padding: var(--spacing-4);
background: var(--color-background-alt);
border-radius: var(--radius-md);
border: 1px solid var(--color-border);
}
swp-note-meta {
display: flex;
align-items: center;
gap: var(--spacing-3);
}
swp-note-type {
font-size: var(--font-size-xs);
font-weight: var(--font-weight-semibold);
color: var(--color-teal);
text-transform: uppercase;
letter-spacing: 0.5px;
}
swp-note-date {
font-size: var(--font-size-xs);
color: var(--color-text-tertiary);
}
swp-note-text {
font-size: var(--font-size-sm);
color: var(--color-text);
line-height: 1.5;
}
swp-see-all-link {
font-size: var(--font-size-sm);
color: var(--color-teal);
cursor: pointer;
text-align: center;
padding-top: var(--spacing-2);
&:hover {
text-decoration: underline;
}
}
/* Edit input variant for drawer */
swp-edit-input {
display: flex;
gap: var(--spacing-2);
input {
flex: 1;
padding: var(--spacing-3) var(--spacing-4);
font-size: var(--font-size-base);
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
background: var(--color-surface);
color: var(--color-text);
&:focus {
outline: none;
border-color: var(--color-teal);
}
&.short {
width: 80px;
flex: none;
}
}
}

View file

@ -33,6 +33,7 @@
[data-drawer="md"] { --drawer-width: 360px; }
[data-drawer="lg"] { --drawer-width: 420px; }
[data-drawer="xl"] { --drawer-width: 480px; }
[data-drawer="xxl"] { --drawer-width: 680px; }
/* Legacy support for existing drawers */
swp-profile-drawer,

View file

@ -286,7 +286,7 @@ swp-employee-status {
&[data-active="false"] {
background: var(--bg-red-medium);
color: var(--color-red);
border: 1px solid var(--bg-red-border);
border: 1px solid var(--border-red);
}
.icon {

View file

@ -226,6 +226,10 @@ swp-quick-stats {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--card-gap);
&.cols-3 {
grid-template-columns: repeat(3, 1fr);
}
}
swp-quick-stat {
@ -235,6 +239,7 @@ swp-quick-stat {
padding: var(--card-padding);
background: var(--color-background-alt);
border-radius: var(--radius-md);
border: 1px solid var(--color-border);
}
swp-quick-stat swp-stat-value {
@ -249,6 +254,11 @@ swp-quick-stat swp-stat-label {
color: var(--color-text-secondary);
}
swp-quick-stat.highlight {
background: var(--bg-teal-subtle);
border: 1px solid var(--bg-teal-border);
}
/* ===========================================
RESPONSIVE
=========================================== */