From 2dc06a0dae3101a8745f65a6a8d0998c0aa238a3 Mon Sep 17 00:00:00 2001 From: FaizHashmi Date: Sun, 20 Sep 2026 15:11:47 +0300 Subject: [PATCH] Bug Fixes --- android/app/src/main/AndroidManifest.xml | 7 + ios/Runner.xcodeproj/project.pbxproj | 3 + lib/config/customer_routes.dart | 3 - lib/main.dart | 18 +- .../fragments/branches_fragment.dart | 178 +++++++++++++----- .../dashboard/fragments/home_fragment.dart | 2 +- 6 files changed, 155 insertions(+), 56 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index f6118da..cad256a 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -66,6 +66,13 @@ + + + + + + + const FavouriteAdsView(), }; } - - -//314187 \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 51dec8d..df98301 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -8,6 +8,7 @@ import 'package:mc_common_app/repositories/chat_repo.dart'; import 'package:mc_common_app/repositories/appointment_repo.dart'; import 'package:mc_common_app/repositories/request_repo.dart'; import 'package:mc_common_app/repositories/setting_options_repo.dart'; +import 'package:mc_common_app/services/ad_deep_link_service.dart'; import 'package:mc_common_app/services/firebase_service.dart'; import 'package:mc_common_app/utils/location/Location.dart'; import 'package:mc_common_app/view_models/appointments_view_model.dart'; @@ -135,9 +136,22 @@ Future main() async { // flutter pub run easy_localization:generate --source-dir ./assets/langs -f keys -o locale_keys.g.dart // command to generate languages data from json -class MyApp extends StatelessWidget { +class MyApp extends StatefulWidget { const MyApp({Key? key}) : super(key: key); + @override + State createState() => _MyAppState(); +} + +class _MyAppState extends State { + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) { + AdDeepLinkService.init(); + }); + } + @override Widget build(BuildContext context) { SystemChrome.setPreferredOrientations([ @@ -169,3 +183,5 @@ class MyApp extends StatelessWidget { ); } } + + diff --git a/lib/views/dashboard/fragments/branches_fragment.dart b/lib/views/dashboard/fragments/branches_fragment.dart index c82f962..69da258 100644 --- a/lib/views/dashboard/fragments/branches_fragment.dart +++ b/lib/views/dashboard/fragments/branches_fragment.dart @@ -18,9 +18,76 @@ import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/shimmer/home_shimmer_widgets.dart'; import 'package:provider/provider.dart'; -class BranchesFragment extends StatelessWidget { +class BranchesFragment extends StatefulWidget { const BranchesFragment({Key? key}) : super(key: key); + @override + State createState() => _BranchesFragmentState(); +} + +class _BranchesFragmentState extends State { + final TextEditingController _searchController = TextEditingController(); + final FocusNode _searchFocusNode = FocusNode(); + String _searchQuery = ''; + + @override + void dispose() { + _searchController.dispose(); + _searchFocusNode.dispose(); + super.dispose(); + } + + List _filterBranches(List branches) { + if (_searchQuery.isEmpty) { + return branches; + } + return branches.where((branch) { + return (branch.branchName ?? '').toLowerCase().contains(_searchQuery.toLowerCase()); + }).toList(); + } + + Widget _buildSearchField() { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 21), + child: Container( + height: 55, + decoration: BoxDecoration( + color: Colors.grey[200], + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.grey[300]!, width: 1), + ), + child: TextField( + controller: _searchController, + focusNode: _searchFocusNode, + style: const TextStyle(fontSize: 16), + onChanged: (value) { + setState(() { + _searchQuery = value; + }); + }, + decoration: InputDecoration( + hintText: LocaleKeys.searchByBranch.tr(), + hintStyle: TextStyle(fontSize: 16, color: Colors.grey[600]), + prefixIcon: Icon(Icons.search, size: 26, color: Colors.grey[700]), + suffixIcon: _searchQuery.isEmpty + ? null + : InkWell( + onTap: () { + setState(() { + _searchController.clear(); + _searchQuery = ''; + }); + }, + child: Icon(Icons.close, size: 22, color: Colors.grey[700]), + ), + border: InputBorder.none, + contentPadding: const EdgeInsets.symmetric(horizontal: 18, vertical: 16), + ), + ), + ), + ); + } + @override Widget build(BuildContext context) { final isArabic = AppState().isArabic(context); @@ -48,59 +115,68 @@ class BranchesFragment extends StatelessWidget { ).toViewOnly(context, onTap: () { navigateWithName(context, AppRoutes.loginWithPassword, arguments: false); }), - body: SizedBox( - width: double.infinity, - height: double.infinity, - child: Column( - children: [ - if (appointmentsVM.branchesCategoriesFilterOptions.isNotEmpty) ...[ + body: GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () => _searchFocusNode.unfocus(), + child: SizedBox( + width: double.infinity, + height: double.infinity, + child: Column( + children: [ 16.height, - FiltersList( - filterList: appointmentsVM.branchesCategoriesFilterOptions, - onFilterTapped: (index, selectedFilterId) => appointmentsVM.applyFilterOnBranches(index: index), - scrollController: appointmentsVM.branchesFilterScrollController, + _buildSearchField(), + if (appointmentsVM.branchesCategoriesFilterOptions.isNotEmpty) ...[ + 16.height, + FiltersList( + filterList: appointmentsVM.branchesCategoriesFilterOptions, + onFilterTapped: (index, selectedFilterId) => appointmentsVM.applyFilterOnBranches(index: index), + scrollController: appointmentsVM.branchesFilterScrollController, + ), + ], + 16.height, + Expanded( + child: Builder(builder: (context) { + final filteredBranches = _filterBranches(appointmentsVM.nearbyBranches); + return RefreshIndicator( + onRefresh: () async { + context.read().getAllNearBranches(isNeedToRebuild: true, isFromRefresh: true); + }, + child: Container( + width: double.infinity, + child: appointmentsVM.state == ViewState.busy + ? const BranchesListShimmer(itemCount: 5) + : filteredBranches.isEmpty + ? Center( + child: LocaleKeys.no_branch.tr().toText( + fontSize: 16, + color: MyColors.lightTextColor, + ), + ) + : ListView.separated( + itemCount: filteredBranches.length, + itemBuilder: (context, index) { + BranchDetailModel branchDetailModel = filteredBranches[index]; + return BranchDetailCard( + onCardTapped: () => navigateWithName(context, AppRoutes.branchDetailView, arguments: branchDetailModel), + providerImageUrl: branchDetailModel.branchProfileImage ?? "", + title: branchDetailModel.branchName ?? "", + providerLocation: branchDetailModel.distanceKm.toString() + " KM", + providerName: branchDetailModel.serviceProviderName ?? "", + providerRatings: branchDetailModel.branchRateAvg ?? 0.0, + services: branchDetailModel.branchServices, + ).toViewOnly(context, onTap: () { + navigateWithName(context, AppRoutes.loginWithPassword, arguments: false); + }); + }, + separatorBuilder: (context, index) => 12.height, + padding: const EdgeInsets.all(12), + ), + ).paddingOnly(left: 10, right: 10), + ); + }), ), ], - 16.height, - Expanded( - child: RefreshIndicator( - onRefresh: () async { - context.read().getAllNearBranches(isNeedToRebuild: true, isFromRefresh: true); - }, - child: Container( - width: double.infinity, - child: appointmentsVM.state == ViewState.busy - ? const BranchesListShimmer(itemCount: 5) - : appointmentsVM.nearbyBranches.isEmpty - ? Center( - child: LocaleKeys.no_branch.tr().toText( - fontSize: 16, - color: MyColors.lightTextColor, - ), - ) - : ListView.separated( - itemCount: appointmentsVM.nearbyBranches.length, - itemBuilder: (context, index) { - BranchDetailModel branchDetailModel = appointmentsVM.nearbyBranches[index]; - return BranchDetailCard( - onCardTapped: () => navigateWithName(context, AppRoutes.branchDetailView, arguments: branchDetailModel), - providerImageUrl: branchDetailModel.branchProfileImage ?? "", - title: branchDetailModel.branchName ?? "", - providerLocation: branchDetailModel.distanceKm.toString() + " KM", - providerName: branchDetailModel.serviceProviderName ?? "", - providerRatings: branchDetailModel.branchRateAvg ?? 0.0, - services: branchDetailModel.branchServices, - ).toViewOnly(context, onTap: () { - navigateWithName(context, AppRoutes.loginWithPassword, arguments: false); - }); - }, - separatorBuilder: (context, index) => 12.height, - padding: const EdgeInsets.all(12), - ), - ).paddingOnly(left: 10, right: 10), - ), - ), - ], + ), ), ), ); diff --git a/lib/views/dashboard/fragments/home_fragment.dart b/lib/views/dashboard/fragments/home_fragment.dart index bf10631..3d5390b 100644 --- a/lib/views/dashboard/fragments/home_fragment.dart +++ b/lib/views/dashboard/fragments/home_fragment.dart @@ -145,7 +145,7 @@ class _HomeFragmentState extends State { @override Widget build(BuildContext context) { - context.locale; + context.locale; return Scaffold( drawer: CustomDrawer(dashboardVM: context.watch()), appBar: CustomAppBar(