Skip to content

Commit

Permalink
chore(backend,frontend): backend improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
IgnisDa committed Aug 26, 2024
1 parent 7ccfcad commit 7589584
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 66 deletions.
7 changes: 5 additions & 2 deletions apps/frontend/app/lib/utilities.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,9 +372,12 @@ export const extendResponseHeaders = (
responseHeaders.append(key, value);
};

export const getWorkoutCookieValue = (request: Request) => {
return parse(request.headers.get("cookie") || "")[CurrentWorkoutKey];
};

export const isWorkoutActive = (request: Request) => {
const cookies = request.headers.get("cookie");
const inProgress = parse(cookies || "")[CurrentWorkoutKey] === "workouts";
const inProgress = getWorkoutCookieValue(request) === "workouts";
return inProgress;
};

Expand Down
77 changes: 41 additions & 36 deletions apps/frontend/app/routes/_dashboard.fitness.$entity.$id._index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -361,42 +361,47 @@ export default function Page() {
)}
/>
) : null}
{Number(loaderData.summary.total.weight) !== 0 ? (
<DisplayStat
icon={<IconWeight size={16} />}
data={displayWeightWithUnit(
unitSystem,
loaderData.summary.total.weight,
)}
/>
) : null}
{Number(loaderData.summary.total.distance) > 0 ? (
<DisplayStat
icon={<IconRun size={16} />}
data={displayDistanceWithUnit(
unitSystem,
loaderData.summary.total.distance,
)}
/>
) : null}
<DisplayStat
icon={<IconBarbell size={16} />}
data={`${loaderData.summary.exercises.length} Exercises`}
/>
{Number(loaderData.summary.total.personalBestsAchieved) !== 0 ? (
<DisplayStat
icon={<IconTrophy size={16} />}
data={`${loaderData.summary.total.personalBestsAchieved} PRs`}
/>
) : null}
{loaderData.summary.total.restTime > 0 ? (
<DisplayStat
icon={<IconZzz size={16} />}
data={humanizeDuration(
loaderData.summary.total.restTime * 1e3,
{ round: true, units: ["m", "s"] },
)}
/>
{loaderData.summary.total ? (
<>
{Number(loaderData.summary.total.weight) !== 0 ? (
<DisplayStat
icon={<IconWeight size={16} />}
data={displayWeightWithUnit(
unitSystem,
loaderData.summary.total.weight,
)}
/>
) : null}
{Number(loaderData.summary.total.distance) > 0 ? (
<DisplayStat
icon={<IconRun size={16} />}
data={displayDistanceWithUnit(
unitSystem,
loaderData.summary.total.distance,
)}
/>
) : null}
<DisplayStat
icon={<IconBarbell size={16} />}
data={`${loaderData.summary.exercises.length} Exercises`}
/>
{Number(loaderData.summary.total.personalBestsAchieved) !==
0 ? (
<DisplayStat
icon={<IconTrophy size={16} />}
data={`${loaderData.summary.total.personalBestsAchieved} PRs`}
/>
) : null}
{loaderData.summary.total.restTime > 0 ? (
<DisplayStat
icon={<IconZzz size={16} />}
data={humanizeDuration(
loaderData.summary.total.restTime * 1e3,
{ round: true, units: ["m", "s"] },
)}
/>
) : null}
</>
) : null}
</SimpleGrid>
</Box>
Expand Down
32 changes: 17 additions & 15 deletions apps/frontend/app/routes/_dashboard.fitness.$entity.list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,23 +160,25 @@ export default function Page() {
data={workout.detail}
/>
) : null}
<Group>
<DisplayStat
icon={<IconWeight size={16} />}
data={displayWeightWithUnit(
unitSystem,
workout.summary.total.weight,
)}
/>
{Number(
workout.summary.total.personalBestsAchieved,
) !== 0 ? (
{workout.summary.total ? (
<Group>
<DisplayStat
icon={<IconTrophy size={16} />}
data={`${workout.summary.total.personalBestsAchieved} PRs`}
icon={<IconWeight size={16} />}
data={displayWeightWithUnit(
unitSystem,
workout.summary.total.weight,
)}
/>
) : null}
</Group>
{Number(
workout.summary.total.personalBestsAchieved,
) !== 0 ? (
<DisplayStat
icon={<IconTrophy size={16} />}
data={`${workout.summary.total.personalBestsAchieved} PRs`}
/>
) : null}
</Group>
) : null}
</Stack>
</Accordion.Control>
<Anchor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ import {
useCurrentWorkout,
} from "~/lib/state/fitness";
import { useAddEntityToCollection } from "~/lib/state/media";
import { serverGqlService } from "~/lib/utilities.server";
import {
getWorkoutCookieValue,
serverGqlService,
} from "~/lib/utilities.server";

const searchParamsSchema = z.object({
defaultTab: z.string().optional(),
Expand All @@ -69,6 +72,7 @@ export type SearchParams = z.infer<typeof searchParamsSchema>;
export const loader = unstable_defineLoader(async ({ params, request }) => {
const { id: exerciseId } = zx.parseParams(params, { id: z.string() });
const query = zx.parseQuery(request, searchParamsSchema);
const workoutInProgress = !!getWorkoutCookieValue(request);
const [{ exerciseDetails }, { userExerciseDetails }] = await Promise.all([
serverGqlService.request(ExerciseDetailsDocument, { exerciseId }),
serverGqlService.authenticatedRequest(
Expand All @@ -77,7 +81,13 @@ export const loader = unstable_defineLoader(async ({ params, request }) => {
{ exerciseId },
),
]);
return { query, exerciseDetails, userExerciseDetails, exerciseId };
return {
query,
workoutInProgress,
exerciseDetails,
userExerciseDetails,
exerciseId,
};
});

export const meta = ({ data }: MetaArgs_SingleFetch<typeof loader>) => {
Expand Down Expand Up @@ -352,7 +362,7 @@ export default function Page() {
</Tabs.Panel>
</Tabs>
</Stack>
{currentWorkout ? (
{currentWorkout && loaderData.workoutInProgress ? (
<Affix position={{ bottom: rem(40), right: rem(30) }}>
<ActionIcon
color="blue"
Expand Down
12 changes: 10 additions & 2 deletions apps/frontend/app/routes/_dashboard.fitness.exercises.list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import {
import { addExerciseToWorkout, useCurrentWorkout } from "~/lib/state/fitness";
import {
getEnhancedCookieName,
getWorkoutCookieValue,
redirectUsingEnhancedCookieSearchParams,
serverGqlService,
} from "~/lib/utilities.server";
Expand Down Expand Up @@ -93,6 +94,7 @@ export const loader = unstable_defineLoader(async ({ request }) => {
const cookieName = await getEnhancedCookieName("exercises.list", request);
await redirectUsingEnhancedCookieSearchParams(request, cookieName);
const query = zx.parseQuery(request, searchParamsSchema);
const workoutInProgress = !!getWorkoutCookieValue(request);
query.sortBy = query.sortBy ?? defaultFiltersValue.sortBy;
query.page = query.page ?? 1;
const [{ exerciseParameters }, { exercisesList }] = await Promise.all([
Expand All @@ -113,7 +115,13 @@ export const loader = unstable_defineLoader(async ({ request }) => {
},
}),
]);
return { query, exerciseParameters, exercisesList, cookieName };
return {
query,
workoutInProgress,
exerciseParameters,
exercisesList,
cookieName,
};
});

export const meta = (_args: MetaArgs_SingleFetch<typeof loader>) => {
Expand Down Expand Up @@ -295,7 +303,7 @@ export default function Page() {
</>
)}
</Stack>
{currentWorkout ? (
{currentWorkout && loaderData.workoutInProgress ? (
<Affix position={{ bottom: rem(40), right: rem(30) }}>
<ActionIcon
color="blue"
Expand Down
3 changes: 2 additions & 1 deletion crates/models/fitness/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,8 @@ pub struct WorkoutSummaryExercise {
)]
#[serde(rename_all = "snake_case")]
pub struct WorkoutSummary {
pub total: WorkoutOrExerciseTotals,
// DEV: This is nullable because it is also used for the workout templates
pub total: Option<WorkoutOrExerciseTotals>,
pub exercises: Vec<WorkoutSummaryExercise>,
}

Expand Down
2 changes: 1 addition & 1 deletion crates/services/fitness/src/logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ pub async fn calculate_and_commit(
user_id: user_id.clone(),
name: input.name,
summary: WorkoutSummary {
total: summary_total,
total: Some(summary_total),
exercises: exercises
.iter()
.map(|(lot, e)| WorkoutSummaryExercise {
Expand Down
2 changes: 1 addition & 1 deletion crates/services/statistics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ impl StatisticsService {
get_activity_count(item.id, &mut activities, user_id, date);
activity.workout_count += 1;
activity.workout_duration += item.duration / 60;
let workout_total = item.summary.total;
let workout_total = item.summary.total.unwrap();
activity.workout_personal_bests += workout_total.personal_bests_achieved as i32;
activity.workout_weight += workout_total.weight.to_i32().unwrap_or_default();
activity.workout_reps += workout_total.reps.to_i32().unwrap_or_default();
Expand Down
2 changes: 1 addition & 1 deletion docs/includes/export-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ export interface WorkoutSummaryExercise {

export interface WorkoutSummary {
exercises: WorkoutSummaryExercise[];
total: WorkoutOrExerciseTotals;
total: WorkoutOrExerciseTotals | null;
}

/** A workout that was completed by the user. */
Expand Down
8 changes: 4 additions & 4 deletions libs/generated/src/graphql/backend/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2464,7 +2464,7 @@ export type WorkoutSetTotals = {

export type WorkoutSummary = {
exercises: Array<WorkoutSummaryExercise>;
total: WorkoutOrExerciseTotals;
total?: Maybe<WorkoutOrExerciseTotals>;
};

/** The summary about an exercise done in a workout. */
Expand Down Expand Up @@ -2920,14 +2920,14 @@ export type UserWorkoutsListQueryVariables = Exact<{
}>;


export type UserWorkoutsListQuery = { userWorkoutsList: { details: { total: number, nextPage?: number | null }, items: Array<{ id: string, name: string, endTime: string, duration: number, startTime: string, summary: { total: { personalBestsAchieved: number, weight: string, reps: string, distance: string, duration: string, restTime: number }, exercises: Array<{ numSets: number, id: string, lot?: ExerciseLot | null, bestSet?: { lot: SetLot, personalBests?: Array<WorkoutSetPersonalBest> | null, statistic: { duration?: string | null, distance?: string | null, reps?: string | null, weight?: string | null, oneRm?: string | null, pace?: string | null, volume?: string | null } } | null }> } }> } };
export type UserWorkoutsListQuery = { userWorkoutsList: { details: { total: number, nextPage?: number | null }, items: Array<{ id: string, name: string, endTime: string, duration: number, startTime: string, summary: { total?: { personalBestsAchieved: number, weight: string, reps: string, distance: string, duration: string, restTime: number } | null, exercises: Array<{ numSets: number, id: string, lot?: ExerciseLot | null, bestSet?: { lot: SetLot, personalBests?: Array<WorkoutSetPersonalBest> | null, statistic: { duration?: string | null, distance?: string | null, reps?: string | null, weight?: string | null, oneRm?: string | null, pace?: string | null, volume?: string | null } } | null }> } }> } };

export type WorkoutDetailsQueryVariables = Exact<{
workoutId: Scalars['String']['input'];
}>;


export type WorkoutDetailsQuery = { workoutDetails: { collections: Array<{ id: string, name: string, userId: string }>, details: { id: string, name: string, endTime: string, duration: number, startTime: string, repeatedFrom?: string | null, summary: { total: { personalBestsAchieved: number, weight: string, reps: string, distance: string, duration: string, restTime: number }, exercises: Array<{ numSets: number, id: string, lot?: ExerciseLot | null, bestSet?: { lot: SetLot, personalBests?: Array<WorkoutSetPersonalBest> | null, statistic: { duration?: string | null, distance?: string | null, reps?: string | null, weight?: string | null, oneRm?: string | null, pace?: string | null, volume?: string | null } } | null }> }, information: { comment?: string | null, assets?: { images: Array<string>, videos: Array<string> } | null, exercises: Array<{ name: string, lot: ExerciseLot, notes: Array<string>, restTime?: number | null, supersetWith: Array<number>, total?: { personalBestsAchieved: number, weight: string, reps: string, distance: string, duration: string, restTime: number } | null, assets?: { images: Array<string>, videos: Array<string> } | null, sets: Array<{ note?: string | null, lot: SetLot, personalBests?: Array<WorkoutSetPersonalBest> | null, confirmedAt?: string | null, statistic: { duration?: string | null, distance?: string | null, reps?: string | null, weight?: string | null, oneRm?: string | null, pace?: string | null, volume?: string | null } }> }> } } } };
export type WorkoutDetailsQuery = { workoutDetails: { collections: Array<{ id: string, name: string, userId: string }>, details: { id: string, name: string, endTime: string, duration: number, startTime: string, repeatedFrom?: string | null, summary: { total?: { personalBestsAchieved: number, weight: string, reps: string, distance: string, duration: string, restTime: number } | null, exercises: Array<{ numSets: number, id: string, lot?: ExerciseLot | null, bestSet?: { lot: SetLot, personalBests?: Array<WorkoutSetPersonalBest> | null, statistic: { duration?: string | null, distance?: string | null, reps?: string | null, weight?: string | null, oneRm?: string | null, pace?: string | null, volume?: string | null } } | null }> }, information: { comment?: string | null, assets?: { images: Array<string>, videos: Array<string> } | null, exercises: Array<{ name: string, lot: ExerciseLot, notes: Array<string>, restTime?: number | null, supersetWith: Array<number>, total?: { personalBestsAchieved: number, weight: string, reps: string, distance: string, duration: string, restTime: number } | null, assets?: { images: Array<string>, videos: Array<string> } | null, sets: Array<{ note?: string | null, lot: SetLot, personalBests?: Array<WorkoutSetPersonalBest> | null, confirmedAt?: string | null, statistic: { duration?: string | null, distance?: string | null, reps?: string | null, weight?: string | null, oneRm?: string | null, pace?: string | null, volume?: string | null } }> }> } } } };

export type GetOidcRedirectUrlQueryVariables = Exact<{ [key: string]: never; }>;

Expand Down Expand Up @@ -3051,7 +3051,7 @@ export type EntityAssetsPartFragment = { images: Array<string>, videos: Array<st

export type WorkoutSetStatisticPartFragment = { duration?: string | null, distance?: string | null, reps?: string | null, weight?: string | null, oneRm?: string | null, pace?: string | null, volume?: string | null };

export type WorkoutSummaryPartFragment = { total: { personalBestsAchieved: number, weight: string, reps: string, distance: string, duration: string, restTime: number }, exercises: Array<{ numSets: number, id: string, lot?: ExerciseLot | null, bestSet?: { lot: SetLot, personalBests?: Array<WorkoutSetPersonalBest> | null, statistic: { duration?: string | null, distance?: string | null, reps?: string | null, weight?: string | null, oneRm?: string | null, pace?: string | null, volume?: string | null } } | null }> };
export type WorkoutSummaryPartFragment = { total?: { personalBestsAchieved: number, weight: string, reps: string, distance: string, duration: string, restTime: number } | null, exercises: Array<{ numSets: number, id: string, lot?: ExerciseLot | null, bestSet?: { lot: SetLot, personalBests?: Array<WorkoutSetPersonalBest> | null, statistic: { duration?: string | null, distance?: string | null, reps?: string | null, weight?: string | null, oneRm?: string | null, pace?: string | null, volume?: string | null } } | null }> };

export type CollectionPartFragment = { id: string, name: string, userId: string };

Expand Down

0 comments on commit 7589584

Please sign in to comment.