import 'package:flutter/material.dart'; import 'package:frontend/provider/quote_provider.dart'; import 'package:frontend/model/quote.dart'; import 'package:frontend/values/strings.dart'; import 'package:provider/provider.dart'; import 'package:frontend/values/constants.dart'; class ListPage extends StatelessWidget { const ListPage({super.key}); @override Widget build(BuildContext context) { final provider = context.watch(); return RefreshIndicator( onRefresh: () async { await provider.readQuotes(); }, child: _bodyBuilder(provider), ); } Widget _bodyBuilder(QuoteProvider provider) { if (provider.loading) { return Center(child: CircularProgressIndicator()); } if (provider.error != null) { return Center(child: Text(provider.error!)); } 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), ], ), ), const PopupMenuItem( value: 'delete', child: Row( children: [ Icon(Icons.delete), SizedBox(width: 10), Text(Strings.deleteQuote), ], ), ), ], ) ); }, ); } void _showUpdateDialog(BuildContext context, QuoteProvider provider, Quote quote) { final bodyController = TextEditingController(text: quote.body); final authorController = TextEditingController(text: quote.author); showDialog( context: context, builder: (context) { return AlertDialog( title: Text(Strings.updateQuote), content: Column( mainAxisSize: MainAxisSize.min, children: [ TextField( autofocus: true, controller: bodyController, ), TextField( controller: authorController, decoration: InputDecoration( label: Text(Strings.author), suffixIcon: IconButton( icon: Icon(Icons.arrow_drop_down), onPressed: () { showModalBottomSheet( context: context, builder: (context) { var authors = provider.authors.toList()..sort(); return SizedBox( height: 300, child: ListView.builder( padding: const EdgeInsets.all(Constants.edgeInset), itemCount: authors.length, itemBuilder: (context, index) { final author = authors[index]; return ListTile( title: Text(author), onTap: () { authorController.text = author; Navigator.pop(context); }, ); }, ), ); }, ); }, ), ), ), ], ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text(Strings.cancel), ), ElevatedButton( onPressed: () { final updatedQuote = Quote( id: quote.id, body: bodyController.text, author: authorController.text, ); Navigator.pop(context); provider.updateQuote(updatedQuote); }, child: const Text(Strings.save), ), ], ); }, ); } void _showDeleteDialog(BuildContext context, QuoteProvider provider, Quote quote) { showDialog( context: context, builder: (context) { return AlertDialog( title: const Text('${Strings.deleteQuote}?'), content: const Text(Strings.noUndo), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text(Strings.cancel), ), ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Colors.red, ), onPressed: () { Navigator.pop(context); provider.deleteQuote(quote); }, child: const Text(Strings.delete), ), ], ); }, ); } }