import AddIcon from '@mui/icons-material/Add'; import FilterListIcon from '@mui/icons-material/FilterList'; import { Box, Button, Container, Pagination, Stack, Typography, useMediaQuery, IconButton } from "@mui/material"; import Grid from '@mui/material/Grid'; import { CategoryFilter, CategoryFilterDropdown } from "@/components/Exercises/widgets/Filter/CategoryFilter"; import { EquipmentFilter, EquipmentFilterDropdown } from "@/components/Exercises/widgets/Filter/EquipmentFilter"; import { MuscleFilter, MuscleFilterDropdown } from "@/components/Exercises/widgets/Filter/MuscleFilter"; import { NameAutocompleter } from "@/components/Exercises/widgets/Filter/NameAutocompleter"; import { Category } from "@/components/Exercises/models/category"; import { Equipment } from "@/components/Exercises/models/equipment"; import { Exercise } from "@/components/Exercises/models/exercise"; import { Muscle } from "@/components/Exercises/models/muscle"; import { ExerciseGrid } from "@/components/Exercises/widgets/Overview/ExerciseGrid"; import { ExerciseGridSkeleton } from "@/components/Exercises/widgets/Overview/ExerciseGridLoadingSkeleton"; import { useExercisesQuery } from "@/components/Exercises/queries"; import React, { useContext, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { Link, useNavigate } from "react-router-dom"; import { makeLink, WgerLink } from "@/core/lib/url"; import { ExerciseFiltersContext } from '../widgets/Filter/ExerciseFiltersContext'; import { FilterDrawer } from '../widgets/Filter/FilterDrawer'; const ContributeExerciseBanner = () => { const [t, i18n] = useTranslation(); return ( {t("exercises.missingExercise")} {t("exercises.missingExerciseDescription")} {t("exercises.contributeExercise")} ); }; export const ExerciseOverviewList = () => { const exerciseQuery = useExercisesQuery(); const [t, i18n] = useTranslation(); const navigate = useNavigate(); const { selectedCategories, selectedEquipment, selectedMuscles } = useContext(ExerciseFiltersContext); const isMobile = useMediaQuery('(max-width:600px)'); const [page, setPage] = React.useState(1); const [showFilters, setShowFilters] = useState(() => { return localStorage.getItem("wger.exerciseSearch.showFilters") !== "false"; }); // eslint-disable-next-line @typescript-eslint/no-explicit-any const handlePageChange = (event: any, value: number) => { setPage(value); window.scrollTo({ top: 0, behavior: 'smooth' }); }; const filteredExercises = useMemo(() => { let filteredExercises = exerciseQuery.data || []; // Filter exercise bases by categories if (selectedCategories.length > 0) { filteredExercises = filteredExercises!.filter(exercise => { return selectedCategories.some( category => exercise.category.id === category.id ); }); } // Filter exercises that have one of the selected equipment if (selectedEquipment.length > 0) { filteredExercises = filteredExercises!.filter(exercise => { return exercise.equipment.some(equipment => selectedEquipment.some( selectedEquipment => selectedEquipment.id === equipment.id ) ); }); } // Filter exercises that have one of the selected muscles if (selectedMuscles.length > 0) { filteredExercises = filteredExercises!.filter(exercise => { return exercise.muscles.some(muscle => selectedMuscles.some(selectedMuscle => selectedMuscle.id === muscle.id) ); }); } return filteredExercises; }, [exerciseQuery.data, selectedCategories, selectedEquipment, selectedMuscles]); // Should be a multiple of three, since there are three columns in the grid const ITEMS_PER_PAGE = 21; // Pagination calculations const pageCount = Math.ceil(filteredExercises!.length / ITEMS_PER_PAGE); const paginatedExercises = filteredExercises!.slice( (page - 1) * ITEMS_PER_PAGE, page * ITEMS_PER_PAGE ); const exerciseAdded = (exercise: Exercise | null) => { if (!exercise) { return; } navigate(makeLink(WgerLink.EXERCISE_DETAIL, i18n.language, { id: exercise.id! })); }; return ( ( {t("exercises.exercises")} {isMobile ? ( <> ) : ( <> { const newValue = !showFilters; setShowFilters(newValue); localStorage.setItem("wger.exerciseSearch.showFilters", String(newValue)); }} title="Toggle filters" > )} {!isMobile && showFilters && ( )} {exerciseQuery.isLoading ? : <> } ) ); }; export const ExerciseOverview = () => { const [selectedEquipment, setSelectedEquipment] = useState([]); const [selectedMuscles, setSelectedMuscles] = useState([]); const [selectedCategories, setSelectedCategories] = React.useState([]); return ( ); };