feat: dynamische Slider-Obergrenzen für Frischwasser und Treibstoff

Nachgefüllt ist auf Restkapazität nach Morgen begrenzt, Stand abends auf Morgen plus Nachgefüllt; Werte werden bei Änderungen automatisch gekürzt.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-31 13:39:46 +02:00
parent 25e1bdded3
commit 23fc940324
3 changed files with 129 additions and 5 deletions
+15
View File
@@ -1,6 +1,8 @@
import { describe, expect, it } from 'vitest'
import {
clampTankLiters,
computeEveningTankMaxLiters,
computeRefilledTankMaxLiters,
extractTankCapacitiesFromYacht,
formatTankLitersForInput,
parseOptionalTankLiters,
@@ -44,4 +46,17 @@ describe('tankCapacity', () => {
expect(clampTankLiters(-5, 200)).toBe(0)
expect(clampTankLiters(50)).toBe(50)
})
it('computes refilled max as capacity minus morning', () => {
expect(computeRefilledTankMaxLiters('10', 60)).toBe(50)
expect(computeRefilledTankMaxLiters('60', 60)).toBeUndefined()
expect(computeRefilledTankMaxLiters('10', undefined)).toBeUndefined()
})
it('computes evening max as morning plus refilled capped by capacity', () => {
expect(computeEveningTankMaxLiters('10', '20', 60)).toBe(30)
expect(computeEveningTankMaxLiters('40', '40', 60)).toBe(60)
expect(computeEveningTankMaxLiters('10', '20')).toBe(30)
expect(computeEveningTankMaxLiters('0', '0', 60)).toBeUndefined()
})
})
+41
View File
@@ -50,6 +50,47 @@ export function extractTankCapacitiesFromYacht(decrypted: unknown): VesselTankCa
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)