diff --git a/images/active.png b/images/active.png new file mode 100644 index 0000000..3f75808 Binary files /dev/null and b/images/active.png differ diff --git a/images/activeoffer.png b/images/activeoffer.png new file mode 100644 index 0000000..dbfdb21 Binary files /dev/null and b/images/activeoffer.png differ diff --git a/images/activeoffer1.png b/images/activeoffer1.png new file mode 100644 index 0000000..7418c38 Binary files /dev/null and b/images/activeoffer1.png differ diff --git a/images/background.png b/images/background.png index 3dc7ddf..152e8cb 100644 Binary files a/images/background.png and b/images/background.png differ diff --git a/images/createoffer.png b/images/createoffer.png new file mode 100644 index 0000000..20b7cd7 Binary files /dev/null and b/images/createoffer.png differ diff --git a/images/createofferic.png b/images/createofferic.png new file mode 100644 index 0000000..3e9d029 Binary files /dev/null and b/images/createofferic.png differ diff --git a/images/editprofile.png b/images/editprofile.png new file mode 100644 index 0000000..ba36d20 Binary files /dev/null and b/images/editprofile.png differ diff --git a/images/emergency.png b/images/emergency.png index 4eeda99..0ce11d9 100644 Binary files a/images/emergency.png and b/images/emergency.png differ diff --git a/images/inactive.png b/images/inactive.png new file mode 100644 index 0000000..69da1a6 Binary files /dev/null and b/images/inactive.png differ diff --git a/images/inactiveoffer.png b/images/inactiveoffer.png new file mode 100644 index 0000000..0b0e12e Binary files /dev/null and b/images/inactiveoffer.png differ diff --git a/images/invitations.png b/images/invitations.png index 43248d5..86dc31d 100644 Binary files a/images/invitations.png and b/images/invitations.png differ diff --git a/images/logo.png b/images/logo.png index 809d8c4..bf8940a 100644 Binary files a/images/logo.png and b/images/logo.png differ diff --git a/images/logout.png b/images/logout.png new file mode 100644 index 0000000..5276913 Binary files /dev/null and b/images/logout.png differ diff --git a/images/medicines.png b/images/medicines.png index 8cd1f94..6c82587 100644 Binary files a/images/medicines.png and b/images/medicines.png differ diff --git a/images/mobilebg.png b/images/mobilebg.png index b831d5a..eacaf4b 100644 Binary files a/images/mobilebg.png and b/images/mobilebg.png differ diff --git a/images/mobilebg2.png b/images/mobilebg2.png new file mode 100644 index 0000000..27ba4df Binary files /dev/null and b/images/mobilebg2.png differ diff --git a/images/mobilebg3.png b/images/mobilebg3.png new file mode 100644 index 0000000..a347415 Binary files /dev/null and b/images/mobilebg3.png differ diff --git a/images/myconnections.png b/images/myconnections.png new file mode 100644 index 0000000..05ceab7 Binary files /dev/null and b/images/myconnections.png differ diff --git a/images/myhealth.png b/images/myhealth.png new file mode 100644 index 0000000..7cfbf73 Binary files /dev/null and b/images/myhealth.png differ diff --git a/images/mymedicinetimings.png b/images/mymedicinetimings.png new file mode 100644 index 0000000..195e82e Binary files /dev/null and b/images/mymedicinetimings.png differ diff --git a/images/no_data.png b/images/no_data.png new file mode 100644 index 0000000..27c28a4 Binary files /dev/null and b/images/no_data.png differ diff --git a/images/prescriptions.png b/images/prescriptions.png index a3f0b4c..4e8c2c6 100644 Binary files a/images/prescriptions.png and b/images/prescriptions.png differ diff --git a/images/prifileuploadpic.png b/images/prifileuploadpic.png new file mode 100644 index 0000000..ce7175f Binary files /dev/null and b/images/prifileuploadpic.png differ diff --git a/images/reportmyself.png b/images/reportmyself.png new file mode 100644 index 0000000..01de7af Binary files /dev/null and b/images/reportmyself.png differ diff --git a/images/reports.png b/images/reports.png index 4f4b8a6..efc7987 100644 Binary files a/images/reports.png and b/images/reports.png differ diff --git a/images/seekopinion.png b/images/seekopinion.png index 665f8ce..df53f08 100644 Binary files a/images/seekopinion.png and b/images/seekopinion.png differ diff --git a/images/splashscreen.png b/images/splashscreen.png index 1da89fd..a8e03ba 100644 Binary files a/images/splashscreen.png and b/images/splashscreen.png differ diff --git a/images/updatemobilenumber.png b/images/updatemobilenumber.png new file mode 100644 index 0000000..962b70a Binary files /dev/null and b/images/updatemobilenumber.png differ diff --git a/images/updatemylocation.png b/images/updatemylocation.png new file mode 100644 index 0000000..0d492f4 Binary files /dev/null and b/images/updatemylocation.png differ diff --git a/images/updatepin.png b/images/updatepin.png new file mode 100644 index 0000000..6a386b7 Binary files /dev/null and b/images/updatepin.png differ diff --git a/lib/dashboard.dart b/lib/dashboard.dart index 87412bd..327416f 100644 --- a/lib/dashboard.dart +++ b/lib/dashboard.dart @@ -1,5 +1,11 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:healthcare_pharmacy/inactiveoffersview.dart'; +import 'package:healthcare_pharmacy/offers.dart'; +import 'package:healthcare_pharmacy/offersview.dart'; +import 'package:healthcare_pharmacy/updateprofile.dart'; import 'package:image_picker/image_picker.dart'; import 'package:carousel_slider/carousel_slider.dart'; import 'dart:ui' as ui; @@ -18,8 +24,8 @@ class _DashboardState extends State { int _selectedIndex = 0; final List imgList = [ 'images/mobilebg.png', - 'images/mobilebg.png', - 'images/mobilebg.png' + 'images/mobilebg2.png', + 'images/mobilebg3.png' ]; final ImagePicker _picker = ImagePicker(); @@ -45,37 +51,41 @@ class _DashboardState extends State { } List images = [ - "images/seekopinion.png", - "images/reports.png", + "images/createoffer.png", + "images/activeoffer.png", + "images/inactiveoffer.png", + + /* "images/reports.png", "images/prescriptions.png", "images/medicines.png", "images/invitations.png", - "images/emergency.png" + "images/emergency.png"*/ ]; gridOntap(int ind){ - if(ind==0){ + if(ind==0){ Navigator.push( context, MaterialPageRoute( - builder: (context) => const SeekOpinion()), + builder: (context) => const offers()), ); } - /*else if(ind==1){ + else if(ind==1){ Navigator.push( context, MaterialPageRoute( - builder: (context) => const Reports()), + builder: (context) => const OffersView()), ); } else if(ind==2){ Navigator.push( context, MaterialPageRoute( - builder: (context) => const Prescriptions()), + builder: (context) => const InActiveOffersView()), ); } +/* else if(ind==3){ Navigator.push( context, @@ -102,9 +112,10 @@ class _DashboardState extends State { Widget _dashBoard() { return Container( - color: Colors.white, + color: Color(0xffA78966), child: Column( children: [ + CarouselSlider( options: CarouselOptions( height: MediaQuery.of(context).size.height * .250, @@ -147,9 +158,9 @@ class _DashboardState extends State { child: GridView.builder( itemCount: images.length, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - crossAxisSpacing: 4.0, - mainAxisSpacing: 4.0,), + crossAxisCount: 3, + crossAxisSpacing: 4.0, + mainAxisSpacing: 4.0,), itemBuilder: (BuildContext context, int index) { return GestureDetector( onTap: (){ @@ -170,6 +181,51 @@ class _DashboardState extends State { devicedetection(); } + Future uploadProfileApi(image) async { + var payload = new Map(); + payload["formData"] = image.toString(); + var response1 = await AppSettings.updateProfilePicture(payload); + + print(response1); + } + + Future pickImageFromGallery() async { + try { + final image = await _picker.pickImage(source: ImageSource.gallery); + if (image == null) return; + final imageTemp = File(image.path); + setState(() { + AppSettings.updatedImage = imageTemp; + }); + uploadProfileApi(image.path); + AppSettings.saveProfile(image.path); + } on PlatformException catch (e) { + print('Failed to pick image: $e'); + } + } + + Future takeImageFromCamera() async { + try { + final image = await _picker.pickImage(source: ImageSource.camera); + if (image == null) return; + final imageTemp = File(image.path); + setState(() { + AppSettings.updatedImage = imageTemp; + }); + + uploadProfileApi(image.path); + AppSettings.saveProfile(image.path); + } on PlatformException catch (e) { + print('Failed to pick image: $e'); + } + } + + + + + + + showLogoutAlertDialog(context) { return showDialog( context: context, @@ -177,28 +233,28 @@ class _DashboardState extends State { builder: (BuildContext context) { return StatefulBuilder( builder: (BuildContext context, StateSetter setState) { - return AlertDialog( - title: const Text('Do you really want to logout?'), - actions: [ - TextButton( - child: Text('No', style: textButtonStyle()), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - TextButton( - child: Text('Yes', style: textButtonStyle()), - onPressed: () async { - await AppSettings.clearSharedPreferences(); - await Navigator.pushAndRemoveUntil( - context, - MaterialPageRoute(builder: (context) => Login()), - (Route route) => false, - ); - }, - ), - ]); - }); + return AlertDialog( + title: const Text('Do you really want to logout?'), + actions: [ + TextButton( + child: Text('No', style: textButtonStyle()), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + TextButton( + child: Text('Yes', style: textButtonStyle()), + onPressed: () async { + await AppSettings.clearSharedPreferences(); + await Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => Login()), + (Route route) => false, + ); + }, + ), + ]); + }); }); } @@ -247,6 +303,8 @@ class _DashboardState extends State { resizeToAvoidBottomInset: false, appBar: AppSettings.appBar('Health Care'), drawer: Drawer( + backgroundColor: secondaryColor, + child: ListView( padding: EdgeInsets.zero, children: [ @@ -262,65 +320,122 @@ class _DashboardState extends State { Expanded( child: GestureDetector( child: Container( - width: MediaQuery.of(context).size.width * .20, + width: MediaQuery.of(context).size.width * .30, height: - MediaQuery.of(context).size.height * .15, + MediaQuery.of(context).size.height * .30, decoration: BoxDecoration( - shape: BoxShape.circle, + shape: BoxShape.rectangle, + border: Border.all(width: 5, color: Colors.blueGrey), image: DecorationImage( - image: AssetImage( - "images/profile_pic.png"), // picked file + image: (AppSettings.updatedImage != + null) + ? FileImage( + AppSettings.updatedImage!) + as ImageProvider + : AssetImage( + "images/mobilebg.png"), // picked file fit: BoxFit.cover)), ), - onTap: () {}, + onTap: () { + showModalBottomSheet( + context: context, + builder: (BuildContext context) { + return SizedBox( + height: 200, + child: Center( + child: Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + GestureDetector( + child: Icon( + Icons.camera_alt_outlined, + size: 100, + color: greyColor, + ), + onTap: () async { + await takeImageFromCamera(); + Navigator.pop(context); + }, + ), + SizedBox( + width: MediaQuery.of(context) + .size + .width * + .20, + ), + GestureDetector( + child: Icon( + Icons.photo, + size: 100, + color: greyColor, + ), + onTap: () async { + await pickImageFromGallery(); + Navigator.pop(context); + }, + ), + ], + ), + ), + ); + }); + }, ), ), + Text( - "Sneha", - //AppSettings.userName, + AppSettings.pharmacyName, style: TextStyle(color: Colors.white, fontSize: 15), ), Text( - '9898989898', - //AppSettings.phoneNumber, + AppSettings.phoneNumber, style: TextStyle(color: Colors.white, fontSize: 15), ), Text( - 'sneha@armintasolutions.com', //AppSettings.email, + AppSettings.email, style: TextStyle(color: Colors.white, fontSize: 15), ), + SizedBox( + height: 10, + ), ], ), Container() ], + )), + ListTile( title: Row( children: const [ Image( - image: const AssetImage('images/01.png'), + image: const AssetImage('images/editprofile.png'), height: 25, width: 25, fit: BoxFit.fill), const SizedBox( width: 10, ), - const SizedBox( - width: 10, - ), - Text('Edit Profile', style: TextStyle(color: primaryColor)), + Text('Edit Profile', style: TextStyle(color: Colors.black)), ], ), - onTap: () {}, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const UpdateProfile()), + ); + }, ), Divider( color: Colors.grey, ), - ListTile( + /* ListTile( title: Row( children: const [ Image( - image: const AssetImage('images/01.png'), + image: const AssetImage('images/myhealth.png'), height: 25, width: 25, fit: BoxFit.fill), @@ -333,7 +448,13 @@ class _DashboardState extends State { Text('My Health', style: TextStyle(color: primaryColor)), ], ), - onTap: () {}, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const MyHealth()), + ); + }, ), Divider( color: Colors.grey, @@ -342,7 +463,7 @@ class _DashboardState extends State { title: Row( children: const [ Image( - image: const AssetImage('images/01.png'), + image: const AssetImage('images/reportmyself.png'), height: 25, width: 25, fit: BoxFit.fill), @@ -364,7 +485,7 @@ class _DashboardState extends State { title: Row( children: const [ Image( - image: const AssetImage('images/01.png'), + image: const AssetImage('images/myconnections.png'), height: 25, width: 25, fit: BoxFit.fill), @@ -386,7 +507,7 @@ class _DashboardState extends State { title: Row( children: const [ Image( - image: const AssetImage('images/01.png'), + image: const AssetImage('images/mymedicinetimings.png'), height: 25, width: 25, fit: BoxFit.fill), @@ -408,7 +529,7 @@ class _DashboardState extends State { title: Row( children: const [ Image( - image: const AssetImage('images/01.png'), + image: const AssetImage('images/updatepin.png'), height: 25, width: 25, fit: BoxFit.fill), @@ -425,25 +546,28 @@ class _DashboardState extends State { ), Divider( color: Colors.grey, - ), + ),*/ ListTile( title: Row( children: const [ Image( - image: const AssetImage('images/01.png'), + image: const AssetImage('images/createofferic.png'), height: 25, width: 25, fit: BoxFit.fill), const SizedBox( width: 10, ), - const SizedBox( - width: 10, - ), - Text('Update Mobile Number', style: TextStyle(color: primaryColor)), + Text('Create Offers', style: TextStyle(color: Colors.black)), ], ), - onTap: () {}, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const offers()), + ); + }, ), Divider( color: Colors.grey, @@ -452,20 +576,23 @@ class _DashboardState extends State { title: Row( children: const [ Image( - image: const AssetImage('images/01.png'), + image: const AssetImage('images/active.png'), height: 25, width: 25, fit: BoxFit.fill), const SizedBox( width: 10, ), - const SizedBox( - width: 10, - ), - Text('Update My Location', style: TextStyle(color: primaryColor)), + Text('ActiveOffersView', style: TextStyle(color: Colors.black)), ], ), - onTap: () {}, + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const OffersView()), + ); + }, ), Divider( color: Colors.grey, @@ -474,20 +601,48 @@ class _DashboardState extends State { title: Row( children: const [ Image( - image: const AssetImage('images/01.png'), + image: const AssetImage('images/inactive.png'), height: 25, width: 25, fit: BoxFit.fill), const SizedBox( width: 10, ), + Text('InActiveOffersView', style: TextStyle(color: Colors.black)), + ], + ), + onTap: () { + + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const InActiveOffersView()), + ); + + + + }, + ), + Divider( + color: Colors.grey, + ), + ListTile( + title: Row( + children: const [ + Image( + image: const AssetImage('images/logout.png'), + height: 25, + width: 25, + fit: BoxFit.fill), const SizedBox( width: 10, ), - Text('Logout', style: TextStyle(color: primaryColor)), + Text('Logout', style: TextStyle(color: Colors.black)), ], ), - onTap: () {}, + onTap: () async { + showLogoutAlertDialog(context); + }, ), ], diff --git a/lib/getmedicines.dart b/lib/getmedicines.dart new file mode 100644 index 0000000..cb2d0bd --- /dev/null +++ b/lib/getmedicines.dart @@ -0,0 +1,374 @@ +import 'dart:convert'; +import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:geolocator/geolocator.dart'; +import 'package:healthcare_pharmacy/models/medicineview_model.dart'; +import 'package:healthcare_pharmacy/settings.dart'; +import 'package:flutter/services.dart'; +import 'package:url_launcher/url_launcher.dart'; +import 'package:cloudinary_public/cloudinary_public.dart'; + +class WaterSuppliers extends StatefulWidget { + const WaterSuppliers({Key? key}) : super(key: key); + + @override + State createState() => _WaterSuppliersState(); +} + +class _WaterSuppliersState extends State with TickerProviderStateMixin { + bool isMedecineDataLoading=false; + bool isSereverIssue = false; + List medecineList = []; + List FilteredList = []; + + TextEditingController searchController = TextEditingController(); + String dropdownArea = '2'; + //String dropdownType = 'Tank'; + + Future getSuppliersDataByMedecineName(var MedecineName) async { + FilteredList=[]; + isMedecineDataLoading = true; + + + try { + var medecineResponse = await AppSettings.getAllMedecines(MedecineName); + + setState(() { + medecineList = + ((jsonDecode(medecineResponse)['medicine']) as List).map((dynamic model) { + return GetMedecineDetailsModel(distance).fromJson(model); + }).toList(); + + FilteredList= medecineList.where( + (x) => x.name.toLowerCase().contains(MedecineName) + ).toList(); + + //FilteredList=suppliersList.where((product) => product.supplier_phone_number.toString()==phnNum).toList(); + + }); + + //FilteredList=suppliersList.where((product) => product.address.toString().toUpperCase()=='SUMP').toList(); + + + isMedecineDataLoading = false; + + + } catch (e) { + setState(() { + isMedecineDataLoading = false; + isSereverIssue = true; + }); + } + } + + + + Future getAllMedecineData(var distance) async { + FilteredList=[]; + isMedecineDataLoading = true; + + + try { + var medecineResponse = await AppSettings.getAllMedecines(); + setState(() { + medecineList = + ((jsonDecode(medecineResponse)['medicine']) as List).map((dynamic model) { + return GetMedecineDetailsModel.fromJson(model); + }).toList(); + FilteredList=[]; + medecineList.forEach((element) async{ + var distanceInM; + if(distance=='2'){ + distanceInM=2000; + } + else if(distance=='5'){ + distanceInM=5000; + } + else if(distance=='10'){ + distanceInM=10000; + } + else if(distance=='25'){ + distanceInM=25000; + } + else if(distance=='50'){ + distanceInM=50000; + } + else if(distance=='100'){ + distanceInM=100000; + } + /* double distanceInMeters = await Geolocator.distanceBetween(element.lat,element.lng,lat,lng); + if(distanceInMeters<=distanceInM){ + FilteredList.add(element); + }*/ + }); + + //FilteredList=suppliersList.where((product) => product.address.toString().toUpperCase()=='SUMP').toList(); + + + isMedecineDataLoading = false; + }); + + + } catch (e) { + setState(() { + isMedecineDataLoading = false; + isSereverIssue = true; + }); + } + } + + @override + void initState() { + // TODO: implement initState + //getAllSuppliers(); + getAllMedecineData(dropdownArea); + super.initState(); + } + + + Widget _tanker() { + if (FilteredList.length != 0) { + return ListView.builder( + padding: EdgeInsets.all(0), + itemCount: FilteredList.length, + itemBuilder: (BuildContext context, int index) { + return GestureDetector( + onTap: () { + // modelBottomSheet(FilteredList[index]); + }, + child: Card( + child: Padding( + padding: EdgeInsets.fromLTRB(0,8,0,0), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: MediaQuery.of(context).size.width * .18, + height: + MediaQuery.of(context).size.height * .10, + decoration: BoxDecoration( + shape: BoxShape.circle, + image: DecorationImage( + image: FilteredList[index].picture=='' + ?AssetImage("images/logo.png") + : NetworkImage(FilteredList[index].picture) as ImageProvider, // picked file + fit: BoxFit.contain)), + ), + /*Container( + width: MediaQuery.of(context).size.width * .15, + height: MediaQuery.of(context).size.height * .10, + child: CircleAvatar( + child:(FilteredList[index].picture)=='' + ? Image(image: AssetImage("images/logo.png")) + : Image.network('https://storage.googleapis.com/arminta_profile_pictures/photo.jpeg'), + ) + ),*/ + SizedBox(width: 5,), + Expanded( + child: Container( + width: MediaQuery.of(context).size.width * .70, + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + FilteredList[index] + .name + .toUpperCase(), + style: wrapTextStyleBlack()), + SizedBox(height: 10,), + Text( + FilteredList[index] + .manufacturers + .toUpperCase(), + style: wrapTextStyleBlack()), + Visibility( + visible: FilteredList[index].name!='', + child: Text( + FilteredList[index] + .salt_composition + .toUpperCase(), + style: wrapTextStyleBlack()),), + SizedBox(height: 10,), + Text( + FilteredList[index] + .mrp + .toUpperCase(), + style: wrapTextStyleBlack()), + Visibility( + visible: FilteredList[index].primary_use!='', + child: SizedBox(height: 10,),), + Visibility( + visible: FilteredList[index].primary_use!='', + child: Text( + FilteredList[index] + .primary_use + .toUpperCase(), + style: wrapTextStyleBlack()),), + SizedBox(height: 10,), + + ], + ) + ), + ), + + + ], + ), + ), + ), + ); + }); + } + else { + return Center( + child: Padding( + padding: EdgeInsets.fromLTRB(0, 40, 0, 0), + child: isSereverIssue + ? Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image( + image: AssetImage('images/serverissue.png'), + // height: MediaQuery.of(context).size.height * .10, + ), + SizedBox( + height: 20, + ), + Text( + 'There is an issue at server please try after some time',style:serverIssueTextStyle() ,), + ], + ) + : userAddress==''?Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + /*Image( + image: AssetImage('images/resourceblue.pngs'), + // height: MediaQuery.of(context).size.height * .10, + ),*/ + Icon(Icons.location_on_outlined,color: primaryColor,size: 40,), + SizedBox( + height: 20, + ), + Text( + 'Please select location to see near by tankers',style:TextStyle( + color: primaryColor, + fontWeight: FontWeight.bold, + ),), + ], + ): + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image( + image: AssetImage('images/no_data.png'), + // height: MediaQuery.of(context).size.height * .10, + ), + SizedBox( + height: 20, + ), + Text( + 'No Tankers',style:serverIssueTextStyle() ,), + ], + ), + )); + } + } + + + + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Medecine Details'), + backgroundColor: primaryColor,), + /* body: */ + body: TabBarView(controller: _controller, children: [ + Container( + //color: Colors.purpleAccent, + child:Column( + children: [ + Padding(padding:EdgeInsets.all(10) , + child: Container( + height: MediaQuery.of(context).size.height * .07, + padding: EdgeInsets.all(5), + child: Center(child: TextField( + + cursorColor: greyColor, + controller: searchController, + keyboardType: TextInputType.number, + onChanged: (string) { + if(string.length>=1){ + getSuppliersDataByPhnNumber(string); + } + else{ + getAllMedecineData(dropdownArea); + } + }, + decoration: InputDecoration( + prefixIcon: Icon( + Icons.search, + color: greyColor, + ), + /*suffixIcon: Icon( + Icons.clear, + color: greyColor, + ),*/ + suffixIcon: IconButton( + icon: Icon( + Icons.clear, + color: greyColor, + ), + onPressed: () { + setState(() { + searchController.text=''; + }); + getAllMedecineData(dropdownArea); + }, + ), + border: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + borderRadius: BorderRadius.circular(30), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + borderRadius: BorderRadius.circular(30), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + borderRadius: BorderRadius.circular(30), + ), + //labelText: 'Search by phone number', + hintText: 'Search phone number', + labelStyle: TextStyle( + color: greyColor, //<-- SEE HERE + ), + ), + ),) + ),), + + + + Expanded(child: Container( + child:isMedecineDataLoading + ? Center( + child: CircularProgressIndicator( + color: primaryColor, + strokeWidth: 5.0, + ), + ) + : _tanker() , + )) + ], + ), + ), + + ]), + ); + } + +} diff --git a/lib/inactiveoffersview.dart b/lib/inactiveoffersview.dart new file mode 100644 index 0000000..ddcc896 --- /dev/null +++ b/lib/inactiveoffersview.dart @@ -0,0 +1,285 @@ +import 'dart:convert'; +import 'package:flutter/material.dart'; +import 'package:healthcare_pharmacy/models/offersview_model.dart'; +import 'package:healthcare_pharmacy/offers.dart'; +import 'package:healthcare_pharmacy/settings.dart'; +import 'package:intl/intl.dart'; +import 'package:flutter_cupertino_datetime_picker/flutter_cupertino_datetime_picker.dart'; + + +class InActiveOffersView extends StatefulWidget { + const InActiveOffersView({Key? key}) : super(key: key); + + @override + State createState() => _InActiveOffersViewState(); +} + +class _InActiveOffersViewState extends State with TickerProviderStateMixin { + bool isSupplierDataLoading=false; + bool isSereverIssue = false; + bool isSereverIssueConnected = false; + bool isSereverIssuePending = false; + var startdate; + var enddate; + + + List offersviewList = []; + TextEditingController offerNameController = TextEditingController(); + TextEditingController offerCodeController = TextEditingController(); + TextEditingController offerDescriptionController = TextEditingController(); + TextEditingController offerDiscountController = TextEditingController(); + TextEditingController offerStartDateController = TextEditingController(); + TextEditingController offerEndDateController = TextEditingController(); + + + bool isLoading=false; + + Future getOffersViewData() async { + isLoading = true; + try { + var response = await AppSettings.getinactiveOffers(); + setState(() { + offersviewList = + ((jsonDecode(response)['data']) as List).map((dynamic model) { + return GetOffersDetailsModel.fromJson(model); + }).toList(); + isLoading = false; + }); + + + } catch (e) { + setState(() { + isLoading = false; + isSereverIssueConnected = true; + }); + } + } + + + + @override + void initState() { + // TODO: implement initState + isLoading=true; + getOffersViewData(); + super.initState(); + } + + Widget renderzUi(){ + if(offersviewList.length!=0){ + + return Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Expanded(child:ListView.builder( + padding: EdgeInsets.all(0), + itemCount: offersviewList.length, + itemBuilder: (BuildContext context, int index) { + return Card( + + color: offersviewList[index].cardColor, + child: Padding( + padding:EdgeInsets.all(8) , + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + + Container( + //width: MediaQuery.of(context).size.width * .55, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('OfferName :',style: labelTextStyle()), + Text('OfferCode :',style: labelTextStyle()), + Text('OfferDes :' ,style: labelTextStyle()), + Text('OfferDis(%) :' ,style: labelTextStyle()), + Text('StartDate :',style: labelTextStyle()), + Text('EndDate :' ,style: labelTextStyle()), + + ], + ), + SizedBox(width: 5,), + Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(offersviewList[index].offer_name,style: valuesTextStyle()), + Text(offersviewList[index].offer_code,style: valuesTextStyle()), + Text(offersviewList[index].description,style: valuesTextStyle()), + Text(offersviewList[index].discount_percentage,style: valuesTextStyle()), + Text(offersviewList[index].starting_date,style: valuesTextStyle()), + Text(offersviewList[index].ending_date,style: valuesTextStyle()) + + ], + ), + ], + ), + ], + ), + ), + + Expanded(child:TextButton( + onPressed: () { + showDialog( + //if set to true allow to close popup by tapping out of the popup + //barrierDismissible: false, + context: context, + builder: (BuildContext context) => AlertDialog( + title: const Text('Do you want to Re_Active offer ??', + style: TextStyle( + color: primaryColor, + fontSize: 16, + )), + actionsAlignment: MainAxisAlignment.spaceBetween, + actions: [ + TextButton( + onPressed: ()async { + bool deleteTankStatus = await AppSettings.reactiveOffers(offersviewList[index].offer_code); + + if(deleteTankStatus){ + getOffersViewData(); + AppSettings.longSuccessToast('offer Re_Active successfully'); + Navigator.of(context).pop(true); + + } + else{ + AppSettings.longFailedToast('offer Re_Active failed'); + } + }, + child: const Text('Yes', + style: TextStyle( + color: primaryColor, + fontSize: 18, + )), + ), + TextButton( + onPressed: () { + Navigator.of(context).pop(true); + }, + child: const Text('No', + style: TextStyle( + color: primaryColor, + fontSize: 18, + )), + ), + ], + ), + ); + }, + child: const Text( + 'RE_ACTIVE', + style: TextStyle( + color: primaryColor, + fontSize: 15, + fontWeight: FontWeight.bold + /* decoration: TextDecoration.underline,*/ + + ), + ), + ), + + ), + + ], + + ), + ), + ); + }) ), + Padding( + padding: EdgeInsets.fromLTRB(8, 8, 8, 8), + child: CircleAvatar( + backgroundColor: primaryColor, + radius: 40, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + iconSize: 40, + icon: const Icon( + Icons.add, + color: Colors.white, + ), + onPressed: () async{ + Navigator.pop(context); + await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => offers()), + ); + //showBoreAddingDialog(); + }, + ), + /* Padding( + padding: EdgeInsets.fromLTRB(5, 0, 5, 5), + child: Text( + 'Add Tanks ', + style: TextStyle(color: Colors.white), + ), + )*/ + ], + ), + ), + ), + ]); + } + else{ + return Center( + child: Padding( + padding: EdgeInsets.fromLTRB(0, 40, 0, 0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox(height: MediaQuery.of(context).size.height * .25,), + Text('Click below icon to add new Offer'), + SizedBox( + height: 20, + ), + CircleAvatar( + backgroundColor: primaryColor, + radius: 40, + child: IconButton( + iconSize: 40, + icon: const Icon( + Icons.add, + color: Colors.white, + ), + onPressed: () async { + Navigator.pop(context); + await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => offers()), + ); + }, + ), + ) + ], + ), + ) + ); + } + } + + @override + Widget build(BuildContext context) { + return SafeArea( + child: Scaffold( + appBar: AppSettings.appBar('InActive OfersView'), + body: isLoading?Center( + child: CircularProgressIndicator( + color: primaryColor, + strokeWidth: 5.0, + ), + ):renderzUi(), + )); + } +} \ No newline at end of file diff --git a/lib/login.dart b/lib/login.dart index 8077dad..fd3096d 100644 --- a/lib/login.dart +++ b/lib/login.dart @@ -105,24 +105,9 @@ class _LoginState extends State { cursorColor: greyColor, controller: mobileNumberController, keyboardType: TextInputType.number, - decoration: const InputDecoration( - prefixIcon: Icon( - Icons.phone, - color: greyColor, - ), - border: OutlineInputBorder( - borderSide: BorderSide(color: primaryColor)), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color:primaryColor), - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: primaryColor), - ), - labelText: 'Enter MobileNumber', - labelStyle: TextStyle( - color: greyColor, //<-- SEE HERE - ), - ), + maxLength: 10, + decoration: textFormFieldDecoration(Icons.phone,'Enter MobileNumber'), + ), ), const SizedBox( @@ -136,10 +121,12 @@ class _LoginState extends State { obscureText: isObscureText, controller: passwordController, decoration: InputDecoration( + filled: true, + fillColor: Colors.white, labelText: 'Password', prefixIcon: const Icon(Icons.password, color: greyColor,), labelStyle: const TextStyle( - color: greyColor, //<-- SEE HERE + color: primaryColor, fontWeight: FontWeight.bold//<-- SEE HERE ), border: const OutlineInputBorder( borderSide: BorderSide(color: primaryColor)), @@ -167,6 +154,8 @@ class _LoginState extends State { ), ), + + Padding(padding: const EdgeInsets.fromLTRB(220, 10, 0,10), child: TextButton( onPressed: () { @@ -178,7 +167,7 @@ class _LoginState extends State { child: const Text( 'Forgot Password?', style: TextStyle( - color: greyColor, + color: Colors.white, fontSize: 15, decoration: TextDecoration.underline, @@ -191,7 +180,7 @@ class _LoginState extends State { padding: const EdgeInsets.fromLTRB(10, 0, 10, 0), child: ElevatedButton( style: ElevatedButton.styleFrom( - primary: primaryColor, // background + primary: buttonColor, // background onPrimary: Colors.white, // foreground ), onPressed: () async{ @@ -254,14 +243,14 @@ class _LoginState extends State { const Text( 'Not a Member Yet?', style: TextStyle( - color: primaryColor, + color: Colors.white, ), ), TextButton( child: const Text( 'Sign Up', style: TextStyle(fontSize: 15, - decoration: TextDecoration.underline,color: greyColor), + decoration: TextDecoration.underline,color: Colors.white), ), onPressed: () { Navigator.push( diff --git a/lib/models/medicineview_model.dart b/lib/models/medicineview_model.dart new file mode 100644 index 0000000..bfbd260 --- /dev/null +++ b/lib/models/medicineview_model.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; + + +class GetMedecineDetailsModel { + String name = ''; + String manufacturers = ''; + String salt_composition = ''; + String mrp=''; + String primary_use=''; + + + String bs64str=''; + String picture=''; + Map picture1={}; + Color text_color=Colors.black; + + + + GetMedecineDetailsModel(); + + factory GetMedecineDetailsModel.fromJson(Map json){ + GetMedecineDetailsModel rtvm = new GetMedecineDetailsModel(); + + rtvm.name = json['name'] ?? ''; + rtvm.manufacturers = json['manufacturers'] ?? ''; + rtvm.salt_composition = json['salt_composition'] ?? ''; + rtvm.mrp = json['mrp'] ?? ''; + rtvm.primary_use = json['primary_use'] ??''; + rtvm.picture = json['picture'] ?? ''; + + return rtvm; + } + +} \ No newline at end of file diff --git a/lib/models/offersview_model.dart b/lib/models/offersview_model.dart new file mode 100644 index 0000000..da9bf12 --- /dev/null +++ b/lib/models/offersview_model.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; + + +class GetOffersDetailsModel { + String offer_name = ''; + String offer_code = ''; + String description = ''; + String discount_percentage=''; + String starting_date=''; + Color cardColor=Colors.white; + String ending_date=''; + + + + GetOffersDetailsModel(); + + factory GetOffersDetailsModel.fromJson(Map json){ + GetOffersDetailsModel rtvm = new GetOffersDetailsModel(); + + rtvm.offer_name = json['offer_name'] ?? ''; + rtvm.offer_code = json['offer_code'] ?? ''; + rtvm.description = json['description'] ?? ''; + rtvm.discount_percentage = json['discount_percentage'] ?? ''; + rtvm.starting_date = json['starting_date'] ??''; + rtvm.ending_date = json['ending_date'] ??''; + + return rtvm; + } + +} \ No newline at end of file diff --git a/lib/offers.dart b/lib/offers.dart new file mode 100644 index 0000000..b3928bb --- /dev/null +++ b/lib/offers.dart @@ -0,0 +1,370 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:healthcare_pharmacy/dashboard.dart'; +import 'package:healthcare_pharmacy/settings.dart'; +import 'package:intl/intl.dart'; +import 'package:flutter_cupertino_datetime_picker/flutter_cupertino_datetime_picker.dart'; + + +class offers extends StatefulWidget { + const offers({Key? key}) : super(key: key); + + @override + State createState() => _offersState(); +} + +class _offersState extends State { + + TextEditingController offer_nameController = TextEditingController(); + TextEditingController offer_codeController = TextEditingController(); + TextEditingController descriptionController = TextEditingController(); + TextEditingController discount_percentageController = TextEditingController(); + TextEditingController starting_dateController = TextEditingController(); + TextEditingController ending_dateController = TextEditingController(); + var selIOS; + + + @override + Widget build(BuildContext context) { + return SafeArea( + child: Scaffold( + appBar: AppSettings.appBar('Cteate Offers'), + body: Stack(children: [ + + GestureDetector( + onTap: () { + FocusManager.instance.primaryFocus?.unfocus(); + }, + child: SafeArea( + child: SingleChildScrollView( + child: Column( + children: [ + + SizedBox( + height: 20, + ), + Container( + //width: double.infinity, + child: Image( + image: const AssetImage('images/logo.png'), + height: MediaQuery.of(context).size.height * .18, + )), + + SizedBox( + height: 05, + ), + Container( + padding: const EdgeInsets.all(10), + child: TextFormField( + cursorColor: greyColor, + controller: offer_nameController, + textCapitalization: TextCapitalization.characters, + decoration: const InputDecoration( + prefixIcon: Icon( + Icons.person, + color: primaryColor, + ), + border: OutlineInputBorder( + borderSide: BorderSide(color: primaryColor)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + labelText: 'Enter Offer Name', + labelStyle: TextStyle( + color: greyColor, //<-- SEE HERE + ), + ), + ), + ), //name + SizedBox( + height: 05, + ), + Container( + padding: const EdgeInsets.all(10), + child: TextFormField( + cursorColor: greyColor, + controller: offer_codeController, + textCapitalization: TextCapitalization.characters, + decoration: const InputDecoration( + prefixIcon: Icon( + Icons.numbers, + color: primaryColor, + ), + border: OutlineInputBorder( + borderSide: BorderSide(color: primaryColor)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + labelText: 'Enter Offer Code', + labelStyle: TextStyle( + color: greyColor, //<-- SEE HERE + ), + ), + ), + ), + const SizedBox( + height: 5, + ), + Container( + padding: const EdgeInsets.all(10), + child: TextFormField( + cursorColor: greyColor, + controller: descriptionController, + textCapitalization: TextCapitalization.characters, + decoration: const InputDecoration( + prefixIcon: Icon( + Icons.description, + color: primaryColor, + ), + border: OutlineInputBorder( + borderSide: BorderSide(color: primaryColor)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + labelText: 'Enter Offer Description', + labelStyle: TextStyle( + color: greyColor, //<-- SEE HERE + ), + ), + ), + ), //mobile + + const SizedBox( + height: 5, + ), + Container( + padding: const EdgeInsets.all(10), + child: TextFormField( + cursorColor: greyColor, + controller: discount_percentageController, + keyboardType: TextInputType.number, + maxLength: 2, + decoration: const InputDecoration( + prefixIcon: Icon( + Icons.percent_outlined, + color: primaryColor, + ), + border: OutlineInputBorder( + borderSide: BorderSide(color: primaryColor)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + labelText: 'Enter Percentage', + labelStyle: TextStyle( + color: greyColor, //<-- SEE HERE + ), + ), + ), + ), + const SizedBox( + height: 5, + ), + + Container( + padding: const EdgeInsets.fromLTRB(10, 10, 10, 0), + child: TextFormField( + readOnly: true, + cursorColor: greyColor, + controller: starting_dateController, + decoration: InputDecoration( + labelText: 'Select Start Date', + prefixIcon: const Icon(Icons.date_range, color: primaryColor,), + labelStyle: const TextStyle( + color: greyColor, //<-- SEE HERE + ), + border: const OutlineInputBorder( + borderSide: BorderSide(color: primaryColor)), + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + suffixIcon: IconButton( + icon: Icon( + Icons.date_range, + ), + onPressed: () async { + DatePicker.showDatePicker( + context, + dateFormat: 'dd MMMM yyyy HH:mm', + initialDateTime: DateTime.now(), + minDateTime:DateTime.now(), + maxDateTime: DateTime.now().add(Duration(days: 365)), + onMonthChangeStartWithFirstDate: true, + pickerMode: DateTimePickerMode.datetime, + pickerTheme: DateTimePickerTheme( + // backgroundColor: Colors.white, + cancelTextStyle: labelTextStyle(), + confirmTextStyle: labelTextStyle(), + // showTitle: true, + //title: Text('Pick date and time'), + itemTextStyle: valuesTextStyle(), + ), + onConfirm: (dateTime, List index)async { + DateTime selectdate = dateTime; + setState(() { + selIOS = DateFormat('dd-MMM-yyyy - HH:mm').format(selectdate); + }); + + if(selIOS!=''){ + setState(() { + starting_dateController.text=selIOS.toString(); + }); + } + else { + AppSettings.longFailedToast('please select date'); + } + }, + ); + }, + ), + + ), + + ), + ), + + const SizedBox( + height: 5, + ), + Container( + padding: const EdgeInsets.fromLTRB(10, 10, 10, 0), + child: TextFormField( + readOnly: true, + cursorColor: greyColor, + controller: ending_dateController, + decoration: InputDecoration( + labelText: 'Select End Date', + prefixIcon: const Icon(Icons.date_range, color: primaryColor,), + labelStyle: const TextStyle( + color: greyColor, //<-- SEE HERE + ), + border: const OutlineInputBorder( + borderSide: BorderSide(color: primaryColor)), + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + suffixIcon: IconButton( + icon: Icon( + Icons.date_range, + ), + onPressed: () async { + DatePicker.showDatePicker( + context, + dateFormat: 'dd MMMM yyyy HH:mm', + initialDateTime: DateTime.now(), + minDateTime:DateTime.now(), + maxDateTime: DateTime.now().add(Duration(days: 365)), + onMonthChangeStartWithFirstDate: true, + pickerMode: DateTimePickerMode.datetime, + pickerTheme: DateTimePickerTheme( + // backgroundColor: Colors.white, + cancelTextStyle: labelTextStyle(), + confirmTextStyle: labelTextStyle(), + // showTitle: true, + //title: Text('Pick date and time'), + itemTextStyle: valuesTextStyle(), + ), + onConfirm: (dateTime, List index)async { + DateTime selectdate = dateTime; + setState(() { + selIOS = DateFormat('dd-MMM-yyyy - HH:mm').format(selectdate); + }); + + if(selIOS!=''){ + setState(() { + ending_dateController.text=selIOS.toString(); + }); + } + else { + AppSettings.longFailedToast('please select date'); + } + }, + ); + }, + ), + + ), + + ), + ),//address description + + const SizedBox( + height:15, + ), + Container( + width:MediaQuery.of(context).size.width * .99, + height: 55, + padding: const EdgeInsets.fromLTRB(3, 0, 3, 0), + child: ElevatedButton( + style: ElevatedButton.styleFrom( + primary: buttonColor, // background + onPrimary: Colors.white, // foreground + ), + onPressed: () async { + if (offer_nameController.text != '' && + offer_codeController.text != '' && + descriptionController.text != ''&& + discount_percentageController.text != ''&& + starting_dateController.text != '' && + ending_dateController.text != '') { + AppSettings.preLoaderDialog(context); + + var payload = new Map(); + payload["offer_name"] = offer_nameController.text.toString(); + payload["offer_code"] = offer_codeController.text.toString(); + payload["description"] = descriptionController.text.toString();; + payload["discount_percentage"] = discount_percentageController.text.toString(); + payload["starting_date"] = starting_dateController.text.toString(); + payload["ending_date"] = ending_dateController.text.toString(); + payload["offer_status"] ="active"; + bool offerStatus = await AppSettings.createOffers(payload); + try{ + if (offerStatus) { + Navigator.pop(context); + Navigator.of(context,rootNavigator: true).pop(); + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Dashboard()), + ); + AppSettings.longSuccessToast("Offer Created Succesfully!!"); + } else { + + AppSettings.longFailedToast("Fields should not be empty !!"); + } + } + catch(exception){ + print(exception); + AppSettings.longFailedToast("Please enter valid details"); + } + } else { + AppSettings.longFailedToast("Offer Not Created!!"); + + } + }, + child: Text('Create'), + )),//login button + + ], + ), + )), + ), + ])), ); + } +} diff --git a/lib/offersview.dart b/lib/offersview.dart new file mode 100644 index 0000000..f966b85 --- /dev/null +++ b/lib/offersview.dart @@ -0,0 +1,623 @@ +import 'dart:convert'; +import 'package:flutter/material.dart'; +import 'package:healthcare_pharmacy/models/offersview_model.dart'; +import 'package:healthcare_pharmacy/offers.dart'; +import 'package:healthcare_pharmacy/settings.dart'; +import 'package:intl/intl.dart'; +import 'package:flutter_cupertino_datetime_picker/flutter_cupertino_datetime_picker.dart'; + + +class OffersView extends StatefulWidget { + const OffersView({Key? key}) : super(key: key); + + @override + State createState() => _OffersViewState(); +} + +class _OffersViewState extends State with TickerProviderStateMixin { + bool isSupplierDataLoading=false; + bool isSereverIssue = false; + bool isSereverIssueConnected = false; + bool isSereverIssuePending = false; + var startdate; + var enddate; + + + List offersviewList = []; + TextEditingController offerNameController = TextEditingController(); + TextEditingController offerCodeController = TextEditingController(); + TextEditingController offerDescriptionController = TextEditingController(); + TextEditingController offerDiscountController = TextEditingController(); + TextEditingController offerStartDateController = TextEditingController(); + TextEditingController offerEndDateController = TextEditingController(); + TextEditingController updateOfferNameController = TextEditingController(); + TextEditingController updateOfferCodeController = TextEditingController(); + TextEditingController updateOfferDescriptionController = TextEditingController(); + TextEditingController updateDiscountController = TextEditingController(); + TextEditingController updateOfferStartDateController = TextEditingController(); + TextEditingController updateOfferEndDateController = TextEditingController(); + + bool isLoading=false; + + Future getOffersViewData() async { + isLoading = true; + try { + var response = await AppSettings.getOffers(); + setState(() { + offersviewList = + ((jsonDecode(response)['data']) as List).map((dynamic model) { + return GetOffersDetailsModel.fromJson(model); + }).toList(); + isLoading = false; + }); + + + } catch (e) { + setState(() { + isLoading = false; + isSereverIssueConnected = true; + }); + } + } + + + + @override + void initState() { + // TODO: implement initState + isLoading=true; + getOffersViewData(); + super.initState(); + } + + showUpdateOfferDialog(var object) async { + updateOfferNameController.text = object.offer_name; + updateOfferCodeController.text = object.offer_code; + updateOfferDescriptionController.text = object.description; + updateDiscountController.text = object.discount_percentage; + updateOfferStartDateController.text=object.starting_date; + updateOfferEndDateController.text=object.ending_date; + return showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + return AlertDialog( + title: const Text('Update Offer'), + content: SingleChildScrollView( + child: ListBody( + children: [ + Container( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: TextFormField( + cursorColor: greyColor, + controller: updateOfferNameController, + textCapitalization: TextCapitalization.characters, + decoration: const InputDecoration( + prefixIcon: Icon( + Icons.person, + color: primaryColor, + ), + border: OutlineInputBorder( + borderSide: BorderSide(color: greyColor)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + ), + labelText: 'Enter offer name', + labelStyle: TextStyle( + color: greyColor, //<-- SEE HERE + ), + ), + ), //tanker name + ), + const SizedBox( + height: 20, + ), + + Container( + //padding: const EdgeInsets.fromLTRB(10, 10, 10, 0), + child: TextFormField( + cursorColor: greyColor, + controller: updateOfferCodeController, + textCapitalization: TextCapitalization.characters, + decoration: const InputDecoration( + prefixIcon: Icon( + Icons.numbers, + color: primaryColor, + ), + border: OutlineInputBorder( + borderSide: BorderSide(color: greyColor)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + ), + labelText: 'Enter Offer Code', + labelStyle: TextStyle( + color: greyColor, //<-- SEE HERE + ), + ), + ), //tanker name + ), + const SizedBox( + height: 20, + ), + Container( + //padding: const EdgeInsets.fromLTRB(10, 10, 10, 0), + child: TextFormField( + cursorColor: greyColor, + controller: updateOfferDescriptionController, + textCapitalization: TextCapitalization.characters, + decoration: const InputDecoration( + prefixIcon: Icon( + Icons.description, + color: primaryColor, + ), + border: OutlineInputBorder( + borderSide: BorderSide(color: greyColor)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + ), + labelText: 'Enter Offer Description', + labelStyle: TextStyle( + color: greyColor, //<-- SEE HERE + ), + ), + ), //tanker name + ), + const SizedBox( + height: 20, + ), + Container( + //padding: const EdgeInsets.fromLTRB(10, 10, 10, 0), + child: TextFormField( + cursorColor: greyColor, + maxLength: 2, + controller: updateDiscountController, + textCapitalization: TextCapitalization.characters, + decoration: const InputDecoration( + prefixIcon: Icon( + Icons.percent_outlined, + color: primaryColor, + ), + border: OutlineInputBorder( + borderSide: BorderSide(color: greyColor)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + ), + labelText: 'Enter Offer Discount', + labelStyle: TextStyle( + color: greyColor, //<-- SEE HERE + ), + ), + ), //tanker name + ), + const SizedBox( + height: 20, + ), + Container( + child: TextFormField( + readOnly: true, + cursorColor: greyColor, + controller: updateOfferStartDateController, + decoration: InputDecoration( + labelText: 'Select Start Date', + prefixIcon: IconButton( + icon: Icon( + Icons.date_range, + color: primaryColor, + ), + onPressed: () async { + DatePicker.showDatePicker( + context, + dateFormat: 'dd MMMM yyyy HH:mm', + initialDateTime: DateTime.now(), + minDateTime:DateTime.now(), + maxDateTime: DateTime.now().add(Duration(days: 15)), + onMonthChangeStartWithFirstDate: true, + pickerMode: DateTimePickerMode.datetime, + pickerTheme: DateTimePickerTheme( + // backgroundColor: Colors.white, + cancelTextStyle: labelTextStyle(), + confirmTextStyle: labelTextStyle(), + // showTitle: true, + //title: Text('Pick date and time'), + itemTextStyle: valuesTextStyle(), + ), + onConfirm: (dateTime, List index)async { + DateTime selectdate = dateTime; + setState(() { + startdate = DateFormat('dd-MMM-yyyy - HH:mm').format(selectdate); + }); + + if(startdate!=''){ + setState(() { + updateOfferStartDateController.text=startdate.toString(); + }); + } + else { + AppSettings.longFailedToast('please select date'); + } + }, + ); + }, + ), + + labelStyle: const TextStyle( + color: greyColor, //<-- SEE HERE + ), + border: const OutlineInputBorder( + borderSide: BorderSide(color: primaryColor)), + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + + ), + + ), + ), + + const SizedBox( + height: 20, + ), + Container( + child: TextFormField( + readOnly: true, + cursorColor: greyColor, + controller: updateOfferEndDateController, + decoration: InputDecoration( + labelText: 'Select End Date', + prefixIcon: IconButton( + icon: Icon( + Icons.date_range, + color: primaryColor, + ), + onPressed: () async { + DatePicker.showDatePicker( + context, + dateFormat: 'dd MMMM yyyy HH:mm', + initialDateTime: DateTime.now(), + minDateTime:DateTime.now(), + maxDateTime: DateTime.now().add(Duration(days: 15)), + onMonthChangeStartWithFirstDate: true, + pickerMode: DateTimePickerMode.datetime, + pickerTheme: DateTimePickerTheme( + // backgroundColor: Colors.white, + cancelTextStyle: labelTextStyle(), + confirmTextStyle: labelTextStyle(), + // showTitle: true, + //title: Text('Pick date and time'), + itemTextStyle: valuesTextStyle(), + ), + onConfirm: (dateTime, List index)async { + DateTime selectdate = dateTime; + setState(() { + enddate = DateFormat('dd-MMM-yyyy - HH:mm').format(selectdate); + }); + + if(enddate!=''){ + setState(() { + updateOfferEndDateController.text=enddate.toString(); + }); + } + else { + AppSettings.longFailedToast('please select date'); + } + }, + ); + }, + ), + + labelStyle: const TextStyle( + color: greyColor, //<-- SEE HERE + ), + border: const OutlineInputBorder( + borderSide: BorderSide(color: primaryColor)), + focusedBorder: const OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + ), + + ), + ),//address description + + const SizedBox( + height: 30, + ), + + ], + ), + ), + actions: [ + TextButton( + child: Text('cancel', style: textButtonStyle()), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + TextButton( + child: Text('Update', style: textButtonStyle()), + onPressed: () async { + if (updateOfferNameController.text != '' ) { + AppSettings.preLoaderDialog(context); + var payload = new Map(); + + payload["offer_name"] = updateOfferNameController.text.toString(); + payload["offer_code"] = updateOfferCodeController.text.toString(); + payload["description"] = updateOfferDescriptionController.text.toString(); + payload["discount_percentage"] = updateDiscountController.text.toString(); + payload["starting_date"] = updateOfferStartDateController.text.toString(); + payload["ending_date"] = updateOfferEndDateController.text.toString(); + payload["offer_status"] ="active"; + + bool offerStatus = await AppSettings.updateOffers(object.offer_code, payload); + try { + if (offerStatus) { + Navigator.of(context, rootNavigator: true).pop(); + AppSettings.longSuccessToast( + "Offer Updated Successfully"); + updateOfferNameController.text = ''; + updateOfferCodeController.text = ''; + updateOfferDescriptionController.text = ''; + updateDiscountController.text = ''; + updateOfferStartDateController.text = ''; + updateOfferEndDateController.text = ''; + + Navigator.of(context).pop(); + await getOffersViewData(); + } else { + Navigator.of(context, rootNavigator: true).pop(); + AppSettings.longFailedStyledToast( + "Offer upadtion failed", context); + Navigator.of(context).pop(); + } + } catch (exception) { + Navigator.of(context).pop(); + print(exception); + } + } else { + AppSettings.longFailedStyledToast("enter details", context); + } + }, + ), + ], + ); + }); + }, + ); + } + + + Widget renderzUi(){ + if(offersviewList.length!=0){ + + return Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Expanded(child:ListView.builder( + padding: EdgeInsets.all(0), + itemCount: offersviewList.length, + itemBuilder: (BuildContext context, int index) { + return Card( + + color: offersviewList[index].cardColor, + child: Padding( + padding:EdgeInsets.all(8) , + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + + Container( + //width: MediaQuery.of(context).size.width * .55, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('OfferName :',style: labelTextStyle()), + Text('OfferCode :',style: labelTextStyle()), + Text('OfferDes :' ,style: labelTextStyle()), + Text('OfferDis(%) :' ,style: labelTextStyle()), + Text('StartDate :',style: labelTextStyle()), + Text('EndDate :' ,style: labelTextStyle()), + + ], + ), + SizedBox(width: 5,), + Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(offersviewList[index].offer_name,style: valuesTextStyle()), + Text(offersviewList[index].offer_code,style: valuesTextStyle()), + Text(offersviewList[index].description,style: valuesTextStyle()), + Text(offersviewList[index].discount_percentage,style: valuesTextStyle()), + Text(offersviewList[index].starting_date,style: valuesTextStyle()), + Text(offersviewList[index].ending_date,style: valuesTextStyle()) + + ], + ), + ], + ), + ], + ), + ), + + Expanded(child:IconButton( + icon: const Icon(Icons.edit,color: primaryColor,), + onPressed: () { + showUpdateOfferDialog(offersviewList[index]); + }, + ),), + Expanded(child:IconButton( + icon: const Icon(Icons.hide_source_rounded,color: primaryColor,), + + onPressed: () async{ + showDialog( + //if set to true allow to close popup by tapping out of the popup + //barrierDismissible: false, + context: context, + builder: (BuildContext context) => AlertDialog( + title: const Text('Do you want In_Active Offer??', + style: TextStyle( + color: primaryColor, + fontSize: 16, + )), + actionsAlignment: MainAxisAlignment.spaceBetween, + actions: [ + TextButton( + onPressed: ()async { + bool deleteOfferStatus = await AppSettings.deleteOffers(offersviewList[index].offer_code); + if(deleteOfferStatus){ + getOffersViewData(); + AppSettings.longSuccessToast('Offer In_Active Successfully!!'); + Navigator.of(context).pop(true); + + } + else{ + AppSettings.longFailedToast('Offer In_Active failed'); + } + }, + child: const Text('Yes', + style: TextStyle( + color: primaryColor, + fontSize: 18, + )), + ), + TextButton( + onPressed: () { + Navigator.of(context).pop(true); + }, + child: const Text('No', + style: TextStyle( + color: primaryColor, + fontSize: 18, + )), + ), + ], + ), + ); + + + + }, + ),) + + ], + + ), + ), + ); + }) ), + Padding( + padding: EdgeInsets.fromLTRB(8, 8, 8, 8), + child: CircleAvatar( + backgroundColor: primaryColor, + radius: 40, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + iconSize: 40, + icon: const Icon( + Icons.add, + color: Colors.white, + ), + onPressed: () async{ + Navigator.pop(context); + await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => offers()), + ); + //showBoreAddingDialog(); + }, + ), + /* Padding( + padding: EdgeInsets.fromLTRB(5, 0, 5, 5), + child: Text( + 'Add Tanks ', + style: TextStyle(color: Colors.white), + ), + )*/ + ], + ), + ), + ), + ]); + } + else{ + return Center( + child: Padding( + padding: EdgeInsets.fromLTRB(0, 40, 0, 0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox(height: MediaQuery.of(context).size.height * .25,), + Text('Click below icon to add new Offer'), + SizedBox( + height: 20, + ), + CircleAvatar( + backgroundColor: primaryColor, + radius: 40, + child: IconButton( + iconSize: 40, + icon: const Icon( + Icons.add, + color: Colors.white, + ), + onPressed: () async { + Navigator.pop(context); + await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => offers()), + ); + }, + ), + ) + ], + ), + ) + ); + } + } + + @override + Widget build(BuildContext context) { + return SafeArea( + child: Scaffold( + appBar: AppSettings.appBar('Active OfersView'), + body: isLoading?Center( + child: CircularProgressIndicator( + color: primaryColor, + strokeWidth: 5.0, + ), + ):renderzUi(), + )); + } +} \ No newline at end of file diff --git a/lib/settings.dart b/lib/settings.dart index ae32dbc..d0af6ef 100644 --- a/lib/settings.dart +++ b/lib/settings.dart @@ -11,8 +11,13 @@ import 'package:flutter_styled_toast/flutter_styled_toast.dart'; import 'dart:async'; import 'package:geolocator/geolocator.dart'; import 'package:dio/dio.dart'; +import 'package:fluttertoast/fluttertoast.dart'; + + +const Color primaryColor = Color(0XFFA78966); +const Color secondaryColor = Color(0XFFF0E0CC); +const Color buttonColor = Color(0XFF6A3632); -const Color primaryColor = Color(0XFF1786A3); const Color greyColor = Color(0XFF8F8E8E); const Color textFieldStartColor = Colors.grey; const Color screenBackgroundColor = Color(0XFFEAF6FF); @@ -100,10 +105,37 @@ Future preloaderWindow(BuildContext context) async { } catch (error) {} } + +InputDecoration textFormFieldDecoration(IconData icon,var text){ + return InputDecoration( + filled: true, + fillColor: Colors.white, + prefixIcon: Icon( + icon, + color: greyColor, + ), + border: OutlineInputBorder(borderSide: BorderSide(color: primaryColor)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: primaryColor), + ), + labelText: text, + labelStyle: + TextStyle(color: primaryColor, fontWeight: FontWeight.bold //<-- SEE HERE + ), + ); +} + class AppSettings { static SharedPreferences sharedPreferences = SharedPreferences.getInstance() as SharedPreferences; static String pharmacyName = ''; + static String MedecineName = ''; + static String pharmacyEmail = ''; + static String pharmacyPhone = ''; + static String pharmacyDescription= ''; static String userAddress = ''; static String email = ''; static String phoneNumber = ''; @@ -113,7 +145,7 @@ class AppSettings { static double userLongitude = 0; static String healthpharmaIdsign = ''; static String profileImage = ''; - static List storedPreferenceValidKeys = ['username', 'access_token']; + static List storedPreferenceValidKeys = ['pharmacyname', 'access_token']; static String preloadText = 'Please wait'; static String latitude = ''; static String longitude = ''; @@ -131,6 +163,7 @@ class AppSettings { static String host = 'http://35.200.129.165:4000/api/'; static String loginUrl = host + 'pharmacylogin'; static String signUpUrl = host + 'addPharmacy'; + static String updatePharmacyUrl = host + 'update/currentPharmacy'; static String verifyPhnUrl = host + 'phone'; static String profilePicUrl = host + 'users/profile-picture'; static String resetTokenUrl = host + 'reset_token'; @@ -138,6 +171,19 @@ class AppSettings { static String resetPasswordUrl = host + 'resetpassword'; static String sendSmsUrl = host + 'sendSms'; static String phoneVerificationUrl = host + 'pharmacyphone'; + static String createOffersUrl = host + 'addoffer'; + static String getOffersActiveDataUrl = host + 'getActivePharmacyOfferdata'; + static String getOffersinActiveDataUrl = host + 'getInActivePharmacyOfferdata'; + static String updateOffersDataUrl = host + 'updateOffer'; + static String deleteOffersDataUrl = host + 'deleteOffer'; + static String reactiveOffersDataUrl = host + 'reactiveOffer'; + static String medecineDataUrl = host + 'medicine'; + + + + + + @@ -210,6 +256,7 @@ class AppSettings { } } + static getData(String _key, type) async { sharedPreferences = await SharedPreferences.getInstance(); if (type == 'STRING') { @@ -299,6 +346,199 @@ class AppSettings { } } + static Future updatePharmaData(payload) async { + try { + var response = await http.put( + Uri.parse(updatePharmacyUrl + '/' + healthpharmaIdsign), + body: json.encode(payload), + headers: await buildRequestHeaders()); + + if (response.statusCode == 200) { + var _response = json.decode(response.body); + pharmacyName = _response['pharmacyname']; + phoneNumber = _response['phone']; + email = _response['emails'][0]['email']; + pharmacyDescription = _response['description']; + return true; + } else { + return false; + } + } catch (e) { + print(e); + return false; + } + } + + static Future createOffers(payload) async { + var uri = Uri.parse(createOffersUrl + '/' + healthpharmaIdsign); + var response = await http.post(uri, + body: json.encode(payload), headers: await buildRequestHeaders()); + if (response.statusCode == 200) { + try { + var _response = json.decode(response.body); + print(_response); + return true; + } catch (e) { + // display error toast + return false; + } + } else if (response.statusCode == 401) { + bool status = await AppSettings.resetToken(); + if (status) { + response = await http.post(uri, + body: json.encode(payload), headers: await buildRequestHeaders()); + if (response.statusCode == 200) { + return true; + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + } + static Future getOffers() async { + //path parameter + var uri = Uri.parse(getOffersActiveDataUrl + '/' + healthpharmaIdsign); + var response = await http.get(uri, headers: await buildRequestHeaders()); + if (response.statusCode == 200) { + return response.body; + } else if (response.statusCode == 401) { + bool status = await AppSettings.resetToken(); + if (status) { + response = await http.get(uri, headers: await buildRequestHeaders()); + if (response.statusCode == 200) { + return response.body; + } else { + return ''; + } + } else { + return ''; + } + } else { + return ''; + } + } + static Future getinactiveOffers() async { + //path parameter + var uri = Uri.parse(getOffersinActiveDataUrl + '/' + healthpharmaIdsign); + var response = await http.get(uri, headers: await buildRequestHeaders()); + if (response.statusCode == 200) { + return response.body; + } else if (response.statusCode == 401) { + bool status = await AppSettings.resetToken(); + if (status) { + response = await http.get(uri, headers: await buildRequestHeaders()); + if (response.statusCode == 200) { + return response.body; + } else { + return ''; + } + } else { + return ''; + } + } else { + return ''; + } + } + static Future updateOffers(offer_code, payload) async { + var uri = Uri.parse(updateOffersDataUrl + '/' + healthpharmaIdsign); + uri = uri.replace(query: 'offer_code=$offer_code'); + + + try { + var response = await http.put(uri, + body: json.encode(payload), headers: await buildRequestHeaders()); + + if (response.statusCode == 200) { + return true; + } else if (response.statusCode == 401) { + bool status = await AppSettings.resetToken(); + if (status) { + response = await http.put(uri, + body: json.encode(payload), headers: await buildRequestHeaders()); + if (response.statusCode == 200) { + return true; + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + } catch (e) { + print(e); + return false; + } + } + static Future deleteOffers(offer_code) async { + var uri = Uri.parse(deleteOffersDataUrl + '/' + healthpharmaIdsign); + uri = uri.replace(query: 'offer_code=$offer_code'); + + try { + var response = + await http.put(uri, headers: await buildPutRequestHeaders()); + + if (response.statusCode == 200) { + return true; + } else if (response.statusCode == 401) { + bool status = await AppSettings.resetToken(); + if (status) { + response = + await http.put(uri, headers: await buildPutRequestHeaders()); + if (response.statusCode == 200) { + return true; + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + } catch (e) { + print(e); + return false; + } + } + + static Future reactiveOffers(offer_code) async { + var uri = Uri.parse(reactiveOffersDataUrl + '/' + healthpharmaIdsign); + uri = uri.replace(query: 'offer_code=$offer_code'); + + try { + var response = + await http.put(uri, headers: await buildPutRequestHeaders()); + + if (response.statusCode == 200) { + return true; + } else if (response.statusCode == 401) { + bool status = await AppSettings.resetToken(); + if (status) { + response = + await http.put(uri, headers: await buildPutRequestHeaders()); + if (response.statusCode == 200) { + return true; + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + } catch (e) { + print(e); + return false; + } + } + static Future sendSms(payload) async{ var response=await http.post(Uri.parse(sendSmsUrl),body: json.encode(payload), headers: {'Content-type': 'application/json'}); if(response.statusCode==200){ @@ -309,6 +549,30 @@ class AppSettings { } } + static Future getAllMedecines(var medicine) async { + var uri = Uri.parse(medecineDataUrl + '/' + medicine); + //uri = uri.replace(query: 'customerId=$customerId'); + + var response = await http.get(uri, headers: await buildRequestHeaders()); + if (response.statusCode == 200) { + return response.body; + } else if (response.statusCode == 401) { + bool status = await AppSettings.resetToken(); + if (status) { + response = await http.get(uri, headers: await buildRequestHeaders()); + if (response.statusCode == 200) { + return response.body; + } else { + return ''; + } + } else { + return ''; + } + } else { + return ''; + } + } + static Future phoneVerification(payload) async{ var response=await http.post(Uri.parse(phoneVerificationUrl),body: json.encode(payload), headers: {'Content-type': 'application/json'}); @@ -320,7 +584,28 @@ class AppSettings { } } + static Future resetToken() async { + var uri = Uri.parse(resetTokenUrl + '/' + pharmacyId); + try { + // var response = await http.get(uri, headers: await buildPutRequestHeaders()); + var response = await http.get(uri, + headers: await buildPutRequestHeadersForResetToken()); + if (response.statusCode == 200) { + print(response.body); + var res = jsonDecode(response.body); + print(res); + + accessToken = res['access_token']; + return true; + } else { + return false; + } + } catch (e) { + print(e); + return false; + } + } static Future verifyPhn(payload) async { var response = await http.post(Uri.parse(verifyPhnUrl), body: json.encode(payload), @@ -344,6 +629,44 @@ class AppSettings { } } + + + static Future updateProfilePicture(payload) async { + var uri = Uri.parse(profilePicUrl + '/' + pharmacyId); + var response = await http.post(uri, + body: json.encode(payload), headers: await buildRequestHeaders()); + + if (response.statusCode == 200) { + try { + var _response = json.decode(response.body); + print(_response); + return true; + } catch (e) { + // display error toast + return false; + } + } + + else if (response.statusCode == 401) { + bool status = await AppSettings.resetToken(); + if (status) { + response = await http.post(uri, + body: json.encode(payload), headers: await buildRequestHeaders()); + if (response.statusCode == 200) { + return true; + } else { + return false; + } + } else { + return false; + } + } + + else { + return false; + } + } + /*Apis ends here*/ //save data local @@ -354,6 +677,7 @@ class AppSettings { await saveData( 'access_token', input['simplydata']['access_token'], 'STRING'); await saveData('phone', input['simplydata']['phone'], 'STRING'); + await saveData('pharmacyId', input['simplydata']['pharmacyId'], 'STRING'); await saveData('email', input['simplydata']['email'][0]['email'], 'STRING'); // await saveData('customerId', input['simplydata']['customerId'], 'STRING'); // await saveData('profile', input['simplydata']['picture'], 'STRING'); @@ -381,12 +705,70 @@ class AppSettings { email = await getData('email', 'STRING'); userAddress = await getData('user_address', 'STRING'); phoneNumber = await getData('phone', 'STRING'); - pharmacyId = await getData('pharmacyId', 'STRING'); + healthpharmaIdsign = await getData('pharmacyId', 'STRING'); userLatitude = await getData('latitude', 'DOUBLE'); userLongitude =await getData('longitude', 'DOUBLE'); fcmId =await getData('fcmId', 'STRING'); } + /*static void longFailedToast(String message) { + Fluttertoast.showToast( + msg: message, + toastLength: Toast.LENGTH_LONG, + gravity: ToastGravity.BOTTOM, + timeInSecForIosWeb: 1, + backgroundColor: Colors.red, + textColor: Colors.white, + fontSize: 16.0); + }*/ + + static void longFailedStyledToast(String message, context) { + showToast( + message, + context: context, + animation: StyledToastAnimation.scale, + reverseAnimation: StyledToastAnimation.fade, + position: StyledToastPosition.bottom, + animDuration: Duration(seconds: 1), + duration: Duration(seconds: 6), + curve: Curves.elasticOut, + reverseCurve: Curves.linear, + backgroundColor: Colors.red, + ); + } + static void longFailedToast(String message) { + Fluttertoast.showToast( + msg: message, + toastLength: Toast.LENGTH_LONG, + gravity: ToastGravity.BOTTOM, + timeInSecForIosWeb: 1, + backgroundColor: Colors.red, + textColor: Colors.white, + fontSize: 16.0); + } + static void longSuccessToast(String message) { + Fluttertoast.showToast( + msg: message, + toastLength: Toast.LENGTH_SHORT, + gravity: ToastGravity.BOTTOM, + timeInSecForIosWeb: 1, + backgroundColor: Colors.green, + textColor: Colors.white, + fontSize: 16.0); + } + + + /* static void longSuccessToast(String message) { + Fluttertoast.showToast( + msg: message, + toastLength: Toast.LENGTH_SHORT, + gravity: ToastGravity.BOTTOM, + timeInSecForIosWeb: 1, + backgroundColor: Colors.green, + textColor: Colors.white, + fontSize: 16.0); + }*/ + static Widget noDataUI(String _tabName) { _tabName = _tabName ?? ''; diff --git a/lib/signup.dart b/lib/signup.dart index c6a1efa..f283c7f 100644 --- a/lib/signup.dart +++ b/lib/signup.dart @@ -13,8 +13,6 @@ import 'dart:io' show File, Platform; import 'package:google_maps_flutter_android/google_maps_flutter_android.dart'; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; import 'package:location/location.dart' as locationmap; -import 'google_maps_place_picker_mb/src/models/pick_result.dart'; -import 'google_maps_place_picker_mb/src/place_picker.dart'; @@ -32,6 +30,9 @@ class _SignUpState extends State { TextEditingController nameController = TextEditingController(); TextEditingController healthpharmaid = TextEditingController(); TextEditingController buildingNameController = TextEditingController(); + TextEditingController pharmaRegController = TextEditingController(); + TextEditingController pharmaOpentimeController = TextEditingController(); + TextEditingController pharmaClosetimeController = TextEditingController(); TextEditingController emailController = TextEditingController(); TextEditingController mobileNumberController = TextEditingController(); TextEditingController userAddressDescriptionController = TextEditingController(); @@ -176,28 +177,23 @@ class _SignUpState extends State { child: TextFormField( cursorColor: greyColor, controller: nameController, - textCapitalization: TextCapitalization.sentences, - decoration: const InputDecoration( - prefixIcon: Icon( - Icons.person, - color: primaryColor, - ), - border: OutlineInputBorder( - borderSide: BorderSide(color: primaryColor)), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: primaryColor), - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: primaryColor), - ), - labelText: 'Name', - labelStyle: TextStyle( - color: greyColor, //<-- SEE HERE - ), - ), + textCapitalization: TextCapitalization.characters, + decoration: textFormFieldDecoration(Icons.person,'Name'), ), ), //name + SizedBox( + height: 05, + ), + Container( + padding: const EdgeInsets.all(10), + child: TextFormField( + cursorColor: greyColor, + controller: pharmaRegController, + textCapitalization: TextCapitalization.characters, + decoration: textFormFieldDecoration(Icons.numbers,'Enter REG Number'), + ), + ), const SizedBox( height: 5, ), @@ -208,24 +204,8 @@ class _SignUpState extends State { controller: mobileNumberController, keyboardType: TextInputType.phone, maxLength: 10, - decoration: const InputDecoration( - prefixIcon: Icon( - Icons.phone_android, - color: primaryColor, - ), - border: OutlineInputBorder( - borderSide: BorderSide(color: primaryColor)), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: primaryColor), - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: primaryColor), - ), - labelText: 'Enter Mobile Number', - labelStyle: TextStyle( - color: greyColor, //<-- SEE HERE - ), - ), + decoration: textFormFieldDecoration(Icons.phone_android,'Enter Mobile Number'), + ), ), //mobile @@ -238,24 +218,8 @@ class _SignUpState extends State { cursorColor: greyColor, controller: emailController, keyboardType: TextInputType.emailAddress, - decoration: const InputDecoration( - prefixIcon: Icon( - Icons.email, - color: primaryColor, - ), - border: OutlineInputBorder( - borderSide: BorderSide(color: primaryColor)), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: primaryColor), - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: primaryColor), - ), - labelText: 'Enter your email', - labelStyle: TextStyle( - color: greyColor, //<-- SEE HERE - ), - ), + decoration: textFormFieldDecoration(Icons.email,'Enter Your Mail'), + ), ), const SizedBox( @@ -371,24 +335,7 @@ class _SignUpState extends State { }, keyboardType: TextInputType.streetAddress, readOnly: true, - decoration: const InputDecoration( - prefixIcon: Icon( - Icons.location_on_rounded, - color: primaryColor, - ), - border: OutlineInputBorder( - borderSide: BorderSide(color: primaryColor)), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: primaryColor), - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: primaryColor), - ), - labelText: 'Click to select address(map)', - labelStyle: TextStyle( - color: greyColor, //<-- SEE HERE - ), - ), + decoration: textFormFieldDecoration(Icons.location_on_rounded,'select address from MAP'), ), ), @@ -404,10 +351,22 @@ class _SignUpState extends State { child: TextFormField( cursorColor: greyColor, controller: userAddressDescriptionController, - keyboardType: TextInputType.emailAddress, + textCapitalization: TextCapitalization.characters, + decoration: textFormFieldDecoration(Icons.plagiarism_outlined,'Address Description (Ex: Flat No)'), + ), + ),//address description + const SizedBox( + height: 5, + ), + /* Container( + padding: const EdgeInsets.all(10), + child: TextFormField( + cursorColor: greyColor, + controller: pharmaOpentimeController, + keyboardType: TextInputType.datetime, decoration: const InputDecoration( prefixIcon: Icon( - Icons.plagiarism_outlined, + Icons.watch_later_outlined, color: primaryColor, ), border: OutlineInputBorder( @@ -418,56 +377,55 @@ class _SignUpState extends State { enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor), ), - labelText: 'Address Description (Ex: Flat No)', + labelText: 'Pharma Open Timing', labelStyle: TextStyle( color: greyColor, //<-- SEE HERE ), ), ), - ),//address description - - - + ), const SizedBox( height: 5, ), - Container( padding: const EdgeInsets.all(10), child: TextFormField( cursorColor: greyColor, - obscureText: isPwdObscureText, - controller: passwordController, - decoration: InputDecoration( - labelText: 'Create Password', - prefixIcon: const Icon( - Icons.lock, + controller: pharmaClosetimeController, + keyboardType: TextInputType.datetime, + decoration: const InputDecoration( + prefixIcon: Icon( + Icons.watch_later_outlined, color: primaryColor, ), - labelStyle: const TextStyle( - color: greyColor, //<-- SEE HERE - ), - border: const OutlineInputBorder( + border: OutlineInputBorder( borderSide: BorderSide(color: primaryColor)), - focusedBorder: const OutlineInputBorder( + focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor), ), - enabledBorder: const OutlineInputBorder( + enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: primaryColor), ), - suffixIcon: IconButton( - icon: Icon( - Icons.visibility_off_outlined, - color: isPwdObscureText?greyColor:primaryColor, - ), - onPressed: () { - setState(() { - isPwdObscureText = !isPwdObscureText; - }); - }, + labelText: 'Pharma Close Timing', + labelStyle: TextStyle( + color: greyColor, //<-- SEE HERE ), ), ), + ), + + const SizedBox( + height: 5, + ),*/ + + Container( + padding: const EdgeInsets.all(10), + child: TextFormField( + cursorColor: greyColor, + obscureText: isPwdObscureText, + controller: passwordController, + decoration: textFormFieldDecoration(Icons.lock,'Create Password'), + ), ), //pwd const SizedBox( height: 5, @@ -478,7 +436,7 @@ class _SignUpState extends State { padding: const EdgeInsets.fromLTRB(3, 0, 3, 0), child: ElevatedButton( style: ElevatedButton.styleFrom( - primary: primaryColor, // background + primary: buttonColor, // background onPrimary: Colors.white, // foreground ), onPressed: () async { @@ -498,6 +456,7 @@ class _SignUpState extends State { {"email": emailController.text.toString()} ]; payload["pharmacy_address"] = userAddressCapturingController.text; + payload["registration_number"] = pharmaRegController.text; payload["city"] = city; payload["state"] = state; payload["zip"] = zip; @@ -552,7 +511,7 @@ class _SignUpState extends State { const Text( 'Are you a Member?', style: TextStyle( - color: primaryColor, + color: Colors.white, ), ), TextButton( @@ -560,7 +519,7 @@ class _SignUpState extends State { 'Login?', style: TextStyle( fontSize: 20, - color: greyColor, + color: Colors.white, decoration: TextDecoration.underline, ), ), diff --git a/lib/updateprofile.dart b/lib/updateprofile.dart new file mode 100644 index 0000000..0a352ae --- /dev/null +++ b/lib/updateprofile.dart @@ -0,0 +1,329 @@ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:healthcare_pharmacy/dashboard.dart'; +import 'package:healthcare_pharmacy/settings.dart'; +import 'package:image_picker/image_picker.dart'; +import 'dart:io'; + + +class UpdateProfile extends StatefulWidget { + const UpdateProfile({Key? key}) : super(key: key); + @override + State createState() => _UpdateprofileState(); +} + +class _UpdateprofileState extends State { + + bool isPwdObscureText=true; + bool isConfirmPwdObscureText=true; + TextEditingController nameController = TextEditingController(); + TextEditingController emailController = TextEditingController(); + TextEditingController mobileNumberController = TextEditingController(); + TextEditingController descriptionController = TextEditingController(); + + + @override + void initState() { + isPwdObscureText=true; + isConfirmPwdObscureText=true; + nameController.text=AppSettings.pharmacyName; + mobileNumberController.text=AppSettings.phoneNumber; + emailController.text=AppSettings.email; + descriptionController.text=AppSettings.pharmacyDescription; + + super.initState(); + } + final ImagePicker _picker = ImagePicker(); + Future pickImageFromGallery() async { + try { + final image = await _picker.pickImage(source: ImageSource.gallery); + if (image == null) return; + final imageTemp = File(image.path); + setState(() { + AppSettings.updatedImage = imageTemp; + }); + //uploadProfileApi(AppSettings.updatedImage); + AppSettings.saveProfile(image.path); + + + } on PlatformException catch (e) { + print('Failed to pick image: $e'); + } + } + + Future takeImageFromCamera() async { + try { + final image = await _picker.pickImage(source: ImageSource.camera); + if (image == null) return; + final imageTemp = File(image.path); + setState(() { + AppSettings.updatedImage = imageTemp; + }); + + // uploadProfileApi(AppSettings.updatedImage); + AppSettings.saveProfile(image.path); + + } on PlatformException catch (e) { + print('Failed to pick image: $e'); + } + } + + @override + Widget build(BuildContext context) { + + return Scaffold( + appBar:AppSettings.appBar('Edit Profile'), + body: Stack(children: [ + Container( + decoration: const BoxDecoration( + /* image: DecorationImage( + image: AssetImage("images/backgroundimage.png"), + fit: BoxFit.cover, + ),*/ + ), + ), + GestureDetector( + onTap: () { + FocusScope.of(context).requestFocus(new FocusNode()); + }, + child: SafeArea( + child: SingleChildScrollView( + child: Column( + children: [ + SizedBox( + height: 40, + ), + /*Container( + child: Image( + image: AssetImage('images/logo.png'), + height: MediaQuery.of(context).size.height * .10, + )),*/ + Container(child: GestureDetector( + child: Container( + width: MediaQuery.of(context).size.width * .60, + height: + MediaQuery.of(context).size.height * .15, + decoration: BoxDecoration( + shape: BoxShape.rectangle, + border: Border.all(width: 5, color: Colors.blueGrey), + image: DecorationImage( + image: (AppSettings.updatedImage != + null) + ? FileImage( + AppSettings.updatedImage!) + as ImageProvider + : AssetImage( + "images/mobilebg.png"), // picked file + fit: BoxFit.cover)), + ), + onTap: () { + showModalBottomSheet( + context: context, + builder: (BuildContext context) { + return SizedBox( + height: 200, + child: Center( + child: Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + GestureDetector( + child: Icon( + Icons.camera_alt_outlined, + size: 100, + color: greyColor, + ), + onTap: () async { + await takeImageFromCamera(); + Navigator.pop(context); + }, + ), + SizedBox( + width: MediaQuery.of(context) + .size + .width * + .20, + ), + GestureDetector( + child: Icon( + Icons.photo, + size: 100, + color: greyColor, + ), + onTap: () async { + await pickImageFromGallery(); + Navigator.pop(context); + }, + ), + ], + ), + ), + ); + }); + }, + ),), + SizedBox( + height: 10, + ), + Container( + padding: const EdgeInsets.all(10), + child: TextFormField( + cursorColor: greyColor, + controller: nameController, + decoration: const InputDecoration( + prefixIcon: Icon( + Icons.person, + color: greyColor, + ), + border: OutlineInputBorder( + borderSide: BorderSide(color: greyColor)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + ), + labelText: 'Username', + labelStyle: TextStyle( + color: greyColor, //<-- SEE HERE + ), + ), + ), + ),//name + const SizedBox( + height: 15, + ), + Container( + padding: const EdgeInsets.all(10), + child: TextFormField( + cursorColor: greyColor, + controller: emailController, + decoration: const InputDecoration( + prefixIcon: Icon( + Icons.email, + color: greyColor, + ), + border: OutlineInputBorder( + borderSide: BorderSide(color: greyColor)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + ), + labelText: 'Enter email ID', + labelStyle: TextStyle( + color: greyColor, //<-- SEE HERE + ), + ), + ), + ), //email + SizedBox( + height: 10, + ), + Container( + padding: const EdgeInsets.all(10), + child: TextFormField( + cursorColor: greyColor, + readOnly: true, + controller: mobileNumberController, + decoration: const InputDecoration( + prefixIcon: Icon( + Icons.phone_android, + color: greyColor, + ), + border: OutlineInputBorder( + borderSide: BorderSide(color: greyColor)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + ), + labelText: 'Enter Mobile Number', + labelStyle: TextStyle( + color: greyColor, //<-- SEE HERE + ), + ), + ), + ), //mobile + SizedBox( + height: 10, + ), + Container( + padding: const EdgeInsets.all(10), + child: TextFormField( + cursorColor: greyColor, + controller: descriptionController, + keyboardType: TextInputType.multiline, + maxLines: null, + decoration: const InputDecoration( + prefixIcon: Icon( + Icons.description, + color:greyColor, + ), + contentPadding: const EdgeInsets.symmetric(vertical: 60.0, horizontal: 30.0), + border: OutlineInputBorder( + borderSide: BorderSide(color: greyColor)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: greyColor), + ), + labelText: 'Enter Description', + labelStyle: TextStyle( + color: greyColor, //<-- SEE HERE + ), + ), + ), + ), + SizedBox( + height: 10, + ), + + Container( + width: 400, + height: 55, + padding: const EdgeInsets.fromLTRB(10, 0, 10, 0), + child: ElevatedButton( + style: ElevatedButton.styleFrom( + primary: buttonColor,// background + onPrimary: Colors.white,// foreground + ), + onPressed: () async{ + var payload = new Map(); + payload["pharmacyname"] = nameController.text.toString(); + payload["phone"] = mobileNumberController.text.toString(); + payload["emails"] = [{"email":emailController.text.toString()}]; + payload["description"] = descriptionController.text.toString(); + bool signUpStatus = await AppSettings.updatePharmaData(payload); + try{ + if (signUpStatus) { + Navigator.pop(context); + Navigator.push( + context, + MaterialPageRoute(builder: (context) => Dashboard()), + ); + AppSettings.longSuccessToast("Pharmacy Profile Updated !!"); + } else { + AppSettings.longFailedToast("Pharmacy Profile Not Updated !!"); + } + } + catch(exception){ + print(exception); + AppSettings.longFailedToast("Please enter valid details"); + } + }, + child: Text('Update'), + ) + ), + ], + ), + )), + ), + ])); + } +} diff --git a/pubspec.lock b/pubspec.lock index cf67ec6..7dea8d6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -392,6 +392,13 @@ packages: description: flutter source: sdk version: "0.0.0" + fluttertoast: + dependency: "direct dev" + description: + name: fluttertoast + url: "https://pub.dartlang.org" + source: hosted + version: "8.2.2" geocoding: dependency: "direct dev" description: @@ -819,6 +826,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.1.0" + photo_view: + dependency: "direct dev" + description: + name: photo_view + url: "https://pub.dartlang.org" + source: hosted + version: "0.14.0" platform: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 8828bdf..dc640df 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -53,6 +53,7 @@ dev_dependencies: device_info_plus: ^3.2.4 overlay_support: ^2.1.0 dio: ^5.1.1 + fluttertoast: ^8.2.2 google_maps_flutter: ^2.2.5 flutter_polyline_points: ^1.0.0 get: ^4.6.5 @@ -60,6 +61,8 @@ dev_dependencies: permission_handler: ^10.2.0 cloudinary_public: ^0.21.0 carousel_slider: ^4.2.1 + photo_view: ^0.14.0 + flutter_icons: