CUB-43: Add inventory dashboard summary component
All checks were successful
Dev Build / build-test (pull_request) Successful in 2m23s

This commit is contained in:
2026-04-27 21:10:16 -04:00
parent 5a2a0a9ce1
commit b7130ad1b9
6 changed files with 485 additions and 268 deletions

View File

@@ -1,93 +1,257 @@
/**
* Inventory Summary Component Styles
* Touch-optimized for kiosk (Raspberry Pi 5) and mobile PWA
* Consistent with dashboard-summary component styling
* Matches the existing dark theme from app.scss
*/
// Touch-optimized sizing
$touch-target-min: 48px;
$kiosk-font-primary: 20px;
$mobile-font-primary: 16px;
$kiosk-font-primary: 24px;
$mobile-font-primary: 18px;
$spacing-unit: 8px;
// Status colors — high contrast for workshop/bright environments
$color-healthy: #4ade70; // Green — stock OK
$color-low: #facc15; // Amber — low stock
$color-critical: #f87171; // Red — critical stock
$color-healthy: #4ade70; // Green
$color-low: #fbbf24; // Amber/Yellow
$color-critical: #f87171; // Red
$color-bg: #1a1a2e; // Matches app.scss
$color-text: #e0e0e0;
$color-text-muted: rgba(255, 255, 255, 0.7);
$color-card-bg: rgba(255, 255, 255, 0.05);
$color-card-border: rgba(255, 255, 255, 0.1);
.inventory-summary {
display: flex;
align-items: center;
align-items: stretch;
gap: $spacing-unit * 2;
padding: $spacing-unit * 2;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
scrollbar-width: thin;
@media (max-width: 480px) {
@media (max-width: 600px) {
flex-wrap: wrap;
padding: $spacing-unit;
gap: $spacing-unit;
}
}
.summary-item {
// Health status indicator
.health-status {
display: flex;
align-items: center;
gap: $spacing-unit;
min-height: $touch-target-min;
padding: $spacing-unit $spacing-unit * 2;
border-radius: 12px;
background-color: rgba(255, 255, 255, 0.05);
border-radius: 24px;
min-height: $touch-target-min;
white-space: nowrap;
transition: background-color 0.3s ease;
@media (max-width: 480px) {
padding: $spacing-unit;
border-radius: 8px;
&.healthy {
background-color: rgba($color-healthy, 0.15);
color: $color-healthy;
}
mat-icon {
font-size: 22px !important;
width: 22px !important;
height: 22px !important;
&.low {
background-color: rgba($color-low, 0.15);
color: $color-low;
}
.metric-value {
font-size: $kiosk-font-primary;
&.critical {
background-color: rgba($color-critical, 0.15);
color: $color-critical;
}
.health-text {
font-size: 14px;
font-weight: 600;
line-height: 1.2;
letter-spacing: 0.02em;
@media (max-width: 480px) {
font-size: $mobile-font-primary;
font-size: 12px;
}
}
.metric-label {
font-size: 12px;
color: rgba(255, 255, 255, 0.7);
text-transform: uppercase;
letter-spacing: 0.05em;
mat-icon {
font-size: 20px !important;
width: 20px !important;
height: 20px !important;
}
}
@media (max-width: 480px) {
font-size: 10px;
// Metric card
.metric-card {
display: flex;
align-items: center;
gap: $spacing-unit;
padding: $spacing-unit $spacing-unit * 2;
background-color: $color-card-bg;
border: 1px solid $color-card-border;
border-radius: 12px;
min-height: $touch-target-min;
white-space: nowrap;
transition: border-color 0.2s ease, background-color 0.2s ease;
&:hover {
border-color: rgba(255, 255, 255, 0.2);
background-color: rgba(255, 255, 255, 0.08);
}
@media (max-width: 480px) {
padding: $spacing-unit;
}
&.has-alert {
border-color: rgba($color-low, 0.4);
}
&.has-critical {
border-color: rgba($color-critical, 0.5);
background-color: rgba($color-critical, 0.08);
}
}
.metric-icon {
color: $color-text-muted;
font-size: 22px !important;
width: 22px !important;
height: 22px !important;
.has-alert & {
color: $color-low;
}
.has-critical & {
color: $color-critical;
}
}
.metric-content {
display: flex;
flex-direction: column;
gap: 2px;
}
.metric-value {
font-size: $kiosk-font-primary;
font-weight: 700;
line-height: 1.2;
color: $color-text;
@media (max-width: 480px) {
font-size: $mobile-font-primary;
}
}
.metric-label {
font-size: 11px;
color: $color-text-muted;
text-transform: uppercase;
letter-spacing: 0.08em;
}
.metric-detail {
font-size: 11px;
color: $color-text-muted;
margin-left: $spacing-unit;
&.critical-detail {
color: $color-critical;
font-weight: 600;
}
}
// Stock bar card
.stock-bar-card {
flex: 1 1 200px;
min-width: 180px;
}
.stock-bar-content {
flex: 1;
min-width: 0;
}
.stock-bar-header {
display: flex;
align-items: baseline;
gap: $spacing-unit;
margin-bottom: 4px;
}
// Progress bar color classes
::ng-deep .mat-mdc-progress-bar {
&.healthy .mdc-linear-progress__bar-inner {
background-color: $color-healthy !important;
}
&.low .mdc-linear-progress__bar-inner {
background-color: $color-low !important;
}
&.critical .mdc-linear-progress__bar-inner {
background-color: $color-critical !important;
}
}
// Loading state
.summary-loading {
display: flex;
align-items: center;
gap: $spacing-unit;
padding: $spacing-unit * 2;
color: $color-text-muted;
font-size: 14px;
.spin {
animation: spin 1s linear infinite;
}
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
// Error state
.summary-error {
display: flex;
align-items: center;
gap: $spacing-unit;
padding: $spacing-unit * 2;
background-color: rgba($color-critical, 0.1);
border: 1px solid rgba($color-critical, 0.3);
border-radius: 12px;
color: $color-critical;
font-size: 14px;
.retry-btn {
display: flex;
align-items: center;
gap: 4px;
background: transparent;
border: 1px solid rgba($color-critical, 0.4);
color: $color-critical;
padding: 4px 12px;
border-radius: 8px;
cursor: pointer;
font-size: 13px;
min-height: $touch-target-min - 8px;
transition: background-color 0.2s ease;
&:hover {
background-color: rgba($color-critical, 0.15);
}
mat-icon {
font-size: 16px !important;
width: 16px !important;
height: 16px !important;
}
}
}
// Low stock states
.low-stock {
&.has-alerts {
background-color: rgba($color-low, 0.15);
mat-icon {
color: $color-low;
}
}
&.has-critical {
background-color: rgba($color-critical, 0.15);
mat-icon {
color: $color-critical;
}
}
// Summary item base
.summary-item {
flex-shrink: 0;
}