vibes
This commit is contained in:
parent
80c093b7ba
commit
f72c43a9fa
101 changed files with 2168 additions and 1177 deletions
|
|
@ -70,7 +70,11 @@ export async function shortenUrl(params: string): Promise<string> {
|
|||
return `${window.location.origin}${data.url}`;
|
||||
}
|
||||
|
||||
export function buildFilterString(filters: FeatureFilters, features: FeatureMeta[], exclude?: string): string {
|
||||
export function buildFilterString(
|
||||
filters: FeatureFilters,
|
||||
features: FeatureMeta[],
|
||||
exclude?: string
|
||||
): string {
|
||||
const entries = Object.entries(filters);
|
||||
if (entries.length === 0) return '';
|
||||
return entries
|
||||
|
|
|
|||
|
|
@ -87,12 +87,7 @@ export const POI_GROUP_COLORS: Record<string, [number, number, number]> = {
|
|||
export const POI_DEFAULT_COLOR: [number, number, number] = [107, 114, 128];
|
||||
|
||||
/** Categories only shown when zoomed in past MINOR_POI_ZOOM_THRESHOLD */
|
||||
export const MINOR_POI_CATEGORIES = new Set([
|
||||
'Bus stop',
|
||||
'Taxi rank',
|
||||
'EV Charging',
|
||||
'Playground',
|
||||
]);
|
||||
export const MINOR_POI_CATEGORIES = new Set(['Bus stop', 'Taxi rank', 'EV Charging', 'Playground']);
|
||||
|
||||
/** Zoom level below which minor POI categories are hidden */
|
||||
export const MINOR_POI_ZOOM_THRESHOLD = 14;
|
||||
|
|
@ -217,16 +212,16 @@ export const STACKED_ENUM_GROUPS: Record<
|
|||
* 10 colors chosen for perceptual distinctness in both light and dark modes.
|
||||
*/
|
||||
export const ENUM_PALETTE: [number, number, number][] = [
|
||||
[59, 130, 246], // blue-500
|
||||
[249, 115, 22], // orange-500
|
||||
[139, 92, 246], // violet-500
|
||||
[34, 197, 94], // green-500
|
||||
[239, 68, 68], // red-500
|
||||
[6, 182, 212], // cyan-500
|
||||
[236, 72, 153], // pink-500
|
||||
[245, 158, 11], // amber-500
|
||||
[20, 184, 166], // teal-500
|
||||
[107, 114, 128], // gray-500
|
||||
[59, 130, 246], // blue-500
|
||||
[249, 115, 22], // orange-500
|
||||
[139, 92, 246], // violet-500
|
||||
[34, 197, 94], // green-500
|
||||
[239, 68, 68], // red-500
|
||||
[6, 182, 212], // cyan-500
|
||||
[236, 72, 153], // pink-500
|
||||
[245, 158, 11], // amber-500
|
||||
[20, 184, 166], // teal-500
|
||||
[107, 114, 128], // gray-500
|
||||
];
|
||||
|
||||
/** Colors for stacked bar segments */
|
||||
|
|
|
|||
|
|
@ -42,11 +42,11 @@ const ZOOPLA_RADII = [0.25, 0.5, 1, 3, 5, 10, 15, 20, 25, 30];
|
|||
|
||||
// Rightmove only accepts these specific price values
|
||||
const RIGHTMOVE_PRICES = [
|
||||
50000, 60000, 70000, 80000, 90000, 100000, 110000, 120000, 125000, 130000, 140000, 150000,
|
||||
160000, 170000, 175000, 180000, 190000, 200000, 210000, 220000, 230000, 240000, 250000, 260000,
|
||||
270000, 280000, 290000, 300000, 325000, 350000, 375000, 400000, 425000, 450000, 475000, 500000,
|
||||
550000, 600000, 650000, 700000, 800000, 900000, 1000000, 1250000, 1500000, 1750000, 2000000,
|
||||
2500000, 3000000, 4000000, 5000000, 7500000, 10000000, 15000000, 20000000,
|
||||
50000, 60000, 70000, 80000, 90000, 100000, 110000, 120000, 125000, 130000, 140000, 150000, 160000,
|
||||
170000, 175000, 180000, 190000, 200000, 210000, 220000, 230000, 240000, 250000, 260000, 270000,
|
||||
280000, 290000, 300000, 325000, 350000, 375000, 400000, 425000, 450000, 475000, 500000, 550000,
|
||||
600000, 650000, 700000, 800000, 900000, 1000000, 1250000, 1500000, 1750000, 2000000, 2500000,
|
||||
3000000, 4000000, 5000000, 7500000, 10000000, 15000000, 20000000,
|
||||
];
|
||||
|
||||
function nearestRadius(target: number, allowed: number[]): number {
|
||||
|
|
@ -99,15 +99,23 @@ export function buildPropertySearchUrls({
|
|||
|
||||
const bedroomFilter = filters['Bedrooms'];
|
||||
const minBedrooms =
|
||||
Array.isArray(bedroomFilter) && typeof bedroomFilter[0] === 'number' ? bedroomFilter[0] : undefined;
|
||||
Array.isArray(bedroomFilter) && typeof bedroomFilter[0] === 'number'
|
||||
? bedroomFilter[0]
|
||||
: undefined;
|
||||
const maxBedrooms =
|
||||
Array.isArray(bedroomFilter) && typeof bedroomFilter[1] === 'number' ? bedroomFilter[1] : undefined;
|
||||
Array.isArray(bedroomFilter) && typeof bedroomFilter[1] === 'number'
|
||||
? bedroomFilter[1]
|
||||
: undefined;
|
||||
|
||||
const bathroomFilter = filters['Bathrooms'];
|
||||
const minBathrooms =
|
||||
Array.isArray(bathroomFilter) && typeof bathroomFilter[0] === 'number' ? bathroomFilter[0] : undefined;
|
||||
Array.isArray(bathroomFilter) && typeof bathroomFilter[0] === 'number'
|
||||
? bathroomFilter[0]
|
||||
: undefined;
|
||||
const maxBathrooms =
|
||||
Array.isArray(bathroomFilter) && typeof bathroomFilter[1] === 'number' ? bathroomFilter[1] : undefined;
|
||||
Array.isArray(bathroomFilter) && typeof bathroomFilter[1] === 'number'
|
||||
? bathroomFilter[1]
|
||||
: undefined;
|
||||
|
||||
const tenureFilter = filters['Leasehold/Freehold'];
|
||||
const selectedTenures =
|
||||
|
|
@ -123,8 +131,10 @@ export function buildPropertySearchUrls({
|
|||
rmParams.set('useLocationIdentifier', 'true');
|
||||
rmParams.set('locationIdentifier', rightmoveLocationId);
|
||||
rmParams.set('radius', String(nearestRadius(radiusMiles, RIGHTMOVE_RADII)));
|
||||
if (minPrice !== undefined) rmParams.set('minPrice', String(snapRightmovePrice(minPrice, 'floor')));
|
||||
if (maxPrice !== undefined) rmParams.set('maxPrice', String(snapRightmovePrice(maxPrice, 'ceil')));
|
||||
if (minPrice !== undefined)
|
||||
rmParams.set('minPrice', String(snapRightmovePrice(minPrice, 'floor')));
|
||||
if (maxPrice !== undefined)
|
||||
rmParams.set('maxPrice', String(snapRightmovePrice(maxPrice, 'ceil')));
|
||||
if (minBedrooms !== undefined) rmParams.set('minBedrooms', String(Math.floor(minBedrooms)));
|
||||
if (maxBedrooms !== undefined) rmParams.set('maxBedrooms', String(Math.ceil(maxBedrooms)));
|
||||
if (minBathrooms !== undefined) rmParams.set('minBathrooms', String(Math.floor(minBathrooms)));
|
||||
|
|
|
|||
|
|
@ -494,10 +494,7 @@ const FEATURE_ICON_PATHS: Record<string, ReactNode> = {
|
|||
/**
|
||||
* Returns a complete SVG icon element for a given feature name, or null if unmapped.
|
||||
*/
|
||||
export function getFeatureIcon(
|
||||
featureName: string,
|
||||
className: string,
|
||||
): ReactElement | null {
|
||||
export function getFeatureIcon(featureName: string, className: string): ReactElement | null {
|
||||
const paths = FEATURE_ICON_PATHS[featureName];
|
||||
if (!paths) return null;
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -30,8 +30,18 @@ export function formatDuration(d: string): string {
|
|||
}
|
||||
|
||||
const MONTH_NAMES = [
|
||||
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
||||
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
|
||||
'Jan',
|
||||
'Feb',
|
||||
'Mar',
|
||||
'Apr',
|
||||
'May',
|
||||
'Jun',
|
||||
'Jul',
|
||||
'Aug',
|
||||
'Sep',
|
||||
'Oct',
|
||||
'Nov',
|
||||
'Dec',
|
||||
];
|
||||
|
||||
export function formatTransactionDate(fractionalYear: number): string {
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ const GROUP_ICONS: Record<string, ComponentType<{ className?: string }>> = {
|
|||
Property: TagIcon,
|
||||
};
|
||||
|
||||
export function getGroupIcon(
|
||||
group: string,
|
||||
): ComponentType<{ className?: string }> | null {
|
||||
export function getGroupIcon(group: string): ComponentType<{ className?: string }> | null {
|
||||
return GROUP_ICONS[group] ?? null;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue