Files
casadoc-app/src/theme/index.ts
T
2026-08-26 23:01:07 +03:00

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';
}
}