import 'package:after_layout/after_layout.dart'; import 'package:carousel_slider/carousel_slider.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/CreateCustomerRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersProductsRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/packages_offers/ClinicOfferAndPackagesPage.dart'; import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackageDetailPage.dart'; import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesCartPage.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; import 'package:diplomaticquarterapp/widgets/Loader/gif_loader_container.dart'; import 'package:diplomaticquarterapp/widgets/carousel_indicator/carousel_indicator.dart'; import 'package:diplomaticquarterapp/widgets/loadings/ShimmerLoading.dart'; import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOfferCard.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_material_pickers/flutter_material_pickers.dart'; dynamic languageID; class PackagesHomePage extends StatefulWidget { dynamic offersModel; PackagesHomePage({@required this.offersModel}); @override _PackagesHomePageState createState() => _PackagesHomePageState(); } class _PackagesHomePageState extends State with AfterLayoutMixin{ getLanguageID() async { languageID = await sharedPref.getString(APP_LANGUAGE); } @override void initState() { super.initState(); getLanguageID(); } @override void afterFirstLayout(BuildContext context) async{ viewModel.service.loadOffersPackagesDataForMainPage(context: context, completion: (){ setState((){}); }); } // Controllers var _searchTextController = TextEditingController(); var _filterTextController = TextEditingController(); var _carouselController = CarouselController(); int carouselIndicatorIndex = 0; CarouselSlider _bannerCarousel; TextField _textFieldSearch; TextField _textFieldFilterSelection; ListView _listViewLatestOffers; ListView _listViewBestSeller; PackagesViewModel viewModel; onCartClick(){ if (viewModel.service.customer == null){ utils.Utils.showErrorToast("Cart is empty for your current session"); return; } Navigator.of(context).push( MaterialPageRoute( builder: (BuildContext context) => PackagesCartPage() ) ); } onProductCartClick(PackagesResponseModel product) async { if(viewModel.service.customer == null) await viewModel.service.createCustomer(PackagesCustomerRequestModel(email: "zikambrani@gmail.com", phoneNumber: "0500409598"), context: context); if(viewModel.service.customer != null){ var request = AddProductToCartRequestModel(product_id: product.id, customer_id: viewModel.service.customer.id); await viewModel.service.addProductToCart(request, context: context).catchError((error) { utils.Utils.showErrorToast(error); }); } } @override Widget build(BuildContext context) { return BaseView( allowAny: true, onModelReady: (model) => viewModel = model, builder: (_, model, wi){ return AppScaffold( appBarTitle: TranslationBase.of(context).offerAndPackages, isShowAppBar: true, isPharmacy: false, showPharmacyCart: false, showHomeAppBarIcon: false, isOfferPackages: true, showOfferPackagesCart: true, isShowDecPage: false, body: ListView( children: [ // Top Banner Carousel AspectRatio( aspectRatio: 2.2/1, child: bannerCarousel() ), Center( child: CarouselIndicator( activeColor: Theme.of(context).appBarTheme.color, color: Colors.grey[300], cornerRadius: 15, width: 15, height: 15, count: _bannerCarousel.itemCount, index: carouselIndicatorIndex, onClick: (index){ debugPrint('onClick at ${index}'); }, ), ), SizedBox(height: 10,), Padding( padding: const EdgeInsets.all(15), child: Column( children: [ // Search Textfield searchTextField(), SizedBox(height: 10,), // Filter Selection filterOptionSelection(), SizedBox(height: 20,), // Horizontal Scrollable Cards Text( "Latest offers", style: TextStyle( fontWeight: FontWeight.bold, color: Colors.black87, fontSize: 20 ), ), // Latest Offers Horizontal Scrollable List AspectRatio( aspectRatio: 1.3/1, child: LayoutBuilder(builder: (context, constraints){ double itemContentPadding = 10; double itemWidth = (constraints.maxWidth/2) - (itemContentPadding*2); return latestOfferListView(itemWidth: itemWidth, itemContentPadding: itemContentPadding); }), ), SizedBox(height: 10,), Text( "Best sellers", style: TextStyle( fontWeight: FontWeight.bold, color: Colors.black87, fontSize: 20 ), ), // Best Seller Horizontal Scrollable List AspectRatio( aspectRatio: 1.3/1, child: LayoutBuilder(builder: (context, constraints){ double itemContentPadding = 10; // 10 is content padding in each item double itemWidth = (constraints.maxWidth/2) - (itemContentPadding*2 /* 2 = LeftRight */); return bestSellerListView(itemWidth: itemWidth, itemContentPadding: itemContentPadding); }), ) ],), ), ], ), ) .setOnAppBarCartClick(onCartClick); } ); } showClinicSelectionList() async { var clinics = viewModel.service.categoryList; if(clinics.isEmpty) { GifLoaderDialogUtils.showMyDialog(context); clinics = await viewModel.service.getAllCategories(OffersCategoriesRequestModel()); GifLoaderDialogUtils.hideDialog(context); } List options = clinics.map((e) => e.toString()).toList(); showMaterialSelectionPicker( context: context, title: "Select Clinic", items: options, selectedItem: options.first, onChanged: (value) async { var selectedClinic = clinics.firstWhere((element) => element.toString() == value); var clinicProducts = await viewModel.service.getAllProducts(request: OffersProductsRequestModel(categoryId: selectedClinic.id), context: context, showLoading: true); if(clinicProducts.isNotEmpty) Navigator.of(context).push( MaterialPageRoute( builder: (BuildContext context) => ClinicPackagesPage(products: clinicProducts) ) ); else utils.Utils.showErrorToast("No offers available for this clinic"); }, ); } //---------------------------------- // Main Widgets of Page //---------------------------------- CarouselSlider bannerCarousel(){ _bannerCarousel = CarouselSlider.builder( carouselController: _carouselController, itemCount: 10, itemBuilder: (BuildContext context, int itemIndex) { return Padding( padding: const EdgeInsets.only(top: 10, bottom: 10, left: 15, right: 15), child: FractionallySizedBox( widthFactor: 1, heightFactor: 1, child: utils.applyShadow( spreadRadius: 1, blurRadius: 5, child: InkWell( child: ClipRRect( borderRadius: BorderRadius.circular(10), child: utils.Utils.loadNetworkImage(url: "https://wallpaperaccess.com/full/30103.jpg",) ), onTap: (){ Navigator.of(context).push( MaterialPageRoute( builder: (BuildContext context) => OfferAndPackagesDetail(model: "",) ) ); }, ) ), ), ); }, options: CarouselOptions( autoPlayInterval: Duration(milliseconds: 3500), enlargeStrategy: CenterPageEnlargeStrategy.scale, enlargeCenterPage: true, autoPlay: false, autoPlayCurve: Curves.fastOutSlowIn, enableInfiniteScroll: true, autoPlayAnimationDuration: Duration(milliseconds: 1500), viewportFraction: 1, onPageChanged: (page, reason){ setState(() { carouselIndicatorIndex = page; }); }, ), ); return _bannerCarousel; } TextField searchTextField(){ return _textFieldSearch = TextField( controller: _searchTextController, decoration: InputDecoration( contentPadding: EdgeInsets.only(top: 0.0, bottom: 0.0, left: 10, right: 10), enabledBorder: OutlineInputBorder( borderSide: BorderSide( width: 0.5, color: Colors.grey), borderRadius: const BorderRadius.all( const Radius.circular(10.0), ), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide( width: 1, color: Colors.grey), borderRadius: const BorderRadius.all( const Radius.circular(10.0), ), ), filled: true, fillColor: Colors.white, hintText: "Search", hintStyle: TextStyle(color: Colors.grey[350], fontWeight: FontWeight.bold), suffixIcon: IconButton( onPressed: (){ // viewModel.search(text: _searchTextController.text); }, icon: Icon(Icons.search_rounded, size: 35,), ), ), ); } Widget filterOptionSelection(){ _textFieldFilterSelection = TextField( enabled: false, controller: _searchTextController, decoration: InputDecoration( contentPadding: EdgeInsets.only(top: 0.0, bottom: 0.0, left: 10, right: 10), border: OutlineInputBorder( borderSide: BorderSide(color: Colors.grey, width: 1), borderRadius: const BorderRadius.all( const Radius.circular(10.0), ), ), disabledBorder: OutlineInputBorder( borderSide: BorderSide( width: 0.5, color: Colors.grey), borderRadius: const BorderRadius.all( const Radius.circular(10.0), ), ), focusedBorder: OutlineInputBorder( borderRadius: const BorderRadius.all( const Radius.circular(10.0), ), ), filled: true, fillColor: Colors.white, hintText: "Browse offers by Clinic", hintStyle: TextStyle(color: Colors.grey[350], fontWeight: FontWeight.bold), suffixIcon: IconButton( onPressed: (){ showClinicSelectionList(); }, icon: Icon(Icons.keyboard_arrow_down_rounded, size: 35, color: Colors.grey,), ), ), ); return InkWell( child: _textFieldFilterSelection, onTap: (){ showClinicSelectionList(); }, ); } Widget latestOfferListView({@required double itemWidth, @required double itemContentPadding}){ return _listViewLatestOffers = ListView.separated( scrollDirection: Axis.horizontal, itemCount: viewModel.bestSellerList.length, itemBuilder: (BuildContext context, int index) { return PackagesItemCard(itemWidth: itemWidth, itemContentPadding: itemContentPadding, itemModel: viewModel.bestSellerList[index], onCartClick: onProductCartClick,); }, separatorBuilder: separator, ); } Widget bestSellerListView({@required double itemWidth, @required double itemContentPadding}){ return _listViewLatestOffers = ListView.separated( scrollDirection: Axis.horizontal, itemCount: viewModel.bestSellerList.length, itemBuilder: (BuildContext context, int index) { return PackagesItemCard(itemWidth: itemWidth, itemContentPadding: itemContentPadding, itemModel: viewModel.bestSellerList[index], onCartClick: onProductCartClick,); }, separatorBuilder: separator, ); } Widget separator(BuildContext context, int index){ return Container( width: 1, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment(-1.0, -2.0), end: Alignment(1.0, 4.0), colors: [ Colors.grey, Colors.grey[100], Colors.grey[200], Colors.grey[300], Colors.grey[400], Colors.grey[500] ] )), ); } }