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

wger-project / react / 25595441085

09 May 2026 07:32AM UTC coverage: 78.159% (+0.007%) from 78.152%
25595441085

push

github

rolandgeider
Refactor the image upload workflow

We now show the image form first and then allow users to upload the new image,
which can now be done via drag-and-drop

2235 of 3149 branches covered (70.97%)

Branch coverage included in aggregate %.

21 of 34 new or added lines in 4 files covered. (61.76%)

1 existing line in 1 file now uncovered.

4836 of 5898 relevant lines covered (81.99%)

33.21 hits per line

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

68.97
/src/components/Exercises/forms/ImageCard.tsx
1
import AddCircleIcon from '@mui/icons-material/AddCircle';
2
import { Box, Button, Card, CardActions, CardMedia } from "@mui/material";
3
import { FormQueryErrorsSnackbar } from "@/core/ui/Widgets/FormError";
4
import { ImageFormModal } from "@/components/Exercises/forms/ImageModal";
5
import { ImageFormData } from "@/components/Exercises/models/exercise";
6
import { ExerciseImage, ImageStyle } from "@/components/Exercises/models/image";
7
import { useAddExerciseImageQuery, useDeleteExerciseImageQuery } from "@/components/Exercises/queries";
8
import React, { useState } from "react";
9
import { useTranslation } from "react-i18next";
10

11
type ImageCardProps = {
12
    exerciseId: number;
13
    image: ExerciseImage;
14
    canDelete: boolean
15
    onEdit: (image: ExerciseImage) => void;
16
};
17

18
export const ImageEditCard = ({ exerciseId, image, canDelete, onEdit }: ImageCardProps) => {
22✔
19
    const [t] = useTranslation();
4✔
20
    const deleteImageQuery = useDeleteExerciseImageQuery(exerciseId);
4✔
21

22
    return <Card>
4✔
23
        <CardMedia
24
            component="img"
25
            image={image.url}
26
            sx={{ height: 120 }}
27
            alt=""
28
        />
29
        <CardActions style={{ justifyContent: 'space-between' }}>
30
            {canDelete &&
8✔
31
                <Button
32
                    color="primary"
33
                    onClick={() => deleteImageQuery.mutate(image.id)}
×
34
                >
35
                    {t('delete')}
36
                </Button>}
37
            {canDelete &&
8✔
38
                <Button
39
                    color="primary"
40
                    onClick={() => onEdit(image)}
1✔
41
                    data-testid={`edit-image-${image.id}`}
42
                >
43
                    {t('edit')}
44
                </Button>
45
            }
46
        </CardActions>
47
    </Card>;
48
};
49

50
type AddImageCardProps = {
51
    exerciseId: number;
52
};
53

54
const emptyImageFormData = (): ImageFormData => ({
22✔
55
    url: '',
56
    file: undefined,
57
    author: '',
58
    authorUrl: '',
59
    title: '',
60
    objectUrl: '',
61
    derivativeSourceUrl: '',
62
    style: ImageStyle.PHOTO,
63
    isAi: false,
64
});
65

66
export const AddImageCard = ({ exerciseId }: AddImageCardProps) => {
22✔
67

68
    const [t] = useTranslation();
6✔
69
    const addImageQuery = useAddExerciseImageQuery();
6✔
70

71
    const [openModal, setOpenModal] = useState(false);
6✔
72

73
    const handleSubmit = (values: ImageFormData) => {
6✔
74
        if (!values.file) {
×
75
            return;
×
76
        }
77
        addImageQuery.mutate({
×
78
            exerciseId: exerciseId,
79
            image: values.file,
80
            imageData: values,
81
        });
NEW
82
        setOpenModal(false);
×
83
    };
84

85
    return <>
6✔
86
        <Card>
87
            <CardMedia>
88
                <Box sx={{
89
                    backgroundColor: "lightgray",
90
                    height: 120,
91
                    display: "flex",
92
                    alignItems: "center",
93
                    justifyContent: "center"
94
                }}>
95
                    <AddCircleIcon sx={{ fontSize: 80, color: "gray" }} />
96
                </Box>
97
            </CardMedia>
98
            <CardActions>
99
                <Button onClick={() => setOpenModal(true)}>
1✔
100
                    {t('add')}
101
                </Button>
102
            </CardActions>
103
        </Card>
104
        <ImageFormModal
105
            open={openModal}
NEW
106
            onClose={() => setOpenModal(false)}
×
107
            image={openModal ? emptyImageFormData() : null}
6✔
108
            onSubmit={handleSubmit}
109
            submitLabel={t('add')}
110
        />
111
        {addImageQuery.isError &&
6!
112
            <FormQueryErrorsSnackbar mutationQuery={addImageQuery} />
113
        }
114
    </>;
115
};
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

© 2026 Coveralls, Inc