From abdfdf0dbff06ba817a03cd629800434709cc37f Mon Sep 17 00:00:00 2001 From: Jake Walker Date: Tue, 24 Mar 2026 13:49:31 +0000 Subject: [PATCH 1/2] Add UK MPG fuel consumption unit --- messages/en.json | 1 + .../components/feature/settings/SettingsModal.svelte | 6 +++++- src/lib/helper/format.helper.ts | 10 ++++++++++ src/lib/helper/settings-form.helper.ts | 11 +++++++++-- src/lib/types/settings.ts | 2 +- src/server/services/fuelLogService.ts | 9 +++++++++ 6 files changed, 35 insertions(+), 4 deletions(-) diff --git a/messages/en.json b/messages/en.json index 6c4e825c..c7536046 100644 --- a/messages/en.json +++ b/messages/en.json @@ -45,6 +45,7 @@ "settings_desc_mileage_format": "Choose how fuel efficiency is displayed", "settings_mileage_format_distance_per_fuel": "Distance per Fuel (e.g., km/L, mpg)", "settings_mileage_format_fuel_per_distance": "Fuel per Distance (e.g., L/100km)", + "settings_mileage_format_uk_mpg": "UK MPG (miles per imperial gallon)", "settings_desc_theme": "Choose your preferred theme", "settings_desc_custom_css": "CSS Styles for customizing the interface", "settings_select_language": "Select language", diff --git a/src/lib/components/feature/settings/SettingsModal.svelte b/src/lib/components/feature/settings/SettingsModal.svelte index 9cbd4ec1..7ca53d7f 100644 --- a/src/lib/components/feature/settings/SettingsModal.svelte +++ b/src/lib/components/feature/settings/SettingsModal.svelte @@ -50,7 +50,7 @@ unitOfLpg: z.enum(['liter', 'gallon', 'kilogram', 'pound']).default('liter'), unitOfCng: z.enum(['liter', 'gallon', 'kilogram', 'pound']).default('kilogram'), mileageUnitFormat: z - .enum(['distance-per-fuel', 'fuel-per-distance']) + .enum(['distance-per-fuel', 'fuel-per-distance', 'uk-mpg']) .default('distance-per-fuel'), theme: z.string().default('light'), customCss: z.string().optional(), @@ -177,6 +177,10 @@ { value: 'fuel-per-distance', label: m.settings_mileage_format_fuel_per_distance() + }, + { + value: 'uk-mpg', + label: m.settings_mileage_format_uk_mpg() } ]; diff --git a/src/lib/helper/format.helper.ts b/src/lib/helper/format.helper.ts index 9128565d..a66f92ee 100644 --- a/src/lib/helper/format.helper.ts +++ b/src/lib/helper/format.helper.ts @@ -210,6 +210,11 @@ const getMileageUnit = (vehicleType: string): string => { return `${fuelLabel}/100${distanceUnit}`; } + // only show uk mpg if miles and liters are used + if (configs.mileageUnitFormat === 'uk-mpg' && configs.unitOfDistance === 'mile' && fuelUnit === 'liter') { + return 'mpg'; + } + // Default: distance-per-fuel (e.g., km/L, mpg) const mileageUnit = `${configs.unitOfDistance}-per-${fuelUnit}`; const label = safeUnitLabel(mileageUnit); @@ -230,6 +235,11 @@ const formatMileage = (mileage: number, vehicleType: string): string => { return `${mileage.toFixed(2)} ${fuelLabel}/100${distanceUnit}`; } + // only show uk mpg if miles and liters are used + if (configs.mileageUnitFormat === 'uk-mpg' && configs.unitOfDistance === 'mile' && fuelUnit === 'liter') { + return `${mileage.toFixed(2)} mpg`; + } + // Default: distance-per-fuel (e.g., km/L, mpg) const mileageUnit = `${configs.unitOfDistance}-per-${fuelUnit}`; return ( diff --git a/src/lib/helper/settings-form.helper.ts b/src/lib/helper/settings-form.helper.ts index 01aa9f3d..f9cece9d 100644 --- a/src/lib/helper/settings-form.helper.ts +++ b/src/lib/helper/settings-form.helper.ts @@ -35,7 +35,7 @@ export function createSettingsConfigSchema( unitOfLpg: z.enum(['liter', 'gallon', 'kilogram', 'pound']).default('liter'), unitOfCng: z.enum(['liter', 'gallon', 'kilogram', 'pound']).default('kilogram'), mileageUnitFormat: z - .enum(['distance-per-fuel', 'fuel-per-distance']) + .enum(['distance-per-fuel', 'fuel-per-distance', 'uk-mpg']) .default('distance-per-fuel'), theme: z.string().default('light'), customCss: z.string().optional(), @@ -46,7 +46,10 @@ export function createSettingsConfigSchema( featureInsurance: z.boolean().default(true), featureOverview: z.boolean().default(true), notificationProcessingEnabled: z.boolean().default(true) - }); + }).refine((obj) => { + if (obj.mileageUnitFormat !== 'uk-mpg') return true; + return obj.unitOfDistance === 'mile' && obj.unitOfVolume === 'liter' + }, 'UK MPG calculation requires unit of distance to be miles and unit of volume to be litres.'); if (!options.includeNotificationProcessingSchedule) { return baseSchema; @@ -108,6 +111,10 @@ export function createSettingsOptions( { value: 'fuel-per-distance', label: m.settings_mileage_format_fuel_per_distance() + }, + { + value: 'uk-mpg', + label: m.settings_mileage_format_uk_mpg() } ], localeOptions: locales.map((code) => ({ diff --git a/src/lib/types/settings.ts b/src/lib/types/settings.ts index c853ea08..862db3b7 100644 --- a/src/lib/types/settings.ts +++ b/src/lib/types/settings.ts @@ -7,7 +7,7 @@ export interface SettingsFormShape extends Record { unitOfVolume: 'liter' | 'gallon'; unitOfLpg: 'liter' | 'gallon' | 'kilogram' | 'pound'; unitOfCng: 'liter' | 'gallon' | 'kilogram' | 'pound'; - mileageUnitFormat: 'distance-per-fuel' | 'fuel-per-distance'; + mileageUnitFormat: 'distance-per-fuel' | 'fuel-per-distance' | 'uk-mpg'; theme: string; customCss?: string; featureFuelLog: boolean; diff --git a/src/server/services/fuelLogService.ts b/src/server/services/fuelLogService.ts index eeb27a9d..c6653edb 100644 --- a/src/server/services/fuelLogService.ts +++ b/src/server/services/fuelLogService.ts @@ -40,6 +40,12 @@ export const getFuelLogs = async (vehicleId: string): Promise => { const mileageFormatConfig = await db.query.configTable.findFirst({ where: (config, { eq }) => eq(config.key, 'mileageUnitFormat') }); + const distanceUnit = (await db.query.configTable.findFirst({ + where: (config, { eq }) => eq(config.key, 'unitOfDistance') + }))?.value; + const volumeUnit = (await db.query.configTable.findFirst({ + where: (config, { eq }) => eq(config.key, 'unitOfVolume') + }))?.value; const mileageFormat = mileageFormatConfig?.value || 'distance-per-fuel'; const fuelLogs = await db.query.fuelLogTable.findMany({ @@ -102,6 +108,9 @@ export const getFuelLogs = async (vehicleId: string): Promise => { if (mileageFormat === 'fuel-per-distance') { // Fuel per 100 distance units (e.g., L/100km, gal/100mi) mileage = (totalFuel / distance) * 100; + } else if (mileageFormat === 'uk-mpg' && distanceUnit === 'mile' && volumeUnit === 'liter') { + // Miles per imperial gallon (mpg) + mileage = (distance / totalFuel) * 4.546; } else { // Distance per fuel unit (e.g., km/L, mpg) - default mileage = distance / totalFuel; From 72f24b69a950f09debbfe65ede4b7a8562e0950e Mon Sep 17 00:00:00 2001 From: Jake Walker Date: Tue, 24 Mar 2026 13:51:28 +0000 Subject: [PATCH 2/2] Fix code formatting --- src/lib/helper/format.helper.ts | 12 +++++- src/lib/helper/settings-form.helper.ts | 52 +++++++++++++------------- src/server/services/fuelLogService.ts | 16 +++++--- 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/src/lib/helper/format.helper.ts b/src/lib/helper/format.helper.ts index a66f92ee..33467f9f 100644 --- a/src/lib/helper/format.helper.ts +++ b/src/lib/helper/format.helper.ts @@ -211,7 +211,11 @@ const getMileageUnit = (vehicleType: string): string => { } // only show uk mpg if miles and liters are used - if (configs.mileageUnitFormat === 'uk-mpg' && configs.unitOfDistance === 'mile' && fuelUnit === 'liter') { + if ( + configs.mileageUnitFormat === 'uk-mpg' && + configs.unitOfDistance === 'mile' && + fuelUnit === 'liter' + ) { return 'mpg'; } @@ -236,7 +240,11 @@ const formatMileage = (mileage: number, vehicleType: string): string => { } // only show uk mpg if miles and liters are used - if (configs.mileageUnitFormat === 'uk-mpg' && configs.unitOfDistance === 'mile' && fuelUnit === 'liter') { + if ( + configs.mileageUnitFormat === 'uk-mpg' && + configs.unitOfDistance === 'mile' && + fuelUnit === 'liter' + ) { return `${mileage.toFixed(2)} mpg`; } diff --git a/src/lib/helper/settings-form.helper.ts b/src/lib/helper/settings-form.helper.ts index f9cece9d..a2e4c4f8 100644 --- a/src/lib/helper/settings-form.helper.ts +++ b/src/lib/helper/settings-form.helper.ts @@ -25,31 +25,33 @@ export function createSettingsConfigSchema( isValidTimezone: (value: string) => boolean, options: SettingsSchemaOptions = {} ) { - const baseSchema = z.object({ - dateFormat: z.string().refine((fmt) => isValidFormat(fmt).valid, 'Format not valid'), - locale: z.string().min(2), - timezone: z.string().min(3).refine(isValidTimezone, 'Invalid timzone value.'), - currency: z.string().min(1, 'Currency is required'), - unitOfDistance: z.enum(['kilometer', 'mile']), - unitOfVolume: z.enum(['liter', 'gallon']), - unitOfLpg: z.enum(['liter', 'gallon', 'kilogram', 'pound']).default('liter'), - unitOfCng: z.enum(['liter', 'gallon', 'kilogram', 'pound']).default('kilogram'), - mileageUnitFormat: z - .enum(['distance-per-fuel', 'fuel-per-distance', 'uk-mpg']) - .default('distance-per-fuel'), - theme: z.string().default('light'), - customCss: z.string().optional(), - featureFuelLog: z.boolean().default(true), - featureMaintenance: z.boolean().default(true), - featurePucc: z.boolean().default(true), - featureReminders: z.boolean().default(true), - featureInsurance: z.boolean().default(true), - featureOverview: z.boolean().default(true), - notificationProcessingEnabled: z.boolean().default(true) - }).refine((obj) => { - if (obj.mileageUnitFormat !== 'uk-mpg') return true; - return obj.unitOfDistance === 'mile' && obj.unitOfVolume === 'liter' - }, 'UK MPG calculation requires unit of distance to be miles and unit of volume to be litres.'); + const baseSchema = z + .object({ + dateFormat: z.string().refine((fmt) => isValidFormat(fmt).valid, 'Format not valid'), + locale: z.string().min(2), + timezone: z.string().min(3).refine(isValidTimezone, 'Invalid timzone value.'), + currency: z.string().min(1, 'Currency is required'), + unitOfDistance: z.enum(['kilometer', 'mile']), + unitOfVolume: z.enum(['liter', 'gallon']), + unitOfLpg: z.enum(['liter', 'gallon', 'kilogram', 'pound']).default('liter'), + unitOfCng: z.enum(['liter', 'gallon', 'kilogram', 'pound']).default('kilogram'), + mileageUnitFormat: z + .enum(['distance-per-fuel', 'fuel-per-distance', 'uk-mpg']) + .default('distance-per-fuel'), + theme: z.string().default('light'), + customCss: z.string().optional(), + featureFuelLog: z.boolean().default(true), + featureMaintenance: z.boolean().default(true), + featurePucc: z.boolean().default(true), + featureReminders: z.boolean().default(true), + featureInsurance: z.boolean().default(true), + featureOverview: z.boolean().default(true), + notificationProcessingEnabled: z.boolean().default(true) + }) + .refine((obj) => { + if (obj.mileageUnitFormat !== 'uk-mpg') return true; + return obj.unitOfDistance === 'mile' && obj.unitOfVolume === 'liter'; + }, 'UK MPG calculation requires unit of distance to be miles and unit of volume to be litres.'); if (!options.includeNotificationProcessingSchedule) { return baseSchema; diff --git a/src/server/services/fuelLogService.ts b/src/server/services/fuelLogService.ts index c6653edb..ef71c210 100644 --- a/src/server/services/fuelLogService.ts +++ b/src/server/services/fuelLogService.ts @@ -40,12 +40,16 @@ export const getFuelLogs = async (vehicleId: string): Promise => { const mileageFormatConfig = await db.query.configTable.findFirst({ where: (config, { eq }) => eq(config.key, 'mileageUnitFormat') }); - const distanceUnit = (await db.query.configTable.findFirst({ - where: (config, { eq }) => eq(config.key, 'unitOfDistance') - }))?.value; - const volumeUnit = (await db.query.configTable.findFirst({ - where: (config, { eq }) => eq(config.key, 'unitOfVolume') - }))?.value; + const distanceUnit = ( + await db.query.configTable.findFirst({ + where: (config, { eq }) => eq(config.key, 'unitOfDistance') + }) + )?.value; + const volumeUnit = ( + await db.query.configTable.findFirst({ + where: (config, { eq }) => eq(config.key, 'unitOfVolume') + }) + )?.value; const mileageFormat = mileageFormatConfig?.value || 'distance-per-fuel'; const fuelLogs = await db.query.fuelLogTable.findMany({