From 2085f010f148157616ceace3df2a1191f589a9d8 Mon Sep 17 00:00:00 2001 From: Odweta Date: Mon, 23 Mar 2026 11:06:39 +0100 Subject: [PATCH] added prototype of the filter bar + all quotes count --- frontend/lib/pages/list.dart | 185 +++++++++++++----- frontend/lib/provider/quote_provider.dart | 6 + .../lib/repository/quote_repository_mock.dart | 16 -- frontend/lib/values/strings.dart | 4 + 4 files changed, 141 insertions(+), 70 deletions(-) delete mode 100644 frontend/lib/repository/quote_repository_mock.dart diff --git a/frontend/lib/pages/list.dart b/frontend/lib/pages/list.dart index bb40a71..bb0c181 100644 --- a/frontend/lib/pages/list.dart +++ b/frontend/lib/pages/list.dart @@ -17,11 +17,11 @@ class ListPage extends StatelessWidget { onRefresh: () async { await provider.readQuotes(); }, - child: _bodyBuilder(provider), + child: _bodyBuilder(context, provider), ); } - Widget _bodyBuilder(QuoteProvider provider) { + Widget _bodyBuilder(BuildContext context, QuoteProvider provider) { if (provider.loading) { return Center(child: CircularProgressIndicator()); } @@ -30,61 +30,79 @@ class ListPage extends StatelessWidget { return Center(child: Text(provider.error!)); } + final quoteCount = provider.quotes.length; + return - ListView.builder( - padding: EdgeInsets.all(Constants.edgeInset), - itemCount: provider.quotes.length, - itemBuilder: (context, index) { - final quote = provider.quotes[index]; - - return - ListTile( - contentPadding: EdgeInsets.only( - bottom: Constants.edgeInset, - left: Constants.edgeInset, - right: Constants.edgeInset, - ), - title: Text(quote.body), - subtitle: Text("– ${quote.author}"), - trailing: PopupMenuButton( - icon: const Icon(Icons.more_vert), - - onSelected: (value) { - if (value == 'update') { - // open a dialog window that allows for mods - _showUpdateDialog(context, provider, quote); - } else if (value == 'delete') { - // open a confirmation dialog window for deletion - _showDeleteDialog(context, provider, quote); - } - }, - - itemBuilder: (context) => [ - const PopupMenuItem( - value: 'update', - child: Row( - children: [ - Icon(Icons.edit), - SizedBox(width: 10), - Text(Strings.updateQuote), - ], + Column( + children: [ + Center( + child: Padding( + padding: const EdgeInsets.all(Constants.edgeInset), + child: Text( + '${Strings.allQuotesCount} – $quoteCount', + style: TextStyle(fontSize: 18), + ), + ), + ), + filterBar(context, provider), + Expanded( + child: ListView.builder( + padding: EdgeInsets.all(Constants.edgeInset), + itemCount: provider.quotes.length, + itemBuilder: (context, index) { + final quote = provider.quotes[index]; + + return + ListTile( + contentPadding: EdgeInsets.only( + bottom: Constants.edgeInset, + left: Constants.edgeInset, + right: Constants.edgeInset, ), - ), - - const PopupMenuItem( - value: 'delete', - child: Row( - children: [ - Icon(Icons.delete), - SizedBox(width: 10), - Text(Strings.deleteQuote), + title: Text(quote.body), + subtitle: Text("– ${quote.author}"), + trailing: PopupMenuButton( + icon: const Icon(Icons.more_vert), + + onSelected: (value) { + if (value == 'update') { + // open a dialog window that allows for mods + _showUpdateDialog(context, provider, quote); + } else if (value == 'delete') { + // open a confirmation dialog window for deletion + _showDeleteDialog(context, provider, quote); + } + }, + + itemBuilder: (context) => [ + const PopupMenuItem( + value: 'update', + child: Row( + children: [ + Icon(Icons.edit), + SizedBox(width: 10), + Text(Strings.updateQuote), + ], + ), + ), + + const PopupMenuItem( + value: 'delete', + child: Row( + children: [ + Icon(Icons.delete), + SizedBox(width: 10), + Text(Strings.deleteQuote), + ], + ), + ), ], - ), - ), - ], - ) - ); - }, + ) + ); + }, + ), + ), + ], ); } @@ -191,4 +209,63 @@ class ListPage extends StatelessWidget { }, ); } + + Widget filterBar(BuildContext context, QuoteProvider provider) { + int filterBy = 0; // 0 = by author, 1 = by quote + return Padding( + padding: const EdgeInsets.all(Constants.edgeInset), + child: Row( + children: [ + Expanded( + child: TextField( + controller: provider.filterController, + decoration: InputDecoration( + label: Text(Strings.filterQuery), + suffixIcon: IconButton( + icon: Icon(Icons.cancel), + onPressed: provider.clearFilterController + ) + ), + ), + ), + IconButton( + icon: Icon(Icons.search), + onPressed: () { + // TODO: filtering + }, + ), + IconButton( + icon: Icon(Icons.more_horiz), + onPressed: () { + _showOptionsBottomSheet(context, provider); + }, + ), + ], + ), + ); + } + + void _showOptionsBottomSheet(BuildContext context, QuoteProvider provider) { + showModalBottomSheet( + context: context, + builder: (context) { + return SizedBox( + height: 300, + child: ListView( + padding: const EdgeInsets.all(Constants.edgeInset), + children: [ + ListTile( + title: Text(Strings.filterBy), + trailing: Icon(Icons.filter_alt), + ), + ListTile( + title: Text(Strings.exportSelectedQuotes), + trailing: Icon(Icons.import_export), + ), + ], + ) + ); + }, + ); + } } \ No newline at end of file diff --git a/frontend/lib/provider/quote_provider.dart b/frontend/lib/provider/quote_provider.dart index ff9ba55..02b2e22 100644 --- a/frontend/lib/provider/quote_provider.dart +++ b/frontend/lib/provider/quote_provider.dart @@ -18,6 +18,12 @@ class QuoteProvider extends ChangeNotifier { final QuoteRepository repo = QuoteRepository(); + var filterController = TextEditingController(text: ''); + + void clearFilterController() { + filterController.text = ''; + } + QuoteProvider() { readQuotes(); // auto-load on creation } diff --git a/frontend/lib/repository/quote_repository_mock.dart b/frontend/lib/repository/quote_repository_mock.dart deleted file mode 100644 index 0b5ad98..0000000 --- a/frontend/lib/repository/quote_repository_mock.dart +++ /dev/null @@ -1,16 +0,0 @@ -// talks to the DB itself -// TODO: mock for now! - -import 'package:frontend/model/quote.dart'; - -class QuoteRepository { - //final String _dbBaseUrl = 'https://hlaskovnik-reimagined-latest.onrender.com'; - - Future> getQuotes() async { - return [ - Quote(id: 1, author: 'Adam', body: 'kratom je vule bozi'), - Quote(id: 2, author: 'Vojta', body: 'kalach s kecupem'), - Quote(id: 3, author: 'Anton', body: 'have you ever noticed how long cows are'), - ]; - } -} \ No newline at end of file diff --git a/frontend/lib/values/strings.dart b/frontend/lib/values/strings.dart index abf1ed8..d80dba4 100644 --- a/frontend/lib/values/strings.dart +++ b/frontend/lib/values/strings.dart @@ -20,4 +20,8 @@ class Strings { static const String author = "Autor"; static const String noUndo = "Tuto akci nelze odčinit."; + static const String filterQuery = "Filtrovací požadavek"; + static const String allQuotesCount = "Celkový počet hlášek"; + static const String filterBy = "Filtrovat podle"; + static const String exportSelectedQuotes = "Exportovat vybrané hlášky"; } \ No newline at end of file