78 lines
2.2 KiB
TypeScript
78 lines
2.2 KiB
TypeScript
export * from './tokens';
|
|
|
|
import { colors } from './tokens';
|
|
|
|
// Backend categories are free-form pages, so unknown slugs are hashed into a
|
|
// stable colour instead of all sharing one accent.
|
|
export const CATEGORY_PALETTE = [
|
|
'#2c8c9e', // teal
|
|
'#5b6cc4', // indigo
|
|
'#c5862a', // amber
|
|
'#4a7a4d', // moss
|
|
'#8a5cb8', // violet
|
|
'#c45d8a', // rose
|
|
'#b56a3b', // clay
|
|
] as const;
|
|
|
|
/** Known categories keep their original colours; the rest are hashed. */
|
|
const NAMED_CATEGORY_COLORS: Record<string, string> = {
|
|
ownership: '#2c8c9e',
|
|
rental: '#5b6cc4',
|
|
sale: '#c5862a',
|
|
technical: '#4a7a4d',
|
|
certifications: '#8a5cb8',
|
|
certs: '#8a5cb8',
|
|
warranties: '#c45d8a',
|
|
warranty: '#c45d8a',
|
|
maintenance: '#b56a3b',
|
|
};
|
|
|
|
export function categoryColor(cat?: string | null): string {
|
|
if (!cat) return colors.slate500;
|
|
const key = cat.toLowerCase();
|
|
const named = NAMED_CATEGORY_COLORS[key];
|
|
if (named) return named;
|
|
// Stable, so a category keeps its colour across screens.
|
|
let hash = 0;
|
|
for (let i = 0; i < key.length; i += 1) {
|
|
hash = (hash * 31 + key.charCodeAt(i)) >>> 0;
|
|
}
|
|
return CATEGORY_PALETTE[hash % CATEGORY_PALETTE.length];
|
|
}
|
|
|
|
/** Tinted background for a coloured icon chip. */
|
|
export function tint(hex: string, alpha = '1f'): string {
|
|
return `${hex}${alpha}`;
|
|
}
|
|
|
|
/** Two stops, dark bottom-right, so white type stays readable on top. */
|
|
export const COVER_GRADIENTS: Record<string, readonly [string, string]> = {
|
|
villa: ['#2c6e7c', '#16263d'],
|
|
house: ['#2c6e7c', '#16263d'],
|
|
apartment: ['#3a4f7a', '#1b2540'],
|
|
building: ['#3a4f7a', '#1b2540'],
|
|
commercial: ['#5b6cc4', '#1d2547'],
|
|
land: ['#4a7a4d', '#1c3120'],
|
|
};
|
|
|
|
export function coverGradient(type?: string | null): readonly [string, string] {
|
|
return COVER_GRADIENTS[type ?? ''] ?? [colors.ink700, colors.ink900];
|
|
}
|
|
|
|
/** Expiry status → badge style. */
|
|
export type ExpiryTone = 'valid' | 'expiring' | 'expired' | 'none';
|
|
|
|
export function expiryTone(status?: string | null): ExpiryTone {
|
|
switch ((status ?? '').toLowerCase()) {
|
|
case 'valid':
|
|
return 'valid';
|
|
case 'expiring':
|
|
case 'expiring_soon':
|
|
return 'expiring';
|
|
case 'expired':
|
|
return 'expired';
|
|
default:
|
|
return 'none';
|
|
}
|
|
}
|