Files
nika-gallery/frontend/lib/format.ts
T
germanandClaude Opus 4.8 ad35d4e992
Deploy / deploy (push) Failing after 5s
feat(#3): frontend scaffold (Next.js 14 App Router, TS, Tailwind, галерея)
Каркас витрины дизайнера Ники: главная (hero + сетка галереи),
страница работы (детали + место под аукцион), список аукционов,
подписка-заглушка. Клиент к backend /api с graceful-фолбэком на
демо-работы при недоступном API. Standalone-сборка + Dockerfile.
Сборка npm run build и tsc --noEmit проходят.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 19:42:13 +03:00

44 lines
1.8 KiB
TypeScript

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} мин`;
}