From a8129eb13427ebce0ab48c4be59c892203274cbb Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Fri, 16 Jan 2026 23:34:47 +0100 Subject: [PATCH 1/9] Implemented first version of group profile --- lib/l10n/arb/app_de.arb | 7 + lib/l10n/arb/app_en.arb | 28 ++ lib/l10n/generated/app_localizations.dart | 42 +++ lib/l10n/generated/app_localizations_de.dart | 21 ++ lib/l10n/generated/app_localizations_en.dart | 21 ++ .../group_view/group_profile_view.dart | 271 ++++++++++++++++++ .../main_menu/group_view/groups_view.dart | 21 +- .../widgets/tiles/group_tile.dart | 119 ++++---- pubspec.yaml | 2 +- 9 files changed, 479 insertions(+), 53 deletions(-) create mode 100644 lib/presentation/views/main_menu/group_view/group_profile_view.dart diff --git a/lib/l10n/arb/app_de.arb b/lib/l10n/arb/app_de.arb index 7091586..2ef9ee9 100644 --- a/lib/l10n/arb/app_de.arb +++ b/lib/l10n/arb/app_de.arb @@ -4,6 +4,7 @@ "all_players_selected": "Alle Spieler:innen ausgewählt", "amount_of_matches": "Anzahl der Spiele", "app_name": "Game Tracker", + "best_player": "Beste:r Spieler:in", "cancel": "Abbrechen", "choose_game": "Spielvorlage wählen", "choose_group": "Gruppe wählen", @@ -13,6 +14,7 @@ "create_match": "Spiel erstellen", "create_new_group": "Neue Gruppe erstellen", "create_new_match": "Neues Spiel erstellen", + "created_on": "Erstellt am", "data": "Daten", "data_successfully_deleted": "Daten erfolgreich gelöscht", "data_successfully_exported": "Daten erfolgreich exportiert", @@ -20,6 +22,8 @@ "days_ago": "vor {count} Tagen", "delete": "Löschen", "delete_all_data": "Alle Daten löschen", + "delete_group": "Gruppe löschen", + "edit_group": "Gruppe bearbeiten", "error_creating_group": "Fehler beim Erstellen der Gruppe, bitte erneut versuchen", "error_reading_file": "Fehler beim Lesen der Datei", "export_canceled": "Export abgebrochen", @@ -29,6 +33,7 @@ "game_name": "Spielvorlagenname", "group": "Gruppe", "group_name": "Gruppenname", + "group_profile": "Gruppenprofil", "groups": "Gruppen", "home": "Startseite", "import_canceled": "Import abgebrochen", @@ -42,6 +47,7 @@ "match_in_progress": "Spiel läuft...", "match_name": "Spieltitel", "matches": "Spiele", + "members": "Mitglieder", "most_points": "Höchste Punkte", "no_data_available": "Keine Daten verfügbar", "no_groups_created_yet": "Noch keine Gruppen erstellt", @@ -57,6 +63,7 @@ "none": "Kein", "none_group": "Keine", "not_available": "Nicht verfügbar", + "played_matches": "Gespielte Spiele", "player_name": "Spieler:innenname", "players": "Spieler:innen", "players_count": "{count} Spieler", diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index 6eb7613..fa4adc8 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -12,6 +12,9 @@ "@app_name": { "description": "The name of the App" }, + "@best_player": { + "description": "Label for best player statistic" + }, "@cancel": { "description": "Cancel button text" }, @@ -39,6 +42,9 @@ "@create_new_match": { "description": "Button text to create a new match" }, + "@created_on": { + "description": "Label for creation date" + }, "@data": { "description": "Data label" }, @@ -65,6 +71,12 @@ "@delete_all_data": { "description": "Confirmation dialog for deleting all data" }, + "@delete_group": { + "description": "Button text to delete a group" + }, + "@edit_group": { + "description": "Button text to edit a group" + }, "@error_creating_group": { "description": "Error message when group creation fails" }, @@ -92,6 +104,9 @@ "@group_name": { "description": "Placeholder for group name input" }, + "@group_profile": { + "description": "Title for group profile view" + }, "@groups": { "description": "Label for groups" }, @@ -131,6 +146,9 @@ "@matches": { "description": "Label for matches" }, + "@members": { + "description": "Label for group members" + }, "@most_points": { "description": "Title for most points ruleset" }, @@ -176,6 +194,9 @@ "@not_available": { "description": "Abbreviation for not available" }, + "@played_matches": { + "description": "Label for played matches statistic" + }, "@player_name": { "description": "Placeholder for player name input" }, @@ -281,6 +302,7 @@ "all_players_selected": "All players selected", "amount_of_matches": "Amount of Matches", "app_name": "Game Tracker", + "best_player": "Best Player", "cancel": "Cancel", "choose_game": "Choose Game", "choose_group": "Choose Group", @@ -289,6 +311,7 @@ "create_group": "Create Group", "create_match": "Create match", "create_new_group": "Create new group", + "created_on": "Created on", "create_new_match": "Create new match", "data": "Data", "data_successfully_deleted": "Data successfully deleted", @@ -297,6 +320,8 @@ "days_ago": "{count} days ago", "delete": "Delete", "delete_all_data": "Delete all data", + "delete_group": "Delete Group", + "edit_group": "Edit Group", "error_creating_group": "Error while creating group, please try again", "error_reading_file": "Error reading file", "export_canceled": "Export canceled", @@ -306,6 +331,7 @@ "game_name": "Game Name", "group": "Group", "group_name": "Group name", + "group_profile": "Group Profile", "groups": "Groups", "home": "Home", "import_canceled": "Import canceled", @@ -319,6 +345,7 @@ "match_in_progress": "Match in progress...", "match_name": "Match name", "matches": "Matches", + "members": "Members", "most_points": "Most Points", "no_data_available": "No data available", "no_groups_created_yet": "No groups created yet", @@ -334,6 +361,7 @@ "none": "None", "none_group": "None", "not_available": "Not available", + "played_matches": "Played Matches", "player_name": "Player name", "players": "Players", "players_count": "{count} Players", diff --git a/lib/l10n/generated/app_localizations.dart b/lib/l10n/generated/app_localizations.dart index e78d69b..57dbdd8 100644 --- a/lib/l10n/generated/app_localizations.dart +++ b/lib/l10n/generated/app_localizations.dart @@ -122,6 +122,12 @@ abstract class AppLocalizations { /// **'Game Tracker'** String get app_name; + /// Label for best player statistic + /// + /// In en, this message translates to: + /// **'Best Player'** + String get best_player; + /// Cancel button text /// /// In en, this message translates to: @@ -170,6 +176,12 @@ abstract class AppLocalizations { /// **'Create new group'** String get create_new_group; + /// Label for creation date + /// + /// In en, this message translates to: + /// **'Created on'** + String get created_on; + /// Button text to create a new match /// /// In en, this message translates to: @@ -218,6 +230,18 @@ abstract class AppLocalizations { /// **'Delete all data'** String get delete_all_data; + /// Button text to delete a group + /// + /// In en, this message translates to: + /// **'Delete Group'** + String get delete_group; + + /// Button text to edit a group + /// + /// In en, this message translates to: + /// **'Edit Group'** + String get edit_group; + /// Error message when group creation fails /// /// In en, this message translates to: @@ -272,6 +296,12 @@ abstract class AppLocalizations { /// **'Group name'** String get group_name; + /// Title for group profile view + /// + /// In en, this message translates to: + /// **'Group Profile'** + String get group_profile; + /// Label for groups /// /// In en, this message translates to: @@ -350,6 +380,12 @@ abstract class AppLocalizations { /// **'Matches'** String get matches; + /// Label for group members + /// + /// In en, this message translates to: + /// **'Members'** + String get members; + /// Title for most points ruleset /// /// In en, this message translates to: @@ -440,6 +476,12 @@ abstract class AppLocalizations { /// **'Not available'** String get not_available; + /// Label for played matches statistic + /// + /// In en, this message translates to: + /// **'Played Matches'** + String get played_matches; + /// Placeholder for player name input /// /// In en, this message translates to: diff --git a/lib/l10n/generated/app_localizations_de.dart b/lib/l10n/generated/app_localizations_de.dart index 8ecc0a7..f78f9f4 100644 --- a/lib/l10n/generated/app_localizations_de.dart +++ b/lib/l10n/generated/app_localizations_de.dart @@ -20,6 +20,9 @@ class AppLocalizationsDe extends AppLocalizations { @override String get app_name => 'Game Tracker'; + @override + String get best_player => 'Beste:r Spieler:in'; + @override String get cancel => 'Abbrechen'; @@ -46,6 +49,9 @@ class AppLocalizationsDe extends AppLocalizations { @override String get create_new_group => 'Neue Gruppe erstellen'; + @override + String get created_on => 'Erstellt am'; + @override String get create_new_match => 'Neues Spiel erstellen'; @@ -72,6 +78,12 @@ class AppLocalizationsDe extends AppLocalizations { @override String get delete_all_data => 'Alle Daten löschen'; + @override + String get delete_group => 'Gruppe löschen'; + + @override + String get edit_group => 'Gruppe bearbeiten'; + @override String get error_creating_group => 'Fehler beim Erstellen der Gruppe, bitte erneut versuchen'; @@ -100,6 +112,9 @@ class AppLocalizationsDe extends AppLocalizations { @override String get group_name => 'Gruppenname'; + @override + String get group_profile => 'Gruppenprofil'; + @override String get groups => 'Gruppen'; @@ -139,6 +154,9 @@ class AppLocalizationsDe extends AppLocalizations { @override String get matches => 'Spiele'; + @override + String get members => 'Mitglieder'; + @override String get most_points => 'Höchste Punkte'; @@ -185,6 +203,9 @@ class AppLocalizationsDe extends AppLocalizations { @override String get not_available => 'Nicht verfügbar'; + @override + String get played_matches => 'Gespielte Spiele'; + @override String get player_name => 'Spieler:innenname'; diff --git a/lib/l10n/generated/app_localizations_en.dart b/lib/l10n/generated/app_localizations_en.dart index b911676..32512c7 100644 --- a/lib/l10n/generated/app_localizations_en.dart +++ b/lib/l10n/generated/app_localizations_en.dart @@ -20,6 +20,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get app_name => 'Game Tracker'; + @override + String get best_player => 'Best Player'; + @override String get cancel => 'Cancel'; @@ -46,6 +49,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get create_new_group => 'Create new group'; + @override + String get created_on => 'Created on'; + @override String get create_new_match => 'Create new match'; @@ -72,6 +78,12 @@ class AppLocalizationsEn extends AppLocalizations { @override String get delete_all_data => 'Delete all data'; + @override + String get delete_group => 'Delete Group'; + + @override + String get edit_group => 'Edit Group'; + @override String get error_creating_group => 'Error while creating group, please try again'; @@ -100,6 +112,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get group_name => 'Group name'; + @override + String get group_profile => 'Group Profile'; + @override String get groups => 'Groups'; @@ -139,6 +154,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get matches => 'Matches'; + @override + String get members => 'Members'; + @override String get most_points => 'Most Points'; @@ -185,6 +203,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get not_available => 'Not available'; + @override + String get played_matches => 'Played Matches'; + @override String get player_name => 'Player name'; diff --git a/lib/presentation/views/main_menu/group_view/group_profile_view.dart b/lib/presentation/views/main_menu/group_view/group_profile_view.dart new file mode 100644 index 0000000..90151c1 --- /dev/null +++ b/lib/presentation/views/main_menu/group_view/group_profile_view.dart @@ -0,0 +1,271 @@ +import 'package:flutter/material.dart'; +import 'package:game_tracker/core/adaptive_page_route.dart'; +import 'package:game_tracker/core/custom_theme.dart'; +import 'package:game_tracker/data/db/database.dart'; +import 'package:game_tracker/data/dto/group.dart'; +import 'package:game_tracker/data/dto/match.dart'; +import 'package:game_tracker/data/dto/player.dart'; +import 'package:game_tracker/l10n/generated/app_localizations.dart'; +import 'package:game_tracker/presentation/views/main_menu/group_view/create_group_view.dart'; +import 'package:game_tracker/presentation/widgets/app_skeleton.dart'; +import 'package:game_tracker/presentation/widgets/buttons/animated_dialog_button.dart'; +import 'package:game_tracker/presentation/widgets/buttons/main_menu_button.dart'; +import 'package:game_tracker/presentation/widgets/custom_alert_dialog.dart'; +import 'package:game_tracker/presentation/widgets/tiles/info_tile.dart'; +import 'package:game_tracker/presentation/widgets/tiles/text_icon_tile.dart'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; + +class GroupProfileView extends StatefulWidget { + /// A view that displays the profile of a group + /// - [group]: The group to display + const GroupProfileView({ + super.key, + required this.group, + required this.callback, + }); + + /// The group to display + final Group group; + + final VoidCallback callback; + + @override + State createState() => _GroupProfileViewState(); +} + +class _GroupProfileViewState extends State { + late final AppDatabase db; + bool isLoading = true; + + /// Total matches played in this group + int totalMatches = 0; + + String bestPlayer = ''; + + @override + void initState() { + super.initState(); + db = Provider.of(context, listen: false); + _loadStatistics(); + } + + @override + Widget build(BuildContext context) { + final loc = AppLocalizations.of(context); + + return Scaffold( + backgroundColor: CustomTheme.backgroundColor, + appBar: AppBar( + title: Text(loc.group_profile), + actions: [ + IconButton( + icon: const Icon(Icons.delete), + onPressed: () async { + showDialog( + context: context, + builder: (context) => CustomAlertDialog( + title: '${loc.delete_group}?', + content: loc.this_cannot_be_undone, + actions: [ + AnimatedDialogButton( + onPressed: () => Navigator.of(context).pop(false), + child: Text( + loc.cancel, + style: const TextStyle(color: CustomTheme.textColor), + ), + ), + AnimatedDialogButton( + onPressed: () => Navigator.of(context).pop(true), + child: Text( + loc.delete, + style: TextStyle(color: CustomTheme.secondaryColor), + ), + ), + ], + ), + ).then((confirmed) async { + if (confirmed! && context.mounted) { + await db.groupDao.deleteGroup(groupId: widget.group.id); + if (!context.mounted) return; + Navigator.pop(context); + widget.callback.call(); + } + }); + }, + ), + ], + ), + body: SafeArea( + child: Stack( + alignment: Alignment.center, + children: [ + ListView( + padding: const EdgeInsets.only( + left: 12, + right: 12, + top: 20, + bottom: 100, + ), + children: [ + Center( + child: Container( + width: 55, + height: 55, + decoration: BoxDecoration( + color: CustomTheme.primaryColor.withGreen(40), + borderRadius: BorderRadius.circular(10), + ), + child: Icon( + Icons.group, + size: 38, + color: CustomTheme.secondaryColor, + ), + ), + ), + const SizedBox(height: 10), + Text( + widget.group.name, + style: const TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + color: CustomTheme.textColor, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 5), + Text( + "${loc.created_on} ${DateFormat('dd.MM.yyyy').format(widget.group.createdAt)}", + style: const TextStyle( + fontSize: 12, + color: CustomTheme.textColor, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 20), + InfoTile( + title: loc.members, + icon: Icons.people, + content: Wrap( + spacing: 8, + runSpacing: 8, + children: widget.group.members.map((member) { + return TextIconTile( + text: member.name, + iconEnabled: false, + ); + }).toList(), + ), + ), + const SizedBox(height: 15), + InfoTile( + title: loc.statistics, + icon: Icons.bar_chart, + content: AppSkeleton( + enabled: isLoading, + child: Column( + children: [ + _buildStatRow( + loc.members, + widget.group.members.length.toString(), + ), + _buildStatRow( + loc.played_matches, + totalMatches.toString(), + ), + _buildStatRow(loc.best_player, bestPlayer), + ], + ), + ), + ), + ], + ), + Positioned( + bottom: MediaQuery.paddingOf(context).bottom, + child: MainMenuButton( + text: loc.edit_group, + icon: Icons.edit, + onPressed: () async { + await Navigator.push( + context, + adaptivePageRoute( + builder: (context) { + return const CreateGroupView(); + }, + ), + ); + }, + ), + ), + ], + ), + ), + ); + } + + /// Builds a single statistic row with a label and value + Widget _buildStatRow(String label, String value) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Text( + label, + style: const TextStyle( + fontSize: 16, + color: CustomTheme.textColor, + ), + ), + ], + ), + Text( + value, + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + ), + ], + ), + ); + } + + /// Loads statistics for this group + Future _loadStatistics() async { + final matches = await db.matchDao.getAllMatches(); + final groupMatches = matches + .where((match) => match.group?.id == widget.group.id) + .toList(); + + setState(() { + totalMatches = groupMatches.length; + bestPlayer = _getBestPlayer(groupMatches); + isLoading = false; + }); + } + + /// Determines the best player in the group based on match wins + String _getBestPlayer(List matches) { + final bestPlayerCounts = {}; + + // Count wins for each player + for (var match in matches) { + if (match.winner != null) { + bestPlayerCounts.update( + match.winner!, + (value) => value + 1, + ifAbsent: () => 1, + ); + } + } + + // Sort players by win count + final sortedPlayers = bestPlayerCounts.entries.toList() + ..sort((a, b) => b.value.compareTo(a.value)); + + // Get the best player + bestPlayer = sortedPlayers.isNotEmpty ? sortedPlayers.first.key.name : '-'; + + return bestPlayer; + } +} diff --git a/lib/presentation/views/main_menu/group_view/groups_view.dart b/lib/presentation/views/main_menu/group_view/groups_view.dart index 10ae148..0083f26 100644 --- a/lib/presentation/views/main_menu/group_view/groups_view.dart +++ b/lib/presentation/views/main_menu/group_view/groups_view.dart @@ -7,6 +7,7 @@ import 'package:game_tracker/data/dto/group.dart'; import 'package:game_tracker/data/dto/player.dart'; import 'package:game_tracker/l10n/generated/app_localizations.dart'; import 'package:game_tracker/presentation/views/main_menu/group_view/create_group_view.dart'; +import 'package:game_tracker/presentation/views/main_menu/group_view/group_profile_view.dart'; import 'package:game_tracker/presentation/widgets/app_skeleton.dart'; import 'package:game_tracker/presentation/widgets/buttons/main_menu_button.dart'; import 'package:game_tracker/presentation/widgets/tiles/group_tile.dart'; @@ -74,7 +75,22 @@ class _GroupsViewState extends State { height: MediaQuery.paddingOf(context).bottom - 20, ); } - return GroupTile(group: groups[index]); + return GroupTile( + group: groups[index], + onTap: () async { + await Navigator.push( + context, + adaptivePageRoute( + builder: (context) { + return GroupProfileView( + group: groups[index], + callback: loadGroups, + ); + }, + ), + ); + }, + ); }, ), ), @@ -105,6 +121,9 @@ class _GroupsViewState extends State { } void loadGroups() { + setState(() { + isLoading = true; + }); Future.wait([ db.groupDao.getAllGroups(), Future.delayed(Constants.minimumSkeletonDuration), diff --git a/lib/presentation/widgets/tiles/group_tile.dart b/lib/presentation/widgets/tiles/group_tile.dart index a06c6b5..c035a04 100644 --- a/lib/presentation/widgets/tiles/group_tile.dart +++ b/lib/presentation/widgets/tiles/group_tile.dart @@ -3,11 +3,17 @@ import 'package:game_tracker/core/custom_theme.dart'; import 'package:game_tracker/data/dto/group.dart'; import 'package:game_tracker/presentation/widgets/tiles/text_icon_tile.dart'; -class GroupTile extends StatelessWidget { +class GroupTile extends StatefulWidget { /// A tile widget that displays information about a group, including its name and members. /// - [group]: The group data to be displayed. /// - [isHighlighted]: Whether the tile should be highlighted. - const GroupTile({super.key, required this.group, this.isHighlighted = false}); + /// - [onTap]: Callback function to be executed when the tile is tapped. + const GroupTile({ + super.key, + required this.group, + this.isHighlighted = false, + this.onTap, + }); /// The group data to be displayed. final Group group; @@ -15,61 +21,72 @@ class GroupTile extends StatelessWidget { /// Whether the tile should be highlighted. final bool isHighlighted; + /// Callback function to be executed when the tile is tapped. + final VoidCallback? onTap; + + @override + State createState() => _GroupTileState(); +} + +class _GroupTileState extends State { @override Widget build(BuildContext context) { - return AnimatedContainer( - margin: CustomTheme.standardMargin, - padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10), - decoration: isHighlighted - ? CustomTheme.highlightedBoxDecoration - : CustomTheme.standardBoxDecoration, - duration: const Duration(milliseconds: 150), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Flexible( - child: Text( - group.name, - overflow: TextOverflow.ellipsis, - style: const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 18, - ), - ), - ), - Row( - children: [ - Text( - '${group.members.length}', + return GestureDetector( + onTap: widget.onTap, + child: AnimatedContainer( + margin: CustomTheme.standardMargin, + padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10), + decoration: widget.isHighlighted + ? CustomTheme.highlightedBoxDecoration + : CustomTheme.standardBoxDecoration, + duration: const Duration(milliseconds: 150), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: Text( + widget.group.name, + overflow: TextOverflow.ellipsis, style: const TextStyle( - fontWeight: FontWeight.w900, + fontWeight: FontWeight.bold, fontSize: 18, ), ), - const SizedBox(width: 3), - const Icon(Icons.group, size: 22), - ], - ), - ], - ), - const SizedBox(height: 5), - Wrap( - alignment: WrapAlignment.start, - crossAxisAlignment: WrapCrossAlignment.start, - spacing: 12.0, - runSpacing: 8.0, - children: [ - for (var member in [ - ...group.members, - ]..sort((a, b) => a.name.compareTo(b.name))) - TextIconTile(text: member.name, iconEnabled: false), - ], - ), - const SizedBox(height: 2.5), - ], + ), + Row( + children: [ + Text( + '${widget.group.members.length}', + style: const TextStyle( + fontWeight: FontWeight.w900, + fontSize: 18, + ), + ), + const SizedBox(width: 3), + const Icon(Icons.group, size: 22), + ], + ), + ], + ), + const SizedBox(height: 5), + Wrap( + alignment: WrapAlignment.start, + crossAxisAlignment: WrapCrossAlignment.start, + spacing: 12.0, + runSpacing: 8.0, + children: [ + for (var member in [ + ...widget.group.members, + ]..sort((a, b) => a.name.compareTo(b.name))) + TextIconTile(text: member.name, iconEnabled: false), + ], + ), + const SizedBox(height: 2.5), + ], + ), ), ); } diff --git a/pubspec.yaml b/pubspec.yaml index e9fd894..3f5a5f8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: game_tracker description: "Game Tracking App for Card Games" publish_to: 'none' -version: 0.0.7+212 +version: 0.0.7+221 environment: sdk: ^3.8.1 From 6a0896d818f2ed5caf9883c793787349e81f3bb6 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Sat, 17 Jan 2026 00:52:09 +0100 Subject: [PATCH 2/9] Implemented ColoredIconContainer --- .../group_view/group_profile_view.dart | 33 +++++------ .../licenses/license_detail_view.dart | 19 ++----- lib/presentation/widgets/colored_icon.dart | 57 +++++++++++++++++++ .../widgets/tiles/license_tile.dart | 17 ++---- .../widgets/tiles/settings_list_tile.dart | 17 ++---- pubspec.yaml | 2 +- 6 files changed, 89 insertions(+), 56 deletions(-) create mode 100644 lib/presentation/widgets/colored_icon.dart diff --git a/lib/presentation/views/main_menu/group_view/group_profile_view.dart b/lib/presentation/views/main_menu/group_view/group_profile_view.dart index 90151c1..2555020 100644 --- a/lib/presentation/views/main_menu/group_view/group_profile_view.dart +++ b/lib/presentation/views/main_menu/group_view/group_profile_view.dart @@ -1,15 +1,14 @@ import 'package:flutter/material.dart'; -import 'package:game_tracker/core/adaptive_page_route.dart'; import 'package:game_tracker/core/custom_theme.dart'; import 'package:game_tracker/data/db/database.dart'; import 'package:game_tracker/data/dto/group.dart'; import 'package:game_tracker/data/dto/match.dart'; import 'package:game_tracker/data/dto/player.dart'; import 'package:game_tracker/l10n/generated/app_localizations.dart'; -import 'package:game_tracker/presentation/views/main_menu/group_view/create_group_view.dart'; import 'package:game_tracker/presentation/widgets/app_skeleton.dart'; import 'package:game_tracker/presentation/widgets/buttons/animated_dialog_button.dart'; import 'package:game_tracker/presentation/widgets/buttons/main_menu_button.dart'; +import 'package:game_tracker/presentation/widgets/colored_icon.dart'; import 'package:game_tracker/presentation/widgets/custom_alert_dialog.dart'; import 'package:game_tracker/presentation/widgets/tiles/info_tile.dart'; import 'package:game_tracker/presentation/widgets/tiles/text_icon_tile.dart'; @@ -108,19 +107,11 @@ class _GroupProfileViewState extends State { bottom: 100, ), children: [ - Center( - child: Container( - width: 55, - height: 55, - decoration: BoxDecoration( - color: CustomTheme.primaryColor.withGreen(40), - borderRadius: BorderRadius.circular(10), - ), - child: Icon( - Icons.group, - size: 38, - color: CustomTheme.secondaryColor, - ), + const Center( + child: ColoredIconContainer( + icon: Icons.group, + containerSize: 55, + iconSize: 38, ), ), const SizedBox(height: 10), @@ -185,15 +176,19 @@ class _GroupProfileViewState extends State { child: MainMenuButton( text: loc.edit_group, icon: Icons.edit, - onPressed: () async { + onPressed: () { + // TODO: Uncomment when GroupDetailView is implemented + /* await Navigator.push( context, adaptivePageRoute( builder: (context) { - return const CreateGroupView(); + + return const GroupDetailView(); }, ), - ); + );*/ + print('Edit Group pressed'); }, ), ), @@ -204,6 +199,8 @@ class _GroupProfileViewState extends State { } /// Builds a single statistic row with a label and value + /// - [label]: The label of the statistic + /// - [value]: The value of the statistic Widget _buildStatRow(String label, String value) { return Padding( padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), diff --git a/lib/presentation/views/main_menu/settings_view/licenses/license_detail_view.dart b/lib/presentation/views/main_menu/settings_view/licenses/license_detail_view.dart index e46fc31..5c5e709 100644 --- a/lib/presentation/views/main_menu/settings_view/licenses/license_detail_view.dart +++ b/lib/presentation/views/main_menu/settings_view/licenses/license_detail_view.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:game_tracker/core/custom_theme.dart'; import 'package:game_tracker/l10n/generated/app_localizations.dart'; import 'package:game_tracker/presentation/views/main_menu/settings_view/licenses/oss_licenses.dart'; +import 'package:game_tracker/presentation/widgets/colored_icon.dart'; import 'package:url_launcher/url_launcher.dart'; class LicenseDetailView extends StatelessWidget { @@ -29,19 +30,11 @@ class LicenseDetailView extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Container( - margin: const EdgeInsetsGeometry.only(right: 15), - width: 60, - height: 60, - decoration: BoxDecoration( - color: CustomTheme.primaryColor.withAlpha(40), - borderRadius: BorderRadius.circular(10), - ), - child: Icon( - Icons.description, - color: CustomTheme.primaryColor, - size: 30, - ), + const ColoredIconContainer( + icon: Icons.description, + margin: EdgeInsetsGeometry.only(right: 15), + containerSize: 60, + iconSize: 30, ), Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/presentation/widgets/colored_icon.dart b/lib/presentation/widgets/colored_icon.dart new file mode 100644 index 0000000..be51cd2 --- /dev/null +++ b/lib/presentation/widgets/colored_icon.dart @@ -0,0 +1,57 @@ +import 'package:flutter/cupertino.dart'; +import 'package:game_tracker/core/custom_theme.dart'; + +class ColoredIconContainer extends StatelessWidget { + /// A customizable container widget that displays an icon with a colored background. + /// - [icon]: The icon to be displayed inside the container. + /// - [containerSize]: The size of the container (width and height). + /// - [iconSize]: The size of the icon inside the container. + /// - [margin]: Optional margin around the container. + /// - [padding]: Optional padding inside the container. + const ColoredIconContainer({ + super.key, + required this.icon, + this.containerSize = 44, + this.iconSize = 28, + this.margin, + this.padding, + }); + + /// The icon to be displayed inside the container. + final IconData icon; + + /// The size of the container (width and height). + final double containerSize; + + /// The size of the icon inside the container. + final double iconSize; + + /// Optional margin around the container. + final EdgeInsetsGeometry? margin; + + /// Optional padding inside the container. + final EdgeInsetsGeometry? padding; + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + Container( + width: containerSize, + height: containerSize, + margin: margin, + padding: padding, + decoration: BoxDecoration( + color: CustomTheme.primaryColor.withAlpha(40), + borderRadius: BorderRadius.circular(10), + ), + child: Icon( + icon, + size: iconSize, + color: CustomTheme.primaryColor.withGreen(40), + ), + ), + ], + ); + } +} diff --git a/lib/presentation/widgets/tiles/license_tile.dart b/lib/presentation/widgets/tiles/license_tile.dart index 14ee2bf..3523adb 100644 --- a/lib/presentation/widgets/tiles/license_tile.dart +++ b/lib/presentation/widgets/tiles/license_tile.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:game_tracker/core/custom_theme.dart'; import 'package:game_tracker/presentation/views/main_menu/settings_view/licenses/license_detail_view.dart'; import 'package:game_tracker/presentation/views/main_menu/settings_view/licenses/oss_licenses.dart'; +import 'package:game_tracker/presentation/widgets/colored_icon.dart'; class LicenseTile extends StatelessWidget { /// A tile widget that displays information about a software package license. @@ -29,18 +30,10 @@ class LicenseTile extends StatelessWidget { ), child: Row( children: [ - Container( - width: 50, - height: 50, - decoration: BoxDecoration( - color: CustomTheme.primaryColor.withAlpha(40), - borderRadius: BorderRadius.circular(10), - ), - child: Icon( - Icons.description, - color: CustomTheme.primaryColor, - size: 32, - ), + const ColoredIconContainer( + icon: Icons.description, + containerSize: 50, + iconSize: 32, ), const SizedBox(width: 16), Expanded( diff --git a/lib/presentation/widgets/tiles/settings_list_tile.dart b/lib/presentation/widgets/tiles/settings_list_tile.dart index 53fb041..50f27d2 100644 --- a/lib/presentation/widgets/tiles/settings_list_tile.dart +++ b/lib/presentation/widgets/tiles/settings_list_tile.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:game_tracker/core/custom_theme.dart'; +import 'package:game_tracker/presentation/widgets/colored_icon.dart'; class SettingsListTile extends StatelessWidget { /// A customizable settings list tile widget that displays an icon, title, and an optional suffix widget. @@ -46,18 +47,10 @@ class SettingsListTile extends StatelessWidget { Row( mainAxisSize: MainAxisSize.min, children: [ - Container( - width: 44, - height: 44, - decoration: BoxDecoration( - color: CustomTheme.primaryColor.withAlpha(40), - borderRadius: BorderRadius.circular(10), - ), - child: Icon( - icon, - size: 28, - color: CustomTheme.primaryColor.withGreen(40), - ), + ColoredIconContainer( + icon: icon, + containerSize: 44, + iconSize: 28, ), const SizedBox(width: 16), Text(title, style: const TextStyle(fontSize: 18)), diff --git a/pubspec.yaml b/pubspec.yaml index 3f5a5f8..e8de5ed 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: game_tracker description: "Game Tracking App for Card Games" publish_to: 'none' -version: 0.0.7+221 +version: 0.0.7+227 environment: sdk: ^3.8.1 From fc6eb2b9cf3ea3490bbac698b5d4e4b7840d7034 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Sat, 17 Jan 2026 00:52:13 +0100 Subject: [PATCH 3/9] Added comments --- lib/core/custom_theme.dart | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/core/custom_theme.dart b/lib/core/custom_theme.dart index 12ac4a8..2c18073 100644 --- a/lib/core/custom_theme.dart +++ b/lib/core/custom_theme.dart @@ -5,14 +5,32 @@ class CustomTheme { CustomTheme._(); // Private constructor to prevent instantiation // ==================== Colors ==================== + + /// Primary color of the app theme static Color primaryColor = const Color(0xFF7505E4); + + /// Secondary color of the app theme static Color secondaryColor = const Color(0xFFAFA2FF); + + /// Background color of the app theme static Color backgroundColor = const Color(0xFF0B0B0B); + + /// Default color for boxes and containers static Color boxColor = const Color(0xFF101010); - static Color onBoxColor = const Color(0xFF181818); + + /// Default border color for boxes and containers static Color boxBorder = const Color(0xFF272727); + + /// Color for boxes and containers displayed on boxes + static Color onBoxColor = const Color(0xFF181818); + + /// Text color used throughout the app static const Color textColor = Colors.white; + + /// Selected color for the [NavbarItem] static Color navBarItemSelectedColor = primaryColor.withGreen(100); + + /// Unselected color for the [NavbarItem] static Color navBarItemUnselectedColor = Colors.grey.shade400; // ==================== Border Radius ==================== From abb0fcbbd62b220665b6321b6ca43b2ed5b06cca Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Sat, 17 Jan 2026 00:57:28 +0100 Subject: [PATCH 4/9] Updated file name --- .../views/main_menu/group_view/group_profile_view.dart | 2 +- .../main_menu/settings_view/licenses/license_detail_view.dart | 2 +- .../widgets/{colored_icon.dart => colored_icon_container.dart} | 0 lib/presentation/widgets/tiles/license_tile.dart | 2 +- lib/presentation/widgets/tiles/settings_list_tile.dart | 2 +- pubspec.yaml | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) rename lib/presentation/widgets/{colored_icon.dart => colored_icon_container.dart} (100%) diff --git a/lib/presentation/views/main_menu/group_view/group_profile_view.dart b/lib/presentation/views/main_menu/group_view/group_profile_view.dart index 2555020..6a92c22 100644 --- a/lib/presentation/views/main_menu/group_view/group_profile_view.dart +++ b/lib/presentation/views/main_menu/group_view/group_profile_view.dart @@ -8,7 +8,7 @@ import 'package:game_tracker/l10n/generated/app_localizations.dart'; import 'package:game_tracker/presentation/widgets/app_skeleton.dart'; import 'package:game_tracker/presentation/widgets/buttons/animated_dialog_button.dart'; import 'package:game_tracker/presentation/widgets/buttons/main_menu_button.dart'; -import 'package:game_tracker/presentation/widgets/colored_icon.dart'; +import 'package:game_tracker/presentation/widgets/colored_icon_container.dart'; import 'package:game_tracker/presentation/widgets/custom_alert_dialog.dart'; import 'package:game_tracker/presentation/widgets/tiles/info_tile.dart'; import 'package:game_tracker/presentation/widgets/tiles/text_icon_tile.dart'; diff --git a/lib/presentation/views/main_menu/settings_view/licenses/license_detail_view.dart b/lib/presentation/views/main_menu/settings_view/licenses/license_detail_view.dart index 5c5e709..54ff34e 100644 --- a/lib/presentation/views/main_menu/settings_view/licenses/license_detail_view.dart +++ b/lib/presentation/views/main_menu/settings_view/licenses/license_detail_view.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:game_tracker/core/custom_theme.dart'; import 'package:game_tracker/l10n/generated/app_localizations.dart'; import 'package:game_tracker/presentation/views/main_menu/settings_view/licenses/oss_licenses.dart'; -import 'package:game_tracker/presentation/widgets/colored_icon.dart'; +import 'package:game_tracker/presentation/widgets/colored_icon_container.dart'; import 'package:url_launcher/url_launcher.dart'; class LicenseDetailView extends StatelessWidget { diff --git a/lib/presentation/widgets/colored_icon.dart b/lib/presentation/widgets/colored_icon_container.dart similarity index 100% rename from lib/presentation/widgets/colored_icon.dart rename to lib/presentation/widgets/colored_icon_container.dart diff --git a/lib/presentation/widgets/tiles/license_tile.dart b/lib/presentation/widgets/tiles/license_tile.dart index 3523adb..33e5a45 100644 --- a/lib/presentation/widgets/tiles/license_tile.dart +++ b/lib/presentation/widgets/tiles/license_tile.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:game_tracker/core/custom_theme.dart'; import 'package:game_tracker/presentation/views/main_menu/settings_view/licenses/license_detail_view.dart'; import 'package:game_tracker/presentation/views/main_menu/settings_view/licenses/oss_licenses.dart'; -import 'package:game_tracker/presentation/widgets/colored_icon.dart'; +import 'package:game_tracker/presentation/widgets/colored_icon_container.dart'; class LicenseTile extends StatelessWidget { /// A tile widget that displays information about a software package license. diff --git a/lib/presentation/widgets/tiles/settings_list_tile.dart b/lib/presentation/widgets/tiles/settings_list_tile.dart index 50f27d2..d4bc6dc 100644 --- a/lib/presentation/widgets/tiles/settings_list_tile.dart +++ b/lib/presentation/widgets/tiles/settings_list_tile.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:game_tracker/core/custom_theme.dart'; -import 'package:game_tracker/presentation/widgets/colored_icon.dart'; +import 'package:game_tracker/presentation/widgets/colored_icon_container.dart'; class SettingsListTile extends StatelessWidget { /// A customizable settings list tile widget that displays an icon, title, and an optional suffix widget. diff --git a/pubspec.yaml b/pubspec.yaml index e8de5ed..f64f521 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: game_tracker description: "Game Tracking App for Card Games" publish_to: 'none' -version: 0.0.7+227 +version: 0.0.8+227 environment: sdk: ^3.8.1 From ff47ef38c1d32f9f322426b8c77c854f6b50f7ea Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Sat, 17 Jan 2026 14:51:12 +0100 Subject: [PATCH 5/9] Changed alignment --- .../views/main_menu/group_view/group_profile_view.dart | 5 ++++- lib/presentation/widgets/tiles/info_tile.dart | 6 +++++- pubspec.yaml | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/presentation/views/main_menu/group_view/group_profile_view.dart b/lib/presentation/views/main_menu/group_view/group_profile_view.dart index 6a92c22..1b19b6a 100644 --- a/lib/presentation/views/main_menu/group_view/group_profile_view.dart +++ b/lib/presentation/views/main_menu/group_view/group_profile_view.dart @@ -137,8 +137,11 @@ class _GroupProfileViewState extends State { InfoTile( title: loc.members, icon: Icons.people, + horizontalAlignment: CrossAxisAlignment.start, content: Wrap( - spacing: 8, + runAlignment: WrapAlignment.start, + crossAxisAlignment: WrapCrossAlignment.start, + spacing: 16, runSpacing: 8, children: widget.group.members.map((member) { return TextIconTile( diff --git a/lib/presentation/widgets/tiles/info_tile.dart b/lib/presentation/widgets/tiles/info_tile.dart index 280c7d7..78d7f28 100644 --- a/lib/presentation/widgets/tiles/info_tile.dart +++ b/lib/presentation/widgets/tiles/info_tile.dart @@ -17,6 +17,7 @@ class InfoTile extends StatefulWidget { this.padding, this.height, this.width, + this.horizontalAlignment = CrossAxisAlignment.center, }); /// The title text displayed on the tile. @@ -37,6 +38,9 @@ class InfoTile extends StatefulWidget { /// Optional width for the tile. final double? width; + /// The main axis alignment for the content. + final CrossAxisAlignment horizontalAlignment; + @override State createState() => _InfoTileState(); } @@ -51,7 +55,7 @@ class _InfoTileState extends State { decoration: CustomTheme.standardBoxDecoration, child: Column( mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, + crossAxisAlignment: widget.horizontalAlignment, children: [ Row( children: [ diff --git a/pubspec.yaml b/pubspec.yaml index f64f521..1ea28cc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: game_tracker description: "Game Tracking App for Card Games" publish_to: 'none' -version: 0.0.8+227 +version: 0.0.8+230 environment: sdk: ^3.8.1 From 514e0f8064b06852e0feb3fc4c7a4fb4bbc0fe68 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Sat, 17 Jan 2026 14:54:06 +0100 Subject: [PATCH 6/9] Changed date format --- .../views/main_menu/group_view/group_profile_view.dart | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/presentation/views/main_menu/group_view/group_profile_view.dart b/lib/presentation/views/main_menu/group_view/group_profile_view.dart index 1b19b6a..c739973 100644 --- a/lib/presentation/views/main_menu/group_view/group_profile_view.dart +++ b/lib/presentation/views/main_menu/group_view/group_profile_view.dart @@ -126,7 +126,7 @@ class _GroupProfileViewState extends State { ), const SizedBox(height: 5), Text( - "${loc.created_on} ${DateFormat('dd.MM.yyyy').format(widget.group.createdAt)}", + "${loc.created_on} ${DateFormat('MMM d, yyyy').format(widget.group.createdAt)}", style: const TextStyle( fontSize: 12, color: CustomTheme.textColor, diff --git a/pubspec.yaml b/pubspec.yaml index 1ea28cc..8b52ca1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: game_tracker description: "Game Tracking App for Card Games" publish_to: 'none' -version: 0.0.8+230 +version: 0.0.8+231 environment: sdk: ^3.8.1 From ddd0a5d8bdb1755ceb84292b7f3093b4193e3865 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Sat, 17 Jan 2026 15:17:33 +0100 Subject: [PATCH 7/9] Updated dateformat to localize --- .../views/main_menu/group_view/group_profile_view.dart | 2 +- lib/presentation/widgets/tiles/match_tile.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/presentation/views/main_menu/group_view/group_profile_view.dart b/lib/presentation/views/main_menu/group_view/group_profile_view.dart index c739973..072bbd6 100644 --- a/lib/presentation/views/main_menu/group_view/group_profile_view.dart +++ b/lib/presentation/views/main_menu/group_view/group_profile_view.dart @@ -126,7 +126,7 @@ class _GroupProfileViewState extends State { ), const SizedBox(height: 5), Text( - "${loc.created_on} ${DateFormat('MMM d, yyyy').format(widget.group.createdAt)}", + '${loc.created_on} ${DateFormat.yMMMd(Localizations.localeOf(context).toString()).format(widget.group.createdAt)}', style: const TextStyle( fontSize: 12, color: CustomTheme.textColor, diff --git a/lib/presentation/widgets/tiles/match_tile.dart b/lib/presentation/widgets/tiles/match_tile.dart index 11cdea0..e1365c1 100644 --- a/lib/presentation/widgets/tiles/match_tile.dart +++ b/lib/presentation/widgets/tiles/match_tile.dart @@ -230,7 +230,7 @@ class _MatchTileState extends State { } else if (difference.inDays < 7) { return loc.days_ago(difference.inDays); } else { - return DateFormat('MMM d, yyyy').format(dateTime); + return '${loc.created_on} ${DateFormat.yMMMd(Localizations.localeOf(context).toString()).format(dateTime)}'; } } From 8a38b9c3ea861933cc34e3e7d07776028d58cf72 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Sat, 17 Jan 2026 15:17:33 +0100 Subject: [PATCH 8/9] Updated dateformat to localize --- .../views/main_menu/group_view/group_profile_view.dart | 2 +- lib/presentation/widgets/tiles/match_tile.dart | 2 +- pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/presentation/views/main_menu/group_view/group_profile_view.dart b/lib/presentation/views/main_menu/group_view/group_profile_view.dart index c739973..072bbd6 100644 --- a/lib/presentation/views/main_menu/group_view/group_profile_view.dart +++ b/lib/presentation/views/main_menu/group_view/group_profile_view.dart @@ -126,7 +126,7 @@ class _GroupProfileViewState extends State { ), const SizedBox(height: 5), Text( - "${loc.created_on} ${DateFormat('MMM d, yyyy').format(widget.group.createdAt)}", + '${loc.created_on} ${DateFormat.yMMMd(Localizations.localeOf(context).toString()).format(widget.group.createdAt)}', style: const TextStyle( fontSize: 12, color: CustomTheme.textColor, diff --git a/lib/presentation/widgets/tiles/match_tile.dart b/lib/presentation/widgets/tiles/match_tile.dart index 11cdea0..e1365c1 100644 --- a/lib/presentation/widgets/tiles/match_tile.dart +++ b/lib/presentation/widgets/tiles/match_tile.dart @@ -230,7 +230,7 @@ class _MatchTileState extends State { } else if (difference.inDays < 7) { return loc.days_ago(difference.inDays); } else { - return DateFormat('MMM d, yyyy').format(dateTime); + return '${loc.created_on} ${DateFormat.yMMMd(Localizations.localeOf(context).toString()).format(dateTime)}'; } } diff --git a/pubspec.yaml b/pubspec.yaml index 6f6fd9b..a8159f8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: game_tracker description: "Game Tracking App for Card Games" publish_to: 'none' -version: 0.0.8+232 +version: 0.0.8+233 environment: sdk: ^3.8.1 From f5924c475834bd138a109f7e2bb5691d8d3c2cdb Mon Sep 17 00:00:00 2001 From: Mathis Kirchner Date: Sat, 17 Jan 2026 21:27:22 +0100 Subject: [PATCH 9/9] adjusted spacing & changed runAlignment to alignment --- .../views/main_menu/group_view/group_profile_view.dart | 4 ++-- pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/presentation/views/main_menu/group_view/group_profile_view.dart b/lib/presentation/views/main_menu/group_view/group_profile_view.dart index 072bbd6..e366834 100644 --- a/lib/presentation/views/main_menu/group_view/group_profile_view.dart +++ b/lib/presentation/views/main_menu/group_view/group_profile_view.dart @@ -139,9 +139,9 @@ class _GroupProfileViewState extends State { icon: Icons.people, horizontalAlignment: CrossAxisAlignment.start, content: Wrap( - runAlignment: WrapAlignment.start, + alignment: WrapAlignment.start, crossAxisAlignment: WrapCrossAlignment.start, - spacing: 16, + spacing: 12, runSpacing: 8, children: widget.group.members.map((member) { return TextIconTile( diff --git a/pubspec.yaml b/pubspec.yaml index a8159f8..432675a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: game_tracker description: "Game Tracking App for Card Games" publish_to: 'none' -version: 0.0.8+233 +version: 0.0.8+234 environment: sdk: ^3.8.1