@wger-project/react-components 25.10.24 → 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 (28) hide show
  1. package/build/chunks/{browser-ponyfill-DL_vVusK.js → browser-ponyfill-CyEkMYuR.js} +3 -3
  2. package/build/chunks/{browser-ponyfill-DL_vVusK.js.map → browser-ponyfill-CyEkMYuR.js.map} +1 -1
  3. package/build/locales/fil/translation.json +3 -0
  4. package/build/locales/sk/translation.json +26 -1
  5. package/build/main.js +131 -229
  6. package/build/main.js.map +1 -1
  7. package/package.json +13 -13
  8. package/src/components/BodyWeight/Form/WeightForm.tsx +3 -4
  9. package/src/components/BodyWeight/WeightChart/index.tsx +26 -29
  10. package/src/components/Exercises/Detail/Head/ExerciseDeleteDialog.tsx +3 -4
  11. package/src/components/Exercises/ExerciseOverview.tsx +4 -4
  12. package/src/components/Exercises/Filter/NameAutcompleter.tsx +41 -39
  13. package/src/components/Exercises/Filter/NameAutocompleter.test.tsx +2 -1
  14. package/src/components/Measurements/Screens/MeasurementCategoryDetail.test.tsx +4 -2
  15. package/src/components/Measurements/widgets/MeasurementChart.tsx +27 -30
  16. package/src/components/Nutrition/components/BmiCalculator.tsx +40 -42
  17. package/src/components/Nutrition/widgets/charts/MacrosPieChart.tsx +17 -19
  18. package/src/components/Nutrition/widgets/charts/NutritionDiaryChart.tsx +39 -38
  19. package/src/components/Nutrition/widgets/charts/NutritionalValuesDashboardChart.tsx +27 -29
  20. package/src/components/Nutrition/widgets/charts/NutritionalValuesPlannedLoggedChart.tsx +20 -19
  21. package/src/components/WorkoutRoutines/Detail/WorkoutStats.tsx +17 -19
  22. package/src/components/WorkoutRoutines/widgets/DayDetails.tsx +3 -3
  23. package/src/components/WorkoutRoutines/widgets/LogWidgets.tsx +35 -38
  24. package/src/components/WorkoutRoutines/widgets/SlotDetails.tsx +4 -4
  25. package/src/components/WorkoutRoutines/widgets/forms/SessionLogsForm.tsx +4 -4
  26. package/src/services/exerciseTranslation.ts +24 -9
  27. package/src/services/responseType.ts +3 -29
  28. package/src/tests/exercises/searchResponse.ts +47 -22
@@ -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 { Bar, BarChart, CartesianGrid, Legend, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts';
4
+ import { Bar, BarChart, CartesianGrid, Legend, Tooltip, XAxis, YAxis } from 'recharts';
5
5
  import { generateChartColors } from "utils/colors";
6
6
  import { numberLocale } from "utils/numbers";
7
7
 
@@ -50,46 +50,47 @@ export const NutritionDiaryChart = ({ showPlanned, planned, today, avg7Days }: N
50
50
  ];
51
51
 
52
52
  return (
53
- <ResponsiveContainer width={"100%"} height={300}>
54
- <BarChart
55
- data={data}
56
- margin={{
57
- top: 20,
58
- right: 30,
59
- left: 20,
60
- bottom: 5,
61
- }}
62
- >
63
- <CartesianGrid strokeDasharray="3 4" />
64
- <XAxis dataKey="name" />
65
- <YAxis
66
- type="number"
67
- orientation="left"
68
- unit={t('nutrition.gramShort')}
69
- />
70
- <Tooltip formatter={(value: number) => numberLocale(value, i18n.language)} />
71
- <Legend />
72
- {showPlanned &&
73
- <Bar
74
- dataKey="planned"
75
- unit={t('nutrition.gramShort')}
76
- name={t('nutrition.planned')}
77
- fill={colorGenerator.next().value!}
78
- />
79
- }
80
- <Bar
81
- dataKey="today"
82
- unit={t('nutrition.gramShort')}
83
- name={t('nutrition.today')}
84
- fill={colorGenerator.next().value!}
85
- />
53
+ <BarChart
54
+ data={data}
55
+ margin={{
56
+ top: 20,
57
+ right: 30,
58
+ left: 20,
59
+ bottom: 5,
60
+ }}
61
+ responsive
62
+ width={"100%"}
63
+ height={300}
64
+ >
65
+ <CartesianGrid strokeDasharray="3 4" />
66
+ <XAxis dataKey="name" />
67
+ <YAxis
68
+ type="number"
69
+ orientation="left"
70
+ unit={t('nutrition.gramShort')}
71
+ />
72
+ <Tooltip formatter={(value: number) => numberLocale(value, i18n.language)} />
73
+ <Legend />
74
+ {showPlanned &&
86
75
  <Bar
87
- dataKey="avg7Days"
76
+ dataKey="planned"
88
77
  unit={t('nutrition.gramShort')}
89
- name={t('nutrition.7dayAvg')}
78
+ name={t('nutrition.planned')}
90
79
  fill={colorGenerator.next().value!}
91
80
  />
92
- </BarChart>
93
- </ResponsiveContainer>
81
+ }
82
+ <Bar
83
+ dataKey="today"
84
+ unit={t('nutrition.gramShort')}
85
+ name={t('nutrition.today')}
86
+ fill={colorGenerator.next().value!}
87
+ />
88
+ <Bar
89
+ dataKey="avg7Days"
90
+ unit={t('nutrition.gramShort')}
91
+ name={t('nutrition.7dayAvg')}
92
+ fill={colorGenerator.next().value!}
93
+ />
94
+ </BarChart>
94
95
  );
95
96
  };
@@ -3,7 +3,7 @@ import { NutritionalValues } from "components/Nutrition/helpers/nutritionalValue
3
3
  import { LinearPlannedLoggedChart } from "components/Nutrition/widgets/charts/LinearPlannedLoggedChart";
4
4
  import React from 'react';
5
5
  import { useTranslation } from "react-i18next";
6
- import { Cell, Pie, PieChart, ResponsiveContainer } from 'recharts';
6
+ import { Cell, Pie, PieChart } from 'recharts';
7
7
  import { numberLocale } from "utils/numbers";
8
8
 
9
9
 
@@ -32,34 +32,32 @@ export const NutritionalValuesDashboardChart = (props: {
32
32
 
33
33
 
34
34
  return <Stack direction={'row'}>
35
- <ResponsiveContainer width={'50%'} height={140}>
36
- <PieChart>
37
- <Pie
38
- // cx={0}
39
- // cy={'10'}
40
- height={100}
41
- data={data}
42
- startAngle={200}
43
- endAngle={-20}
44
- innerRadius={60}
45
- outerRadius={70}
46
- paddingAngle={2}
47
- dataKey="value"
48
- >
49
- {data.map((entry, index) => (
50
- <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
51
- ))}
52
- </Pie>
53
- <g>
54
- <text x={'50%'} y={'45%'} fontSize="1.25em" textAnchor="middle">{/*fill="#333"*/}
55
- {t('nutrition.valueEnergyKcal', { value: numberLocale(energyDiff, i18n.language) })}
56
- </text>
57
- <text x={'50%'} y={'60%'} fontSize="1em" textAnchor="middle">
58
- {props.planned.energy > 0 && t(energyPercentage < 100 ? 'nutrition.valueRemaining' : 'nutrition.valueTooMany')}
59
- </text>
60
- </g>
61
- </PieChart>
62
- </ResponsiveContainer>
35
+ <PieChart responsive width={'50%'} height={140}>
36
+ <Pie
37
+ // cx={0}
38
+ // cy={'10'}
39
+ height={100}
40
+ data={data}
41
+ startAngle={200}
42
+ endAngle={-20}
43
+ innerRadius={60}
44
+ outerRadius={70}
45
+ paddingAngle={2}
46
+ dataKey="value"
47
+ >
48
+ {data.map((entry, index) => (
49
+ <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
50
+ ))}
51
+ </Pie>
52
+ <g>
53
+ <text x={'50%'} y={'45%'} fontSize="1.25em" textAnchor="middle">{/*fill="#333"*/}
54
+ {t('nutrition.valueEnergyKcal', { value: numberLocale(energyDiff, i18n.language) })}
55
+ </text>
56
+ <text x={'50%'} y={'60%'} fontSize="1em" textAnchor="middle">
57
+ {props.planned.energy > 0 && t(energyPercentage < 100 ? 'nutrition.valueRemaining' : 'nutrition.valueTooMany')}
58
+ </text>
59
+ </g>
60
+ </PieChart>
63
61
  <Stack width={'50%'} spacing={1}>
64
62
  <LinearPlannedLoggedChart
65
63
  title={t('nutrition.protein')}
@@ -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 { Bar, BarChart, CartesianGrid, ResponsiveContainer, XAxis, YAxis } from 'recharts';
4
+ import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from 'recharts';
5
5
  import { generateChartColors } from "utils/colors";
6
6
 
7
7
 
@@ -32,23 +32,24 @@ export const NutritionalValuesPlannedLoggedChart = (props: {
32
32
 
33
33
 
34
34
  return (
35
- <ResponsiveContainer width={"100%"} height={150}>
36
- <BarChart
37
- data={data}
38
- layout="vertical"
39
- margin={{
40
- left: 60,
41
- }}
42
- >
43
- <CartesianGrid strokeDasharray="3 4" />
44
- <XAxis type={'number'} unit={'%'} />
45
- <YAxis type={'category'} dataKey={'name'} />
46
- <Bar
47
- dataKey="value"
48
- unit={'%'}
49
- fill={colorGenerator.next().value!}
50
- />
51
- </BarChart>
52
- </ResponsiveContainer>
35
+ <BarChart
36
+ data={data}
37
+ layout="vertical"
38
+ margin={{
39
+ left: 60,
40
+ }}
41
+ responsive
42
+ width={"100%"}
43
+ height={150}
44
+ >
45
+ <CartesianGrid strokeDasharray="3 4" />
46
+ <XAxis type={'number'} unit={'%'} />
47
+ <YAxis type={'category'} dataKey={'name'} />
48
+ <Bar
49
+ dataKey="value"
50
+ unit={'%'}
51
+ fill={colorGenerator.next().value!}
52
+ />
53
+ </BarChart>
53
54
  );
54
55
  };
@@ -209,25 +209,23 @@ export const WorkoutStats = () => {
209
209
 
210
210
  <Grid size={12}>
211
211
  <Box width="100%" height={400}>
212
- <ResponsiveContainer width="100%" height="100%">
213
- <LineChart width={500} height={300}>
214
- <CartesianGrid strokeDasharray="3 3" />
215
- <XAxis dataKey="category" type="category" allowDuplicatedCategory={false} />
216
- <YAxis dataKey="value" />
217
- <Tooltip
218
- formatter={(value: number) => Number.isInteger(value) ? value.toFixed(0) : value.toFixed(2)} />
219
- <Legend
220
- layout={"vertical"}
221
- verticalAlign="middle"
222
- align="right"
223
- wrapperStyle={{ paddingLeft: "20px" }}
224
- />
225
- {chartData.map((s) => (
226
- <Line dataKey="value" data={s.data} name={s.name} key={s.name}
227
- stroke={colorGenerator.next()!.value!} />
228
- ))}
229
- </LineChart>
230
- </ResponsiveContainer>
212
+ <LineChart width="100%" height="100%" responsive>
213
+ <CartesianGrid strokeDasharray="3 3" />
214
+ <XAxis dataKey="category" type="category" allowDuplicatedCategory={false} />
215
+ <YAxis dataKey="value" />
216
+ <Tooltip
217
+ formatter={(value: number) => Number.isInteger(value) ? value.toFixed(0) : value.toFixed(2)} />
218
+ <Legend
219
+ layout={"vertical"}
220
+ verticalAlign="middle"
221
+ align="right"
222
+ wrapperStyle={{ paddingLeft: "20px" }}
223
+ />
224
+ {chartData.map((s) => (
225
+ <Line dataKey="value" data={s.data} name={s.name} key={s.name}
226
+ stroke={colorGenerator.next()!.value!} />
227
+ ))}
228
+ </LineChart>
231
229
  </Box>
232
230
  </Grid>
233
231
 
@@ -24,6 +24,7 @@ import {
24
24
  import Grid from '@mui/material/Grid';
25
25
  import { LoadingPlaceholder, LoadingProgressIcon } from "components/Core/LoadingWidget/LoadingWidget";
26
26
  import { NameAutocompleter } from "components/Exercises/Filter/NameAutcompleter";
27
+ import { Exercise } from "components/Exercises/models/exercise";
27
28
  import { useProfileQuery } from "components/User/queries/profile";
28
29
  import { Day } from "components/WorkoutRoutines/models/Day";
29
30
  import { Slot } from "components/WorkoutRoutines/models/Slot";
@@ -43,7 +44,6 @@ import { SlotDetails } from "components/WorkoutRoutines/widgets/SlotDetails";
43
44
  import React, { useState } from "react";
44
45
  import { useTranslation } from "react-i18next";
45
46
  import { Link } from "react-router-dom";
46
- import { ExerciseSearchResponse } from "services/responseType";
47
47
  import { SNACKBAR_AUTO_HIDE_DURATION, WEIGHT_UNIT_KG, WEIGHT_UNIT_LB } from "utils/consts";
48
48
  import { makeLink, WgerLink } from "utils/url";
49
49
 
@@ -381,13 +381,13 @@ export const DayDetails = (props: {
381
381
  && <Grid size={12}>
382
382
  <Box height={20} />
383
383
  <NameAutocompleter
384
- callback={(exercise: ExerciseSearchResponse | null) => {
384
+ callback={(exercise: Exercise | null) => {
385
385
  if (exercise === null) {
386
386
  return;
387
387
  }
388
388
  addSlotEntryQuery.mutate(new SlotEntry({
389
389
  slotId: slot.id!,
390
- exerciseId: exercise.data.base_id,
390
+ exerciseId: exercise.id!,
391
391
  type: 'normal',
392
392
  order: slot.entries.length + 1,
393
393
  weightUnitId: userProfileQuery.data!.useMetric ? WEIGHT_UNIT_KG : WEIGHT_UNIT_LB,
@@ -27,7 +27,6 @@ import { useTranslation } from "react-i18next";
27
27
  import {
28
28
  CartesianGrid,
29
29
  Legend,
30
- ResponsiveContainer,
31
30
  Scatter,
32
31
  ScatterChart,
33
32
  Tooltip,
@@ -292,43 +291,41 @@ export const TimeSeriesChart = (props: { data: WorkoutLog[] }) => {
292
291
 
293
292
  return (
294
293
  <Box>
295
- <ResponsiveContainer width={"100%"} height={250}>
296
- <ScatterChart>
297
- <XAxis
298
- dataKey="time"
299
- domain={["auto", "auto"]}
300
- name="Time"
301
- tickFormatter={unixTime => luxonDateTimeToLocale(DateTime.fromMillis(unixTime))}
302
- type="number"
303
- />
304
- <YAxis
305
- domain={["auto", "auto"]}
306
- dataKey="value"
307
- name="Value"
308
- unit="kg"
309
- />
310
-
311
- {Array.from(result).map(([key, value]) => {
312
- const color = colorGenerator.next().value!;
313
- const formattedData = formatData(value);
314
-
315
- return <Scatter
316
- key={key}
317
- data={formattedData}
318
- fill={color}
319
- line={{ stroke: color }}
320
- lineType="joint"
321
- lineJointType="monotoneX"
322
- name={key?.toString()}
323
- />;
324
- }
325
- )}
326
-
327
- <Tooltip content={<ExerciseLogTooltip />} />
328
- <CartesianGrid strokeDasharray="3 3" />
329
- <Legend />
330
- </ScatterChart>
331
- </ResponsiveContainer>
294
+ <ScatterChart responsive width={"100%"} height={250}>
295
+ <XAxis
296
+ dataKey="time"
297
+ domain={["auto", "auto"]}
298
+ name="Time"
299
+ tickFormatter={unixTime => luxonDateTimeToLocale(DateTime.fromMillis(unixTime))}
300
+ type="number"
301
+ />
302
+ <YAxis
303
+ domain={["auto", "auto"]}
304
+ dataKey="value"
305
+ name="Value"
306
+ unit="kg"
307
+ />
308
+
309
+ {Array.from(result).map(([key, value]) => {
310
+ const color = colorGenerator.next().value!;
311
+ const formattedData = formatData(value);
312
+
313
+ return <Scatter
314
+ key={key}
315
+ data={formattedData}
316
+ fill={color}
317
+ line={{ stroke: color }}
318
+ lineType="joint"
319
+ lineJointType="monotoneX"
320
+ name={key?.toString()}
321
+ />;
322
+ }
323
+ )}
324
+
325
+ <Tooltip content={<ExerciseLogTooltip />} />
326
+ <CartesianGrid strokeDasharray="3 3" />
327
+ <Legend />
328
+ </ScatterChart>
332
329
  </Box>
333
330
  );
334
331
  };
@@ -4,6 +4,7 @@ import EditOffIcon from '@mui/icons-material/EditOff';
4
4
  import { Alert, AlertTitle, IconButton, Typography } from "@mui/material";
5
5
  import Grid from '@mui/material/Grid';
6
6
  import { NameAutocompleter } from "components/Exercises/Filter/NameAutcompleter";
7
+ import { Exercise } from "components/Exercises/models/exercise";
7
8
  import { useLanguageQuery } from "components/Exercises/queries";
8
9
  import { BaseConfig } from "components/WorkoutRoutines/models/BaseConfig";
9
10
  import { Slot } from "components/WorkoutRoutines/models/Slot";
@@ -21,7 +22,6 @@ import {
21
22
  import React, { useState } from "react";
22
23
  import { useTranslation } from "react-i18next";
23
24
  import { getLanguageByShortName } from "services";
24
- import { ExerciseSearchResponse } from "services/responseType";
25
25
 
26
26
  /*
27
27
  * Converts a number to an alphabetic string, useful for counting
@@ -95,12 +95,12 @@ export const SlotEntryDetails = (props: {
95
95
 
96
96
  const isPending = editSlotEntryQuery.isPending || deleteSlotEntryQuery.isPending;
97
97
 
98
- const handleExerciseChange = (searchResponse: ExerciseSearchResponse | null) => {
99
- if (searchResponse === null) {
98
+ const handleExerciseChange = (exercise: Exercise | null) => {
99
+ if (exercise === null) {
100
100
  return;
101
101
  }
102
102
 
103
- editSlotEntryQuery.mutate(SlotEntry.clone(props.slotEntry, { exerciseId: searchResponse.data.base_id }));
103
+ editSlotEntryQuery.mutate(SlotEntry.clone(props.slotEntry, { exerciseId: exercise.id! }));
104
104
  setEditExercise(false);
105
105
  };
106
106
 
@@ -6,6 +6,7 @@ import Grid from '@mui/material/Grid';
6
6
  import { WgerTextField } from "components/Common/forms/WgerTextField";
7
7
  import { LoadingPlaceholder } from "components/Core/LoadingWidget/LoadingWidget";
8
8
  import { NameAutocompleter } from "components/Exercises/Filter/NameAutcompleter";
9
+ import { Exercise } from "components/Exercises/models/exercise";
9
10
  import { useLanguageQuery } from "components/Exercises/queries";
10
11
  import { RIR_VALUES_SELECT } from "components/WorkoutRoutines/models/BaseConfig";
11
12
  import { LogEntryForm } from "components/WorkoutRoutines/models/WorkoutLog";
@@ -15,7 +16,6 @@ import { DateTime } from "luxon";
15
16
  import React, { useState } from 'react';
16
17
  import { useTranslation } from "react-i18next";
17
18
  import { getLanguageByShortName } from "services";
18
- import { ExerciseSearchResponse } from "services/responseType";
19
19
  import { REP_UNIT_REPETITIONS, SNACKBAR_AUTO_HIDE_DURATION } from "utils/consts";
20
20
  import * as yup from "yup";
21
21
 
@@ -96,11 +96,11 @@ export const SessionLogsForm = ({ dayId, routineId, selectedDate }: SessionLogsF
96
96
  setSnackbarOpen(true);
97
97
  };
98
98
 
99
- const handleCallback = async (exerciseResponse: ExerciseSearchResponse | null, formik: FormikProps<{
99
+ const handleCallback = async (exercise: Exercise | null, formik: FormikProps<{
100
100
  logs: LogEntryForm[]
101
101
  }>) => {
102
102
 
103
- if (exerciseResponse === null) {
103
+ if (exercise === null) {
104
104
  return;
105
105
  }
106
106
 
@@ -115,7 +115,7 @@ export const SessionLogsForm = ({ dayId, routineId, selectedDate }: SessionLogsF
115
115
  repetitionsTarget: '',
116
116
  rir: '',
117
117
  rirTarget: '',
118
- exercise: exerciseResponse.exercise!,
118
+ exercise: exercise,
119
119
  };
120
120
  }
121
121
  return log;
@@ -1,12 +1,12 @@
1
1
  import axios from 'axios';
2
+ import { Exercise, ExerciseAdapter } from "components/Exercises/models/exercise";
2
3
  import { Translation, TranslationAdapter } from "components/Exercises/models/translation";
3
4
  import { ENGLISH_LANGUAGE_CODE, LANGUAGE_SHORT_ENGLISH } from "utils/consts";
4
5
  import { makeHeader, makeUrl } from "utils/url";
5
- import { ExerciseSearchResponse, ExerciseSearchType, ResponseType } from "./responseType";
6
+ import { ResponseType } from "./responseType";
6
7
 
7
8
  export const EXERCISE_PATH = 'exercise';
8
9
  export const EXERCISE_TRANSLATION_PATH = 'exercise-translation';
9
- export const EXERCISE_SEARCH_PATH = 'exercise/search';
10
10
 
11
11
 
12
12
  /*
@@ -15,7 +15,7 @@ export const EXERCISE_SEARCH_PATH = 'exercise/search';
15
15
  export const getExerciseTranslations = async (id: number): Promise<Translation[]> => {
16
16
  const url = makeUrl(EXERCISE_PATH, { query: { exercise: id } });
17
17
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
- const { data } = await axios.get<ResponseType<any>>(url, {
18
+ const { data } = await axios.get<ResponseType<Translation>>(url, {
19
19
  headers: makeHeader(),
20
20
  });
21
21
  const adapter = new TranslationAdapter();
@@ -24,19 +24,34 @@ export const getExerciseTranslations = async (id: number): Promise<Translation[]
24
24
 
25
25
 
26
26
  /*
27
- * Fetch all exercise translations for a given exercise base
27
+ * Search for exercises by name using the exerciseinfo endpoint
28
28
  */
29
- export const searchExerciseTranslations = async (name: string, languageCode: string = ENGLISH_LANGUAGE_CODE, searchEnglish: boolean = true,): Promise<ExerciseSearchResponse[]> => {
29
+ export const searchExerciseTranslations = async (name: string,languageCode: string = ENGLISH_LANGUAGE_CODE,searchEnglish: boolean = true): Promise<Exercise[]> => {
30
30
  const languages = [languageCode];
31
31
  if (languageCode !== LANGUAGE_SHORT_ENGLISH && searchEnglish) {
32
32
  languages.push(LANGUAGE_SHORT_ENGLISH);
33
33
  }
34
34
 
35
+ const url = makeUrl('exerciseinfo', {
36
+ query: {
37
+ name__search: name,
38
+ language__code: languages.join(','),
39
+ limit: 50,
40
+ }
41
+ });
35
42
 
36
- const url = makeUrl(EXERCISE_SEARCH_PATH, { query: { term: name, language: languages.join(',') } });
37
-
38
- const { data } = await axios.get<ExerciseSearchType>(url);
39
- return data.suggestions;
43
+ try {
44
+ const { data } = await axios.get<ResponseType<Exercise>>(url);
45
+
46
+ if (!data || !data.results || !Array.isArray(data.results)) {
47
+ return [];
48
+ }
49
+
50
+ const adapter = new ExerciseAdapter();
51
+ return data.results.map((item: unknown) => adapter.fromJson(item));
52
+ } catch {
53
+ return [];
54
+ }
40
55
  };
41
56
 
42
57
 
@@ -1,35 +1,9 @@
1
- import { Exercise } from "components/Exercises/models/exercise";
2
-
1
+ /*
2
+ * Generic paginated response from the wger API
3
+ */
3
4
  export interface ResponseType<T> {
4
5
  count: number,
5
6
  next: number | null,
6
7
  previous: number | null,
7
8
  results: T[]
8
9
  }
9
-
10
- export interface ExerciseSearchResponse {
11
- value: string,
12
- data: {
13
- id: number,
14
- base_id: number,
15
- name: string,
16
- category: string,
17
- image: string | null,
18
- image_thumbnail: string | null,
19
- },
20
- exercise?: Exercise
21
- }
22
-
23
- export interface ExerciseSearchType {
24
- suggestions: ExerciseSearchResponse[];
25
- }
26
-
27
- export interface IngredientSearchResponse {
28
- value: string,
29
- data: {
30
- id: number,
31
- name: string,
32
- image: string | null,
33
- image_thumbnail: string | null,
34
- }
35
- }
@@ -1,23 +1,48 @@
1
- export const searchResponse = [
2
- {
3
- "value": "Crunches an Negativbank",
4
- "data": {
5
- "id": 1149,
6
- "base_id": 998,
7
- "name": "Crunches an Negativbank",
8
- "category": "Bauch",
9
- "image": null,
10
- "image_thumbnail": null
11
- }
12
- }, {
13
- "value": "Crunches am Seil",
14
- "data": {
15
- "id": 1213,
16
- "base_id": 979,
17
- "name": "Crunches am Seil",
18
- "category": "Brust",
19
- "image": null,
20
- "image_thumbnail": null
21
- }
22
- }
1
+ import { Exercise } from "components/Exercises/models/exercise";
2
+ import { Category } from "components/Exercises/models/category";
3
+ import { Translation } from "components/Exercises/models/translation";
4
+
5
+ export const searchResponse: Exercise[] = [
6
+ new Exercise(
7
+ 998, // id
8
+ "uuid-998", // uuid
9
+ new Category(8, "Bauch"), // category
10
+ [], // equipment
11
+ [], // muscles
12
+ [], // musclesSecondary
13
+ [], // images
14
+ null, // variationId
15
+ [
16
+ new Translation(
17
+ 1149, // id
18
+ "uuid-1149", // uuid
19
+ "Crunches an Negativbank", // name
20
+ "", // description
21
+ 1 // language (German)
22
+ )
23
+ ], // translations
24
+ [], // videos
25
+ [] // authors
26
+ ),
27
+ new Exercise(
28
+ 979, // id
29
+ "uuid-979", // uuid
30
+ new Category(11, "Brust"), // category
31
+ [], // equipment
32
+ [], // muscles
33
+ [], // musclesSecondary
34
+ [], // images
35
+ null, // variationId
36
+ [
37
+ new Translation(
38
+ 1213, // id
39
+ "uuid-1213", // uuid
40
+ "Crunches am Seil", // name
41
+ "", // description
42
+ 1 // language (German)
43
+ )
44
+ ], // translations
45
+ [], // videos
46
+ [] // authors
47
+ )
23
48
  ];