Files
kapteins-daagbok/client/src/utils/tankCapacity.ts
T
elpatron 3cab735754 refactor: replace parseFloat with parseAppDecimal and formatAppDecimal for improved number handling
Updated various components to utilize parseAppDecimal and formatAppDecimal for consistent decimal parsing and formatting. This change enhances the handling of numeric inputs across the application, ensuring better accuracy and user experience in forms and displays.
2026-06-03 18:07:22 +02:00

102 lines
3.3 KiB
TypeScript

import { formatTankLiters, parseAppDecimal } from './numberFormat.js'
export interface VesselTankCapacities {
freshwaterCapacityL?: number
fuelCapacityL?: number
greywaterCapacityL?: number
}
export function parseOptionalTankLiters(input: string): number | undefined {
const trimmed = input.trim()
if (!trimmed) return undefined
const parsed = parseAppDecimal(trimmed)
if (parsed == null || parsed < 0) {
throw new Error('invalid_tank_liters')
}
return parsed
}
export function formatTankLitersForInput(liters: number): string {
return formatTankLiters(liters)
}
function capacityFromStored(value: unknown): number | undefined {
if (value == null || value === '') return undefined
if (typeof value === 'number' && Number.isFinite(value) && value >= 0) return value
if (typeof value === 'string') {
const trimmed = value.trim()
if (!trimmed) return undefined
const parsed = parseAppDecimal(trimmed)
if (parsed != null && parsed >= 0) return parsed
}
return undefined
}
export function tankCapacityInputFromStored(value: unknown): string {
const n = capacityFromStored(value)
return n != null ? formatTankLitersForInput(n) : ''
}
export function extractTankCapacitiesFromYacht(decrypted: unknown): VesselTankCapacities {
if (!decrypted || typeof decrypted !== 'object') return {}
const y = decrypted as Record<string, unknown>
const capacities: VesselTankCapacities = {}
const fw = capacityFromStored(y.freshwaterCapacityL)
const fuel = capacityFromStored(y.fuelCapacityL)
const gw = capacityFromStored(y.greywaterCapacityL)
if (fw != null) capacities.freshwaterCapacityL = fw
if (fuel != null) capacities.fuelCapacityL = fuel
if (gw != null) capacities.greywaterCapacityL = gw
return capacities
}
/** Parse a liter amount from form state (string). */
export function parseTankLitersFromInput(input: string): number {
const trimmed = input.trim().replace(',', '.')
if (!trimmed) return 0
const parsed = Number(trimmed)
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0
}
/**
* Max for refilled amount: remaining capacity after morning level.
* Returns undefined when no positive max (no slider).
*/
export function computeRefilledTankMaxLiters(
morningInput: string,
tankCapacityL?: number
): number | undefined {
if (tankCapacityL == null || tankCapacityL <= 0) return undefined
const remaining = tankCapacityL - parseTankLitersFromInput(morningInput)
if (remaining <= 0) return undefined
return remaining
}
/**
* Max for evening fill level: morning + refilled, capped by tank capacity when known.
* Returns undefined when no positive max (no slider).
*/
export function computeEveningTankMaxLiters(
morningInput: string,
refilledInput: string,
tankCapacityL?: number
): number | undefined {
const sum = parseTankLitersFromInput(morningInput) + parseTankLitersFromInput(refilledInput)
if (sum <= 0) return undefined
if (tankCapacityL != null && tankCapacityL > 0) {
return Math.min(tankCapacityL, sum)
}
return sum
}
/** Clamp numeric liter value to [0, max] when max is known. */
export function clampTankLiters(value: number, maxLiters?: number): number {
const clamped = Math.max(0, value)
if (maxLiters != null && maxLiters > 0) {
return Math.min(clamped, maxLiters)
}
return clamped
}