diff --git a/khelo/assets/images/ic_error.svg b/khelo/assets/images/ic_error.svg
new file mode 100644
index 00000000..5abf543f
--- /dev/null
+++ b/khelo/assets/images/ic_error.svg
@@ -0,0 +1,31 @@
+
diff --git a/khelo/assets/images/ic_no_internet.svg b/khelo/assets/images/ic_no_internet.svg
new file mode 100644
index 00000000..2f6c4560
--- /dev/null
+++ b/khelo/assets/images/ic_no_internet.svg
@@ -0,0 +1,25 @@
+
diff --git a/khelo/assets/locales/app_en.arb b/khelo/assets/locales/app_en.arb
index 6fc709d1..2b523e03 100644
--- a/khelo/assets/locales/app_en.arb
+++ b/khelo/assets/locales/app_en.arb
@@ -77,10 +77,10 @@
},
"error_something_went_wrong": "Something went wrong! Please try again later.",
"error_no_internet": "No internet connection! Please check your network connectivity.",
- "no_internet_error_title": "No internet connected!!",
- "no_internet_error_description": "Please check your network connectivity and try again",
+ "no_internet_error_title": "No internet!",
+ "no_internet_error_description": "Network error. Please check connection and try again.",
"something_went_wrong_error_title": "Something went wrong",
- "something_went_wrong_error_description": "Your content is not loaded because of some unknown problem. We will fix it soon, Please try again later.",
+ "something_went_wrong_error_description": "This is all the information we have, but we won't rest until we resolve the issue!",
"@_ONBOARDING": {
},
@@ -121,7 +121,10 @@
"add_team_member_details_title": "Details",
"add_team_member_search_placeholder_text": "Search member name",
"add_team_member_verify_title": "Verify",
- "add_team_member_search_hint_text": "Search the person name above to add them in your team.",
+ "add_team_member_empty_title": "Your cricket crew awaits!",
+ "add_team_member_empty_description_text": "The pitch is set, but you need your players. Find them with a quick search.",
+ "add_team_member_search_no_result_title": "Oops! No User Found",
+ "add_team_member_search_description_text": "It seems we don't have anyone by that name. Give another name a go!",
"add_team_member_added_text": "ADDED",
"add_team_member_verify_error_text": "Please enter correct digits",
"add_team_member_verify_placeholder_text": "Enter the last {count} digits of the phone number of the selected player.",
@@ -138,9 +141,11 @@
"team_list_all_teams_title": "All teams",
"team_list_created_by_me_title": "Created by me",
"team_list_me_as_member_title": "Me as member",
- "team_list_empty_list_description": "Tap on '+' button to create your team.",
+ "team_list_no_teams_created_title": "No teams created",
+ "team_list_empty_list_description": "Tap on the “ + ” icon to create a team",
- "match_list_no_match_yet_title": "No Matches Yet",
+ "match_list_no_match_here_title": "No matches here",
+ "match_list_empty_list_description": "Tap on the “ + ” icon to create a match",
"match_list_overs_title": "{overs, plural, =0{{overs} overs} =1{{overs} over} other{{overs} overs}}",
"@match_list_overs_title": {
"description": "overs, plural, =0{{overs} overs} =1{{overs} over} other{{overs} overs}}",
@@ -192,7 +197,8 @@
"add_match_invalid_squad_error": "Please select valid squad",
"search_user_hint_title": "Search user name",
- "search_user_empty_text": "Search the person name in above input area.",
+ "search_user_empty_title": "Time to gather your officials!",
+ "search_user_empty_description_text": "Search and assign officials for your next match. Get ready for cricket action!",
"search_team_screen_title": "Search Team",
"search_team_your_teams_title": "Your Teams",
"search_team_selection_error_text": "The team must have at least 2 players to add it in a match.",
@@ -229,12 +235,15 @@
"team_detail_screen_title": "Team Detail",
"team_detail_member_tab_title": "Member",
- "team_detail_empty_member_title": "No team member are added to the team.",
+ "team_detail_empty_matches_title": "No matches scheduled yet!",
+ "team_detail_empty_matches_description_text": "Get your cricket game on! Schedule your cricket match with ease!",
+ "team_detail_empty_member_title": "You haven't any member!",
+ "team_detail_empty_member_description_text": "Invite your friends to build your dream team and start tracking matches together.",
+ "team_detail_empty_stat_title": "No stats available yet!",
+ "team_detail_empty_stat_description_text": "The players are warming up! Stay tuned for exciting stats as the team progresses.",
+ "team_detail_add_member_title": "Add member",
"team_detail_match_tab_title": "Match",
- "team_detail_empty_match_title": "Team hasn't compete with opponent till now.",
"team_detail_stat_tab_title": "Stat",
- "team_detail_empty_stat_title": "Team's analysis will be shown here based on it's previous matches.",
- "team_detail_add_member_title": "Add member",
"team_detail_won_title": "Won({win})",
"@team_detail_won_title": {
"description": "Won({win})",
@@ -303,6 +312,10 @@
"match_detail_match_info_tab_title": "Info",
"match_detail_highlight_tab_title": "Highlight",
"match_detail_overs_tab_title": "Overs",
+ "match_detail_match_not_started_error_title": "Match has not started yet.",
+ "match_detail_error_description_text": "The detailed will be available after the start of the match.",
+ "match_detail_highlight_empty_title": "No highlights currently available.",
+ "match_detail_highlight_empty_description_text": "No events recorded yet. Check back later for updates and highlights.",
"match_info_match_title": "Match",
"match_info_date_title": "Date",
@@ -418,7 +431,6 @@
"match_commentary_back_to_attack_text": " is back to attack",
"match_commentary_end_inning_text_part_1": " wraps up their innings, leaving ",
"match_commentary_end_inning_text_part_2": " for victory.",
- "match_commentary_empty_commentary_text": "Commentary will be shown here as soon as the match starts.",
"match_commentary_inning_count_text": "Inning {count}",
"@match_commentary_inning_count_text": {
"description": "Inning {count}",
@@ -510,8 +522,6 @@
"match_highlight_filter_all_text": "All",
"match_highlight_filter_fours_text": "Fours",
"match_highlight_filter_sixes_text": "Sixes",
- "match_highlight_empty_highlight_text": "No highlights to show here",
- "match_overs_empty_over_text": "Overs will be shown here as soon as the match starts",
"@_SCOREBOARD": {
},
diff --git a/khelo/lib/components/empty_screen.dart b/khelo/lib/components/empty_screen.dart
new file mode 100644
index 00000000..f096016b
--- /dev/null
+++ b/khelo/lib/components/empty_screen.dart
@@ -0,0 +1,62 @@
+import 'package:flutter/material.dart';
+import 'package:style/button/primary_button.dart';
+import 'package:style/extensions/context_extensions.dart';
+import 'package:style/text/app_text_style.dart';
+
+class EmptyScreen extends StatelessWidget {
+ final String title;
+ final String description;
+ final bool isShowButton;
+ final String? buttonTitle;
+ final Function()? onTap;
+
+ const EmptyScreen({
+ super.key,
+ required this.title,
+ required this.description,
+ this.isShowButton = true,
+ this.buttonTitle,
+ this.onTap,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return SingleChildScrollView(
+ child: ConstrainedBox(
+ constraints:
+ BoxConstraints(minHeight: context.mediaQuerySize.height / 1.4),
+ child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16.0),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(
+ title,
+ style: AppTextStyle.header2
+ .copyWith(color: context.colorScheme.textPrimary),
+ textAlign: TextAlign.center,
+ ),
+ const SizedBox(height: 8),
+ Text(
+ description,
+ style: AppTextStyle.subtitle1
+ .copyWith(color: context.colorScheme.textDisabled),
+ textAlign: TextAlign.center,
+ ),
+ if (isShowButton) ...[
+ const SizedBox(height: 24),
+ PrimaryButton(
+ buttonTitle ?? '',
+ edgeInsets:
+ const EdgeInsets.symmetric(horizontal: 24, vertical: 8),
+ expanded: false,
+ onPressed: onTap,
+ ),
+ ],
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/khelo/lib/components/error_screen.dart b/khelo/lib/components/error_screen.dart
index 6a4a7052..7ad152f6 100644
--- a/khelo/lib/components/error_screen.dart
+++ b/khelo/lib/components/error_screen.dart
@@ -1,8 +1,11 @@
import 'package:data/errors/app_error.dart';
import 'package:flutter/cupertino.dart';
+import 'package:flutter_svg/svg.dart';
import 'package:khelo/components/place_holder_screen.dart';
import 'package:khelo/domain/extensions/context_extensions.dart';
+import '../gen/assets.gen.dart';
+
class ErrorScreen extends StatelessWidget {
final Object? error;
final VoidCallback onRetryTap;
@@ -19,7 +22,11 @@ class ErrorScreen extends StatelessWidget {
}
Widget _noInternetConnectionScreen(BuildContext context) => PlaceHolderScreen(
- image: const SizedBox(),
+ image: SvgPicture.asset(
+ Assets.images.icNoInternet,
+ height: 140,
+ width: 140,
+ ),
title: context.l10n.no_internet_error_title,
message: context.l10n.no_internet_error_description,
onActionBtnTap: onRetryTap,
@@ -27,7 +34,11 @@ class ErrorScreen extends StatelessWidget {
);
Widget _errorScreen(BuildContext context) => PlaceHolderScreen(
- image: const SizedBox(),
+ image: SvgPicture.asset(
+ Assets.images.icError,
+ height: 140,
+ width: 140,
+ ),
title: context.l10n.something_went_wrong_error_title,
message: context.l10n.something_went_wrong_error_description,
onActionBtnTap: onRetryTap,
diff --git a/khelo/lib/components/place_holder_screen.dart b/khelo/lib/components/place_holder_screen.dart
index ba76815a..12202f6a 100644
--- a/khelo/lib/components/place_holder_screen.dart
+++ b/khelo/lib/components/place_holder_screen.dart
@@ -28,46 +28,48 @@ class PlaceHolderScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return Padding(
- padding: padding + context.mediaQueryPadding,
- child: Column(
- mainAxisSize: MainAxisSize.max,
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- image,
- SizedBox(
- height: 40,
- width: context.mediaQuerySize.width,
- ),
- Text(
- title,
- style: AppTextStyle.header1.copyWith(
- color: context.colorScheme.textPrimary,
+ return SingleChildScrollView(
+ child: ConstrainedBox(
+ constraints:
+ BoxConstraints(minHeight: context.mediaQuerySize.height / 1.3),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ image,
+ SizedBox(
+ height: 40,
+ width: context.mediaQuerySize.width,
),
- ),
- const SizedBox(height: 16),
- Visibility(
- visible: messageWidget != null,
- replacement: Text(
- message ?? '',
- style: AppTextStyle.subtitle1.copyWith(
- color: context.colorScheme.textSecondary,
+ Text(
+ title,
+ style: AppTextStyle.header1.copyWith(
+ color: context.colorScheme.textPrimary,
),
- textAlign: TextAlign.center,
),
- child: messageWidget ?? const SizedBox(),
- ),
- const SizedBox(height: 40),
- if (actionBtnTitle != null) ...[
- PrimaryButton(
- edgeInsets:
- const EdgeInsets.symmetric(vertical: 16, horizontal: 32),
- actionBtnTitle ?? '',
- onPressed: onActionBtnTap,
- expanded: false,
+ const SizedBox(height: 16),
+ Visibility(
+ visible: messageWidget != null,
+ replacement: Text(
+ message ?? '',
+ style: AppTextStyle.subtitle1.copyWith(
+ color: context.colorScheme.textSecondary,
+ ),
+ textAlign: TextAlign.center,
+ ),
+ child: messageWidget ?? const SizedBox(),
),
+ const SizedBox(height: 40),
+ if (actionBtnTitle != null) ...[
+ PrimaryButton(
+ edgeInsets:
+ const EdgeInsets.symmetric(vertical: 16, horizontal: 32),
+ actionBtnTitle ?? '',
+ onPressed: onActionBtnTap,
+ expanded: false,
+ ),
+ ],
],
- ],
+ ),
),
);
}
diff --git a/khelo/lib/gen/assets.gen.dart b/khelo/lib/gen/assets.gen.dart
index b171e6a3..a3a30052 100644
--- a/khelo/lib/gen/assets.gen.dart
+++ b/khelo/lib/gen/assets.gen.dart
@@ -49,6 +49,9 @@ class $AssetsImagesGen {
/// File path: assets/images/ic_edit.svg
String get icEdit => 'assets/images/ic_edit.svg';
+ /// File path: assets/images/ic_error.svg
+ String get icError => 'assets/images/ic_error.svg';
+
/// File path: assets/images/ic_gallery.svg
String get icGallery => 'assets/images/ic_gallery.svg';
@@ -61,6 +64,9 @@ class $AssetsImagesGen {
/// File path: assets/images/ic_location.svg
String get icLocation => 'assets/images/ic_location.svg';
+ /// File path: assets/images/ic_no_internet.svg
+ String get icNoInternet => 'assets/images/ic_no_internet.svg';
+
/// File path: assets/images/ic_privacy_policy.svg
String get icPrivacyPolicy => 'assets/images/ic_privacy_policy.svg';
@@ -130,10 +136,12 @@ class $AssetsImagesGen {
icContactSupport,
icCricket,
icEdit,
+ icError,
icGallery,
icGroup,
icHome,
icLocation,
+ icNoInternet,
icPrivacyPolicy,
icProfile,
icProfileThin,
diff --git a/khelo/lib/ui/flow/home/home_screen.dart b/khelo/lib/ui/flow/home/home_screen.dart
index 43cacfd9..79f370e9 100644
--- a/khelo/lib/ui/flow/home/home_screen.dart
+++ b/khelo/lib/ui/flow/home/home_screen.dart
@@ -38,7 +38,9 @@ class _HomeScreenState extends ConsumerState {
return AppPage(
title: context.l10n.common_matches_title,
- body: _body(context, notifier, state),
+ body: Builder(builder: (context) {
+ return _body(context, notifier, state);
+ }),
);
}
diff --git a/khelo/lib/ui/flow/matches/add_match/match_officials/search_user/search_user_screen.dart b/khelo/lib/ui/flow/matches/add_match/match_officials/search_user/search_user_screen.dart
index f1a5e8cd..a72529ff 100644
--- a/khelo/lib/ui/flow/matches/add_match/match_officials/search_user/search_user_screen.dart
+++ b/khelo/lib/ui/flow/matches/add_match/match_officials/search_user/search_user_screen.dart
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
+import 'package:khelo/components/empty_screen.dart';
import 'package:khelo/components/error_screen.dart';
import 'package:khelo/components/user_detail_cell.dart';
import 'package:khelo/domain/extensions/context_extensions.dart';
@@ -11,7 +12,6 @@ import 'package:khelo/ui/flow/matches/add_match/select_squad/components/user_det
import 'package:khelo/ui/flow/team/add_team_member/components/verify_team_member_sheet.dart';
import 'package:style/button/secondary_button.dart';
import 'package:style/extensions/context_extensions.dart';
-import 'package:style/text/app_text_style.dart';
import 'package:style/text/search_text_field.dart';
class SearchUserBottomSheet extends ConsumerWidget {
@@ -63,17 +63,14 @@ class SearchUserBottomSheet extends ConsumerWidget {
}
return state.searchedUsers.isEmpty
- ? Padding(
- padding: const EdgeInsets.symmetric(horizontal: 16.0),
- child: Center(
- child: Text(
- context.l10n.search_user_empty_text,
- textAlign: TextAlign.center,
- style: AppTextStyle.body1.copyWith(
- color: context.colorScheme.textPrimary,
- ),
- ),
- ),
+ ? EmptyScreen(
+ title: (state.searchController.text.isNotEmpty)
+ ? context.l10n.add_team_member_search_no_result_title
+ : context.l10n.search_user_empty_title,
+ description: (state.searchController.text.isNotEmpty)
+ ? context.l10n.add_team_member_search_description_text
+ : context.l10n.search_user_empty_description_text,
+ isShowButton: false,
)
: ListView.separated(
separatorBuilder: (context, index) {
diff --git a/khelo/lib/ui/flow/matches/add_match/match_officials/search_user/search_user_view_model.dart b/khelo/lib/ui/flow/matches/add_match/match_officials/search_user/search_user_view_model.dart
index 416c88af..6bd82ebe 100644
--- a/khelo/lib/ui/flow/matches/add_match/match_officials/search_user/search_user_view_model.dart
+++ b/khelo/lib/ui/flow/matches/add_match/match_officials/search_user/search_user_view_model.dart
@@ -24,7 +24,10 @@ class SearchUserViewNotifier extends StateNotifier {
Future search(String searchKey) async {
try {
- state = state.copyWith(error: null);
+ if (searchKey.isEmpty) {
+ state = state.copyWith(searchedUsers: [], error: null);
+ return;
+ }
final users = await _userService.searchUser(searchKey);
state = state.copyWith(searchedUsers: users);
} catch (e) {
@@ -39,9 +42,7 @@ class SearchUserViewNotifier extends StateNotifier {
}
_debounce = Timer(const Duration(milliseconds: 500), () async {
- if (state.searchController.text.isNotEmpty) {
- search(state.searchController.text.trim());
- }
+ search(state.searchController.text.trim());
});
}
diff --git a/khelo/lib/ui/flow/matches/match_detail/components/match_detail_commentary_view.dart b/khelo/lib/ui/flow/matches/match_detail/components/match_detail_commentary_view.dart
index a05d89f0..91c36f7d 100644
--- a/khelo/lib/ui/flow/matches/match_detail/components/match_detail_commentary_view.dart
+++ b/khelo/lib/ui/flow/matches/match_detail/components/match_detail_commentary_view.dart
@@ -4,6 +4,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:khelo/components/empty_screen.dart';
import 'package:khelo/components/error_screen.dart';
import 'package:khelo/domain/extensions/context_extensions.dart';
import 'package:khelo/ui/flow/matches/match_detail/components/commentary_ball_summary.dart';
@@ -38,24 +39,16 @@ class MatchDetailCommentaryView extends ConsumerWidget {
);
}
- if (state.overList.isEmpty) {
- return Center(
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 16.0),
- child: Text(
- context.l10n.match_commentary_empty_commentary_text,
- textAlign: TextAlign.center,
- style: AppTextStyle.body1
- .copyWith(color: context.colorScheme.textPrimary),
- ),
- ),
- );
- }
-
- return ListView(
- padding: context.mediaQueryPadding,
- children: _buildCommentaryList(context, state),
- );
+ return (state.overList.isNotEmpty)
+ ? ListView(
+ padding: context.mediaQueryPadding,
+ children: _buildCommentaryList(context, state),
+ )
+ : EmptyScreen(
+ title: context.l10n.match_detail_match_not_started_error_title,
+ description: context.l10n.match_detail_error_description_text,
+ isShowButton: false,
+ );
}
List _buildCommentaryList(
diff --git a/khelo/lib/ui/flow/matches/match_detail/components/match_detail_highlight_view.dart b/khelo/lib/ui/flow/matches/match_detail/components/match_detail_highlight_view.dart
index 6c06ec92..ac2452ea 100644
--- a/khelo/lib/ui/flow/matches/match_detail/components/match_detail_highlight_view.dart
+++ b/khelo/lib/ui/flow/matches/match_detail/components/match_detail_highlight_view.dart
@@ -5,13 +5,13 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart';
import 'package:khelo/components/action_bottom_sheet.dart';
+import 'package:khelo/components/empty_screen.dart';
import 'package:khelo/components/error_screen.dart';
import 'package:khelo/domain/extensions/context_extensions.dart';
import 'package:khelo/ui/flow/matches/match_detail/components/commentary_ball_summary.dart';
import 'package:khelo/ui/flow/matches/match_detail/match_detail_tab_view_model.dart';
import 'package:style/extensions/context_extensions.dart';
import 'package:style/indicator/progress_indicator.dart';
-import 'package:style/text/app_text_style.dart';
import 'package:style/widgets/adaptive_outlined_tile.dart';
import '../../../../../gen/assets.gen.dart';
@@ -126,29 +126,23 @@ class MatchDetailHighlightView extends ConsumerWidget {
final highlight = state.filteredHighlight;
if (highlight.isEmpty) {
- return Center(
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 16),
- child: Text(
- context.l10n.match_highlight_empty_highlight_text,
- textAlign: TextAlign.center,
- style: AppTextStyle.body1
- .copyWith(color: context.colorScheme.textPrimary),
- ),
- ),
+ return EmptyScreen(
+ title: context.l10n.match_detail_highlight_empty_title,
+ description: context.l10n.match_detail_highlight_empty_description_text,
+ isShowButton: false,
+ );
+ } else {
+ return ListView.separated(
+ itemCount: highlight.length,
+ padding: const EdgeInsets.only(top: 24),
+ separatorBuilder: (context, index) =>
+ Divider(color: context.colorScheme.outline, height: 32),
+ itemBuilder: (context, index) {
+ final overSummary = highlight[index];
+ return Column(children: _buildHighlightList(context, overSummary));
+ },
);
}
-
- return ListView.separated(
- itemCount: highlight.length,
- padding: const EdgeInsets.only(top: 24),
- separatorBuilder: (context, index) =>
- Divider(color: context.colorScheme.outline, height: 32),
- itemBuilder: (context, index) {
- final overSummary = highlight[index];
- return Column(children: _buildHighlightList(context, overSummary));
- },
- );
}
List _buildHighlightList(
diff --git a/khelo/lib/ui/flow/matches/match_detail/components/match_detail_overs_view.dart b/khelo/lib/ui/flow/matches/match_detail/components/match_detail_overs_view.dart
index 9c94edbe..e9506546 100644
--- a/khelo/lib/ui/flow/matches/match_detail/components/match_detail_overs_view.dart
+++ b/khelo/lib/ui/flow/matches/match_detail/components/match_detail_overs_view.dart
@@ -10,6 +10,8 @@ import 'package:style/extensions/context_extensions.dart';
import 'package:style/indicator/progress_indicator.dart';
import 'package:style/text/app_text_style.dart';
+import '../../../../../components/empty_screen.dart';
+
class MatchDetailOversView extends ConsumerWidget {
const MatchDetailOversView({super.key});
@@ -34,29 +36,21 @@ class MatchDetailOversView extends ConsumerWidget {
);
}
- if (state.overList.isEmpty) {
- return Center(
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 16.0),
- child: Text(
- context.l10n.match_overs_empty_over_text,
- textAlign: TextAlign.center,
- style: AppTextStyle.body1
- .copyWith(color: context.colorScheme.textPrimary),
- ),
- ),
- );
- }
-
- return ListView(
- padding: context.mediaQueryPadding,
- children: [
- const Padding(
- padding: EdgeInsets.symmetric(horizontal: 16.0),
- child: FinalScoreView(),
- ),
- ..._buildOverList(context, state),
- ],
+ return (state.overList.isNotEmpty)
+ ? ListView(
+ padding: context.mediaQueryPadding,
+ children: [
+ const Padding(
+ padding: EdgeInsets.symmetric(horizontal: 16.0),
+ child: FinalScoreView(),
+ ),
+ ..._buildOverList(context, state),
+ ],
+ )
+ : EmptyScreen(
+ title: context.l10n.match_detail_match_not_started_error_title,
+ description: context.l10n.match_detail_error_description_text,
+ isShowButton: false,
);
}
diff --git a/khelo/lib/ui/flow/matches/match_detail/components/match_detail_scorecard_view.dart b/khelo/lib/ui/flow/matches/match_detail/components/match_detail_scorecard_view.dart
index 08858e18..e2a94f15 100644
--- a/khelo/lib/ui/flow/matches/match_detail/components/match_detail_scorecard_view.dart
+++ b/khelo/lib/ui/flow/matches/match_detail/components/match_detail_scorecard_view.dart
@@ -13,6 +13,8 @@ import 'package:style/extensions/context_extensions.dart';
import 'package:style/indicator/progress_indicator.dart';
import 'package:style/text/app_text_style.dart';
+import '../../../../../components/empty_screen.dart';
+
class MatchDetailScorecardView extends ConsumerWidget {
const MatchDetailScorecardView({super.key});
@@ -36,19 +38,20 @@ class MatchDetailScorecardView extends ConsumerWidget {
);
}
- if (state.overList.isEmpty) {
- return Center(
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 16),
- child: Text(
- context.l10n.match_scorecard_empty_scorecard_text,
- textAlign: TextAlign.center,
- style: AppTextStyle.body1
- .copyWith(color: context.colorScheme.textPrimary),
- ),
- ),
- );
- }
+ return (state.overList.isNotEmpty)
+ ? _content(context, notifier, state)
+ : EmptyScreen(
+ title: context.l10n.match_detail_match_not_started_error_title,
+ description: context.l10n.match_detail_error_description_text,
+ isShowButton: false,
+ );
+ }
+
+ Widget _content(
+ BuildContext context,
+ MatchDetailTabViewNotifier notifier,
+ MatchDetailTabState state,
+ ) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
diff --git a/khelo/lib/ui/flow/matches/match_list_screen.dart b/khelo/lib/ui/flow/matches/match_list_screen.dart
index e1398dbe..90312967 100644
--- a/khelo/lib/ui/flow/matches/match_list_screen.dart
+++ b/khelo/lib/ui/flow/matches/match_list_screen.dart
@@ -1,13 +1,13 @@
import 'package:data/api/match/match_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:khelo/components/empty_screen.dart';
import 'package:khelo/components/error_screen.dart';
import 'package:khelo/components/match_detail_cell.dart';
import 'package:khelo/domain/extensions/context_extensions.dart';
import 'package:khelo/ui/app_route.dart';
import 'package:style/extensions/context_extensions.dart';
import 'package:style/indicator/progress_indicator.dart';
-import 'package:style/text/app_text_style.dart';
import 'match_list_view_model.dart';
@@ -60,47 +60,43 @@ class _MatchListScreenState extends ConsumerState
);
}
- if (state.matches != null && state.matches!.isNotEmpty) {
- return ListView.separated(
- padding: context.mediaQueryPadding +
- const EdgeInsets.all(16) +
- const EdgeInsets.only(bottom: 70),
- itemCount: state.matches!.length,
- separatorBuilder: (context, index) {
- return const SizedBox(height: 16);
- },
- itemBuilder: (context, index) {
- final match = state.matches![index];
- return MatchDetailCell(
- match: match,
- showActionButtons: match.created_by == state.currentUserId,
- onTap: () =>
- AppRoute.matchDetailTab(matchId: match.id ?? "").push(context),
- onActionTap: () {
- if (match.match_status == MatchStatus.yetToStart) {
- AppRoute.addMatch(matchId: match.id).push(context);
- } else {
- if (match.toss_decision == null ||
- match.toss_winner_id == null) {
- AppRoute.addTossDetail(matchId: match.id ?? "INVALID_ID")
- .push(context);
- } else {
- AppRoute.scoreBoard(matchId: match.id ?? "INVALID_ID")
- .push(context);
- }
- }
+ return (state.matches != null && state.matches!.isNotEmpty)
+ ? ListView.separated(
+ padding: context.mediaQueryPadding +
+ const EdgeInsets.all(16) +
+ const EdgeInsets.only(bottom: 70),
+ itemCount: state.matches!.length,
+ separatorBuilder: (context, index) {
+ return const SizedBox(height: 16);
},
+ itemBuilder: (context, index) {
+ final match = state.matches![index];
+ return MatchDetailCell(
+ match: match,
+ showActionButtons: match.created_by == state.currentUserId,
+ onTap: () => AppRoute.matchDetailTab(matchId: match.id ?? "")
+ .push(context),
+ onActionTap: () {
+ if (match.match_status == MatchStatus.yetToStart) {
+ AppRoute.addMatch(matchId: match.id).push(context);
+ } else {
+ if (match.toss_decision == null ||
+ match.toss_winner_id == null) {
+ AppRoute.addTossDetail(matchId: match.id ?? "INVALID_ID")
+ .push(context);
+ } else {
+ AppRoute.scoreBoard(matchId: match.id ?? "INVALID_ID")
+ .push(context);
+ }
+ }
+ },
+ );
+ },
+ )
+ : EmptyScreen(
+ title: context.l10n.match_list_no_match_here_title,
+ description: context.l10n.match_list_empty_list_description,
+ isShowButton: false,
);
- },
- );
- } else {
- return Center(
- child: Text(
- context.l10n.match_list_no_match_yet_title,
- style: AppTextStyle.body1
- .copyWith(color: context.colorScheme.textPrimary),
- ),
- );
- }
}
}
diff --git a/khelo/lib/ui/flow/my_game/my_game_tab_screen.dart b/khelo/lib/ui/flow/my_game/my_game_tab_screen.dart
index 61358e54..b24ddbf3 100644
--- a/khelo/lib/ui/flow/my_game/my_game_tab_screen.dart
+++ b/khelo/lib/ui/flow/my_game/my_game_tab_screen.dart
@@ -106,7 +106,8 @@ class _MyGameTabScreenState extends ConsumerState
},
),
const Spacer(),
- if (_selectedTab == 1) ...[
+ if (_selectedTab == 1 &&
+ ref.watch(teamListViewStateProvider).teams.isNotEmpty) ...[
actionButton(context,
onPressed: () => ref
.read(teamListViewStateProvider.notifier)
diff --git a/khelo/lib/ui/flow/stats/user_match/user_match_list_screen.dart b/khelo/lib/ui/flow/stats/user_match/user_match_list_screen.dart
index 8fa9a705..be522c47 100644
--- a/khelo/lib/ui/flow/stats/user_match/user_match_list_screen.dart
+++ b/khelo/lib/ui/flow/stats/user_match/user_match_list_screen.dart
@@ -1,13 +1,14 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:khelo/components/empty_screen.dart';
import 'package:khelo/components/error_screen.dart';
import 'package:khelo/components/match_detail_cell.dart';
import 'package:khelo/domain/extensions/context_extensions.dart';
import 'package:khelo/ui/app_route.dart';
+
import 'package:khelo/ui/flow/stats/user_match/user_match_list_view_model.dart';
import 'package:style/extensions/context_extensions.dart';
import 'package:style/indicator/progress_indicator.dart';
-import 'package:style/text/app_text_style.dart';
class UserMatchListScreen extends ConsumerStatefulWidget {
const UserMatchListScreen({super.key});
@@ -56,27 +57,26 @@ class _UserMatchListScreenState extends ConsumerState
);
}
- if (state.matches.isNotEmpty) {
- return ListView.separated(
- padding: const EdgeInsets.all(16) + context.mediaQueryPadding,
- itemCount: state.matches.length,
- itemBuilder: (context, index) => MatchDetailCell(
- match: state.matches.elementAt(index),
- showStatusTag: false,
- onTap: () => AppRoute.matchDetailTab(
- matchId: state.matches.elementAt(index).id ?? "INVALID ID")
- .push(context),
- ),
- separatorBuilder: (context, index) => const SizedBox(height: 16),
- );
- } else {
- return Center(
- child: Text(
- context.l10n.match_list_no_match_yet_title,
- style: AppTextStyle.body1
- .copyWith(color: context.colorScheme.textPrimary),
- ),
- );
- }
+ return (state.matches.isNotEmpty)
+ ? ListView.separated(
+ padding: const EdgeInsets.all(16) + context.mediaQueryPadding,
+ itemCount: state.matches.length,
+ itemBuilder: (context, index) => MatchDetailCell(
+ match: state.matches.elementAt(index),
+ showStatusTag: false,
+ onTap: () => AppRoute.matchDetailTab(
+ matchId:
+ state.matches.elementAt(index).id ?? "INVALID ID")
+ .push(context),
+ ),
+ separatorBuilder: (context, index) => const SizedBox(height: 16),
+ )
+ : EmptyScreen(
+ title: context.l10n.match_list_no_match_here_title,
+ description:
+ context.l10n.team_detail_empty_matches_description_text,
+ buttonTitle: context.l10n.add_match_screen_title,
+ onTap: () => AppRoute.addMatch().push(context),
+ );
}
}
diff --git a/khelo/lib/ui/flow/team/add_team_member/add_team_member_screen.dart b/khelo/lib/ui/flow/team/add_team_member/add_team_member_screen.dart
index eea067b0..d3b2f4a9 100644
--- a/khelo/lib/ui/flow/team/add_team_member/add_team_member_screen.dart
+++ b/khelo/lib/ui/flow/team/add_team_member/add_team_member_screen.dart
@@ -5,6 +5,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart';
import 'package:khelo/components/app_page.dart';
+import 'package:khelo/components/empty_screen.dart';
import 'package:khelo/components/error_screen.dart';
import 'package:khelo/components/error_snackbar.dart';
import 'package:khelo/components/image_avatar.dart';
@@ -67,26 +68,11 @@ class _AddTeamMemberScreenState extends ConsumerState {
),
),
],
- body: Builder(builder: (context) {
- return Padding(
- padding: context.mediaQueryPadding +
- const EdgeInsets.symmetric(vertical: 8),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- _searchField(context, state),
- if (state.selectedUsers.isNotEmpty) ...[
- _selectedPlayerList(context, state),
- ],
- _content(context, state),
- ],
- ),
- );
- }),
+ body: Builder(builder: (context) => _body(context, state)),
);
}
- Widget _content(
+ Widget _body(
BuildContext context,
AddTeamMemberState state,
) {
@@ -96,15 +82,37 @@ class _AddTeamMemberScreenState extends ConsumerState {
onRetryTap: notifier.onSearchChanged,
);
}
+
+ return Padding(
+ padding:
+ context.mediaQueryPadding + const EdgeInsets.symmetric(vertical: 8),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ _searchField(context, state),
+ if (state.selectedUsers.isNotEmpty) ...[
+ _selectedPlayerList(context, state),
+ ],
+ _searchedPlayerList(context, state),
+ ],
+ ),
+ );
+ }
+
+ Widget _searchedPlayerList(
+ BuildContext context,
+ AddTeamMemberState state,
+ ) {
return Expanded(
- child: state.searchedUsers.isEmpty
- ? Center(
- child: Text(
- context.l10n.add_team_member_search_hint_text,
- textAlign: TextAlign.center,
- style: AppTextStyle.subtitle1
- .copyWith(color: context.colorScheme.textDisabled),
- ),
+ child: (state.searchedUsers.isEmpty)
+ ? EmptyScreen(
+ title: (state.searchController.text.isNotEmpty)
+ ? context.l10n.add_team_member_search_no_result_title
+ : context.l10n.add_team_member_empty_title,
+ description: (state.searchController.text.isNotEmpty)
+ ? context.l10n.add_team_member_search_description_text
+ : context.l10n.add_team_member_empty_description_text,
+ isShowButton: false,
)
: ListView.separated(
itemCount: state.searchedUsers.length,
diff --git a/khelo/lib/ui/flow/team/add_team_member/add_team_member_view_model.dart b/khelo/lib/ui/flow/team/add_team_member/add_team_member_view_model.dart
index c78ca0c1..905892f6 100644
--- a/khelo/lib/ui/flow/team/add_team_member/add_team_member_view_model.dart
+++ b/khelo/lib/ui/flow/team/add_team_member/add_team_member_view_model.dart
@@ -27,6 +27,10 @@ class AddTeamMemberViewNotifier extends StateNotifier {
Future search(String searchKey) async {
try {
+ if (searchKey.isEmpty) {
+ state = state.copyWith(searchedUsers: []);
+ return;
+ }
final users = await _userService.searchUser(searchKey);
state = state.copyWith(searchedUsers: users, error: null);
} catch (e) {
@@ -41,9 +45,7 @@ class AddTeamMemberViewNotifier extends StateNotifier {
}
_debounce = Timer(const Duration(milliseconds: 500), () async {
- if (state.searchController.text.isNotEmpty) {
- search(state.searchController.text.trim());
- }
+ search(state.searchController.text.trim());
});
}
diff --git a/khelo/lib/ui/flow/team/detail/components/team_detail_match_content.dart b/khelo/lib/ui/flow/team/detail/components/team_detail_match_content.dart
index 76fb4bb4..c8c8ae74 100644
--- a/khelo/lib/ui/flow/team/detail/components/team_detail_match_content.dart
+++ b/khelo/lib/ui/flow/team/detail/components/team_detail_match_content.dart
@@ -1,12 +1,11 @@
import 'package:data/api/match/match_model.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:khelo/components/empty_screen.dart';
import 'package:khelo/components/match_detail_cell.dart';
import 'package:khelo/domain/extensions/context_extensions.dart';
import 'package:khelo/ui/app_route.dart';
import 'package:khelo/ui/flow/team/detail/team_detail_view_model.dart';
-import 'package:style/extensions/context_extensions.dart';
-import 'package:style/text/app_text_style.dart';
class TeamDetailMatchContent extends ConsumerWidget {
const TeamDetailMatchContent({super.key});
@@ -45,17 +44,20 @@ class TeamDetailMatchContent extends ConsumerWidget {
separatorBuilder: (context, index) => const SizedBox(height: 16),
);
} else {
- return Center(
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 16.0),
- child: Text(
- context.l10n.team_detail_empty_match_title,
- textAlign: TextAlign.center,
- style: AppTextStyle.body2
- .copyWith(color: context.colorScheme.textPrimary),
- ),
- ),
- );
+ return EmptyScreen(
+ title: context.l10n.team_detail_empty_matches_title,
+ description: context.l10n.team_detail_empty_matches_description_text,
+ buttonTitle: context.l10n.add_match_screen_title,
+ onTap: () async {
+ bool? isUpdated = await AppRoute.addMatch(
+ defaultTeam: (state.team?.players?.length ?? 0) >= 2
+ ? state.team
+ : null)
+ .push(context);
+ if (isUpdated == true && context.mounted) {
+ ref.read(teamDetailStateProvider.notifier).loadTeamById();
+ }
+ });
}
}
}
diff --git a/khelo/lib/ui/flow/team/detail/components/team_detail_member_content.dart b/khelo/lib/ui/flow/team/detail/components/team_detail_member_content.dart
index e9e6062a..9f49c314 100644
--- a/khelo/lib/ui/flow/team/detail/components/team_detail_member_content.dart
+++ b/khelo/lib/ui/flow/team/detail/components/team_detail_member_content.dart
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:khelo/components/empty_screen.dart';
import 'package:khelo/components/user_detail_cell.dart';
import 'package:khelo/domain/extensions/context_extensions.dart';
import 'package:khelo/ui/app_route.dart';
@@ -39,16 +40,11 @@ class TeamDetailMemberContent extends ConsumerWidget {
separatorBuilder: (context, index) => const SizedBox(height: 16),
);
} else {
- return Center(
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 16.0),
- child: Text(
- context.l10n.team_detail_empty_member_title,
- textAlign: TextAlign.center,
- style: AppTextStyle.body2
- .copyWith(color: context.colorScheme.textPrimary),
- ),
- ),
+ return EmptyScreen(
+ title: context.l10n.team_detail_empty_member_title,
+ description: context.l10n.team_detail_empty_member_description_text,
+ buttonTitle: context.l10n.team_list_add_members_title,
+ onTap: () => AppRoute.addTeamMember(team: state.team!).push(context),
);
}
}
diff --git a/khelo/lib/ui/flow/team/detail/components/team_detail_stat_content.dart b/khelo/lib/ui/flow/team/detail/components/team_detail_stat_content.dart
index b43ea37e..c7fde5e6 100644
--- a/khelo/lib/ui/flow/team/detail/components/team_detail_stat_content.dart
+++ b/khelo/lib/ui/flow/team/detail/components/team_detail_stat_content.dart
@@ -3,6 +3,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:khelo/components/empty_screen.dart';
import 'package:khelo/domain/extensions/context_extensions.dart';
import 'package:khelo/ui/flow/team/detail/components/primer_progress_bar.dart';
import 'package:khelo/ui/flow/team/detail/team_detail_view_model.dart';
@@ -20,16 +21,10 @@ class TeamDetailStatContent extends ConsumerWidget {
?.where((element) => element.match_status == MatchStatus.finish)
.isEmpty ??
true) {
- return Center(
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 16.0),
- child: Text(
- context.l10n.team_detail_empty_stat_title,
- textAlign: TextAlign.center,
- style: AppTextStyle.body2
- .copyWith(color: context.colorScheme.textPrimary),
- ),
- ),
+ return EmptyScreen(
+ title: context.l10n.team_detail_empty_stat_title,
+ description: context.l10n.team_detail_empty_stat_description_text,
+ isShowButton: false,
);
}
diff --git a/khelo/lib/ui/flow/team/detail/team_detail_view_model.dart b/khelo/lib/ui/flow/team/detail/team_detail_view_model.dart
index f196e123..4a6dc0f1 100644
--- a/khelo/lib/ui/flow/team/detail/team_detail_view_model.dart
+++ b/khelo/lib/ui/flow/team/detail/team_detail_view_model.dart
@@ -67,8 +67,8 @@ class TeamDetailViewNotifier extends StateNotifier {
}
TeamStat _calculateTeamStat(List matches) {
- if (matches.isEmpty) return const TeamStat();
final finishedMatches = _filterFinishedMatches(matches);
+ if (finishedMatches.isEmpty) return const TeamStat();
return TeamStat(
played: finishedMatches.length,
status: _teamMatchStatus(finishedMatches),
diff --git a/khelo/lib/ui/flow/team/team_list_screen.dart b/khelo/lib/ui/flow/team/team_list_screen.dart
index fcddae8f..85fba11f 100644
--- a/khelo/lib/ui/flow/team/team_list_screen.dart
+++ b/khelo/lib/ui/flow/team/team_list_screen.dart
@@ -5,6 +5,7 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:go_router/go_router.dart';
import 'package:khelo/components/action_bottom_sheet.dart';
import 'package:khelo/components/app_page.dart';
+import 'package:khelo/components/empty_screen.dart';
import 'package:khelo/components/error_screen.dart';
import 'package:khelo/components/image_avatar.dart';
import 'package:khelo/domain/extensions/context_extensions.dart';
@@ -75,35 +76,27 @@ class _TeamListScreenState extends ConsumerState
BuildContext context,
TeamListViewState state,
) {
- if (state.filteredTeams.isEmpty) {
- return Padding(
- padding: const EdgeInsets.all(16.0),
- child: Center(
- child: Text(
- context.l10n.team_list_empty_list_description,
- textAlign: TextAlign.center,
- style: AppTextStyle.body2
- .copyWith(color: context.colorScheme.textPrimary),
- ),
- ),
- );
- }
-
- return ListView.separated(
- itemCount: state.filteredTeams.length,
- padding: const EdgeInsets.symmetric(horizontal: 16) +
- context.mediaQueryPadding,
- separatorBuilder: (context, index) =>
- Divider(color: context.colorScheme.outline),
- itemBuilder: (context, index) {
- final team = state.filteredTeams[index];
- return _teamListCell(
- context,
- team: team,
- showMoreOptionButton: state.currentUserId == team.created_by,
- );
- },
- );
+ return (state.filteredTeams.isNotEmpty)
+ ? ListView.separated(
+ itemCount: state.filteredTeams.length,
+ padding: const EdgeInsets.symmetric(horizontal: 16) +
+ context.mediaQueryPadding,
+ separatorBuilder: (context, index) =>
+ Divider(color: context.colorScheme.outline),
+ itemBuilder: (context, index) {
+ final team = state.filteredTeams[index];
+ return _teamListCell(
+ context,
+ team: team,
+ showMoreOptionButton: state.currentUserId == team.created_by,
+ );
+ },
+ )
+ : EmptyScreen(
+ title: context.l10n.team_list_no_teams_created_title,
+ description: context.l10n.team_list_empty_list_description,
+ isShowButton: false,
+ );
}
Widget _teamListCell(