@wger-project/react-components 25.10.16 → 25.11.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +1 -1
  2. package/build/chunks/{browser-ponyfill-DL_vVusK.js → browser-ponyfill-CyEkMYuR.js} +3 -3
  3. package/build/chunks/{browser-ponyfill-DL_vVusK.js.map → browser-ponyfill-CyEkMYuR.js.map} +1 -1
  4. package/build/locales/de/translation.json +334 -334
  5. package/build/locales/en/translation.json +12 -2
  6. package/build/locales/fil/translation.json +3 -0
  7. package/build/locales/fr/translation.json +347 -337
  8. package/build/locales/hr/translation.json +344 -244
  9. package/build/locales/it/translation.json +333 -333
  10. package/build/locales/ko/translation.json +327 -327
  11. package/build/locales/pt_PT/translation.json +330 -330
  12. package/build/locales/sk/translation.json +26 -1
  13. package/build/locales/sl/translation.json +321 -321
  14. package/build/locales/ta/translation.json +325 -325
  15. package/build/locales/uk/translation.json +344 -334
  16. package/build/locales/zh_Hans/translation.json +332 -332
  17. package/build/main.js +137 -236
  18. package/build/main.js.map +1 -1
  19. package/package.json +13 -13
  20. package/src/components/BodyWeight/Form/WeightForm.tsx +3 -4
  21. package/src/components/BodyWeight/WeightChart/index.tsx +26 -29
  22. package/src/components/Exercises/Detail/Head/ExerciseDeleteDialog.tsx +3 -4
  23. package/src/components/Exercises/ExerciseOverview.tsx +4 -4
  24. package/src/components/Exercises/Filter/NameAutcompleter.tsx +41 -39
  25. package/src/components/Exercises/Filter/NameAutocompleter.test.tsx +2 -1
  26. package/src/components/Measurements/Screens/MeasurementCategoryDetail.test.tsx +4 -2
  27. package/src/components/Measurements/widgets/MeasurementChart.tsx +27 -30
  28. package/src/components/Nutrition/components/BmiCalculator.tsx +40 -42
  29. package/src/components/Nutrition/widgets/IngredientAutcompleter.tsx +1 -1
  30. package/src/components/Nutrition/widgets/charts/MacrosPieChart.tsx +17 -19
  31. package/src/components/Nutrition/widgets/charts/NutritionDiaryChart.tsx +39 -38
  32. package/src/components/Nutrition/widgets/charts/NutritionalValuesDashboardChart.tsx +27 -29
  33. package/src/components/Nutrition/widgets/charts/NutritionalValuesPlannedLoggedChart.tsx +20 -19
  34. package/src/components/Nutrition/widgets/forms/NutritionDiaryEntryForm.tsx +15 -4
  35. package/src/components/WorkoutRoutines/Detail/RoutineDetailsTable.tsx +3 -3
  36. package/src/components/WorkoutRoutines/Detail/WorkoutStats.tsx +17 -19
  37. package/src/components/WorkoutRoutines/models/Day.ts +16 -6
  38. package/src/components/WorkoutRoutines/models/SlotEntry.ts +7 -2
  39. package/src/components/WorkoutRoutines/widgets/DayDetails.tsx +4 -4
  40. package/src/components/WorkoutRoutines/widgets/LogWidgets.tsx +35 -38
  41. package/src/components/WorkoutRoutines/widgets/RoutineDetailsCard.tsx +8 -11
  42. package/src/components/WorkoutRoutines/widgets/SlotDetails.tsx +4 -4
  43. package/src/components/WorkoutRoutines/widgets/forms/DayForm.tsx +21 -9
  44. package/src/components/WorkoutRoutines/widgets/forms/DayTypeSelect.tsx +66 -0
  45. package/src/components/WorkoutRoutines/widgets/forms/SessionForm.test.tsx +0 -2
  46. package/src/components/WorkoutRoutines/widgets/forms/SessionLogsForm.tsx +4 -4
  47. package/src/components/WorkoutRoutines/widgets/forms/SlotEntryForm.test.tsx +12 -10
  48. package/src/components/WorkoutRoutines/widgets/forms/SlotEntryForm.tsx +2 -1
  49. package/src/components/WorkoutRoutines/widgets/forms/SlotForm.tsx +1 -1
  50. package/src/services/exerciseTranslation.ts +24 -9
  51. package/src/services/responseType.ts +3 -29
  52. package/src/tests/exercises/searchResponse.ts +47 -22
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "exports": {
12
12
  ".": "./build/index.js"
13
13
  },
14
- "version": "25.10.16",
14
+ "version": "25.11.17",
15
15
  "repository": "https://github.com/wger-project/react",
16
16
  "type": "module",
17
17
  "publishConfig": {
@@ -22,14 +22,14 @@
22
22
  "@emotion/react": "^11.14.0",
23
23
  "@emotion/styled": "^11.14.1",
24
24
  "@hello-pangea/dnd": "^18.0.1",
25
- "@mui/icons-material": "^7.3.4",
25
+ "@mui/icons-material": "^7.3.5",
26
26
  "@mui/lab": "^7.0.1-beta.18",
27
27
  "@mui/material": "^7.3.4",
28
28
  "@mui/system": "^7.3.3",
29
- "@mui/x-data-grid": "^8.14.0",
30
- "@mui/x-date-pickers": "^8.14.0",
29
+ "@mui/x-data-grid": "^8.18.0",
30
+ "@mui/x-date-pickers": "^8.18.0",
31
31
  "@tanstack/react-query": "^5.90.2",
32
- "@vitejs/plugin-react": "^5.0.4",
32
+ "@vitejs/plugin-react": "^5.1.1",
33
33
  "axios": "^1.12.2",
34
34
  "formik": "^2.4.6",
35
35
  "history": "^5.3.0",
@@ -44,7 +44,7 @@
44
44
  "react-responsive": "^10.0.1",
45
45
  "react-router-dom": "^7.9.4",
46
46
  "react-simple-wysiwyg": "^3.4.1",
47
- "recharts": "^3.2.1",
47
+ "recharts": "^3.4.1",
48
48
  "slug": "^9.1.0",
49
49
  "typescript": "^5.9.3",
50
50
  "vite-tsconfig-paths": "^5.1.4",
@@ -52,7 +52,7 @@
52
52
  "yup": "^1.7.1"
53
53
  },
54
54
  "devDependencies": {
55
- "@eslint/js": "^9.37.0",
55
+ "@eslint/js": "^9.39.1",
56
56
  "@tanstack/react-query-devtools": "^5.90.2",
57
57
  "@testing-library/dom": "^10.4.1",
58
58
  "@testing-library/jest-dom": "^6.9.1",
@@ -62,12 +62,12 @@
62
62
  "@types/lodash": "^4.17.20",
63
63
  "@types/luxon": "^3.7.1",
64
64
  "@types/node": "^22.18.9",
65
- "@types/react": "^19.2.2",
66
- "@types/react-dom": "^19.2.1",
65
+ "@types/react": "^19.2.5",
66
+ "@types/react-dom": "^19.2.3",
67
67
  "@types/react-is": "^19.2.0",
68
68
  "@types/slug": "^5.0.9",
69
- "@typescript-eslint/eslint-plugin": "^8.46.0",
70
- "@typescript-eslint/parser": "^8.46.0",
69
+ "@typescript-eslint/eslint-plugin": "^8.47.0",
70
+ "@typescript-eslint/parser": "^8.47.0",
71
71
  "eslint": "^9.37.0",
72
72
  "eslint-plugin-import": "^2.32.0",
73
73
  "eslint-plugin-jsx-a11y": "^6.10.2",
@@ -76,10 +76,10 @@
76
76
  "i18next-parser": "^9.3.0",
77
77
  "jest": "^30.2.0",
78
78
  "jest-environment-jsdom": "^30.2.0",
79
- "jsdom": "^27.0.0",
79
+ "jsdom": "^27.2.0",
80
80
  "ts-jest": "^29.4.5",
81
81
  "typescript-eslint": "^8.46.0",
82
- "vite": "^7.1.9",
82
+ "vite": "^7.2.2",
83
83
  "vite-plugin-eslint": "^1.8.1",
84
84
  "vitest": "^3.2.4"
85
85
  },
@@ -8,7 +8,6 @@ import { Form, Formik } from "formik";
8
8
  import { DateTime } from "luxon";
9
9
  import { useState } from 'react';
10
10
  import { useTranslation } from "react-i18next";
11
- import { dateToYYYYMMDD } from "utils/date";
12
11
  import * as yup from 'yup';
13
12
 
14
13
  interface WeightFormProps {
@@ -41,7 +40,7 @@ export const WeightForm = ({ weightEntry, closeFn }: WeightFormProps) => {
41
40
  (<Formik
42
41
  initialValues={{
43
42
  weight: weightEntry ? weightEntry.weight : 0,
44
- date: weightEntry ? dateToYYYYMMDD(weightEntry.date) : dateToYYYYMMDD(new Date()),
43
+ date: weightEntry ? weightEntry.date : new Date(),
45
44
  }}
46
45
  validationSchema={validationSchema}
47
46
  onSubmit={async (values) => {
@@ -49,12 +48,12 @@ export const WeightForm = ({ weightEntry, closeFn }: WeightFormProps) => {
49
48
  // Edit existing weight entry
50
49
  if (weightEntry) {
51
50
  weightEntry.weight = values.weight;
52
- weightEntry.date = new Date(values.date);
51
+ weightEntry.date = values.date;
53
52
  editWeightQuery.mutate(weightEntry);
54
53
 
55
54
  // Create a new weight entry
56
55
  } else {
57
- weightEntry = new WeightEntry(new Date(values.date), values.weight);
56
+ weightEntry = new WeightEntry(values.date, values.weight);
58
57
  addWeightQuery.mutate(weightEntry);
59
58
  }
60
59
 
@@ -4,7 +4,7 @@ import { WeightEntry } from "components/BodyWeight/model";
4
4
  import { WgerModal } from "components/Core/Modals/WgerModal";
5
5
  import React from 'react';
6
6
  import { useTranslation } from "react-i18next";
7
- import { CartesianGrid, DotProps, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts';
7
+ import { CartesianGrid, DotProps, Line, LineChart, Tooltip, XAxis, YAxis } from 'recharts';
8
8
  import { dateToLocale } from "utils/date";
9
9
 
10
10
  export interface WeightChartProps {
@@ -72,34 +72,31 @@ export const WeightChart = ({ weights, height }: WeightChartProps) => {
72
72
  <WeightForm weightEntry={currentEntry} />
73
73
  </WgerModal>
74
74
  }
75
- <ResponsiveContainer height={height}>
76
-
77
- <LineChart data={weightData}>
78
- <Line
79
- type="monotone"
80
- dataKey="weight"
81
- stroke={theme.palette.secondary.main}
82
- strokeWidth={2}
83
- dot={weightData.length > NR_OF_WEIGHTS_CHART_DOT ? false : { strokeWidth: 1, r: 4 }}
84
- activeDot={{
85
- stroke: 'black',
86
- strokeWidth: 1,
87
- r: 6,
88
- onClick: handleClick
89
- }} />
90
- <CartesianGrid
91
- stroke="#ccc"
92
- strokeDasharray="5 5" />
93
- <XAxis
94
- dataKey="date"
95
- type={'number'}
96
- domain={['dataMin', 'dataMax']}
97
- tickFormatter={timeStr => dateToLocale(new Date(timeStr))}
98
- />
99
- <YAxis domain={['auto', 'auto']} />
100
- <Tooltip content={<CustomTooltip />} />
101
- </LineChart>
102
- </ResponsiveContainer>
75
+ <LineChart data={weightData} responsive height={height}>
76
+ <Line
77
+ type="monotone"
78
+ dataKey="weight"
79
+ stroke={theme.palette.secondary.main}
80
+ strokeWidth={2}
81
+ dot={weightData.length > NR_OF_WEIGHTS_CHART_DOT ? false : { strokeWidth: 1, r: 4 }}
82
+ activeDot={{
83
+ stroke: 'black',
84
+ strokeWidth: 1,
85
+ r: 6,
86
+ onClick: handleClick
87
+ }} />
88
+ <CartesianGrid
89
+ stroke="#ccc"
90
+ strokeDasharray="5 5" />
91
+ <XAxis
92
+ dataKey="date"
93
+ type={'number'}
94
+ domain={['dataMin', 'dataMax']}
95
+ tickFormatter={timeStr => dateToLocale(new Date(timeStr))}
96
+ />
97
+ <YAxis domain={['auto', 'auto']} />
98
+ <Tooltip content={<CustomTooltip />} />
99
+ </LineChart>
103
100
  </div>
104
101
  );
105
102
  };
@@ -24,7 +24,6 @@ import React from "react";
24
24
  import { useTranslation } from "react-i18next";
25
25
  import { useNavigate } from "react-router-dom";
26
26
  import { deleteExercise, deleteExerciseTranslation, getExercise } from "services";
27
- import { ExerciseSearchResponse } from "services/responseType";
28
27
 
29
28
  export function ExerciseDeleteDialog(props: {
30
29
  onClose: () => void,
@@ -91,10 +90,10 @@ export function ExerciseDeleteDialog(props: {
91
90
  <p>{t('exercises.replacementsSearch')}</p>
92
91
 
93
92
  <NameAutocompleter
94
- callback={(exercise: ExerciseSearchResponse | null) => {
93
+ callback={(exercise: Exercise | null) => {
95
94
  if (exercise !== null) {
96
- setReplacementId(exercise.data.base_id);
97
- loadCurrentReplacement(exercise.data.base_id);
95
+ setReplacementId(exercise.id!);
96
+ loadCurrentReplacement(exercise.id!);
98
97
  }
99
98
  }}
100
99
  />
@@ -15,7 +15,7 @@ import { useExercisesQuery } from "components/Exercises/queries";
15
15
  import React, { useContext, useMemo, useState } from "react";
16
16
  import { useTranslation } from "react-i18next";
17
17
  import { Link, useNavigate } from "react-router-dom";
18
- import { ExerciseSearchResponse } from "services/responseType";
18
+ import { Exercise } from "components/Exercises/models/exercise";
19
19
  import { makeLink, WgerLink } from "utils/url";
20
20
  import { ExerciseFiltersContext } from './Filter/ExerciseFiltersContext';
21
21
  import { FilterDrawer } from './Filter/FilterDrawer';
@@ -135,12 +135,12 @@ export const ExerciseOverviewList = () => {
135
135
  page * ITEMS_PER_PAGE
136
136
  );
137
137
 
138
- const exerciseAdded = (exerciseResponse: ExerciseSearchResponse | null) => {
139
- if (!exerciseResponse) {
138
+ const exerciseAdded = (exercise: Exercise | null) => {
139
+ if (!exercise) {
140
140
  return;
141
141
  }
142
142
 
143
- navigate(makeLink(WgerLink.EXERCISE_DETAIL, i18n.language, { id: exerciseResponse.data.base_id }));
143
+ navigate(makeLink(WgerLink.EXERCISE_DETAIL, i18n.language, { id: exercise.id }));
144
144
  };
145
145
 
146
146
  return (
@@ -12,25 +12,25 @@ import {
12
12
  Switch,
13
13
  TextField,
14
14
  } from "@mui/material";
15
+ import { Exercise } from "components/Exercises/models/exercise";
15
16
  import { SERVER_URL } from "config";
16
17
  import debounce from "lodash/debounce";
17
18
  import * as React from "react";
18
19
  import { useState } from "react";
19
20
  import { useTranslation } from "react-i18next";
20
- import { getExercise, searchExerciseTranslations } from "services";
21
- import { ExerciseSearchResponse } from "services/responseType";
21
+ import { searchExerciseTranslations } from "services";
22
22
  import { LANGUAGE_SHORT_ENGLISH } from "utils/consts";
23
23
 
24
24
  type NameAutocompleterProps = {
25
- callback: (exerciseResponse: ExerciseSearchResponse | null) => void;
25
+ callback: (exercise: Exercise | null) => void;
26
26
  loadExercise?: boolean;
27
27
  };
28
28
 
29
29
  export function NameAutocompleter({ callback, loadExercise }: NameAutocompleterProps) {
30
- const [value, setValue] = React.useState<ExerciseSearchResponse | null>(null);
30
+ const [value, setValue] = React.useState<Exercise | null>(null);
31
31
  const [inputValue, setInputValue] = React.useState("");
32
32
  const [searchEnglish, setSearchEnglish] = useState<boolean>(true);
33
- const [options, setOptions] = React.useState<readonly ExerciseSearchResponse[]>([]);
33
+ const [options, setOptions] = React.useState<readonly Exercise[]>([]);
34
34
  const [t, i18n] = useTranslation();
35
35
 
36
36
  loadExercise = loadExercise === undefined ? false : loadExercise;
@@ -61,7 +61,7 @@ export function NameAutocompleter({ callback, loadExercise }: NameAutocompleterP
61
61
  <>
62
62
  <Autocomplete
63
63
  id="exercise-name-autocomplete"
64
- getOptionLabel={(option) => option.value}
64
+ getOptionLabel={(option) => option.getTranslation().name}
65
65
  data-testid="autocomplete"
66
66
  filterOptions={(x) => x}
67
67
  options={options}
@@ -70,13 +70,10 @@ export function NameAutocompleter({ callback, loadExercise }: NameAutocompleterP
70
70
  filterSelectedOptions
71
71
  value={value}
72
72
  noOptionsText={t("noResults")}
73
- isOptionEqualToValue={(option, value) => option.value === value.value}
74
- onChange={async (event: React.SyntheticEvent, newValue: ExerciseSearchResponse | null) => {
73
+ isOptionEqualToValue={(option, value) => option.id === value.id}
74
+ onChange={async (event: React.SyntheticEvent, newValue: Exercise | null) => {
75
75
  setOptions(newValue ? [newValue, ...options] : options);
76
76
  setValue(newValue);
77
- if (loadExercise && newValue !== null) {
78
- newValue.exercise = await getExercise(newValue.data.base_id);
79
- }
80
77
  callback(newValue);
81
78
  }}
82
79
  onInputChange={(event, newInputValue) => {
@@ -102,34 +99,39 @@ export function NameAutocompleter({ callback, loadExercise }: NameAutocompleterP
102
99
  }}
103
100
  />
104
101
  )}
105
- renderOption={(props, option, state) => (
106
- <li
107
- {...props}
108
- key={`exercise-${state.index}-${option.data.id}`}
109
- data-testid={`autocompleter-result-${option.data.base_id}`}
110
- >
111
- <ListItem disablePadding component="div">
112
- <ListItemIcon>
113
- {option.data.image ? (
114
- <Avatar alt="" src={`${SERVER_URL}${option.data.image}`} variant="rounded" />
115
- ) : (
116
- <PhotoIcon fontSize="large" />
117
- )}
118
- </ListItemIcon>
119
- <ListItemText
120
- primary={option.value}
121
- slotProps={{
122
- primary: {
123
- whiteSpace: "nowrap",
124
- overflow: "hidden",
125
- textOverflow: "ellipsis",
126
- },
127
- }}
128
- secondary={option.data.category}
129
- />
130
- </ListItem>
131
- </li>
132
- )}
102
+ renderOption={(props, option, state) => {
103
+ const translation = option.getTranslation();
104
+ const mainImage = option.mainImage;
105
+
106
+ return (
107
+ <li
108
+ {...props}
109
+ key={`exercise-${state.index}-${option.id}`}
110
+ data-testid={`autocompleter-result-${option.id}`}
111
+ >
112
+ <ListItem disablePadding component="div">
113
+ <ListItemIcon>
114
+ {mainImage ? (
115
+ <Avatar alt="" src={`${SERVER_URL}${mainImage.url}`} variant="rounded" />
116
+ ) : (
117
+ <PhotoIcon fontSize="large" />
118
+ )}
119
+ </ListItemIcon>
120
+ <ListItemText
121
+ primary={translation.name}
122
+ slotProps={{
123
+ primary: {
124
+ whiteSpace: "nowrap",
125
+ overflow: "hidden",
126
+ textOverflow: "ellipsis",
127
+ },
128
+ }}
129
+ secondary={option.category.name}
130
+ />
131
+ </ListItem>
132
+ </li>
133
+ );
134
+ }}
133
135
  />
134
136
  {i18n.language !== LANGUAGE_SHORT_ENGLISH && (
135
137
  <FormGroup>
@@ -3,6 +3,7 @@ import { NameAutocompleter } from "components/Exercises/Filter/NameAutcompleter"
3
3
  import React from 'react';
4
4
  import { searchExerciseTranslations } from "services";
5
5
  import { searchResponse } from "tests/exercises/searchResponse";
6
+ import { Exercise } from "components/Exercises/models/exercise";
6
7
 
7
8
  jest.mock("services");
8
9
  const mockCallback = jest.fn();
@@ -71,6 +72,6 @@ describe("Test the NameAutocompleter component", () => {
71
72
  });
72
73
 
73
74
  // Assert
74
- expect(mockCallback).toHaveBeenLastCalledWith(searchResponse[0]);
75
+ expect(mockCallback).toHaveBeenCalledWith(expect.any(Exercise));
75
76
  });
76
77
  });
@@ -52,15 +52,17 @@ describe("Test the MeasurementCategoryDetail component", () => {
52
52
  </QueryClientProvider>
53
53
  );
54
54
 
55
+ screen.logTestingPlaygroundURL();
56
+
55
57
  // Assert
56
58
  expect(useMeasurementsQuery).toHaveBeenCalled();
57
59
  expect(screen.getByText('Biceps')).toBeInTheDocument();
58
60
 
59
- expect(screen.getByText('10cm')).toBeInTheDocument();
61
+ expect(screen.getByRole('gridcell', { name: /10cm/i })).toBeInTheDocument();
60
62
  expect(screen.getByText(/Feb 1, 2023/i)).toBeInTheDocument();
61
63
  expect(screen.getByText('test note')).toBeInTheDocument();
62
64
 
63
- expect(screen.getByText('20cm')).toBeInTheDocument();
65
+ expect(screen.getByRole('gridcell', { name: /20cm/i })).toBeInTheDocument();
64
66
  expect(screen.getByText(/Feb 2, 2023/i)).toBeInTheDocument();
65
67
  expect(screen.getByText('important note')).toBeInTheDocument();
66
68
  });
@@ -1,7 +1,7 @@
1
1
  import { Box } from "@mui/material";
2
2
  import { MeasurementCategory } from "components/Measurements/models/Category";
3
3
  import React from "react";
4
- import { CartesianGrid, Line, LineChart, ResponsiveContainer, XAxis, YAxis } from "recharts";
4
+ import { CartesianGrid, Line, LineChart, XAxis, YAxis } from "recharts";
5
5
  import { theme } from "theme";
6
6
  import { dateToLocale } from "utils/date";
7
7
 
@@ -19,34 +19,31 @@ export const MeasurementChart = (props: { category: MeasurementCategory }) => {
19
19
 
20
20
 
21
21
  return <Box alignItems={'center'} display={'flex'} flexDirection={'column'}>
22
- <ResponsiveContainer width="90%" height={200}>
23
-
24
- <LineChart data={entryData}>
25
- <Line
26
- type="monotone"
27
- dataKey="value"
28
- stroke={theme.palette.secondary.main}
29
- strokeWidth={2}
30
- dot={entryData.length > NR_OF_ENTRIES_CHART_DOT ? false : { strokeWidth: 1, r: 4 }}
31
- activeDot={{
32
- stroke: 'black',
33
- strokeWidth: 1,
34
- r: 6,
35
- //onClick: handleClick
36
- }} />
37
- <CartesianGrid
38
- stroke="#ccc"
39
- strokeDasharray="5 5" />
40
- <XAxis
41
- dataKey="date"
42
- type={'number'}
43
- domain={['dataMin', 'dataMax']}
44
- tickFormatter={timeStr => dateToLocale(new Date(timeStr))!}
45
- tickCount={10}
46
- />
47
- <YAxis domain={['auto', 'auto']} unit={props.category.unit} />
48
- {/*<Tooltip content={<CustomTooltip />} />*/}
49
- </LineChart>
50
- </ResponsiveContainer>
22
+ <LineChart data={entryData} responsive width="90%" height={200}>
23
+ <Line
24
+ type="monotone"
25
+ dataKey="value"
26
+ stroke={theme.palette.secondary.main}
27
+ strokeWidth={2}
28
+ dot={entryData.length > NR_OF_ENTRIES_CHART_DOT ? false : { strokeWidth: 1, r: 4 }}
29
+ activeDot={{
30
+ stroke: 'black',
31
+ strokeWidth: 1,
32
+ r: 6,
33
+ //onClick: handleClick
34
+ }} />
35
+ <CartesianGrid
36
+ stroke="#ccc"
37
+ strokeDasharray="5 5" />
38
+ <XAxis
39
+ dataKey="date"
40
+ type={'number'}
41
+ domain={['dataMin', 'dataMax']}
42
+ tickFormatter={timeStr => dateToLocale(new Date(timeStr))!}
43
+ tickCount={10}
44
+ />
45
+ <YAxis domain={['auto', 'auto']} unit={props.category.unit} />
46
+ {/*<Tooltip content={<CustomTooltip />} />*/}
47
+ </LineChart>
51
48
  </Box>;
52
49
  };
@@ -6,7 +6,7 @@ import { WgerContainerRightSidebar } from "components/Core/Widgets/Container";
6
6
  import { useProfileQuery } from "components/User/queries/profile";
7
7
  import React, { useEffect, useState } from "react";
8
8
  import { useTranslation } from "react-i18next";
9
- import { Area, AreaChart, CartesianGrid, ReferenceDot, ResponsiveContainer, Tooltip, XAxis, YAxis, } from "recharts";
9
+ import { Area, AreaChart, CartesianGrid, ReferenceDot, Tooltip, XAxis, YAxis, } from "recharts";
10
10
 
11
11
  const bmiRanges = [
12
12
  { range: "obese", color: "#FF5733", min: 30, max: 100 },
@@ -128,48 +128,46 @@ export const BmiCalculator = () => {
128
128
  {t('bmi.result', { value: bmi.toFixed(1) })}
129
129
  </Typography>
130
130
  }
131
- <ResponsiveContainer width="100%" height={400}>
132
- <AreaChart data={chartData}>
133
- <XAxis
134
- dataKey="height"
135
- type="number"
136
- domain={[140, 220]}
137
- unit="cm"
138
- />
139
- <YAxis
140
- domain={[40, 150]}
141
- tickFormatter={(value) => Math.round(value).toString()} // Format as integers
142
- unit="kg"
131
+ <AreaChart data={chartData} responsive width="100%" height={400}>
132
+ <XAxis
133
+ dataKey="height"
134
+ type="number"
135
+ domain={[140, 220]}
136
+ unit="cm"
137
+ />
138
+ <YAxis
139
+ domain={[40, 150]}
140
+ tickFormatter={(value) => Math.round(value).toString()} // Format as integers
141
+ unit="kg"
142
+ />
143
+ <CartesianGrid strokeDasharray="3 3" />
144
+ <Tooltip
145
+ // @ts-ignore
146
+ formatter={(value, name) => [Math.round(value as number), t('bmi.' + (name as string))]}
147
+ />
148
+
149
+ {bmiRanges.map((range) => (
150
+ <Area
151
+ key={range.range}
152
+ type="monotone"
153
+ dataKey={range.range}
154
+ stroke={"black"}
155
+ // stroke={range.color}
156
+ fill={range.color}
157
+ fillOpacity={0.8}
143
158
  />
144
- <CartesianGrid strokeDasharray="3 3" />
145
- <Tooltip
146
- // @ts-ignore
147
- formatter={(value, name) => [Math.round(value as number), t('bmi.' + (name as string))]}
148
- />
149
-
150
- {bmiRanges.map((range) => (
151
- <Area
152
- key={range.range}
153
- type="monotone"
154
- dataKey={range.range}
155
- stroke={"black"}
156
- // stroke={range.color}
157
- fill={range.color}
158
- fillOpacity={0.8}
159
- />
160
- ))}
161
-
162
- {bmi !== null &&
163
- <ReferenceDot
164
- x={height!}
165
- y={weight!}
166
- r={8}
167
- fill="black"
168
- stroke="none"
169
- />}
170
-
171
- </AreaChart>
172
- </ResponsiveContainer>
159
+ ))}
160
+
161
+ {bmi !== null &&
162
+ <ReferenceDot
163
+ x={height!}
164
+ y={weight!}
165
+ r={8}
166
+ fill="black"
167
+ stroke="none"
168
+ />}
169
+
170
+ </AreaChart>
173
171
  <Stack direction={"row"} justifyContent="center">
174
172
  <Box
175
173
  height={20}
@@ -22,7 +22,7 @@ import { searchIngredient } from "services";
22
22
  import { LANGUAGE_SHORT_ENGLISH } from "utils/consts";
23
23
 
24
24
  type IngredientAutocompleterProps = {
25
- callback: () => void;
25
+ callback: (ingredient: Ingredient | null) => void;
26
26
  initialIngredient?: Ingredient | null;
27
27
  };
28
28
 
@@ -1,7 +1,7 @@
1
1
  import { NutritionalValues } from "components/Nutrition/helpers/nutritionalValues";
2
2
  import React from "react";
3
3
  import { useTranslation } from "react-i18next";
4
- import { Cell, Legend, Pie, PieChart, ResponsiveContainer } from 'recharts';
4
+ import { Cell, Legend, Pie, PieChart } from 'recharts';
5
5
  import { generateChartColors } from "utils/colors";
6
6
  import { numberGramLocale } from "utils/numbers";
7
7
 
@@ -45,22 +45,20 @@ export const MacrosPieChart = (props: { data: NutritionalValues }) => {
45
45
  };
46
46
 
47
47
 
48
- return <ResponsiveContainer width={"100%"} height={300}>
49
- <PieChart>
50
- <Pie
51
- data={data}
52
- labelLine={false}
53
- // outerRadius={80}
54
- label={renderCustomizedLabel}
55
- fill="#8884d8"
56
- dataKey="value"
57
- >
58
- {data.map((entry, index) => (
59
- <Cell key={`cell-${index}`} fill={colorGenerator.next().value!} />
60
- ))}
61
- </Pie>
62
- {/*<Tooltip />*/}
63
- <Legend />
64
- </PieChart>
65
- </ResponsiveContainer>;
48
+ return <PieChart responsive width={"100%"} height={300}>
49
+ <Pie
50
+ data={data}
51
+ labelLine={false}
52
+ // outerRadius={80}
53
+ label={renderCustomizedLabel}
54
+ fill="#8884d8"
55
+ dataKey="value"
56
+ >
57
+ {data.map((entry, index) => (
58
+ <Cell key={`cell-${index}`} fill={colorGenerator.next().value!} />
59
+ ))}
60
+ </Pie>
61
+ {/*<Tooltip />*/}
62
+ <Legend />
63
+ </PieChart>;
66
64
  };