Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions src/components/Calendar/Components/CalendarComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export interface DayProps {
const CalendarComponent = (props: { isStandalone?: boolean }) => {
const [t] = useTranslation();

const currentDate = new Date();
const currentDate = useMemo(() => new Date(), []);
const [currentMonth, setCurrentMonth] = useState(currentDate.getMonth());
const [currentYear, setCurrentYear] = useState(currentDate.getFullYear());

Expand Down Expand Up @@ -133,7 +133,7 @@ const CalendarComponent = (props: { isStandalone?: boolean }) => {
setSelectedDay(todayWithData);
}
}
}, [isSuccess]);
}, [currentDate, days, isSuccess]);


useEffect(() => {
Expand Down Expand Up @@ -246,4 +246,4 @@ const CalendarComponent = (props: { isStandalone?: boolean }) => {
);
};

export default CalendarComponent;
export default CalendarComponent;
10 changes: 5 additions & 5 deletions src/components/Calendar/Components/CalendarDayGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ const CalendarDayGrid: React.FC<CalendarDayGridProps> = ({

return (
<Grid container spacing={1} rowSpacing={2}>
{weekDays.map((day, index) => (
<Grid size={12 / 7} key={`weekday-${index}`}>
{weekDays.map((day) => (
<Grid size={12 / 7} key={`weekday-${day}`}>
<Typography variant="body1" sx={{ fontWeight: 'bold', textAlign: 'center' }}>
{day}
</Typography>
</Grid>
))}

{days.map((day, index) => (
<Grid size={12 / 7} key={`day-${index}`} sx={{ display: 'flex', justifyContent: 'center' }}>
{days.map((day) => (
<Grid size={12 / 7} key={`day-${day.date.toISOString()}`} sx={{ display: 'flex', justifyContent: 'center' }}>
<CalendarDay
day={day}
currentMonth={currentMonth}
Expand All @@ -50,4 +50,4 @@ const CalendarDayGrid: React.FC<CalendarDayGridProps> = ({
);
};

export default CalendarDayGrid;
export default CalendarDayGrid;
6 changes: 3 additions & 3 deletions src/components/Calendar/Components/Entries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ const Entries: React.FC<LogProps> = ({ selectedDay, isStandalone }) => {
</ListItem>
<Collapse in={openMeasurements} timeout="auto" unmountOnExit>
<List sx={{ pl: 4, pt: 0 }}>
{selectedDay.measurements.map((measurement, key) => (
<ListItem key={key} dense>
{selectedDay.measurements.map((measurement) => (
<ListItem key={`${measurement.date.toISOString()}-${measurement.name}-${measurement.unit}`} dense>
<ListItemText
primary={measurement.name}
secondary={`${measurement.value} ${measurement.unit}`}
Expand Down Expand Up @@ -169,4 +169,4 @@ const Entries: React.FC<LogProps> = ({ selectedDay, isStandalone }) => {
);
};

export default Entries;
export default Entries;
6 changes: 4 additions & 2 deletions src/components/Dashboard/RoutineCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,13 @@ const DayListItem = (props: { dayData: RoutineDayData }) => {

<Collapse in={expandView} timeout="auto" unmountOnExit>
{props.dayData.slots.map((slotData, index) => (
// The API doesn't expose an id for the slots and they are not reordered here
// eslint-disable-next-line @eslint-react/no-array-index-key
<div key={index}>
{slotData.setConfigs.map((setConfigData, index) => (
{slotData.setConfigs.map((setConfigData) => (
<SetConfigDataDetails
setConfigData={setConfigData}
key={index}
key={`set-config-${setConfigData.slotEntryId}-${setConfigData.exerciseId}`}
rowHeight={"70px"}
showExercise={true}
/>
Expand Down
24 changes: 18 additions & 6 deletions src/components/Exercises/forms/ExerciseAliases.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,22 @@ export function ExerciseAliases(props: { fieldName: string }) {
const [t] = useTranslation();
const [field, meta, helpers] = useField<AliasItem[]>(props.fieldName);

const normalize = (items: (AliasItem | string)[] | null | undefined): AliasItem[] =>
(items || []).map(item =>
typeof item === "string" ? { alias: item } : ("alias" in item ? (item as AliasItem) : { alias: String(item) })
);
const normalize = (items: (AliasItem | string)[] | null | undefined): AliasItem[] => {
const seen = new Set<string>();

return (items || [])
.map(item =>
typeof item === "string" ? { alias: item } : ("alias" in item ? (item as AliasItem) : { alias: String(item) })
)
.filter(item => {
if (seen.has(item.alias)) {
return false;
}
seen.add(item.alias);

return true;
});
};

/**
* Extract a human-readable error string from the Yup alias validator, which
Expand Down Expand Up @@ -68,7 +80,7 @@ export function ExerciseAliases(props: { fieldName: string }) {
newVal.splice(index, 1);
helpers.setValue(newVal);
}}
key={option.id ?? `${option.alias}-${index}`}
key={option.id ?? option.alias}
/>
));

Expand Down Expand Up @@ -98,4 +110,4 @@ export function ExerciseAliases(props: { fieldName: string }) {
);
}}
/>;
}
}
10 changes: 7 additions & 3 deletions src/components/Exercises/forms/ExerciseNotes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ import DeleteIcon from '@mui/icons-material/Delete';
import { IconButton, InputAdornment, TextField } from "@mui/material";
import Grid from '@mui/material/Grid';
import { useField } from "formik";
import React, { useState } from "react";
import React, { useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { randomUUID } from "@/core/lib/uuid";

export function ExerciseNotes(props: { fieldName: string }) {
const [t] = useTranslation();
const [field, meta, helpers] = useField(props.fieldName);
const [newNoteValue, setNewNoteValue] = useState<string>('');
const noteKeys = useRef<string[]>(field.value.map(() => randomUUID()));

const deleteAtIndex = (index: number) => {
noteKeys.current.splice(index, 1);
helpers.setValue(field.value.filter((_: string, b: number) => b !== index));
};

Expand All @@ -20,6 +23,7 @@ export function ExerciseNotes(props: { fieldName: string }) {
helpers.setValue(field.value);
};
const addEntry = () => {
noteKeys.current.push(randomUUID());
field.value.push(newNoteValue);
helpers.setValue(field.value);
setNewNoteValue('');
Expand Down Expand Up @@ -51,7 +55,7 @@ export function ExerciseNotes(props: { fieldName: string }) {
</Grid>
{field.value.map((note: string, index: number) =>
<TextField
key={index}
key={noteKeys.current[index]}
fullWidth
value={note}
onChange={(event) => setNoteValueIndex(index, event.target.value)}
Expand All @@ -73,4 +77,4 @@ export function ExerciseNotes(props: { fieldName: string }) {
/>
)}
</>;
}
}
3 changes: 2 additions & 1 deletion src/components/Exercises/forms/Variation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState } from "react";
import { VariationSelect } from "@/components/Exercises/forms/VariationSelect";
import { useEditExerciseQuery } from "@/components/Exercises/queries";
import { useProfileQuery } from "@/components/User";
import { randomUUID } from "@/core/lib/uuid";

export function EditExerciseVariation(props: { exerciseId: number, initial: string | null }) {
const [selectedVariationId, setSelectedVariationId] = useState<string | null>(props.initial);
Expand Down Expand Up @@ -31,7 +32,7 @@ export function EditExerciseVariation(props: { exerciseId: number, initial: stri

if (id !== null) {
// Generate a new variation group UUID and assign both exercises to it
const variationGroup = crypto.randomUUID();
const variationGroup = randomUUID();
try {
await editMutation.mutateAsync({
id: props.exerciseId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export const ExerciseDetailView = ({
</>}

<Typography variant="h5">{t("exercises.description")}</Typography>
<div dangerouslySetInnerHTML={{ __html: currentTranslation?.description! }} />
<div dangerouslySetInnerHTML={{ __html: currentTranslation?.description ?? "" }} />
<PaddingBox />

{currentTranslation?.notes.length > 0 && <Typography variant="h5">{t("exercises.notes")}</Typography>}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Exercises/screens/Detail/Head/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export interface HeadProp {
languages: Language[]
changeLanguage: (lang: Language) => void,
language: Language | undefined // language displayed in the head since it's not found in the translations
setEditMode: Function,
setEditMode: (editMode: boolean) => void,
editMode: boolean
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import React from "react";

export const ExerciseGridSkeleton = () => {

const skeletonIds = Array.from({ length: 21 }, (_, id) => `exercise-skeleton-${id + 1}`);

return (
(<Grid container spacing={1}>
{[...Array(21)].map((skeletonBase, idx) => (
<Grid key={idx} sx={{ display: "flex" }} size={4}>
{skeletonIds.map((skeletonId) => (
<Grid key={skeletonId} sx={{ display: "flex" }} size={4}>
<Card>
<CardMedia>
<Skeleton variant="rectangular" width={250} height={150} />
Expand Down
4 changes: 2 additions & 2 deletions src/components/Nutrition/screens/BmiCalculator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export const BmiCalculator = () => {
/>
<CartesianGrid strokeDasharray="3 3" />
<Tooltip
// @ts-ignore
// @ts-expect-error -- Recharts exposes broader formatter value types than this chart accepts.
formatter={(value, name) => [Math.round(value as number), t('bmi.' + (name as string))]}
/>

Expand Down Expand Up @@ -202,4 +202,4 @@ export const BmiCalculator = () => {
</>}
/>
);
};
};
8 changes: 4 additions & 4 deletions src/components/Nutrition/widgets/DiaryOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const DiaryOverview = (props: {
</TableRow>
</TableHead>
<TableBody>
{Array.from(props.logged).map(([key]) =>
{Array.from(props.logged).map(([key, diaryEntries]) =>
<TableRow key={key}>
<TableCell>
<Link
Expand All @@ -37,15 +37,15 @@ export const DiaryOverview = (props: {
</TableCell>
<TableCell align="right">
{t('nutrition.valueEnergyKcal',
{ value: numberLocale(props.logged.get(key)?.nutritionalValues.energy!, i18n.language) }
{ value: numberLocale(diaryEntries.nutritionalValues.energy, i18n.language) }
)}
</TableCell>
<TableCell align="right">
{numberLocale(props.logged.get(key)?.nutritionalValues.energy! - props.planned.energy, i18n.language)}
{numberLocale(diaryEntries.nutritionalValues.energy - props.planned.energy, i18n.language)}
</TableCell>
</TableRow>)
}
</TableBody>
</Table>
</TableContainer>;
};
};
4 changes: 2 additions & 2 deletions src/components/Nutrition/widgets/charts/MacrosPieChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ export const MacrosPieChart = (props: { data: NutritionalValues }) => {
fill="#8884d8"
dataKey="value"
>
{data.map((entry, index) => (
<Cell key={`cell-${index}`} fill={colorGenerator.next().value!} />
{data.map((entry) => (
<Cell key={`cell-${entry.name}`} fill={colorGenerator.next().value!} />
))}
</Pie>
{/*<Tooltip />*/}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ export const NutritionalValuesDashboardChart = (props: {
const [t, i18n] = useTranslation();
const data = [
{
id: 'logged',
name: '',
value: energyPercentage,
},
{
id: 'remaining',
name: '',
value: energyPercentage < 100 ? 100 - energyPercentage : 0,
},
Expand All @@ -46,7 +48,7 @@ export const NutritionalValuesDashboardChart = (props: {
dataKey="value"
>
{data.map((entry, index) => (
<Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
<Cell key={`cell-${entry.id}`} fill={COLORS[index % COLORS.length]} />
))}
</Pie>
<g>
Expand Down
3 changes: 2 additions & 1 deletion src/components/Routines/models/WorkoutLog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { WeightUnit } from "@/components/Routines/models/WeightUnit";
import { Adapter } from "@/core/lib/Adapter";

export interface LogEntryForm {
clientKey: string;
exercise: Exercise | null;
repetitionsUnit: RepetitionUnit | null;
weightUnit: WeightUnit | null;
Expand Down Expand Up @@ -159,4 +160,4 @@ export class WorkoutLogAdapter implements Adapter<WorkoutLog> {
rest: item.restTime,
rest_target: item.restTimeTarget
});
}
}
6 changes: 3 additions & 3 deletions src/components/Routines/screens/Detail/WorkoutStats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ export const WorkoutStats = () => {
{statsData.data.map((row) => (
<TableRow key={row.key}>
<TableCell>{row.key}</TableCell>
{row.values.map((value, index) => (
{statsData.headers.map((header, index) => (
<TableCell
key={index}
key={header}
sx={{ textAlign: 'right', }}
>{value?.toFixed(selectedValueType === StatType.Intensity ? 2 : 0) || ""}
>{row.values[index]?.toFixed(selectedValueType === StatType.Intensity ? 2 : 0) || ""}
</TableCell>
))}
</TableRow>
Expand Down
4 changes: 3 additions & 1 deletion src/components/Routines/widgets/RoutineDetailsCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ function SlotDataList(props: { slotData: SlotData }) {
return <SetConfigDataDetails
setConfigData={setConfig}
marginBottom="1em"
key={index}
key={`set-config-${setConfig.slotEntryId}-${setConfig.exerciseId}`}
showExercise={showExercise}
/>;
})}
Expand Down Expand Up @@ -248,6 +248,8 @@ export const DayDetailsCard = (props: {
{slotData.length > 0 && <CardContent sx={{ padding: 0, marginBottom: 0 }}>
<Stack>
{slotData.map((slotData, index) => (
// The API doesn't expose an id for the slots and they are not reordered here
// eslint-disable-next-line @eslint-react/no-array-index-key
<div key={index}>
<Box sx={{ padding: 1 }}>
<SlotDataList slotData={slotData} />
Expand Down
6 changes: 3 additions & 3 deletions src/components/Routines/widgets/forms/BaseConfigForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,8 @@ export const ConfigDetailsRequirementsField = (props: {
open={Boolean(anchorEl)}
onClose={() => setAnchorEl(null)}
>
{...REQUIREMENTS_VALUES.map((e, index) => <MenuItem
key={index}
{...REQUIREMENTS_VALUES.map((e) => <MenuItem
key={e}
onClick={() => handleSelection(e as unknown as RequirementsType)}>
<ListItemIcon>
{selectedElements.includes(e as unknown as RequirementsType)
Expand Down Expand Up @@ -504,4 +504,4 @@ export const EntryDetailsStepField = (props: {
</>);
};

*/
*/
6 changes: 3 additions & 3 deletions src/components/Routines/widgets/forms/ProgressionForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ export const ProgressionForm = (props: {
{({ insert, remove }) => (<>

{formik.values.entries.map((log, index) => (
<React.Fragment key={index}>
<React.Fragment key={`progression-${log.iteration}`}>
<Grid size={2} sx={{
display: 'flex',
justifyContent: 'space-around',
Expand Down Expand Up @@ -453,8 +453,8 @@ export const ProgressionForm = (props: {
values={log.requirements}
fieldName={`entries.${index}.requirements`} />}
{log.requirements.length >= 0 && <br />}
{log.requirements.length >= 0 && log.requirements.map((requirement, index) => (
<Typography key={index} variant={'caption'}>
{log.requirements.length >= 0 && log.requirements.map((requirement) => (
<Typography key={JSON.stringify(requirement)} variant={'caption'}>
{requirement} &nbsp;
</Typography>
))}
Expand Down
Loading
Loading