import type { Work } from './types'; // Форматирование цены в рублях. NUMERIC из pg приходит строкой. export function formatPrice(value: string | number | null | undefined): string { if (value === null || value === undefined || value === '') return 'Цена по запросу'; const n = typeof value === 'string' ? Number(value) : value; if (Number.isNaN(n)) return 'Цена по запросу'; return new Intl.NumberFormat('ru-RU', { style: 'currency', currency: 'RUB', maximumFractionDigits: 0, }).format(n); } // Детерминированный плейсхолдер из picsum по seed (id/slug работы), // пока не пришли реальные изображения. Стабилен между сборками. export function placeholderImage(seed: string, w = 800, h = 1000): string { const s = encodeURIComponent(seed || 'nika'); return `https://picsum.photos/seed/${s}/${w}/${h}`; } // Выбираем обложку работы: cover_url из view → первое media → плейсхолдер. export function coverOf(work: Work, w?: number, h?: number): string { return ( work.cover_url || work.cover_thumb || work.media?.[0]?.url || placeholderImage(work.slug || work.id, w, h) ); } // Оставшееся время аукциона в человекочитаемом виде. export function timeLeft(endAt: string): string { const ms = new Date(endAt).getTime() - Date.now(); if (Number.isNaN(ms)) return ''; if (ms <= 0) return 'Завершён'; const d = Math.floor(ms / 86_400_000); const h = Math.floor((ms % 86_400_000) / 3_600_000); const m = Math.floor((ms % 3_600_000) / 60_000); if (d > 0) return `${d} д ${h} ч`; if (h > 0) return `${h} ч ${m} мин`; return `${m} мин`; }