You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
PatientApp-KKUMC/lib/pages/packages_offers/OfferAndPackagesPage.dart

419 lines
16 KiB
Dart

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/PackagesCustomerResponseModel.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/CreateCustomerDailogPage.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/data_display/text.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<PackagesHomePage> with AfterLayoutMixin<PackagesHomePage>{
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)
viewModel.service.customer = await CreateCustomerDialogPage(context: context).show();
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).then((response){
appScaffold.appBar.badgeUpdater(viewModel.service.cartItemCount);
}).catchError((error) {
utils.Utils.showErrorToast(error);
});
}
}
AppScaffold appScaffold;
@override
Widget build(BuildContext context) {
return BaseView<PackagesViewModel>(
allowAny: true,
onModelReady: (model) => viewModel = model,
builder: (_, model, wi){
return
appScaffold =
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
Texts(
"Latest offers",
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,),
Texts(
"Best sellers",
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<String> 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]
]
)),
);
}
}