WFDASHDRIVER-APP/lib/utils.ts

111 lines
3.1 KiB
TypeScript
Raw Normal View History

import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
export function formatDate(dateString: string): string {
if (!dateString) return 'N/A';
const date = new Date(dateString);
return date.toLocaleDateString('en-ZA', {
day: '2-digit',
month: 'short',
year: 'numeric',
});
}
export function formatDateTime(dateString: string): string {
if (!dateString) return 'N/A';
const date = new Date(dateString);
return date.toLocaleString('en-ZA', {
day: '2-digit',
month: 'short',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
});
}
export function formatCurrency(amount: number): string {
return new Intl.NumberFormat('en-ZA', {
style: 'currency',
currency: 'ZAR',
}).format(amount);
}
export function getRelativeTime(dateString: string): string {
const date = new Date(dateString);
const now = new Date();
const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);
if (diffInSeconds < 60) return 'Just now';
if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}m ago`;
if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}h ago`;
if (diffInSeconds < 604800) return `${Math.floor(diffInSeconds / 86400)}d ago`;
return formatDate(dateString);
}
export function debounce<T extends (...args: unknown[]) => unknown>(
func: T,
wait: number
): (...args: Parameters<T>) => void {
let timeout: ReturnType<typeof setTimeout>;
return (...args: Parameters<T>) => {
clearTimeout(timeout);
timeout = setTimeout(() => func(...args), wait);
};
}
export function groupBy<T>(array: T[], key: keyof T): Record<string, T[]> {
return array.reduce((result, item) => {
const groupKey = String(item[key]);
if (!result[groupKey]) {
result[groupKey] = [];
}
result[groupKey].push(item);
return result;
}, {} as Record<string, T[]>);
}
export function calculateDistance(
lat1: number,
lon1: number,
lat2: number,
lon2: number
): number {
const R = 6371; // Earth's radius in km
const dLat = (lat2 - lat1) * Math.PI / 180;
const dLon = (lon2 - lon1) * Math.PI / 180;
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
}
/**
* Parse coordinates from a text field.
* Supports formats like:
* "-33.9249, 18.4241"
* "-33.9249 18.4241"
* "lat: -33.9249, lng: 18.4241"
* Returns null if parsing fails.
*/
export function parseCoordinates(coordString: string | undefined): { latitude: number; longitude: number } | null {
if (!coordString) return null;
// Try to extract two numbers that look like lat/lng
const matches = coordString.match(/-?\d+\.?\d*/g);
if (matches && matches.length >= 2) {
const lat = parseFloat(matches[0]);
const lng = parseFloat(matches[1]);
if (!isNaN(lat) && !isNaN(lng)) {
return { latitude: lat, longitude: lng };
}
}
return null;
}