• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wger-project / react / 15066523227

16 May 2025 10:36AM UTC coverage: 76.412%. First build
15066523227

Pull #1072

github

web-flow
Merge d99167029 into 02a87f6fe
Pull Request #1072: Better handling of dynamic translations

1345 of 1963 branches covered (68.52%)

Branch coverage included in aggregate %.

30 of 32 new or added lines in 12 files covered. (93.75%)

5377 of 6834 relevant lines covered (78.68%)

28.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.86
/src/components/Exercises/Detail/ExerciseDetailView.tsx
1
import { Box, Button, Divider, Typography } from "@mui/material";
6✔
2
import Grid from '@mui/material/Grid';
6✔
3
import { PaddingBox } from "components/Exercises/Detail/ExerciseDetails";
6✔
4
import { OverviewCard } from "components/Exercises/Detail/OverviewCard";
6✔
5
import { SideGallery, SideVideoGallery } from "components/Exercises/Detail/SideGallery";
6✔
6
import { Exercise } from "components/Exercises/models/exercise";
7
import { Language } from "components/Exercises/models/language";
8
import { Muscle } from "components/Exercises/models/muscle";
9
import { Note } from "components/Exercises/models/note";
10
import { MuscleOverview } from "components/Muscles/MuscleOverview";
6✔
11
import { useCanContributeExercises } from "components/User/queries/contribute";
6✔
12
import React from "react";
6✔
13
import { useTranslation } from "react-i18next";
6✔
14

15

16
const TranslateExerciseBanner = ({ setEditMode }: { setEditMode: (mode: boolean) => void }) => {
6✔
17
    const [t] = useTranslation();
2✔
18

19
    return (
2✔
20
        <Box
21
            mb={2}
22
            paddingY={2}
23
            sx={{
24
                width: "100%",
25
                backgroundColor: "#ebebeb",
26
                textAlign: "center",
27
            }}
28
        >
29
            <Typography variant={"h5"}>
30
                {t("exercises.exerciseNotTranslated")}
31
            </Typography>
32

33
            <Typography gutterBottom variant="body1" component="div">
34
                {t("exercises.exerciseNotTranslatedBody")}
35
            </Typography>
36

37
            <Button variant="contained" onClick={() => setEditMode(true)}>
×
38
                {t("exercises.translateExerciseNow")}
39
            </Button>
40

41
        </Box>
42
    );
43
};
44

45
export interface ViewProps {
46
    exercise: Exercise
47
    variations: Exercise[],
48
    language: Language,
49
    setEditMode: (mode: boolean) => void
50
}
51

52
export const ExerciseDetailView = ({
6✔
53
                                       exercise,
54
                                       variations,
55
                                       language,
56
                                       setEditMode
57
                                   }: ViewProps) => {
58
    const [t] = useTranslation();
7✔
59
    const contributeQuery = useCanContributeExercises();
7✔
60
    const currentTranslation = exercise.getTranslation(language);
7✔
61
    const isNewTranslation = language && language.id !== currentTranslation.language;
7✔
62

63
    return (
7✔
64
        <Grid container>
65
            {isNewTranslation
14✔
66
                && contributeQuery.canContribute
67
                && <Grid
68
                    order={{ xs: 2, sm: 1 }}
69
                    size={{
70
                        xs: 12,
71
                        sm: 7,
72
                        md: 12
73
                    }}>
74
                    <TranslateExerciseBanner setEditMode={setEditMode} />
75
                </Grid>
76
            }
77
            <Grid
78
                order={{ xs: 2, sm: 1 }}
79
                size={{
80
                    xs: 12,
81
                    sm: 7,
82
                    md: 8
83
                }}>
84

85
                {currentTranslation?.aliases.length > 0
7!
86
                    && <>
87
                        <p>
88
                            {t("exercises.alsoKnownAs")} &nbsp;
89
                            {currentTranslation?.aliases?.map(e => e.alias).join(", ")}
×
90
                        </p>
91
                        <PaddingBox />
92
                    </>}
93

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

99
                {currentTranslation?.notes.length > 0 && <Typography variant="h5">{t("exercises.notes")}</Typography>}
7!
100
                <ul>
101
                    {currentTranslation?.notes.map((note: Note) => (
102
                        <li key={note.id}>{note.note}</li>
×
103
                    ))}
104
                </ul>
105
                <PaddingBox />
106

107
                <Typography variant="h5">{t("exercises.muscles")}</Typography>
108
                <Grid container>
109
                    <Grid
110
                        order={{ xs: 1 }}
111
                        size={{
112
                            xs: 6,
113
                            md: 3
114
                        }}>
115
                        <MuscleOverview
116
                            primaryMuscles={exercise.muscles}
117
                            secondaryMuscles={exercise.musclesSecondary}
118
                            isFront={true}
119
                        />
120
                    </Grid>
121
                    <Grid
122
                        order={{ xs: 2, md: 3 }}
123
                        size={{
124
                            xs: 6,
125
                            md: 3
126
                        }}>
127
                        <h3>{t("exercises.primaryMuscles")}</h3>
128
                        <ul>
129
                            {exercise.muscles.map((m: Muscle) => (
130
                                <li key={m.id}>{m.getName()}</li>
10✔
131
                            ))}
132
                        </ul>
133
                    </Grid>
134

135
                    <Grid
136
                        order={{ xs: 3, md: 2 }}
137
                        size={{
138
                            xs: 6,
139
                            md: 3
140
                        }}>
141
                        <MuscleOverview
142
                            primaryMuscles={exercise.muscles}
143
                            secondaryMuscles={exercise.musclesSecondary}
144
                            isFront={false}
145
                        />
146
                    </Grid>
147

148

149
                    <Grid
150
                        order={{ xs: 4 }}
151
                        size={{
152
                            xs: 6,
153
                            md: 3
154
                        }}>
155
                        <h3>{t("exercises.secondaryMuscles")}</h3>
156
                        <ul>
157
                            {exercise.musclesSecondary.map((m: Muscle) => (
NEW
158
                                <li key={m.id}>{m.getName()}</li>
×
159
                            ))}
160
                        </ul>
161
                    </Grid>
162

163
                </Grid>
164
                <PaddingBox />
165
            </Grid>
166
            <Grid
167
                order={{ xs: 1, sm: 2 }}
168
                size={{
169
                    xs: 12,
170
                    sm: 5,
171
                    md: 4
172
                }}>
173
                { /*
174
                            <Carousel>
175
                                <CarouselItem>
176
                                    <img
177
                                        style={{width: "100%"}}
178
                                        src="https://images.unsplash.com/photo-1434682881908-b43d0467b798?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1174&q=80"
179
                                        alt="detail"
180
                                    />
181
                                </CarouselItem>
182
                                <CarouselItem>
183
                                    <img
184
                                        style={{width: "100%"}}
185
                                        src="https://images.unsplash.com/photo-1434682881908-b43d0467b798?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1174&q=80"
186
                                        alt="detail"
187
                                    />
188
                                </CarouselItem>
189
                                <CarouselItem>
190
                                    <img
191
                                        style={{width: "100%"}}
192
                                        src="https://images.unsplash.com/photo-1434682881908-b43d0467b798?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1174&q=80"
193
                                        alt="detail"
194
                                    />
195
                                </CarouselItem>
196
                            </Carousel>
197
                            */}
198

199
                {/* This gallery only displays on medium screens upwards */}
200
                <SideGallery
201
                    mainImage={exercise.mainImage}
202
                    sideImages={exercise.sideImages}
203
                />
204

205
                <PaddingBox />
206
                <SideVideoGallery videos={exercise.videos} />
207
            </Grid>
208

209

210
            <Grid order={{ xs: 3 }} size={12}>
211

212
                <Divider />
213
                <PaddingBox />
214

215
                {variations.length > 0 && <Typography variant={"h5"}>{t('exercises.variations')}</Typography>}
9✔
216
                <Grid container spacing={2}>
217
                    {variations.map((variation: Exercise) =>
218
                        <Grid
4✔
219
                            key={variation.id}
220
                            size={{
221
                                xs: 6,
222
                                md: 2
223
                            }}>
224
                            <OverviewCard
225
                                key={variation.id}
226
                                exercise={variation}
227
                                language={language}
228
                            />
229
                        </Grid>
230
                    )}
231
                </Grid>
232
            </Grid>
233
            <Grid order={{ xs: 4 }} size={12}>
234
                <Typography variant="caption" display="block" mt={2}>
235
                    The text on this page is available under the <a
236
                    href="https://creativecommons.org/licenses/by-sa/4.0/deed">CC BY-SA 4
237
                    License</a>.
238
                </Typography>
239
            </Grid>
240
        </Grid>
241
    );
242
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc