feat(back-end): shop ui implementation
All checks were successful
PR Checks / prettier-autofix (pull_request) Successful in 19s
PR Checks / security-sast (pull_request) Successful in 34s
PR Checks / test-backend (pull_request) Successful in 29s
PR Checks / test-frontend (pull_request) Successful in 59s

This commit is contained in:
2026-03-10 08:31:29 +01:00
parent cd0c13203f
commit a212a1d8cc
32 changed files with 4233 additions and 396 deletions

View File

@@ -67,12 +67,26 @@
</option>
</select>
</label>
<label class="toolbar-field" for="order-type-filter">
<span>Tipo ordine</span>
<select
class="ui-form-control"
id="order-type-filter"
[ngModel]="orderTypeFilter"
(ngModelChange)="onOrderTypeFilterChange($event)"
>
<option *ngFor="let option of orderTypeFilterOptions" [ngValue]="option">
{{ option }}
</option>
</select>
</label>
</div>
<div class="table-wrap ui-table-wrap">
<table class="ui-data-table">
<thead>
<tr>
<th>Ordine</th>
<th>Tipo</th>
<th>Email</th>
<th>Pagamento</th>
<th>Stato ordine</th>
@@ -86,6 +100,15 @@
(click)="openDetails(order.id)"
>
<td>{{ order.orderNumber }}</td>
<td>
<span
class="order-type-badge"
[class.order-type-badge--shop]="orderKind(order) === 'SHOP'"
[class.order-type-badge--mixed]="orderKind(order) === 'MIXED'"
>
{{ orderKindLabel(order) }}
</span>
</td>
<td>{{ order.customerEmail }}</td>
<td>{{ order.paymentStatus || "PENDING" }}</td>
<td>{{ order.status }}</td>
@@ -94,7 +117,7 @@
</td>
</tr>
<tr class="no-results" *ngIf="filteredOrders.length === 0">
<td colspan="5">
<td colspan="6">
Nessun ordine trovato per i filtri selezionati.
</td>
</tr>
@@ -105,7 +128,16 @@
<section class="detail-panel ui-detail-panel" *ngIf="selectedOrder">
<div class="detail-header">
<h2>Dettaglio ordine {{ selectedOrder.orderNumber }}</h2>
<div class="detail-title-row">
<h2>Dettaglio ordine {{ selectedOrder.orderNumber }}</h2>
<span
class="order-type-badge"
[class.order-type-badge--shop]="orderKind(selectedOrder) === 'SHOP'"
[class.order-type-badge--mixed]="orderKind(selectedOrder) === 'MIXED'"
>
{{ orderKindLabel(selectedOrder) }}
</span>
</div>
<p class="order-uuid">
UUID:
<code
@@ -129,6 +161,9 @@
<div class="ui-meta-item">
<strong>Stato ordine</strong><span>{{ selectedOrder.status }}</span>
</div>
<div class="ui-meta-item">
<strong>Tipo ordine</strong><span>{{ orderKindLabel(selectedOrder) }}</span>
</div>
<div class="ui-meta-item">
<strong>Totale</strong
><span>{{
@@ -207,6 +242,7 @@
type="button"
class="ui-button ui-button--ghost"
(click)="openPrintDetails()"
[disabled]="!hasPrintItems(selectedOrder)"
>
Dettagli stampa
</button>
@@ -215,38 +251,60 @@
<div class="items">
<div class="item" *ngFor="let item of selectedOrder.items">
<div class="item-main">
<p class="file-name">
<strong>{{ item.originalFilename }}</strong>
</p>
<p class="item-meta">
Qta: {{ item.quantity }} | Materiale:
{{ getItemMaterialLabel(item) }} | Colore:
<div class="item-heading">
<p class="file-name">
<strong>{{ itemDisplayName(item) }}</strong>
</p>
<span
class="color-swatch"
*ngIf="getItemColorHex(item) as colorHex"
[style.background-color]="colorHex"
></span>
<span>
{{ getItemColorLabel(item) }}
<ng-container *ngIf="getItemColorCodeSuffix(item) as colorCode">
({{ colorCode }})
</ng-container>
class="item-kind-badge"
[class.item-kind-badge--shop]="isShopItem(item)"
>
{{ isShopItem(item) ? "Shop" : "Calcolatore" }}
</span>
| Nozzle: {{ item.nozzleDiameterMm ?? "-" }} mm | Layer:
</div>
<p class="item-meta">
<span>Qta: {{ item.quantity }}</span>
<span *ngIf="showItemMaterial(item)">
Materiale: {{ getItemMaterialLabel(item) }}
</span>
<span *ngIf="itemVariantLabel(item) as variantLabel">
Variante: {{ variantLabel }}
</span>
<span class="item-meta__color">
Colore:
<span
class="color-swatch"
*ngIf="getItemColorHex(item) as colorHex"
[style.background-color]="colorHex"
></span>
<span>
{{ getItemColorLabel(item) }}
<ng-container *ngIf="getItemColorCodeSuffix(item) as colorCode">
({{ colorCode }})
</ng-container>
</span>
</span>
</p>
<p class="item-tech" *ngIf="showItemPrintDetails(item)">
Nozzle: {{ item.nozzleDiameterMm ?? "-" }} mm | Layer:
{{ item.layerHeightMm ?? "-" }} mm | Infill:
{{ item.infillPercent ?? "-" }}% | Supporti:
{{ formatSupports(item.supportsEnabled) }}
| Riga:
</p>
<p class="item-total">
Riga:
{{ item.lineTotalChf | currency: "CHF" : "symbol" : "1.2-2" }}
</p>
</div>
<button
type="button"
class="ui-button ui-button--ghost"
(click)="downloadItemFile(item.id, item.originalFilename)"
>
Scarica file
</button>
<div class="item-actions">
<button
type="button"
class="ui-button ui-button--ghost"
(click)="downloadItemFile(item.id, item.originalFilename || itemDisplayName(item))"
>
{{ downloadItemLabel(item) }}
</button>
</div>
</div>
</div>
</section>
@@ -315,7 +373,7 @@
<h4>Parametri per file</h4>
<div class="file-color-list">
<div class="file-color-row" *ngFor="let item of selectedOrder.items">
<div class="file-color-row" *ngFor="let item of printItems(selectedOrder)">
<span class="filename">{{ item.originalFilename }}</span>
<span class="file-color">
{{ getItemMaterialLabel(item) }} | Colore: