feat: add distance value object and ci workflows
This commit is contained in:
+40
-40
@@ -1,80 +1,80 @@
|
||||
import { type ClassValue, clsx } from 'clsx'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { type ClassValue, clsx } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
export type Coordinates = {
|
||||
lat: number
|
||||
lng: number
|
||||
}
|
||||
lat: number;
|
||||
lng: number;
|
||||
};
|
||||
|
||||
export function cn(...inputs: ClassValue[]): string {
|
||||
return twMerge(clsx(inputs))
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
|
||||
export function formatCoordinate(value: number, locale = 'en-US'): string {
|
||||
export function formatCoordinate(value: number, locale = "en-US"): string {
|
||||
const formatter = new Intl.NumberFormat(locale, {
|
||||
minimumFractionDigits: 3,
|
||||
maximumFractionDigits: 3,
|
||||
})
|
||||
return formatter.format(value)
|
||||
});
|
||||
return formatter.format(value);
|
||||
}
|
||||
|
||||
export function formatRelativeTime(dateIso: string, locale = 'en-US'): string {
|
||||
const date = new Date(dateIso)
|
||||
const now = new Date()
|
||||
const diff = Math.max(0, now.getTime() - date.getTime())
|
||||
export function formatRelativeTime(dateIso: string, locale = "en-US"): string {
|
||||
const date = new Date(dateIso);
|
||||
const now = new Date();
|
||||
const diff = Math.max(0, now.getTime() - date.getTime());
|
||||
|
||||
const seconds = Math.floor(diff / 1000)
|
||||
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' })
|
||||
const seconds = Math.floor(diff / 1000);
|
||||
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
|
||||
|
||||
if (seconds < 60) {
|
||||
return rtf.format(-seconds, 'second')
|
||||
return rtf.format(-seconds, "second");
|
||||
}
|
||||
|
||||
const minutes = Math.floor(seconds / 60)
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
if (minutes < 60) {
|
||||
return rtf.format(-minutes, 'minute')
|
||||
return rtf.format(-minutes, "minute");
|
||||
}
|
||||
|
||||
const hours = Math.floor(minutes / 60)
|
||||
const hours = Math.floor(minutes / 60);
|
||||
if (hours < 24) {
|
||||
return rtf.format(-hours, 'hour')
|
||||
return rtf.format(-hours, "hour");
|
||||
}
|
||||
|
||||
const days = Math.floor(hours / 24)
|
||||
const days = Math.floor(hours / 24);
|
||||
if (days < 7) {
|
||||
return rtf.format(-days, 'day')
|
||||
return rtf.format(-days, "day");
|
||||
}
|
||||
|
||||
const weeks = Math.floor(days / 7)
|
||||
return rtf.format(-weeks, 'week')
|
||||
const weeks = Math.floor(days / 7);
|
||||
return rtf.format(-weeks, "week");
|
||||
}
|
||||
|
||||
export function formatTimestamp(dateIso: string, locale = 'en-US'): string {
|
||||
const date = new Date(dateIso)
|
||||
export function formatTimestamp(dateIso: string, locale = "en-US"): string {
|
||||
const date = new Date(dateIso);
|
||||
return new Intl.DateTimeFormat(locale, {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: '2-digit',
|
||||
}).format(date)
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
hour: "numeric",
|
||||
minute: "2-digit",
|
||||
}).format(date);
|
||||
}
|
||||
|
||||
const EARTH_RADIUS_KM = 6371
|
||||
const EARTH_RADIUS_KM = 6371;
|
||||
|
||||
export function distanceInKm(a: Coordinates, b: Coordinates): number {
|
||||
const lat1 = toRadians(a.lat)
|
||||
const lat2 = toRadians(b.lat)
|
||||
const deltaLat = toRadians(b.lat - a.lat)
|
||||
const deltaLng = toRadians(b.lng - a.lng)
|
||||
const lat1 = toRadians(a.lat);
|
||||
const lat2 = toRadians(b.lat);
|
||||
const deltaLat = toRadians(b.lat - a.lat);
|
||||
const deltaLng = toRadians(b.lng - a.lng);
|
||||
|
||||
const haversine =
|
||||
Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
|
||||
Math.cos(lat1) * Math.cos(lat2) * Math.sin(deltaLng / 2) * Math.sin(deltaLng / 2)
|
||||
Math.cos(lat1) * Math.cos(lat2) * Math.sin(deltaLng / 2) * Math.sin(deltaLng / 2);
|
||||
|
||||
const c = 2 * Math.atan2(Math.sqrt(haversine), Math.sqrt(1 - haversine))
|
||||
return EARTH_RADIUS_KM * c
|
||||
const c = 2 * Math.atan2(Math.sqrt(haversine), Math.sqrt(1 - haversine));
|
||||
return EARTH_RADIUS_KM * c;
|
||||
}
|
||||
|
||||
function toRadians(value: number): number {
|
||||
return (value * Math.PI) / 180
|
||||
return (value * Math.PI) / 180;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user