diff --git a/src/app/pages/item-detail/item-detail.component.html b/src/app/pages/item-detail/item-detail.component.html
index 0329b3c..95e33f9 100644
--- a/src/app/pages/item-detail/item-detail.component.html
+++ b/src/app/pages/item-detail/item-detail.component.html
@@ -102,19 +102,19 @@
}
- @if (availableColours().length || availableSizes().length || item()!.colour || item()!.size) {
+ @if (availableColours().length || availableSizes().length || item()!.colour || (item()!.size && item()!.size!.toLowerCase() !== 'default')) {
@if (availableColours().length) {
{{ 'itemDetail.colour' | translate }}:
@for (c of availableColours(); track c) {
- {{ c }}
+
}
} @else if (item()!.colour) {
{{ 'itemDetail.colour' | translate }}:
- {{ item()!.colour }}
+
}
@if (availableSizes().length) {
@@ -124,7 +124,7 @@
{{ s }}
}
- } @else if (item()!.size) {
+ } @else if (item()!.size && item()!.size!.toLowerCase() !== 'default') {
{{ 'itemDetail.size' | translate }}:
{{ item()!.size }}
@@ -381,19 +381,19 @@
}
- @if (availableColours().length || availableSizes().length || item()!.colour || item()!.size) {
+ @if (availableColours().length || availableSizes().length || item()!.colour || (item()!.size && item()!.size!.toLowerCase() !== 'default')) {
@if (availableColours().length) {
{{ 'itemDetail.colour' | translate }}:
@for (c of availableColours(); track c) {
- {{ c }}
+
}
} @else if (item()!.colour) {
{{ 'itemDetail.colour' | translate }}:
- {{ item()!.colour }}
+
}
@if (availableSizes().length) {
@@ -403,7 +403,7 @@
{{ s }}
}
- } @else if (item()!.size) {
+ } @else if (item()!.size && item()!.size!.toLowerCase() !== 'default') {
{{ 'itemDetail.size' | translate }}:
{{ item()!.size }}
diff --git a/src/app/pages/item-detail/item-detail.component.scss b/src/app/pages/item-detail/item-detail.component.scss
index b895b12..4dab463 100644
--- a/src/app/pages/item-detail/item-detail.component.scss
+++ b/src/app/pages/item-detail/item-detail.component.scss
@@ -296,7 +296,7 @@ $dx-card-bg: #f5f3f9;
// Variant chips (colour/size) — shared between dexar and novo
.dx-variants, .novo-variants {
display: flex;
- flex-wrap: wrap;
+ flex-direction: column;
gap: 12px;
margin-bottom: 12px;
@@ -304,6 +304,7 @@ $dx-card-bg: #f5f3f9;
display: flex;
align-items: center;
gap: 8px;
+ flex-wrap: wrap;
}
.variant-label {
@@ -335,6 +336,25 @@ $dx-card-bg: #f5f3f9;
box-shadow: 0 0 0 2px rgba(73, 118, 113, 0.25);
}
}
+
+ .colour-swatch {
+ width: 32px;
+ height: 32px;
+ border-radius: 50%;
+ border: 2px solid $dx-border;
+ cursor: pointer;
+ transition: border-color 0.15s, box-shadow 0.15s;
+ flex-shrink: 0;
+
+ &:hover {
+ border-color: $dx-primary;
+ }
+
+ &.active {
+ border-color: $dx-primary;
+ box-shadow: 0 0 0 2px rgba(73, 118, 113, 0.25);
+ }
+ }
}
.dx-attributes, .novo-attributes {
diff --git a/src/app/pages/item-detail/item-detail.component.ts b/src/app/pages/item-detail/item-detail.component.ts
index 24b63da..35477da 100644
--- a/src/app/pages/item-detail/item-detail.component.ts
+++ b/src/app/pages/item-detail/item-detail.component.ts
@@ -47,7 +47,7 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
const filtered = colour
? details.filter(d => (d.colour || d.color) === colour)
: details;
- const unique = [...new Set(filtered.map(d => d.size).filter((s): s is string => !!s))];
+ const unique = [...new Set(filtered.map(d => d.size).filter((s): s is string => !!s && s.toLowerCase() !== 'default'))];
return unique;
});
diff --git a/src/app/services/api.service.ts b/src/app/services/api.service.ts
index c30ff0b..ef45d1b 100644
--- a/src/app/services/api.service.ts
+++ b/src/app/services/api.service.ts
@@ -24,6 +24,12 @@ export class ApiService {
return map[apiLang] || apiLang.toLowerCase();
}
+ /** Convert Go-style hex colour (0xfffca0) → CSS hex (#fffca0) */
+ private normalizeColor(c: string): string {
+ if (!c) return '';
+ return c.startsWith('0x') ? '#' + c.slice(2) : c;
+ }
+
/** Resolve relative image URLs (e.g. ./images/x.webp) against site origin */
private resolveImageUrl(url: string): string {
if (!url) return '';
@@ -46,10 +52,14 @@ export class ApiService {
const details = raw.itemDetails || raw.itemdetails;
if (details && Array.isArray(details) && details.length > 0) {
const detail = details[0];
- item.itemDetails = raw.itemDetails;
+ item.itemDetails = details.map((d: any) => ({
+ ...d,
+ colour: this.normalizeColor(d.colour || d.color || ''),
+ color: undefined,
+ }));
if (item.price == null || item.price === 0) item.price = detail.price;
if (!item.currency) item.currency = detail.currency;
- if (!item.colour) item.colour = detail.colour || detail.color || '';
+ if (!item.colour) item.colour = this.normalizeColor(detail.colour || detail.color || '');
if (!item.size) item.size = detail.size || '';
// Use remaining from detail for stock level
if (raw.remaining == null && detail.remaining != null) {
@@ -111,7 +121,7 @@ export class ApiService {
item.attributes = raw.attributes || [];
// Preserve colour & size (only if not already set from itemDetails)
- if (!item.colour) item.colour = raw.colour || '';
+ if (!item.colour) item.colour = this.normalizeColor(raw.colour || '');
if (!item.size) item.size = raw.size || '';
// Map backOffice comments → legacy callbacks