Translate pages

This commit is contained in:
Andras Schmelczer 2026-04-04 09:47:18 +01:00
parent a7aaf5effa
commit 96402228e3
49 changed files with 1458 additions and 926 deletions

View file

@ -13,7 +13,7 @@ export const MAP_MIN_ZOOM = 5.5;
export const BUFFER_MULTIPLIER = 1.5;
/** Inner London free zone bounds (south, west, north, east) — must match server FREE_ZONE_BOUNDS */
/** Demo free zone bounds (south, west, north, east) — must match server FREE_ZONE_BOUNDS */
export const FREE_ZONE_BOUNDS = { south: 51.44, west: -0.31, north: 51.59, east: 0.05 };
export const INITIAL_VIEW_STATE: ViewState = {

View file

@ -44,8 +44,12 @@ export function parseInputValue(
}
export function formatDuration(d: string): string {
if (d === 'F') return 'Freehold';
if (d === 'L') return 'Leasehold';
if (d === 'F' || d === 'L') {
// These are server enum values — translate via ts()
const { ts } = require('../i18n/server') as { ts: (v: string) => string };
if (d === 'F') return ts('Freehold');
return ts('Leasehold');
}
return d;
}
@ -82,17 +86,18 @@ export function formatNumber(value: number | undefined, decimals = 0): string {
}
export function formatRelativeTime(isoDate: string): string {
const i18n = require('../i18n').default as { t: (key: string, opts?: Record<string, unknown>) => string };
const now = Date.now();
const then = new Date(isoDate).getTime();
const diffMs = now - then;
const diffSec = Math.floor(diffMs / 1000);
if (diffSec < 60) return 'just now';
if (diffSec < 60) return i18n.t('format.justNow');
const diffMin = Math.floor(diffSec / 60);
if (diffMin < 60) return `${diffMin}m ago`;
if (diffMin < 60) return i18n.t('format.minutesAgo', { count: diffMin });
const diffHr = Math.floor(diffMin / 60);
if (diffHr < 24) return `${diffHr}h ago`;
if (diffHr < 24) return i18n.t('format.hoursAgo', { count: diffHr });
const diffDay = Math.floor(diffHr / 24);
if (diffDay < 30) return `${diffDay}d ago`;
if (diffDay < 30) return i18n.t('format.daysAgo', { count: diffDay });
return new Date(isoDate).toLocaleDateString();
}

View file

@ -160,6 +160,8 @@ export function stateToParams(
}
export function summarizeParams(queryString: string): string {
const i18n = require('../i18n').default as { t: (key: string, opts?: Record<string, unknown>) => string };
const { ts } = require('../i18n/server') as { ts: (v: string) => string };
const params = new URLSearchParams(queryString);
const parts: string[] = [];
@ -173,7 +175,9 @@ export function summarizeParams(queryString: string): string {
.filter((n) => n && n !== 'Listing status');
if (filterNames.length > 0) {
parts.push(
filterNames.length <= 2 ? filterNames.join(', ') : `${filterNames.length} filters`
filterNames.length <= 2
? filterNames.map((n) => ts(n)).join(', ')
: i18n.t('format.nFilters', { count: filterNames.length })
);
}
}
@ -182,7 +186,11 @@ export function summarizeParams(queryString: string): string {
if (poiParams.length > 0) {
const count = poiParams.filter(Boolean).length;
if (count > 0) {
parts.push(`${count} POI ${count === 1 ? 'category' : 'categories'}`);
parts.push(
count === 1
? i18n.t('format.poiCategory', { count })
: i18n.t('format.poiCategories', { count })
);
}
}
@ -190,9 +198,13 @@ export function summarizeParams(queryString: string): string {
if (ttParams.length > 0) {
const count = ttParams.filter(Boolean).length;
if (count > 0) {
parts.push(`${count} travel time ${count === 1 ? 'destination' : 'destinations'}`);
parts.push(
count === 1
? i18n.t('format.travelDestination', { count })
: i18n.t('format.travelDestinations', { count })
);
}
}
return parts.length > 0 ? parts.join(' + ') : 'No filters';
return parts.length > 0 ? parts.join(' + ') : i18n.t('format.noFilters');
}