Sprint 28, scoped to admin/* (user decision — full marketplace audit declined in favor of a bounded pass over the 8 admin features from Sprints 20-27). - a11y: aria-label added to every bare <select> not already inside a <label> across categories/products/orders/transactions/users/monitoring - loading states: app-skeleton rows/cards added to list pages that previously rendered blank during the initial fetch (categories, orders, transactions, users, monitoring's event feed, analytics summary cards) - admin-dashboard-card's custom shimmer CSS replaced with the shared SkeletonComponent (same visual result, one less duplicated animation) - bundle-size budget warning (~198kB over) confirmed pre-existing — present at Sprint 20's first build before any admin/* code existed, and new admin pages are all lazy-loaded — documented as out of scope for this pass rather than chased docs/ADMIN.md + docs/SPRINT-PLAN.md updated with the scope decision and what was explicitly not done (Lighthouse, animations, SEO/sitemap, storefront/editor a11y). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
24 lines
1.1 KiB
HTML
24 lines
1.1 KiB
HTML
<article class="dashboard-card" [class.dashboard-card--error]="status === 'error'" [class.dashboard-card--pending]="status === 'pending-backend'">
|
|
<header class="dashboard-card__header">
|
|
<span class="dashboard-card__icon" *ngIf="icon" aria-hidden="true">{{ icon }}</span>
|
|
<h3 class="dashboard-card__title">{{ title }}</h3>
|
|
</header>
|
|
|
|
<div class="dashboard-card__body">
|
|
<ng-container [ngSwitch]="status">
|
|
<app-skeleton *ngSwitchCase="'loading'" shape="rect" height="24px" width="60%" />
|
|
|
|
<p class="dashboard-card__muted" *ngSwitchCase="'empty'">{{ 'dashboard.stateEmpty' | translate }}</p>
|
|
|
|
<p class="dashboard-card__muted dashboard-card__muted--error" *ngSwitchCase="'error'">{{ 'dashboard.stateError' | translate }}</p>
|
|
|
|
<p class="dashboard-card__muted" *ngSwitchCase="'pending-backend'">{{ 'dashboard.statePendingBackend' | translate }}</p>
|
|
|
|
<ng-container *ngSwitchDefault>
|
|
<p class="dashboard-card__value">{{ value }}</p>
|
|
<p class="dashboard-card__subtitle" *ngIf="subtitle">{{ subtitle }}</p>
|
|
</ng-container>
|
|
</ng-container>
|
|
</div>
|
|
</article>
|