foamking/lib/distance.ts
mikl0s 3ebb63dc6c Add admin dashboard, authentication, step wizard, and quote management
Expand the calculator with a multi-step wizard flow, admin dashboard with
quote tracking, login/auth system, distance API integration, and history
page. Add new UI components (dialog, progress, select, slider, switch),
update pricing logic, and improve the overall design with new assets.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 20:59:11 +00:00

154 lines
3.7 KiB
TypeScript

// Predefined distances from 4550 Asnæs to major postal codes (round trip in km)
// This is a simplified approach for MVP - can be replaced with actual API later
export const POSTAL_CODE_DISTANCES: Record<string, number> = {
// København (2000-2999)
"2000": 200, // København K
"2100": 206, // København Ø
"2200": 208, // København N
"2300": 200, // København S
"2400": 210, // København NV
"2450": 216, // København SV
"2500": 194, // Valby
"2600": 182, // Glostrup
"2700": 188, // Brønshøj
"2800": 162, // Lyngby
"2900": 154, // Hellerup
// Nordsjælland (3000-3999)
"3000": 138, // Helsingør
"3050": 132, // Humlebæk
"3100": 128, // Hornbæk
"3200": 110, // Helsinge
"3300": 92, // Frederiksværk
"3400": 112, // Hillerød
"3460": 144, // Birkerød
"3500": 116, // Værløse
"3600": 90, // Frederikssund
// Vestsjælland (4000-4999)
"4000": 66, // Roskilde
"4100": 56, // Ringsted
"4200": 86, // Slagelse
"4300": 32, // Holbæk
"4400": 20, // Kalundborg
"4500": 16, // Nykøbing Sjælland
"4550": 0, // Asnæs (hjemmebase)
"4600": 70, // Køge
"4700": 132, // Næstved
"4800": 216, // Nykøbing F
"4900": 256, // Nakskov
// Fyn (5000-5999)
"5000": 290, // Odense C
"5100": 330, // Odense C
"5200": 300, // Odense V
"5220": 296, // Odense SØ
"5250": 284, // Odense SV
"5260": 288, // Odense S
"5270": 292, // Odense N
"5500": 350, // Middelfart
"5600": 360, // Faaborg
"5700": 340, // Svendborg
"5800": 380, // Nyborg
"5900": 370, // Rudkøbing
}
// Default distances based on first two digits of postal code
const DEFAULT_DISTANCES: Record<string, number> = {
// København centrum (1000-1999)
"10": 200,
"11": 200,
"12": 200,
"13": 200,
"14": 200,
"15": 200,
"16": 200,
"17": 200,
"18": 200,
"19": 200,
// København (2000-2999)
"20": 200, // København området
"21": 206,
"22": 208,
"23": 200,
"24": 210,
"25": 194,
"26": 182,
"27": 188,
"28": 162,
"29": 154,
"30": 138, // Nordsjælland
"31": 128,
"32": 110,
"33": 92,
"34": 112,
"35": 116,
"36": 90,
"40": 66, // Vestsjælland
"41": 56,
"42": 86,
"43": 32,
"44": 20,
"45": 16,
"46": 70,
"47": 132,
"48": 216, // Lolland-Falster
"49": 256,
"50": 290, // Fyn
"51": 330,
"52": 296,
"53": 310,
"54": 320,
"55": 350,
"56": 360,
"57": 340,
"58": 380,
"59": 370,
}
export function getDistance(postalCode: string): number {
// First check if we have an exact match
if (POSTAL_CODE_DISTANCES[postalCode]) {
return POSTAL_CODE_DISTANCES[postalCode]
}
// Otherwise use default based on first two digits
const prefix = postalCode.slice(0, 2)
if (DEFAULT_DISTANCES[prefix]) {
return DEFAULT_DISTANCES[prefix]
}
// If still no match, estimate based on region
const firstDigit = postalCode[0]
switch (firstDigit) {
case "1":
return 200 // København centrum average
case "2":
return 190 // København average
case "3":
return 110 // Nordsjælland average
case "4":
return 100 // Vestsjælland average
case "5":
return 320 // Fyn average
default:
return 200 // Default fallback
}
}
export function isInCoverageArea(postalCode: string): boolean {
const postalNumber = parseInt(postalCode)
// Coverage area: 0-5999 (Sjælland, Lolland-Falster, Fyn)
return postalNumber >= 0 && postalNumber <= 5999
}
export function validateDanishPostalCode(postalCode: string): boolean {
// Danish postal codes are 4 digits
if (!/^\d{4}$/.test(postalCode)) {
return false
}
// Valid ranges for Danish postal codes
const code = parseInt(postalCode)
return code >= 1000 && code <= 9999
}