45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
// Fare model tuned to the Lebanese market:
|
||
// - Distance-based with a base fare (like CTaxi/local taxis), not time-only.
|
||
// - Typical Beirut rides land in the $3–8 range riders expect.
|
||
// - Prices are quoted in USD (the de facto ride-hailing currency) with an
|
||
// L.B.P. equivalent shown for cash settlement.
|
||
|
||
import { DEFAULT_SERVICE, SERVICES, type ServiceId } from "@/constants/services";
|
||
import { tr } from "@/lib/i18n";
|
||
|
||
export const FARE = {
|
||
base: 1.5, // USD, flag drop
|
||
perKm: 0.55, // USD per kilometer of the trip
|
||
perMin: 0.15, // USD per minute of the trip
|
||
minimum: 3.0, // USD minimum fare
|
||
} as const;
|
||
|
||
// Parallel market rate used for the L.B.P. cash equivalent shown in-app.
|
||
export const LBP_RATE = 89500;
|
||
|
||
export const calculateFare = (
|
||
{
|
||
distanceMeters,
|
||
durationSeconds,
|
||
}: {
|
||
distanceMeters: number;
|
||
durationSeconds: number;
|
||
},
|
||
service: ServiceId = DEFAULT_SERVICE,
|
||
): string => {
|
||
const km = distanceMeters / 1000;
|
||
const minutes = durationSeconds / 60;
|
||
|
||
const multiplier =
|
||
SERVICES.find((s) => s.id === service)?.fareMultiplier ?? 1;
|
||
const fare = (FARE.base + km * FARE.perKm + minutes * FARE.perMin) * multiplier;
|
||
|
||
// The minimum fare is a floor on the final amount.
|
||
return Math.max(fare, FARE.minimum).toFixed(2);
|
||
};
|
||
|
||
// Rounds to the nearest 1,000 L.B.P. — the smallest practical cash note.
|
||
// The currency suffix is localized (" L.B.P." / " ل.ل." / " LBP").
|
||
export const formatLBP = (usd: number): string =>
|
||
`${(Math.round((usd * LBP_RATE) / 1000) * 1000).toLocaleString("en-US")}${tr("units.lbpSuffix")}`;
|