feat: add search functionality for formulas by name and tags

This commit is contained in:
Álvaro González 2025-09-22 10:42:43 +02:00 committed by Álvaro González (aider)
parent 00eb595d2d
commit 88f55a1e32

View file

@ -3,7 +3,7 @@ import 'package:d4rt_formulas/formula_models.dart';
import '../corpus.dart'; import '../corpus.dart';
import 'formula_screen.dart'; import 'formula_screen.dart';
class FormulaList extends StatelessWidget { class FormulaList extends StatefulWidget {
final Corpus corpus; final Corpus corpus;
final List<Formula> formulas; final List<Formula> formulas;
@ -13,27 +13,84 @@ class FormulaList extends StatelessWidget {
required this.formulas, required this.formulas,
}); });
@override
State<FormulaList> createState() => _FormulaListState();
}
class _FormulaListState extends State<FormulaList> {
final TextEditingController _searchController = TextEditingController();
String _searchQuery = '';
@override
void initState() {
super.initState();
_searchController.addListener(_onSearchChanged);
}
void _onSearchChanged() {
setState(() {
_searchQuery = _searchController.text.toLowerCase();
});
}
@override
void dispose() {
_searchController.dispose();
super.dispose();
}
List<Formula> get _filteredFormulas {
if (_searchQuery.isEmpty) return widget.formulas;
return widget.formulas.where((formula) {
final nameMatch = formula.name.toLowerCase().contains(_searchQuery);
final tagMatch = formula.tags.any((tag) => tag.toLowerCase().contains(_searchQuery));
return nameMatch || tagMatch;
}).toList();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ListView.builder( return Column(
itemCount: formulas.length, children: [
itemBuilder: (context, index) { Padding(
final formula = formulas[index]; padding: const EdgeInsets.all(16.0),
return ListTile( child: TextField(
title: Text(formula.name), controller: _searchController,
onTap: () { decoration: const InputDecoration(
Navigator.push( labelText: 'Search formulas',
context, hintText: 'Search by name or tag...',
MaterialPageRoute( prefixIcon: Icon(Icons.search),
builder: (context) => FormulaScreen( border: OutlineInputBorder(),
formula: formula, ),
corpus: corpus, ),
), ),
), Expanded(
); child: ListView.builder(
}, itemCount: _filteredFormulas.length,
); itemBuilder: (context, index) {
}, final formula = _filteredFormulas[index];
return ListTile(
title: Text(formula.name),
subtitle: formula.tags.isNotEmpty
? Text('Tags: ${formula.tags.join(', ')}')
: null,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => FormulaScreen(
formula: formula,
corpus: widget.corpus,
),
),
);
},
);
},
),
),
],
); );
} }
} }