diff --git a/frontend/lib/pages/add.dart b/frontend/lib/pages/add.dart index fb8be0e..bfb5e98 100644 --- a/frontend/lib/pages/add.dart +++ b/frontend/lib/pages/add.dart @@ -21,18 +21,9 @@ class AddPage extends StatelessWidget { padding: const EdgeInsets.all(Constants.edgeInset), child: Column( mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, children: [ - Text( - Strings.createQuote, - style: const TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), - ), - - const SizedBox(height: 12), - TextField( autofocus: true, controller: bodyController, diff --git a/frontend/lib/pages/leaderboard.dart b/frontend/lib/pages/leaderboard.dart index 5b99915..96b2cdf 100644 --- a/frontend/lib/pages/leaderboard.dart +++ b/frontend/lib/pages/leaderboard.dart @@ -1,10 +1,48 @@ import 'package:flutter/material.dart'; +import 'package:frontend/provider/quote_provider.dart'; +import 'package:frontend/values/constants.dart'; +import 'package:provider/provider.dart'; class LeaderboardPage extends StatelessWidget { const LeaderboardPage({super.key}); @override Widget build(BuildContext context) { - return const Center(child: Text('top 3!')); + final provider = context.watch(); + return Center( + child: Column( + children: [ + Expanded( + child: ListView.builder( + padding: EdgeInsets.all(Constants.edgeInset), + itemCount: provider.filteredQuotes.length, + itemBuilder: (context, index) { + return + Card( + color: provider.getLeaderboardEntryBgColor(context, index), + child: ListTile( + contentPadding: EdgeInsets.symmetric( + vertical: 0, + horizontal: Constants.edgeInset, + ), + title: Text(provider.sortedAuthorCounts[index].key, + style: TextStyle( + color: provider.getLeaderboardEntryFgColor(context, index) + ), + ), + trailing: Text(provider.sortedAuthorCounts[index].value.toString(), + style: TextStyle( + fontSize: 16, + color: provider.getLeaderboardEntryFgColor(context, index), + ), + ), + ), + ); + }, + ), + ), + ], + ), + ); } } \ No newline at end of file diff --git a/frontend/lib/provider/quote_provider.dart b/frontend/lib/provider/quote_provider.dart index 9e7bf04..1ade5b5 100644 --- a/frontend/lib/provider/quote_provider.dart +++ b/frontend/lib/provider/quote_provider.dart @@ -38,7 +38,7 @@ class QuoteProvider extends ChangeNotifier { return filtered; } - Map get authorCounts { + Map get _authorCounts { final counts = {}; for (var quote in filteredQuotes) { @@ -52,6 +52,23 @@ class QuoteProvider extends ChangeNotifier { return counts; } + List> get sortedAuthorCounts { + final counts = {}; + + for (var quote in filteredQuotes) { + counts.update( + quote.author, + (value) => value + 1, + ifAbsent: () => 1, + ); + } + + final list = counts.entries.toList() + ..sort((a, b) => b.value.compareTo(a.value)); // descending + + return list; + } + final QuoteRepository repo = QuoteRepository(); int filterBy = 0; // 0 = by author, 1 = by quote @@ -191,4 +208,30 @@ class QuoteProvider extends ChangeNotifier { final file = File('${dir.path}/hlasky_$datetime.txt'); await file.writeAsString("${filteredQuotes.join("\n")}\n"); } + + Color getLeaderboardEntryBgColor(BuildContext context, int index) { + switch (index) { + case 0: + return Colors.yellow.shade300; // 1st place + case 1: + return Colors.grey.shade300; // 2nd place + case 2: + return Colors.brown.shade300; // 3rd place + default: + return Theme.of(context).cardColor; // default for all other entries + } + } + + Color getLeaderboardEntryFgColor(BuildContext context, int index) { + switch (index) { + case 0: + return Colors.black; // 1st place + case 1: + return Colors.black; // 2nd place + case 2: + return Colors.black; // 3rd place + default: + return Colors.white; // default for all other entries + } + } } \ No newline at end of file