Exercises filter by name

This commit is contained in:
AG
2025-11-26 22:18:42 +02:00
parent 85a351ea4e
commit 53d11c6665
2 changed files with 17 additions and 0 deletions

View File

@@ -46,6 +46,7 @@ const Profile: React.FC<ProfileProps> = ({ user, onLogout, lang, onLanguageChang
const [showArchived, setShowArchived] = useState(false); const [showArchived, setShowArchived] = useState(false);
const [editingExercise, setEditingExercise] = useState<ExerciseDef | null>(null); const [editingExercise, setEditingExercise] = useState<ExerciseDef | null>(null);
const [isCreatingEx, setIsCreatingEx] = useState(false); const [isCreatingEx, setIsCreatingEx] = useState(false);
const [exerciseNameFilter, setExerciseNameFilter] = useState('');
const exerciseTypeLabels: Record<ExerciseType, string> = { const exerciseTypeLabels: Record<ExerciseType, string> = {
[ExerciseType.STRENGTH]: t('type_strength', lang), [ExerciseType.STRENGTH]: t('type_strength', lang),
@@ -282,6 +283,17 @@ const Profile: React.FC<ProfileProps> = ({ user, onLogout, lang, onLanguageChang
<Plus size={16} /> {t('create_exercise', lang)} <Plus size={16} /> {t('create_exercise', lang)}
</button> </button>
<div className="bg-surface-container-high rounded-t-lg border-b border-outline-variant px-3 py-2">
<label className="text-[10px] text-on-surface-variant font-medium">{t('filter_by_name', lang) || 'Filter by name'}</label>
<input
type="text"
value={exerciseNameFilter}
onChange={(e) => setExerciseNameFilter(e.target.value)}
placeholder={t('type_to_filter', lang) || 'Type to filter...'}
className="w-full bg-transparent text-on-surface focus:outline-none"
/>
</div>
<div className="flex items-center justify-end gap-2"> <div className="flex items-center justify-end gap-2">
<label className="text-xs text-on-surface-variant">{t('show_archived', lang)}</label> <label className="text-xs text-on-surface-variant">{t('show_archived', lang)}</label>
<input <input
@@ -295,6 +307,7 @@ const Profile: React.FC<ProfileProps> = ({ user, onLogout, lang, onLanguageChang
<div className="space-y-2"> <div className="space-y-2">
{exercises {exercises
.filter(e => showArchived || !e.isArchived) .filter(e => showArchived || !e.isArchived)
.filter(e => e.name.toLowerCase().includes(exerciseNameFilter.toLowerCase()))
.sort((a, b) => a.name.localeCompare(b.name)) .sort((a, b) => a.name.localeCompare(b.name))
.map(ex => ( .map(ex => (
<div key={ex.id} className={`p-3 rounded-lg flex justify-between items-center border border-outline-variant/20 ${ex.isArchived ? 'bg-surface-container-low opacity-60' : 'bg-surface-container-high'}`}> <div key={ex.id} className={`p-3 rounded-lg flex justify-between items-center border border-outline-variant/20 ${ex.isArchived ? 'bg-surface-container-low opacity-60' : 'bg-surface-container-high'}`}>

View File

@@ -153,6 +153,8 @@ const translations = {
archive: 'Archive', archive: 'Archive',
unarchive: 'Unarchive', unarchive: 'Unarchive',
show_archived: 'Show Archived', show_archived: 'Show Archived',
filter_by_name: 'Filter by name',
type_to_filter: 'Type to filter...',
profile_saved: 'Profile saved successfully', profile_saved: 'Profile saved successfully',
}, },
ru: { ru: {
@@ -300,6 +302,8 @@ const translations = {
archive: 'Архив', archive: 'Архив',
unarchive: 'Вернуть', unarchive: 'Вернуть',
show_archived: 'Показать архивные', show_archived: 'Показать архивные',
filter_by_name: 'Фильтр по названию',
type_to_filter: 'Введите для фильтрации...',
profile_saved: 'Профиль успешно сохранен', profile_saved: 'Профиль успешно сохранен',
} }
}; };