[dart] page search

Viewer

copydownloadembedprintName: page search
  1.  
  2. import 'package:easy_localization/easy_localization.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter_screenutil/flutter_screenutil.dart';
  5. import 'package:provider/provider.dart';
  6. import 'package:thawaf/common/extensions/buildcontext_extension.dart';
  7. import 'package:thawaf/common/providers/app_setting.dart';
  8. import 'package:thawaf/common/providers/user_behavior.dart';
  9. import 'package:thawaf/common/utils/datetime_utils.dart';
  10. import 'package:thawaf/common/utils/global_function_utils.dart';
  11. import 'package:thawaf/common/utils/global_variable_utils.dart';
  12. import 'package:thawaf/resources/data_state/data_item_model.dart';
  13. import 'package:thawaf/resources/models/user_model.dart';
  14. import 'package:thawaf/screens/home/tabs/home/providers/features_provider.dart';
  15. import 'package:thawaf/screens/home/tabs/home/providers/news_provider.dart';
  16.  
  17. import 'package:thawaf/screens/home/tabs/home/home_screen.dart';
  18. import 'package:thawaf/screens/home/tabs/home/providers/home_screen_provider.dart';
  19. import 'package:thawaf/screens/home/tabs/home/providers/panduan_state_provider.dart';
  20. import 'package:thawaf/screens/home/tabs/home/resources/model/features_model.dart';
  21. import 'package:thawaf/screens/home/tabs/home/widgets/home_features_widget.dart';
  22. import 'package:thawaf/screens/home/tabs/home/widgets/home_widgets.dart';
  23. import 'package:thawaf/screens/news/news_detail.dart';
  24. import 'package:thawaf/screens/news/resources/models/news_model.dart';
  25. import 'package:thawaf/screens/panduan/detail_panduan.dart';
  26. import 'package:thawaf/screens/panduan/resources/models/panduan_umrah_model.dart';
  27. import 'package:thawaf/widgets/app_widget/app_widget.dart';
  28. import 'package:thawaf/widgets/image_widget/image_network_widget.dart';
  29.  
  30. class HomeSearch extends StatefulWidget {
  31.   final UserModel userModel;
  32.  
  33.   HomeSearch({Key? key, required this.userModel}) : super(key: key);
  34.  
  35.   @override
  36.   State<HomeSearch> createState() => _HomeSearchState();
  37. }
  38.  
  39. class _HomeSearchState extends State<HomeSearch> {
  40.   bool isLoading = false;
  41.   List<DataItem> featureData = [];
  42.   List<DataItem> newsData = [];
  43.   List<DataItem> panduanData = [];
  44.  
  45.   final FocusNode _focusNode = FocusNode();
  46.   final TextEditingController _searchController = TextEditingController();
  47.  
  48.   @override
  49.   void initState() {
  50.     super.initState();
  51.   }
  52.  
  53.   @override
  54.   void dispose() {
  55.     _focusNode.dispose();
  56.     _searchController.dispose();
  57.     super.dispose();
  58.   }
  59.  
  60.   @override
  61.   Widget build(BuildContext context) {
  62.     UserModel userModel = Provider.of<UserModel>(context);
  63.     FeatureProvider fP = Provider.of<FeatureProvider>(context);
  64.     NewsProvider nP = Provider.of<NewsProvider>(context);
  65.     PanduanStateProvider pP = Provider.of<PanduanStateProvider>(context);
  66.  
  67.     if ((!fP.isInit || fP.isLoading) ||
  68.         (!nP.isInit || nP.isLoading) ||
  69.         (!pP.isInit || pP.isLoading)) {
  70.       return Scaffold(
  71.         body: Center(
  72.           child: AppWidget.loadingData(),
  73.         ),
  74.       );
  75.     }
  76.  
  77.     void _onSearch() async {
  78.       isLoading = true;
  79.       setState(() {});
  80.  
  81.       try {
  82.         featureData = await fP.dataStateFeature.find(
  83.           search: SearchDataState(
  84.             keys: ['featureIdName', 'featureEnName'],
  85.             value: _searchController.text,
  86.           ),
  87.         );
  88.         newsData = await nP.dataStateNews.find(
  89.           search:
  90.               SearchDataState(keys: ['title'], value: _searchController.text),
  91.         );
  92.         panduanData = await pP.dataStatePanduan.find(
  93.           search:
  94.               SearchDataState(keys: ['title'], value: _searchController.text),
  95.         );
  96.       } catch (e) {
  97.         print('Search error: $e');
  98.       }
  99.  
  100.       isLoading = false;
  101.       setState(() {});
  102.     }
  103.  
  104.     return GestureDetector(
  105.       onTap: () {
  106.         context.requestFocus();
  107.       },
  108.       child: Scaffold(
  109.         appBar: AppBar(
  110.           toolbarHeight: 80,
  111.           leading: IconButton(
  112.             icon: Icon(Icons.arrow_back, color: Colors.black),
  113.             onPressed: () => Navigator.of(context).pop(),
  114.           ),
  115.           title: Container(
  116.             height: 50,
  117.             padding: const EdgeInsets.symmetric(horizontal: 15),
  118.             decoration: BoxDecoration(
  119.               color: Colors.white,
  120.               borderRadius: BorderRadius.circular(10),
  121.               border: Border.all(width: 1, color: Color(0xFF9E9E9E)),
  122.             ),
  123.             child: Row(
  124.               children: [
  125.                 Icon(Icons.search, color: Color(0xFF9E9E9E)),
  126.                 SizedBox(width: 10),
  127.                 Expanded(
  128.                   child: TextField(
  129.                     controller: _searchController,
  130.                     focusNode: _focusNode,
  131.                     autofocus: true,
  132.                     onChanged: (_) {
  133.                       _onSearch();
  134.                     },
  135.                     decoration: InputDecoration(
  136.                       hintText: 'home.search'.tr(),
  137.                       border: InputBorder.none,
  138.                       hintStyle: TextStyle(
  139.                         color: Color(0xFF9E9E9E),
  140.                         fontSize: 14,
  141.                         fontFamily: 'Lato',
  142.                         fontWeight: FontWeight.w500,
  143.                         letterSpacing: 0.07,
  144.                       ),
  145.                     ),
  146.                     onSubmitted: (value) => _onSearch(), // Update here
  147.                   ),
  148.                 ),
  149.               ],
  150.             ),
  151.           ),
  152.           backgroundColor: Colors.transparent,
  153.           elevation: 0,
  154.           centerTitle: false,
  155.         ),
  156.         body: NotificationListener<OverscrollIndicatorNotification>(
  157.           onNotification: (overscroll) {
  158.             overscroll.disallowIndicator();
  159.             return true;
  160.           },
  161.           child: SizedBox(
  162.             width: context.width(),
  163.             height: context.height(),
  164.             child: Builder(
  165.               builder: (_) {
  166.                 // mode search
  167.                 if (_searchController.text.isNotEmpty) {
  168.                   if (featureData.isEmpty &&
  169.                       newsData.isEmpty &&
  170.                       panduanData.isEmpty) {
  171.                     return Column(
  172.                       mainAxisAlignment: MainAxisAlignment.center,
  173.                       crossAxisAlignment: CrossAxisAlignment.center,
  174.                       children: [
  175.                         Text('home.no_search_data'.tr()),
  176.                       ],
  177.                     );
  178.                   }
  179.                   return NotificationListener<OverscrollIndicatorNotification>(
  180.                     onNotification: (overscroll) {
  181.                       overscroll.disallowIndicator();
  182.                       return true;
  183.                     },
  184.                     child: SingleChildScrollView(
  185.                       physics: ClampingScrollPhysics(),
  186.                       child: Column(
  187.                         mainAxisAlignment: MainAxisAlignment.start,
  188.                         children: [
  189.                           if (featureData.isNotEmpty)
  190.                             Column(
  191.                               children: [
  192.                                 dividerMenu(
  193.                                   title: 'home.feature'.tr(),
  194.                                   withLine: false,
  195.                                 ),
  196.                                 Padding(
  197.                                   padding: const EdgeInsets.only(
  198.                                       left: 10, right: 10),
  199.                                   child: SizedBox(
  200.                                     width: context.width(),
  201.                                     child: SingleChildScrollView(
  202.                                       scrollDirection: Axis.horizontal,
  203.                                       child: Row(
  204.                                         mainAxisAlignment:
  205.                                             MainAxisAlignment.start,
  206.                                         crossAxisAlignment:
  207.                                             CrossAxisAlignment.start,
  208.                                         children: featureData.map((e) {
  209.                                           FeaturesModel feature =
  210.                                               FeaturesModel.fromDataItem(e);
  211.                                           return Padding(
  212.                                             padding: EdgeInsets.only(
  213.                                                 right: 8.0, bottom: 10.0),
  214.                                             child: GestureDetector(
  215.                                               onTap: () {
  216.                                                 if (feature.route ==
  217.                                                     'panicButton') {
  218.                                                   HomeWidgets
  219.                                                       .panicButtonActionSheet(
  220.                                                     pageContext: context,
  221.                                                     userData: userModel,
  222.                                                   );
  223.  
  224.                                                   // User Behavior - function clicked features
  225.                                                   Provider.of<UserBehavior>(
  226.                                                           context,
  227.                                                           listen: false)
  228.                                                       .clickedFeature(
  229.                                                     docId: userModel.docUid,
  230.                                                     identifier: 'Tersesat',
  231.                                                   );
  232.                                                 } else {
  233.                                                   AppFunction.pushNamed(
  234.                                                     context: context,
  235.                                                     route: feature.route,
  236.                                                     arguments:
  237.                                                         feature.withGetUserData,
  238.                                                   );
  239.  
  240.                                                   // User Behavior - function clicked features
  241.                                                   Provider.of<UserBehavior>(
  242.                                                           context,
  243.                                                           listen: false)
  244.                                                       .clickedFeature(
  245.                                                     docId: userModel.docUid,
  246.                                                     identifier:
  247.                                                         feature.identifier,
  248.                                                   );
  249.                                                 }
  250.                                               },
  251.                                               child: Column(
  252.                                                 mainAxisAlignment:
  253.                                                     MainAxisAlignment.start,
  254.                                                 crossAxisAlignment:
  255.                                                     CrossAxisAlignment.center,
  256.                                                 mainAxisSize: MainAxisSize.min,
  257.                                                 children: [
  258.                                                   Container(
  259.                                                     width: 65.w,
  260.                                                     height: 60.h,
  261.                                                     decoration: BoxDecoration(
  262.                                                         borderRadius:
  263.                                                             BorderRadius
  264.                                                                 .circular(10)),
  265.                                                     child: ClipRRect(
  266.                                                       borderRadius:
  267.                                                           BorderRadius.circular(
  268.                                                               10),
  269.                                                       child: Image.asset(
  270.                                                         feature.iconPath,
  271.                                                         fit: BoxFit.cover,
  272.                                                       ),
  273.                                                     ), // Use iconPath from feature
  274.                                                   ),
  275.                                                   SizedBox(height: 3.h),
  276.                                                   Consumer<AppSettings>(builder:
  277.                                                       (_,
  278.                                                           AppSettings
  279.                                                               appSettings,
  280.                                                           __) {
  281.                                                     return Container(
  282.                                                       width: 70.w,
  283.                                                       child: Text(
  284.                                                         appSettings.isIndonesianLanguage
  285.                                                             ? feature
  286.                                                                 .featureIdName
  287.                                                             : feature
  288.                                                                 .featureEnName,
  289.                                                         overflow:
  290.                                                             TextOverflow.clip,
  291.                                                         textAlign:
  292.                                                             TextAlign.center,
  293.                                                         style: TextStyle(
  294.                                                           color: ThawafMisc
  295.                                                               .appTheme
  296.                                                               .smokyBlackColor,
  297.                                                           fontFamily: 'Lato',
  298.                                                           fontSize: 12.sp,
  299.                                                         ),
  300.                                                       ),
  301.                                                     );
  302.                                                   }),
  303.                                                 ],
  304.                                               ),
  305.                                             ),
  306.                                           );
  307.                                         }).toList(),
  308.                                       ),
  309.                                     ),
  310.                                   ),
  311.                                 ),
  312.                                 SizedBox(
  313.                                   height: 14,
  314.                                 ),
  315.                               ],
  316.                             ),
  317.                           if (newsData.isNotEmpty)
  318.                             Column(
  319.                               children: [
  320.                                 dividerMenu(
  321.                                   title: 'home.news'.tr(),
  322.                                   withLine: false,
  323.                                 ),
  324.                                 Padding(
  325.                                   padding: const EdgeInsets.only(
  326.                                       left: 10, right: 10, bottom: 30),
  327.                                   child: Column(
  328.                                     mainAxisAlignment: MainAxisAlignment.start,
  329.                                     children: newsData.map((e) {
  330.                                       NewsModel news =
  331.                                           NewsModel.formDataItem(e);
  332.                                       return Padding(
  333.                                         padding:
  334.                                             const EdgeInsets.only(bottom: 10),
  335.                                         child: GestureDetector(
  336.                                           onTap: () {
  337.                                             AppFunction.push(
  338.                                               context: context,
  339.                                               page: NewsDetail(docs: news),
  340.                                               withGetUserData: false,
  341.                                             );
  342.                                           },
  343.                                           child: Container(
  344.                                             width: MediaQuery.of(context)
  345.                                                 .size
  346.                                                 .width,
  347.                                             height: 120,
  348.                                             decoration: ShapeDecoration(
  349.                                               color: Colors.white,
  350.                                               shape: RoundedRectangleBorder(
  351.                                                 borderRadius:
  352.                                                     BorderRadius.circular(10),
  353.                                               ),
  354.                                               shadows: [AppTheme().shadow1],
  355.                                             ),
  356.                                             child: Padding(
  357.                                               padding: const EdgeInsets.all(10),
  358.                                               child: Row(
  359.                                                 crossAxisAlignment:
  360.                                                     CrossAxisAlignment.start,
  361.                                                 mainAxisAlignment:
  362.                                                     MainAxisAlignment.start,
  363.                                                 children: [
  364.                                                   Container(
  365.                                                     height: 85.h,
  366.                                                     width: 85.w,
  367.                                                     child: ClipRRect(
  368.                                                       borderRadius:
  369.                                                           BorderRadius.circular(
  370.                                                               5.r),
  371.                                                       child: ImageNetworkWidget(
  372.                                                         news.cover.toString(),
  373.                                                         progressIndicatorBuilder:
  374.                                                             (_, __, ___) {
  375.                                                           return Image.asset(
  376.                                                               "assets/icons/icon_placeholder_news.png");
  377.                                                         },
  378.                                                         fit: BoxFit.cover,
  379.                                                       ),
  380.                                                     ),
  381.                                                   ),
  382.                                                   SizedBox(
  383.                                                     width: 10,
  384.                                                   ),
  385.                                                   Expanded(
  386.                                                     child: Column(
  387.                                                       crossAxisAlignment:
  388.                                                           CrossAxisAlignment
  389.                                                               .start,
  390.                                                       mainAxisAlignment:
  391.                                                           MainAxisAlignment
  392.                                                               .center,
  393.                                                       children: [
  394.                                                         Text(
  395.                                                           DateTimeUtils
  396.                                                               .dateFormat(news
  397.                                                                   .createdAt),
  398.                                                           overflow: TextOverflow
  399.                                                               .ellipsis,
  400.                                                           style: TextStyle(
  401.                                                             fontSize: 10,
  402.                                                             fontFamily: 'Lato',
  403.                                                             fontWeight:
  404.                                                                 FontWeight.w500,
  405.                                                             color: AppTheme()
  406.                                                                 .greyDisableColor,
  407.                                                           ),
  408.                                                         ),
  409.                                                         SizedBox(
  410.                                                           height: 6,
  411.                                                         ),
  412.                                                         Text(
  413.                                                           news.title,
  414.                                                           maxLines: 3,
  415.                                                           overflow: TextOverflow
  416.                                                               .ellipsis,
  417.                                                           style: TextStyle(
  418.                                                             fontSize: 16.sp,
  419.                                                             fontFamily: 'Lato',
  420.                                                             fontWeight:
  421.                                                                 FontWeight.w500,
  422.                                                           ),
  423.                                                         ),
  424.                                                       ],
  425.                                                     ),
  426.                                                   ),
  427.                                                 ],
  428.                                               ),
  429.                                             ),
  430.                                           ),
  431.                                         ),
  432.                                       );
  433.                                     }).toList(),
  434.                                   ),
  435.                                 )
  436.                               ],
  437.                             ),
  438.                           if (panduanData.isNotEmpty)
  439.                             Column(
  440.                               children: [
  441.                                 dividerMenu(
  442.                                   title: 'home.guide_text'.tr(),
  443.                                   withLine: false,
  444.                                 ),
  445.                                 Padding(
  446.                                   padding: const EdgeInsets.only(
  447.                                       left: 10, right: 10, bottom: 30),
  448.                                   child: Column(
  449.                                     mainAxisAlignment: MainAxisAlignment.start,
  450.                                     children: panduanData.map((e) {
  451.                                       PanduanModel panduan =
  452.                                           PanduanModel.fromDataItem(e);
  453.                                       return Padding(
  454.                                         padding:
  455.                                             const EdgeInsets.only(bottom: 10),
  456.                                         child: GestureDetector(
  457.                                           onTap: () {
  458.                                             AppFunction.push(
  459.                                               context: context,
  460.                                               page: DetailPanduanScreen(
  461.                                                 data: panduan,
  462.                                                 pageTitle:
  463.                                                     'home.hajj_guide'.tr(),
  464.                                               ),
  465.                                               withGetUserData: false,
  466.                                             );
  467.                                           },
  468.                                           child: Container(
  469.                                             width: MediaQuery.of(context)
  470.                                                 .size
  471.                                                 .width,
  472.                                             height: 120,
  473.                                             decoration: ShapeDecoration(
  474.                                               color: Colors.white,
  475.                                               shape: RoundedRectangleBorder(
  476.                                                 borderRadius:
  477.                                                     BorderRadius.circular(10),
  478.                                               ),
  479.                                               shadows: [AppTheme().shadow1],
  480.                                             ),
  481.                                             child: Padding(
  482.                                               padding: const EdgeInsets.all(10),
  483.                                               child: Row(
  484.                                                 crossAxisAlignment:
  485.                                                     CrossAxisAlignment.start,
  486.                                                 mainAxisAlignment:
  487.                                                     MainAxisAlignment.start,
  488.                                                 children: [
  489.                                                   Container(
  490.                                                     height: 85.h,
  491.                                                     width: 85.w,
  492.                                                     child: ClipRRect(
  493.                                                       borderRadius:
  494.                                                           BorderRadius.circular(
  495.                                                               5.r),
  496.                                                       child: ImageNetworkWidget(
  497.                                                         panduan.cover
  498.                                                             .toString(),
  499.                                                         progressIndicatorBuilder:
  500.                                                             (_, __, ___) {
  501.                                                           return Image.asset(
  502.                                                               "assets/icons/icon_placeholder_news.png");
  503.                                                         },
  504.                                                         fit: BoxFit.cover,
  505.                                                       ),
  506.                                                     ),
  507.                                                   ),
  508.                                                   SizedBox(
  509.                                                     width: 10,
  510.                                                   ),
  511.                                                   Expanded(
  512.                                                     child: Column(
  513.                                                       crossAxisAlignment:
  514.                                                           CrossAxisAlignment
  515.                                                               .start,
  516.                                                       mainAxisAlignment:
  517.                                                           MainAxisAlignment
  518.                                                               .center,
  519.                                                       children: [
  520.                                                         Text(
  521.                                                           DateTimeUtils
  522.                                                               .dateFormat(panduan
  523.                                                                   .createdAt),
  524.                                                           overflow: TextOverflow
  525.                                                               .ellipsis,
  526.                                                           style: TextStyle(
  527.                                                             fontSize: 10,
  528.                                                             fontFamily: 'Lato',
  529.                                                             fontWeight:
  530.                                                                 FontWeight.w500,
  531.                                                             color: AppTheme()
  532.                                                                 .greyDisableColor,
  533.                                                           ),
  534.                                                         ),
  535.                                                         SizedBox(
  536.                                                           height: 6,
  537.                                                         ),
  538.                                                         Text(
  539.                                                           panduan.title,
  540.                                                           maxLines: 3,
  541.                                                           overflow: TextOverflow
  542.                                                               .ellipsis,
  543.                                                           style: TextStyle(
  544.                                                             fontSize: 16.sp,
  545.                                                             fontFamily: 'Lato',
  546.                                                             fontWeight:
  547.                                                                 FontWeight.w500,
  548.                                                           ),
  549.                                                         ),
  550.                                                       ],
  551.                                                     ),
  552.                                                   ),
  553.                                                 ],
  554.                                               ),
  555.                                             ),
  556.                                           ),
  557.                                         ),
  558.                                       );
  559.                                     }).toList(),
  560.                                   ),
  561.                                 )
  562.                               ],
  563.                             ),
  564.                         ],
  565.                       ),
  566.                     ),
  567.                   );
  568.                 }
  569.                 return NotificationListener<OverscrollIndicatorNotification>(
  570.                   onNotification: (overscroll) {
  571.                     overscroll.disallowIndicator();
  572.                     return true;
  573.                   },
  574.                   child: SingleChildScrollView(
  575.                     physics: ClampingScrollPhysics(),
  576.                     child: Column(
  577.                       mainAxisAlignment: MainAxisAlignment.start,
  578.                       children: [
  579.                         dividerMenu(
  580.                           title: 'home.feature'.tr(),
  581.                           withLine: false,
  582.                         ),
  583.                         if (_searchController.text.isEmpty)
  584.                           Padding(
  585.                             padding: EdgeInsets.only(left: 10, right: 10),
  586.                             child: Consumer<HomeScreenProvider>(
  587.                               builder:
  588.                                   (_, HomeScreenProvider homeProvider, __) {
  589.                                 return ConstrainedBox(
  590.                                   key: homeProvider.featureListTutorialKey,
  591.                                   constraints: BoxConstraints(
  592.                                     minHeight: 80.h,
  593.                                     maxHeight: 100.h,
  594.                                   ),
  595.                                   child: HomeFeaturesWidget(
  596.                                     userModel: widget.userModel,
  597.                                     maxItems: 4,
  598.                                     showLainnya: false,
  599.                                   ),
  600.                                 );
  601.                               },
  602.                             ),
  603.                           ),
  604.                         SizedBox(
  605.                           height: 14,
  606.                         ),
  607.                         dividerMenu(
  608.                           title: 'home.news'.tr(),
  609.                           withLine: false,
  610.                         ),
  611.                         if (_searchController.text.isEmpty)
  612.                           Consumer<HomeScreenProvider>(
  613.                             builder: (_, HomeScreenProvider homeProvider, __) {
  614.                               return Container(
  615.                                 padding: EdgeInsets.only(left: 10, right: 10),
  616.                                 child: HomeFeaturesWidget.newsSliderWidget(
  617.                                     context),
  618.                               );
  619.                             },
  620.                           ),
  621.                         dividerMenu(
  622.                           title: 'home.guide_text'.tr(),
  623.                           withLine: false,
  624.                         ),
  625.                         if (_searchController.text.isEmpty)
  626.                           Consumer<HomeScreenProvider>(
  627.                             builder: (_, HomeScreenProvider homeProvider, __) {
  628.                               return Container(
  629.                                 padding: EdgeInsets.only(left: 10, right: 10),
  630.                                 child: HomeFeaturesWidget.newsSliderWidget(
  631.                                     context),
  632.                               );
  633.                             },
  634.                           ),
  635.                       ],
  636.                     ),
  637.                   ),
  638.                 );
  639.               },
  640.             ),
  641.           ),
  642.         ),
  643.       ),
  644.     );
  645.   }
  646. }
  647.  

Editor

You can edit this paste and save as new:


File Description
  • page search
  • Paste Code
  • 23 Apr-2024
  • 34.21 Kb
You can Share it: