Files
dashfront/src/components/brand/BrandThumb.jsx
2026-10-05 01:01:03 +02:00

117 lines
3.4 KiB
JavaScript

import Box from '@mui/material/Box';
import ThumbHashImage, { getThumbHashDimensions } from '../article/ThumbHashImage';
import brandAutomat from '../../automats/brandAutomat';
import {
SHADOW_THUMB_RING,
TINT_ROW_HOVER,
} from '../../colors';
/**
* Extracts thumbHash from various brand representations:
* - Direct thumbHash / thumbhash property
* - Brand with pics array (e.g. brand.pics[0].thumbHash)
* - Brand by name or id looked up in brandAutomat.state.brands
*/
export function extractBrandThumbInfo(brand, thumbHashOverride) {
if (thumbHashOverride) {
const dims = getThumbHashDimensions(thumbHashOverride);
return {
thumbHash: thumbHashOverride,
thumbW: dims?.w ?? null,
thumbH: dims?.h ?? null,
};
}
if (!brand) return null;
// Direct thumbHash on brand object
let hash = brand.thumbHash ?? brand.thumbhash;
let thumbW = brand.thumbW ?? brand.thumbw;
let thumbH = brand.thumbH ?? brand.thumbh;
// Check pics array
if (!hash && Array.isArray(brand.pics) && brand.pics.length > 0) {
const firstPic = brand.pics[0];
hash = firstPic?.thumbHash ?? firstPic?.thumbhash;
thumbW = firstPic?.thumbW ?? firstPic?.thumbw;
thumbH = firstPic?.thumbH ?? firstPic?.thumbh;
}
// Fallback: look up in brandAutomat
if (!hash) {
const brands = brandAutomat.state?.brands;
if (Array.isArray(brands)) {
const id = typeof brand === 'object' ? brand.id : (typeof brand === 'number' ? brand : null);
const name = typeof brand === 'object' ? brand.name : (typeof brand === 'string' ? brand : null);
const found = brands.find(
(b) =>
(id != null && b.id === id) ||
(name && String(b.name || '').trim().toLowerCase() === String(name).trim().toLowerCase())
);
if (found) {
hash = found.thumbHash ?? found.thumbhash ?? found.pics?.[0]?.thumbHash ?? found.pics?.[0]?.thumbhash;
thumbW = found.thumbW ?? found.thumbw ?? found.pics?.[0]?.thumbW ?? found.pics?.[0]?.thumbw;
thumbH = found.thumbH ?? found.thumbh ?? found.pics?.[0]?.thumbH ?? found.pics?.[0]?.thumbh;
}
}
}
if (!hash) return null;
if (thumbW == null || thumbH == null) {
const dims = getThumbHashDimensions(hash);
if (dims) {
thumbW = dims.w;
thumbH = dims.h;
}
}
return { thumbHash: hash, thumbW, thumbH };
}
export default function BrandThumb({
brand,
thumbHash: thumbHashProp,
size = 20,
fallback = null,
sx,
}) {
const info = extractBrandThumbInfo(brand, thumbHashProp);
if (!info?.thumbHash) {
return fallback;
}
const { thumbHash, thumbW, thumbH } = info;
const ratio = (thumbW && thumbH) ? (thumbW / thumbH) : 1;
const calcWidth = Math.round(size * Math.max(0.6, Math.min(ratio, 2.5)));
return (
<Box
component="span"
sx={{
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
height: size,
width: calcWidth,
minWidth: Math.round(size * 0.6),
maxWidth: Math.round(size * 2.5),
borderRadius: size >= 24 ? '4px' : '3px',
overflow: 'hidden',
flexShrink: 0,
verticalAlign: 'middle',
bgcolor: TINT_ROW_HOVER,
boxShadow: SHADOW_THUMB_RING,
...sx,
}}
>
<ThumbHashImage
thumbHash={thumbHash}
width={calcWidth}
height={size}
/>
</Box>
);
}