Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New fitness analytics page #1118

Draft
wants to merge 77 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
61d7c40
feat(migrations): create new columns for daily user activities
IgnisDa Nov 24, 2024
614729e
chore(migrations): remove newlines
IgnisDa Nov 24, 2024
24f3a73
feat(backend): store data in new dua columns
IgnisDa Nov 24, 2024
91f9577
chore(backend): change data type of muscles stored in db
IgnisDa Nov 24, 2024
7e4599e
Merge branch 'main' into issue-1113
IgnisDa Nov 24, 2024
b2d498a
Merge branch 'main' into issue-1113
IgnisDa Nov 24, 2024
7293bec
chore: make start time less than end time
IgnisDa Nov 25, 2024
d9b8837
chore: make start date less than end date
IgnisDa Nov 25, 2024
01587f6
chore(backend): common input struct for date range
IgnisDa Nov 25, 2024
c45defb
chore(backend): add comment to input struct
IgnisDa Nov 25, 2024
9633ee7
chore(frontend): adapt to new gql schema
IgnisDa Nov 25, 2024
b0c1d90
chore(utils): add debug logs for user activity calculation
IgnisDa Nov 25, 2024
dac8fd7
feat(models): add new struct to return response for analytics
IgnisDa Nov 25, 2024
6160b20
build(models/dependent): add new deps
IgnisDa Nov 25, 2024
89b93b1
build(backend): add new required deps
IgnisDa Nov 25, 2024
cac10a4
feat(backend): add new query for getting fitness analytics
IgnisDa Nov 25, 2024
dd715e7
feat(backend): add query fragment for fitness analytics
IgnisDa Nov 25, 2024
d4a7e75
build(services/statistics): add new deps to crate
IgnisDa Nov 25, 2024
4596668
feat(services/statistics): calculate hour counts
IgnisDa Nov 25, 2024
bb4b063
feat(backend): complete implementation of fitness statistics
IgnisDa Nov 25, 2024
e3c05ba
feat(backend): compute additional fields
IgnisDa Nov 25, 2024
7885b14
feat(migrations): add new column to store value
IgnisDa Nov 25, 2024
d41fa64
feat(backend): allow saving value in application cache
IgnisDa Nov 25, 2024
6bd9e69
feat(backend): cache fitness analytics for 2 hours
IgnisDa Nov 25, 2024
84429bf
feat(frontend): add basic fitness analytics page
IgnisDa Nov 25, 2024
76cedd5
fix(frontend): pass correct schema to parser
IgnisDa Nov 25, 2024
e50e905
feat(backend): add new preference for fitness analytics
IgnisDa Nov 25, 2024
3f349d8
feat(frontend): add fitness analytics to sidebar
IgnisDa Nov 25, 2024
935ad4d
feat(frontend): design basic webpage
IgnisDa Nov 25, 2024
6315b21
feat(frontend): do most calculations on the server loader
IgnisDa Nov 25, 2024
17589b5
feat(frontend): get fallback search params
IgnisDa Nov 25, 2024
9189043
feat(frontend): allow specifying custom time ranges
IgnisDa Nov 25, 2024
34b5750
feat(frontend): fetch data for fitness analytics
IgnisDa Nov 25, 2024
ca8e59d
chore(services/cache): log when cache key found
IgnisDa Nov 25, 2024
e6e5068
Revert "chore(services/cache): log when cache key found"
IgnisDa Nov 25, 2024
f02330a
feat(frontend): display basic pie chart
IgnisDa Nov 25, 2024
11fcaad
refactor(frontend): extract component to display chart container
IgnisDa Nov 25, 2024
e7995f4
feat(frontend): allow changing how many muscles to display
IgnisDa Nov 25, 2024
1f7c55e
feat(frontend): save count of muscles shown in local storage
IgnisDa Nov 25, 2024
1200f9e
feat(frontend): also allow setting analytics timespan to "All Time"
IgnisDa Nov 25, 2024
628d082
chore(docs): remove fragment from link
IgnisDa Nov 25, 2024
037202d
feat(frontend): add bar chart for exercises done
IgnisDa Nov 25, 2024
38b4e11
chore(frontend): minor enhancements to chart
IgnisDa Nov 25, 2024
47794fa
feat(frontend): handle cases when no analytics present
IgnisDa Nov 27, 2024
5f68630
Merge branch 'main' into issue-1113
IgnisDa Nov 27, 2024
2faaf1f
feat(backend): save igdb settings in application cache
IgnisDa Nov 27, 2024
1fe5871
feat(backend): save listennotes settings in application cache
IgnisDa Nov 27, 2024
6d010b0
perf(backend): remove extra parameter
IgnisDa Nov 27, 2024
cf75754
refactor(backend): change function name
IgnisDa Nov 27, 2024
f2fec30
perf(backend): do not make a useless clone
IgnisDa Nov 27, 2024
79ff3c8
feat(backend): save tmdb settings in application cache
IgnisDa Nov 27, 2024
db0947e
fix(providers): cache tmdb settings in the database
IgnisDa Nov 27, 2024
6e79e67
chore(migrations): make column non nullable
IgnisDa Nov 27, 2024
dce86b1
chore(backend): adapt to new database schema
IgnisDa Nov 27, 2024
c158727
refactor(backend): change function names
IgnisDa Nov 27, 2024
581c1f3
chore(frontend): minor changes to graphs
IgnisDa Nov 27, 2024
825ed52
chore(gql): fix formatting of query
IgnisDa Nov 27, 2024
fcbebc7
feat(frontend): use better colors for graphs
IgnisDa Nov 27, 2024
33f28da
Merge branch 'main' into issue-1113
IgnisDa Nov 27, 2024
8f943d1
fix(frontend): remove text align from page heading
IgnisDa Nov 27, 2024
9cf4e74
chore(frontend): select entire text when focusing on input
IgnisDa Nov 27, 2024
a6c0837
chore(frontend): change how props are structured
IgnisDa Nov 28, 2024
14af0b1
feat(frontend): function to convert utc hour to local hour
IgnisDa Nov 28, 2024
160a954
feat(frontend): start section to display time of day
IgnisDa Nov 28, 2024
993bc3e
fix(utils/database): calculate hour correctly
IgnisDa Nov 28, 2024
d1401b6
feat(frontend): generate correct data for time of day chart
IgnisDa Nov 28, 2024
29d244a
fix(frontend): generate correct arrays
IgnisDa Nov 28, 2024
8f99589
feat(frontend): display bubble chart for time of day
IgnisDa Nov 28, 2024
abd9670
chore(frontend): better types of stuff
IgnisDa Nov 28, 2024
35019ef
docs: better wording for authentication caveat
IgnisDa Nov 28, 2024
9ce1d04
feat(backend): setting to exclude exercise from analytics
IgnisDa Nov 28, 2024
831425c
feat(utils/database): respect new exercise setting
IgnisDa Nov 28, 2024
aca3fda
fix(services/fitness): handle edge case for updating exercise settings
IgnisDa Nov 28, 2024
b757fb2
feat(frontend): allow excluding exercise from analytics
IgnisDa Nov 28, 2024
e759bbb
feat(frontend): display the active episode for shows and podcasts
IgnisDa Nov 28, 2024
ebb7145
feat(frontend): remove scroll margin when it is no longer first exercise
IgnisDa Nov 28, 2024
4af5829
fix(providers): do not unwrap directly
IgnisDa Nov 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions apps/frontend/app/lib/generals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,11 @@ export const getStringAsciiValue = (input: string) => {
return total;
};

export const selectRandomElement = <T>(array: T[], input: string): T => {
// taken from https://stackoverflow.com/questions/44975435/using-mod-operator-in-javascript-to-wrap-around#comment76926119_44975435
return array[(getStringAsciiValue(input) + array.length) % array.length];
};

export const getMetadataIcon = (lot: MediaLot) =>
match(lot)
.with(MediaLot.Book, () => IconBook)
Expand Down Expand Up @@ -452,3 +457,13 @@ export const refreshUserMetadataDetails = (metadataId: string) =>
queryKey: queryFactory.media.userMetadataDetails(metadataId).queryKey,
});
}, 1500);

export const convertUtcHourToLocalHour = (
utcHour: number,
userTimezone?: string,
) => {
const targetTimezone = userTimezone || dayjs.tz.guess();
const utcDate = dayjs.utc().hour(utcHour).minute(0).second(0);
const localDate = utcDate.tz(targetTimezone);
return localDate.hour();
};
6 changes: 2 additions & 4 deletions apps/frontend/app/lib/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import {
FitnessAction,
dayjsLib,
getMetadataDetailsQuery,
getStringAsciiValue,
getUserMetadataDetailsQuery,
selectRandomElement,
} from "~/lib/generals";
import { type InProgressWorkout, useCurrentWorkout } from "~/lib/state/fitness";
import type { loader as dashboardLoader } from "~/routes/_dashboard";
Expand All @@ -34,9 +34,7 @@ export const useGetMantineColors = () => {

export const useGetRandomMantineColor = (input: string) => {
const colors = useGetMantineColors();

// taken from https://stackoverflow.com/questions/44975435/using-mod-operator-in-javascript-to-wrap-around#comment76926119_44975435
return colors[(getStringAsciiValue(input) + colors.length) % colors.length];
return selectRandomElement(colors, input);
};

export const useFallbackImageUrl = (text = "No Image") => {
Expand Down
1 change: 1 addition & 0 deletions apps/frontend/app/lib/state/fitness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export type Exercise = {
isCollapsed?: boolean;
sets: Array<ExerciseSet>;
isShowDetailsOpen: boolean;
scrollMarginRemoved?: true;
openedDetailsTab?: "images" | "history";
alreadyDoneSets: Array<AlreadyDoneExerciseSet>;
};
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/app/routes/_dashboard._index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ const ActivitySection = () => {
queryFn: async () => {
const { dailyUserActivities } = await clientGqlService.request(
DailyUserActivitiesDocument,
{ input: { startDate, endDate } },
{ input: { dateRange: { startDate, endDate } } },
);
const trackSeries = mapValues(MediaColors, () => false);
const data = dailyUserActivities.items.map((d) => {
Expand Down
3 changes: 2 additions & 1 deletion apps/frontend/app/routes/_dashboard.fitness.$action.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1101,7 +1101,7 @@ const ExerciseDisplay = (props: {
<Paper
radius={0}
style={{
scrollMargin: "60px",
scrollMargin: exercise.scrollMarginRemoved ? "10px" : "60px",
borderLeft: partOfSuperset
? `3px solid ${theme.colors[partOfSuperset.color][6]}`
: undefined,
Expand Down Expand Up @@ -1856,6 +1856,7 @@ const SetDisplay = (props: {
draft.exercises[props.exerciseIdx];
currentExercise.sets[props.setIdx].confirmedAt =
newConfirmed ? dayjsLib().toISOString() : null;
currentExercise.scrollMarginRemoved = true;
if (newConfirmed) {
const nextSet = getNextSetInWorkout(
draft,
Expand Down
Loading