SkateSpots/src/lib/spotStatus.ts
SkateSpots e357833557 i18n(es): batch 3 part 3 — shared label maps + leftover routing/Sasquatch strings
- labelsUi.* (221+ keys): spot categories/features/types, access, shelter, event
  types, gear categories/conditions, price/listings, tours, crews,
  member-visibility, tag categories, spot status. New src/lib/labelKeys.ts holds
  the shared value->key maps (one source; the five duplicated EVENT_TYPE_KEYS
  copies now import it). spotStatus.statusTimeAgo() uses the locale date shim.
- formatPrice() now takes an optional t so FREE/Trade/Make Offer translate.
- Route helpers: skateTime/distanceReadout/maneuver descriptors/formatAge
  translated (routeUi.*), consumers updated.
- Sasquatch: PRO_TIERS labels/badges + summarizeDraft titles/lines/ctas
  translated (sasquatchUi.*).
- Lab *_LABELS/_DESCRIPTIONS maps remain English (documented out of scope).
2026-10-02 15:31:27 +07:00

91 lines
2.9 KiB
TypeScript

import type { SpotStatusValue } from '@/lib/types';
import { formatDistanceToNow } from '@/lib/dateFnsI18n';
import { STATUS_KEYS, STATUS_DESC_KEYS } from '@/lib/labelKeys';
export interface SpotStatusMeta {
value: SpotStatusValue;
/** Short human label (English fallback — translate via `labelKey`). */
label: string;
/** `labelsUi.status.*` translation key for `label`. */
labelKey: string;
/** Emoji used in compact contexts. */
emoji: string;
/** One-line description for pickers (English fallback — translate via `descriptionKey`). */
description: string;
/** `labelsUi.status.*` translation key for `description`. */
descriptionKey: string;
/** Tailwind classes for badge text + background + border. */
badgeClass: string;
/** Hex dot color for map/legend use. */
dot: string;
}
export const SPOT_STATUS_META: Record<SpotStatusValue, SpotStatusMeta> = {
active: {
value: 'active',
label: 'Active',
labelKey: STATUS_KEYS.active,
emoji: '🟢',
description: 'Good to go — skate it.',
descriptionKey: STATUS_DESC_KEYS.active,
badgeClass: 'text-green-400 bg-green-500/10 border-green-500/30',
dot: '#22c55e',
},
bust: {
value: 'bust',
label: 'Bust',
labelKey: STATUS_KEYS.bust,
emoji: '🟡',
description: 'Heavy kick-out risk — security or cops.',
descriptionKey: STATUS_DESC_KEYS.bust,
badgeClass: 'text-yellow-400 bg-yellow-500/10 border-yellow-500/30',
dot: '#eab308',
},
skate_stopped: {
value: 'skate_stopped',
label: 'Skate-stopped',
labelKey: STATUS_KEYS.skate_stopped,
emoji: '🟠',
description: 'Knobbed / capped, but partially skateable.',
descriptionKey: STATUS_DESC_KEYS.skate_stopped,
badgeClass: 'text-orange-400 bg-orange-500/10 border-orange-500/30',
dot: '#f97316',
},
closed: {
value: 'closed',
label: 'Closed',
labelKey: STATUS_KEYS.closed,
emoji: '⚪',
description: 'Temporarily closed — construction or event.',
descriptionKey: STATUS_DESC_KEYS.closed,
badgeClass: 'text-gray-300 bg-gray-500/10 border-gray-500/30',
dot: '#9ca3af',
},
gone: {
value: 'gone',
label: 'Gone',
labelKey: STATUS_KEYS.gone,
emoji: '🔴',
description: 'Demolished, paved over, or fenced off for good.',
descriptionKey: STATUS_DESC_KEYS.gone,
badgeClass: 'text-red-400 bg-red-500/10 border-red-500/40',
dot: '#ef4444',
},
};
/** Ordered list for pickers/legends (best → worst). */
export const SPOT_STATUS_ORDER: SpotStatusValue[] = [
'active',
'bust',
'skate_stopped',
'closed',
'gone',
];
/**
* Human "time ago" for a unix-seconds timestamp, in the active app language
* (via the locale-aware `dateFnsI18n` shim — "3 days ago" / "hace 3 días").
*/
export function statusTimeAgo(unixSeconds: number): string {
return formatDistanceToNow(new Date(unixSeconds * 1000), { addSuffix: true });
}