Skip to content

Commit 3dd3641

Browse files
committed
feat: enhance exercise filtering to include muscle search capability
1 parent 6926f3d commit 3dd3641

3 files changed

Lines changed: 18 additions & 5 deletions

File tree

frontend/components/exerciseView/hooks/useExerciseFilters.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ExerciseStats } from '../../../types';
33
import { analyzeExerciseTrendCore, ExerciseTrendStatus, summarizeExerciseHistory } from '../../../utils/analysis/exerciseTrend';
44
import type { ExerciseTrendMode } from '../../../utils/storage/localStorage';
55
import { analyzeExerciseTrend, type StatusResult } from '../trend/exerciseTrendUi';
6+
import type { ExerciseMuscleData } from '../../../utils/muscle/mapping';
67

78
export type ExerciseListSortMode = 'recent' | 'trend';
89

@@ -40,13 +41,15 @@ export interface UseExerciseFiltersProps {
4041
weightUnit: 'kg' | 'lbs';
4142
exerciseTrendMode: ExerciseTrendMode;
4243
effectiveNow: Date;
44+
muscleDataMap?: Map<string, ExerciseMuscleData>;
4345
}
4446

4547
export function useExerciseFilters({
4648
stats,
4749
weightUnit,
4850
exerciseTrendMode,
4951
effectiveNow,
52+
muscleDataMap,
5053
}: UseExerciseFiltersProps): UseExerciseFiltersReturn {
5154
const [searchTerm, setSearchTerm] = useState('');
5255
const [trendFilter, setTrendFilter] = useState<ExerciseTrendStatus | null>(null);
@@ -149,7 +152,16 @@ export function useExerciseFilters({
149152
// Filtered and sorted exercises
150153
const filteredExercises = useMemo(() =>
151154
stats
152-
.filter(s => s.name.toLowerCase().includes(searchTerm.toLowerCase()))
155+
.filter(s => {
156+
const term = searchTerm.toLowerCase();
157+
if (s.name.toLowerCase().includes(term)) return true;
158+
const m = muscleDataMap?.get(s.name.toLowerCase());
159+
if (!m) return false;
160+
return (
161+
(m.primary_muscle && m.primary_muscle.toLowerCase().includes(term)) ||
162+
(m.secondary_muscle && m.secondary_muscle.toLowerCase().includes(term))
163+
);
164+
})
153165
.filter(s => {
154166
if (!trendFilter) return true;
155167
if (!trainingStructure.eligibleNames.has(s.name)) return false;

frontend/components/exerciseView/ui/ExerciseListPanel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ export const ExerciseListPanel: React.FC<ExerciseListPanelProps> = ({
9898
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-slate-500" />
9999
<input
100100
type="text"
101-
placeholder="Search for exercises..."
101+
placeholder="Search exercises or muscles..."
102102
className="w-full bg-black/20 border border-slate-700/50 rounded-lg pl-9 pr-[8.5rem] py-1 sm:py-2 text-[11px] sm:text-xs text-slate-200 focus:outline-none focus:border-transparent transition-all"
103103
value={searchTerm}
104104
onChange={(e) => setSearchTerm(e.target.value)}

frontend/components/exerciseView/ui/ExerciseView.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ export const ExerciseView: React.FC<ExerciseViewProps> = ({
5959
// Calculate user's training level for personalized volume thresholds
6060
const { trainingLevel } = useTrainingLevel(filteredData, effectiveNow);
6161

62+
const [assetsMap, setAssetsMap] = useState<Map<string, ExerciseAsset> | null>(null);
63+
const [exerciseMuscleData, setExerciseMuscleData] = useState<Map<string, ExerciseMuscleData>>(new Map());
64+
6265
const {
6366
searchTerm,
6467
setSearchTerm,
@@ -82,6 +85,7 @@ export const ExerciseView: React.FC<ExerciseViewProps> = ({
8285
weightUnit: weightUnit ?? 'kg',
8386
exerciseTrendMode,
8487
effectiveNow,
88+
muscleDataMap: exerciseMuscleData,
8589
});
8690

8791
const {
@@ -95,9 +99,6 @@ export const ExerciseView: React.FC<ExerciseViewProps> = ({
9599
defaultExerciseName: filteredExercises[0]?.name ?? '',
96100
});
97101

98-
const [assetsMap, setAssetsMap] = useState<Map<string, ExerciseAsset> | null>(null);
99-
const [exerciseMuscleData, setExerciseMuscleData] = useState<Map<string, ExerciseMuscleData>>(new Map());
100-
101102
const assetLookup = useMemo<ExerciseAssetLookup | null>(() => {
102103
if (!assetsMap) return null;
103104
return createExerciseAssetLookup(assetsMap);

0 commit comments

Comments
 (0)