Skip to content

Commit 12000a2

Browse files
authored
Allow customizing unit for calories burnt (#1226)
* feat(migrations): add for new calories burnt unit * feat(backend): add support for new workout logging unit * feat(frontend): allow customizing new preference * chore(frontend): reduce size of input * feat(frontend): display new unit * fix(frontend): duplicate the workout calories burnt as well
1 parent 3c84938 commit 12000a2

File tree

12 files changed

+68
-14
lines changed

12 files changed

+68
-14
lines changed

apps/frontend/app/lib/state/fitness.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ export const useMergingExercise = () => useAtom(mergingExerciseAtom);
295295
export const duplicateOldWorkout = async (
296296
name: string,
297297
fitnessEntity: FitnessAction,
298+
caloriesBurnt: number | undefined,
298299
workoutInformation: WorkoutInformation,
299300
coreDetails: ReturnType<typeof useCoreDetails>,
300301
userFitnessPreferences: UserFitnessPreferences,
@@ -307,11 +308,12 @@ export const duplicateOldWorkout = async (
307308
) => {
308309
const inProgress = getDefaultWorkout(fitnessEntity);
309310
inProgress.name = name;
310-
inProgress.repeatedFrom = params.repeatedFromId;
311+
inProgress.caloriesBurnt = caloriesBurnt;
311312
inProgress.templateId = params.templateId;
313+
inProgress.repeatedFrom = params.repeatedFromId;
312314
inProgress.updateWorkoutId = params.updateWorkoutId;
313-
inProgress.updateWorkoutTemplateId = params.updateWorkoutTemplateId;
314315
inProgress.comment = workoutInformation.comment || undefined;
316+
inProgress.updateWorkoutTemplateId = params.updateWorkoutTemplateId;
315317
for (const [exerciseIdx, ex] of workoutInformation.exercises.entries()) {
316318
const sets = ex.sets.map((v) =>
317319
convertHistorySetToCurrentSet(

apps/frontend/app/routes/_dashboard.analytics.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,7 @@ const StatItem = (props: {
608608
};
609609

610610
const StatisticsCard = () => {
611+
const userPreferences = useUserPreferences();
611612
const unitSystem = useUserUnitSystem();
612613

613614
const displayDuration = (duration: number) => {
@@ -637,7 +638,9 @@ const StatisticsCard = () => {
637638
/>
638639
<StatItem
639640
label={
640-
fitness.workoutCaloriesBurnt > 0 ? "Calories Burnt" : "Reps"
641+
fitness.workoutCaloriesBurnt > 0
642+
? `${userPreferences.fitness.logging.caloriesBurntUnit}`
643+
: "Reps"
641644
}
642645
icon={fitness.workoutCaloriesBurnt > 0 ? IconFlame : IconRepeat}
643646
tooltipLabel={

apps/frontend/app/routes/_dashboard.fitness.$action.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,7 @@ const NameAndOtherInputs = (props: {
718718
openAssetsModal: () => void;
719719
}) => {
720720
const loaderData = useLoaderData<typeof loader>();
721+
const userPreferences = useUserPreferences();
721722
const [currentWorkout, setCurrentWorkout] = useCurrentWorkout();
722723
invariant(currentWorkout);
723724

@@ -767,8 +768,8 @@ const NameAndOtherInputs = (props: {
767768
<Stack gap="xs">
768769
<NumberInput
769770
size="sm"
770-
label="Calories burnt"
771771
value={currentWorkout.caloriesBurnt}
772+
label={`Energy burnt in ${userPreferences.fitness.logging.caloriesBurntUnit}`}
772773
onChange={(e) => setCaloriesBurnt(isNumber(e) ? e : undefined)}
773774
/>
774775
<Textarea

apps/frontend/app/routes/_dashboard.fitness.$entity.$id._index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ export default function Page() {
247247
const workout = await duplicateOldWorkout(
248248
loaderData.entityName,
249249
params.action,
250+
loaderData.caloriesBurnt ? Number(loaderData.caloriesBurnt) : undefined,
250251
loaderData.information,
251252
coreDetails,
252253
userPreferences.fitness,
@@ -548,7 +549,7 @@ export default function Page() {
548549
Number(loaderData.caloriesBurnt) > 0 ? (
549550
<DisplayStat
550551
icon={<IconFlame size={16} />}
551-
data={`${loaderData.caloriesBurnt} calories`}
552+
data={`${loaderData.caloriesBurnt} ${userPreferences.fitness.logging.caloriesBurntUnit}`}
552553
/>
553554
) : null}
554555
</>

apps/frontend/app/routes/_dashboard.settings.preferences.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
Tabs,
2121
TagsInput,
2222
Text,
23+
TextInput,
2324
Title,
2425
rem,
2526
} from "@mantine/core";
@@ -649,6 +650,21 @@ export default function Page() {
649650
/>
650651
);
651652
})}
653+
<TextInput
654+
size="xs"
655+
label="Calories burnt unit"
656+
disabled={!!isEditDisabled}
657+
description="The unit to use for tracking calories burnt"
658+
defaultValue={userPreferences.fitness.logging.caloriesBurntUnit}
659+
onChange={(val) => {
660+
if (val) {
661+
updatePreference((draft) => {
662+
draft.fitness.logging.caloriesBurntUnit =
663+
val.target.value;
664+
});
665+
}
666+
}}
667+
/>
652668
<Divider />
653669
<Input.Wrapper label="The default measurements you want to keep track of">
654670
<SimpleGrid cols={2} mt="xs">

crates/migrations/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ mod m20241214_create_user_notification;
2929
mod m20250118_is_v8_migration;
3030
mod m20250122_changes_for_issue_1188;
3131
mod m20250126_changes_for_issue_1201;
32+
mod m20250201_changes_for_issue_1211;
3233

3334
pub use m20230404_create_user::User as AliasedUser;
3435
pub use m20230410_create_metadata::Metadata as AliasedMetadata;
@@ -79,6 +80,7 @@ impl MigratorTrait for Migrator {
7980
Box::new(m20250118_is_v8_migration::Migration),
8081
Box::new(m20250122_changes_for_issue_1188::Migration),
8182
Box::new(m20250126_changes_for_issue_1201::Migration),
83+
Box::new(m20250201_changes_for_issue_1211::Migration),
8284
]
8385
}
8486
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use sea_orm_migration::prelude::*;
2+
3+
#[derive(DeriveMigrationName)]
4+
pub struct Migration;
5+
6+
#[async_trait::async_trait]
7+
impl MigrationTrait for Migration {
8+
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
9+
let db = manager.get_connection();
10+
db.execute_unprepared(
11+
r#"
12+
UPDATE "user" SET "preferences" = jsonb_set("preferences", '{fitness,logging,calories_burnt_unit}', '"kcal"');
13+
"#,
14+
)
15+
.await?;
16+
Ok(())
17+
}
18+
19+
async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> {
20+
Ok(())
21+
}
22+
}

crates/models/user/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ pub struct UserFitnessFeaturesEnabledPreferences {
129129
#[educe(Default)]
130130
pub struct UserFitnessLoggingPreferences {
131131
pub mute_sounds: bool,
132+
#[educe(Default = "kcal")]
133+
pub calories_burnt_unit: String,
132134
pub prompt_for_rest_timer: bool,
133135
#[educe(Default = true)]
134136
pub show_details_while_editing: bool,

libs/generated/src/graphql/backend/gql.ts

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)