change UI & fix bugs
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
export type ProductColorEntry = {
|
||||
name: string;
|
||||
imageUrl?: string;
|
||||
};
|
||||
|
||||
export function parseColorEntries(
|
||||
colorsJson: unknown,
|
||||
fallbackColor?: string,
|
||||
): ProductColorEntry[] {
|
||||
if (!Array.isArray(colorsJson) || colorsJson.length === 0) {
|
||||
const name = fallbackColor?.trim();
|
||||
return name ? [{ name }] : [];
|
||||
}
|
||||
|
||||
return colorsJson
|
||||
.map((item): ProductColorEntry | null => {
|
||||
if (typeof item === 'string') {
|
||||
const name = item.trim();
|
||||
return name ? { name } : null;
|
||||
}
|
||||
if (item && typeof item === 'object') {
|
||||
const raw = item as { name?: unknown; imageUrl?: unknown };
|
||||
const name = String(raw.name ?? '').trim();
|
||||
if (!name) return null;
|
||||
const imageUrl =
|
||||
typeof raw.imageUrl === 'string' && raw.imageUrl.trim()
|
||||
? raw.imageUrl
|
||||
: undefined;
|
||||
return { name, imageUrl };
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter((entry): entry is ProductColorEntry => Boolean(entry));
|
||||
}
|
||||
|
||||
export function mergeProductImages(
|
||||
entries: ProductColorEntry[],
|
||||
imageUrlsJson: unknown,
|
||||
): string[] {
|
||||
const extras = Array.isArray(imageUrlsJson)
|
||||
? imageUrlsJson.filter((url): url is string => typeof url === 'string' && url.trim().length > 0)
|
||||
: [];
|
||||
const fromColors = entries
|
||||
.map((entry) => entry.imageUrl)
|
||||
.filter((url): url is string => Boolean(url));
|
||||
const seen = new Set(fromColors);
|
||||
return [...fromColors, ...extras.filter((url) => !seen.has(url))];
|
||||
}
|
||||
@@ -128,7 +128,7 @@ export class CreateProductDto {
|
||||
isNew?: boolean;
|
||||
|
||||
@IsOptional()
|
||||
colorsJson?: string[];
|
||||
colorsJson?: Array<string | { name: string; imageUrl?: string }>;
|
||||
|
||||
@IsOptional()
|
||||
imageUrlsJson?: string[];
|
||||
@@ -253,7 +253,7 @@ export class UpdateProductDto {
|
||||
isNew?: boolean;
|
||||
|
||||
@IsOptional()
|
||||
colorsJson?: string[];
|
||||
colorsJson?: Array<string | { name: string; imageUrl?: string }>;
|
||||
|
||||
@IsOptional()
|
||||
imageUrlsJson?: string[];
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Prisma } from '@prisma/client';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { CreateProductDto, UpdateProductDto } from './dto/product.dto';
|
||||
import { loadCatalogCategories } from '../catalog/category-defs';
|
||||
import { mergeProductImages, parseColorEntries } from './color-entries';
|
||||
|
||||
@Injectable()
|
||||
export class ProductsService {
|
||||
@@ -107,8 +108,8 @@ export class ProductsService {
|
||||
subtitle: dto.subtitle?.trim() || null,
|
||||
rollMeters: dto.rollMeters,
|
||||
isNew: dto.isNew,
|
||||
colorsJson: dto.colorsJson ?? undefined,
|
||||
imageUrlsJson: dto.imageUrlsJson ?? undefined,
|
||||
colorsJson: (dto.colorsJson ?? undefined) as Prisma.InputJsonValue | undefined,
|
||||
imageUrlsJson: (dto.imageUrlsJson ?? undefined) as Prisma.InputJsonValue | undefined,
|
||||
tagsJson: dto.tagsJson ?? undefined,
|
||||
},
|
||||
include: {
|
||||
@@ -188,8 +189,14 @@ export class ProductsService {
|
||||
: dto.subtitle?.trim() || null,
|
||||
rollMeters: dto.rollMeters,
|
||||
isNew: dto.isNew,
|
||||
colorsJson: dto.colorsJson,
|
||||
imageUrlsJson: dto.imageUrlsJson,
|
||||
colorsJson:
|
||||
dto.colorsJson === undefined
|
||||
? undefined
|
||||
: (dto.colorsJson as Prisma.InputJsonValue),
|
||||
imageUrlsJson:
|
||||
dto.imageUrlsJson === undefined
|
||||
? undefined
|
||||
: (dto.imageUrlsJson as Prisma.InputJsonValue),
|
||||
tagsJson: dto.tagsJson,
|
||||
},
|
||||
include: {
|
||||
@@ -303,11 +310,10 @@ export class ProductsService {
|
||||
},
|
||||
hidePrice = false,
|
||||
) {
|
||||
const colors = Array.isArray(product.colorsJson)
|
||||
? (product.colorsJson as string[])
|
||||
: product.color
|
||||
? [product.color]
|
||||
: [];
|
||||
const colorEntries = parseColorEntries(product.colorsJson, product.color);
|
||||
const colors = colorEntries.map((entry) => entry.name);
|
||||
const colorImages = colorEntries.map((entry) => entry.imageUrl ?? null);
|
||||
const imageUrls = mergeProductImages(colorEntries, product.imageUrlsJson);
|
||||
const tags = Array.isArray(product.tagsJson)
|
||||
? (product.tagsJson as string[])
|
||||
: [];
|
||||
@@ -340,10 +346,9 @@ export class ProductsService {
|
||||
weightGrams: product.weightGrams ?? undefined,
|
||||
weaveType: product.weaveType ?? undefined,
|
||||
colors,
|
||||
colorImages,
|
||||
tags,
|
||||
imageUrls: Array.isArray(product.imageUrlsJson)
|
||||
? product.imageUrlsJson
|
||||
: [],
|
||||
imageUrls,
|
||||
subtitle: product.subtitle ?? undefined,
|
||||
rollMeters: product.rollMeters ?? 50,
|
||||
isNew: product.isNew ?? false,
|
||||
|
||||
Reference in New Issue
Block a user