diff --git a/Frontend/lib/mih_apis/mih_mzansi_wallet_apis.dart b/Frontend/lib/mih_apis/mih_mzansi_wallet_apis.dart index 6f70dddd..9bf002bb 100644 --- a/Frontend/lib/mih_apis/mih_mzansi_wallet_apis.dart +++ b/Frontend/lib/mih_apis/mih_mzansi_wallet_apis.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; import 'package:mzansi_innovation_hub/mih_objects/app_user.dart'; +import 'package:mzansi_innovation_hub/mih_objects/arguments.dart'; import 'package:mzansi_innovation_hub/mih_objects/loyalty_card.dart'; import 'package:flutter/material.dart'; // import '../mih_components/mih_pop_up_messages/mih_error_message.dart'; @@ -40,7 +41,6 @@ class MIHMzansiWalletApis { // print("Code: ${response.statusCode}"); // errorCode = response.statusCode.toString(); // errorBody = response.body; - if (response.statusCode == 200) { //print("Here1"); Iterable l = jsonDecode(response.body); @@ -55,6 +55,36 @@ class MIHMzansiWalletApis { } } + /// This function is used to fetch a list of loyalty cards for a user. + /// + /// Patameters: app_id . + /// + /// Returns List. + static Future> getFavouriteLoyaltyCards( + String app_id, + ) async { + //print("Patien manager page: $endpoint"); + final response = await http.get(Uri.parse( + "${AppEnviroment.baseApiUrl}/mzasni-wallet/loyalty-cards/favourites/$app_id")); + // print("Here"); + // print("Body: ${response.body}"); + // print("Code: ${response.statusCode}"); + // errorCode = response.statusCode.toString(); + // errorBody = response.body; + if (response.statusCode == 200) { + // print("Here1"); + Iterable l = jsonDecode(response.body); + //print("Here2"); + List patientQueue = List.from( + l.map((model) => MIHLoyaltyCard.fromJson(model))); + //print("Here3"); + //print(patientQueue); + return patientQueue; + } else { + throw Exception('failed to fatch loyalty cards'); + } + } + /// This function is used to Delete loyalty card from users mzansi wallet. /// /// Patameters:- @@ -66,6 +96,7 @@ class MIHMzansiWalletApis { static Future deleteLoyaltyCardAPICall( AppUser signedInUser, int idloyalty_cards, + int navIndex, BuildContext context, ) async { loadingPopUp(context); @@ -83,14 +114,16 @@ class MIHMzansiWalletApis { Navigator.of(context).pop(); Navigator.of(context).pop(); Navigator.of(context).pop(); + Navigator.of(context).pop(); Navigator.of(context).pushNamed( '/mzansi-wallet', - arguments: signedInUser, + arguments: WalletArguments(signedInUser, navIndex), ); String message = "The loyalty card has been deleted successfully. This means it will no longer be visible in your Mzansi Wallet."; successPopUp(message, context); } else { + Navigator.pop(context); internetConnectionPopUp(context); } } @@ -110,6 +143,9 @@ class MIHMzansiWalletApis { String app_id, String shop_name, String card_number, + String favourite, + int priority_index, + int navIndex, BuildContext context, ) async { loadingPopUp(context); @@ -123,6 +159,8 @@ class MIHMzansiWalletApis { "app_id": app_id, "shop_name": shop_name, "card_number": card_number, + "favourite": favourite, + "priority_index": priority_index, }), ); if (response.statusCode == 201) { @@ -133,7 +171,7 @@ class MIHMzansiWalletApis { Navigator.pop(context); Navigator.of(context).pushNamed( '/mzansi-wallet', - arguments: signedInUser, + arguments: WalletArguments(signedInUser, navIndex), ); successPopUp(message, context); } else { @@ -142,6 +180,54 @@ class MIHMzansiWalletApis { } } + /// This function is used to Update loyalty card from users mzansi wallet. + /// + /// Patameters:- + /// AppUser signedInUser, + /// int idloyalty_cards, + /// BuildContext context, + /// + /// Returns VOID (TRIGGERS NOTIGICATIOPN ON SUCCESS) + static Future updateLoyaltyCardAPICall( + AppUser signedInUser, + int idloyalty_cards, + String favourite, + int priority_index, + int navIndex, + BuildContext context, + ) async { + loadingPopUp(context); + var response = await http.put( + Uri.parse( + "${AppEnviroment.baseApiUrl}/mzasni-wallet/loyalty-cards/update/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "idloyalty_cards": idloyalty_cards, + "favourite": favourite, + "priority_index": priority_index, + }), + ); + //print("Here4"); + //print(response.statusCode); + if (response.statusCode == 200) { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pushNamed( + '/mzansi-wallet', + arguments: WalletArguments(signedInUser, navIndex), + ); + String message = "The loyalty card has been added to your favourites."; + successPopUp(message, context); + } else { + Navigator.pop(context); + internetConnectionPopUp(context); + } + } + //================== POP UPS ========================================================================== static void internetConnectionPopUp(BuildContext context) { diff --git a/Frontend/lib/mih_objects/loyalty_card.dart b/Frontend/lib/mih_objects/loyalty_card.dart index a5a137df..daa368e7 100644 --- a/Frontend/lib/mih_objects/loyalty_card.dart +++ b/Frontend/lib/mih_objects/loyalty_card.dart @@ -3,12 +3,16 @@ class MIHLoyaltyCard { final String app_id; final String shop_name; final String card_number; + final String favourite; + final int priority_index; const MIHLoyaltyCard({ required this.idloyalty_cards, required this.app_id, required this.shop_name, required this.card_number, + required this.favourite, + required this.priority_index, }); factory MIHLoyaltyCard.fromJson(Map json) { @@ -18,12 +22,16 @@ class MIHLoyaltyCard { "app_id": String app_id, "shop_name": String shop_name, "card_number": String card_number, + "favourite": String favourite, + "priority_index": int priority_index, } => MIHLoyaltyCard( idloyalty_cards: idloyalty_cards, app_id: app_id, shop_name: shop_name, card_number: card_number, + favourite: favourite, + priority_index: priority_index, ), _ => throw const FormatException('Failed to load loyalty card objects'), }; diff --git a/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart b/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart index 294ba169..6640524a 100644 --- a/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart +++ b/Frontend/lib/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart @@ -1,6 +1,8 @@ import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_wallet_apis.dart'; -import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_window.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_button.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_app_alert.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_app_window.dart'; import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_delete_message.dart'; import 'package:mzansi_innovation_hub/mih_objects/app_user.dart'; import 'package:mzansi_innovation_hub/mih_objects/loyalty_card.dart'; @@ -13,10 +15,13 @@ import 'package:barcode_widget/barcode_widget.dart'; class BuildLoyaltyCardList extends StatefulWidget { final AppUser signedInUser; final List cardList; + final int navIndex; + const BuildLoyaltyCardList({ super.key, required this.signedInUser, required this.cardList, + required this.navIndex, }); @override @@ -24,6 +29,8 @@ class BuildLoyaltyCardList extends StatefulWidget { } class _BuildLoyaltyCardListState extends State { + late int _noFavourites; + void deleteCardWindow(BuildContext ctxt, int index) { showDialog( context: context, @@ -35,6 +42,7 @@ class _BuildLoyaltyCardListState extends State { MIHMzansiWalletApis.deleteLoyaltyCardAPICall( widget.signedInUser, widget.cardList[index].idloyalty_cards, + widget.navIndex, context, ); }); @@ -42,6 +50,114 @@ class _BuildLoyaltyCardListState extends State { ); } + void addToFavCardWindow(BuildContext ctxt, int index) { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) { + return MihAppAlert( + alertIcon: Icon( + Icons.favorite, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + size: 100, + ), + alertTitle: "Add to Favourites", + alertBody: Column( + children: [ + Text( + "Are you sure you want to add this card to your favourites?", + style: TextStyle( + fontSize: 20, + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + const SizedBox( + height: 15, + ), + SizedBox( + width: 300, + height: 50, + child: MIHButton( + onTap: () { + MIHMzansiWalletApis.updateLoyaltyCardAPICall( + widget.signedInUser, + widget.cardList[index].idloyalty_cards, + "Yes", + _noFavourites, + 0, + ctxt, + ); + }, + buttonText: "Add", + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + textColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ), + ], + ), + alertColour: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ); + }, + ); + } + + void removeFromFavCardWindow(BuildContext ctxt, int index) { + showDialog( + context: context, + barrierDismissible: false, + builder: (context) { + return MihAppAlert( + alertIcon: Icon( + Icons.favorite_border, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + size: 100, + ), + alertTitle: "Remove From Favourites", + alertBody: Column( + children: [ + Text( + "Are you sure you want to remove this card from your favourites?", + style: TextStyle( + fontSize: 20, + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + const SizedBox( + height: 15, + ), + SizedBox( + width: 300, + height: 50, + child: MIHButton( + onTap: () { + MIHMzansiWalletApis.updateLoyaltyCardAPICall( + widget.signedInUser, + widget.cardList[index].idloyalty_cards, + "", + 0, + 0, + ctxt, + ); + }, + buttonText: "Remove", + buttonColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + textColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + ), + ), + ], + ), + alertColour: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ); + }, + ); + } + void viewCardWindow(int index) { //print(widget.cardList[index].card_number); String formattedCardNumber = ""; @@ -54,74 +170,104 @@ class _BuildLoyaltyCardListState extends State { showDialog( context: context, barrierDismissible: false, - builder: (context) => MIHWindow( + builder: (context) => MihAppWindow( fullscreen: false, windowTitle: widget.cardList[index].shop_name.toUpperCase(), - windowTools: [ - IconButton( - onPressed: () { - deleteCardWindow(context, index); - }, - icon: Icon( - Icons.delete, - color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + windowTools: Row( + children: [ + IconButton( + onPressed: () { + deleteCardWindow(context, index); + }, + icon: Icon( + Icons.delete, + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), ), - ), - ], + Visibility( + visible: widget.cardList[index].favourite == "", + child: IconButton( + onPressed: () { + addToFavCardWindow(context, index); + }, + icon: Icon( + Icons.favorite, + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + ), + Visibility( + visible: widget.cardList[index].favourite != "", + child: IconButton( + onPressed: () { + removeFromFavCardWindow(context, index); + }, + icon: Icon( + Icons.favorite_border, + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + ), + ], + ), onWindowTapClose: () { Navigator.pop(context); }, - windowBody: [ - Container( - child: MihCardDisplay( - shopName: widget.cardList[index].shop_name, height: 250), - ), - const SizedBox(height: 20), - Container( - width: 500, - //color: Colors.white, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white, + windowBody: Column( + children: [ + Container( + child: MihCardDisplay( + shopName: widget.cardList[index].shop_name, height: 250), ), - child: Column( - children: [ - // const SizedBox(height: 10), - Padding( - padding: const EdgeInsets.all(10.0), - child: SizedBox( - height: 75, - width: 300, - child: BarcodeWidget( - //color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - barcode: Barcode.code128(), - backgroundColor: Colors.white, - data: widget.cardList[index].card_number, - drawText: false, - ), - // SfBarcodeGenerator( - // backgroundColor: Colors.white, - // barColor: Colors.black, - // value: widget.cardList[index].card_number, - // symbology: Code128(), - // //showValue: true, - // ), - ), - ), - // const SizedBox(height: 10), - Text( - formattedCardNumber, - style: const TextStyle( - color: Colors.black, - fontSize: 25, - fontWeight: FontWeight.bold - //MzanziInnovationHub.of(context)!.theme.secondaryColor(), + const SizedBox(height: 20), + Container( + width: 500, + //color: Colors.white, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white, + ), + child: Column( + children: [ + // const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.all(10.0), + child: SizedBox( + height: 75, + width: 300, + child: BarcodeWidget( + //color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + barcode: Barcode.code128(), + backgroundColor: Colors.white, + data: widget.cardList[index].card_number, + drawText: false, ), - ), - ], - ), - ) - ], + // SfBarcodeGenerator( + // backgroundColor: Colors.white, + // barColor: Colors.black, + // value: widget.cardList[index].card_number, + // symbology: Code128(), + // //showValue: true, + // ), + ), + ), + // const SizedBox(height: 10), + Text( + formattedCardNumber, + style: const TextStyle( + color: Colors.black, + fontSize: 25, + fontWeight: FontWeight.bold + //MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + ], + ), + ) + ], + ), ), ); } @@ -134,6 +280,24 @@ class _BuildLoyaltyCardListState extends State { } } + int countFavourites() { + int count = 0; + for (var card in widget.cardList) { + if (card.favourite != "") { + count++; + } + } + return count; + } + + @override + void initState() { + super.initState(); + setState(() { + _noFavourites = countFavourites(); + }); + } + @override Widget build(BuildContext context) { final Size size = MediaQuery.sizeOf(context); diff --git a/Frontend/lib/mih_packages/mzansi_wallet/package_tiles/mih_wallet_tile.dart b/Frontend/lib/mih_packages/mzansi_wallet/package_tiles/mih_wallet_tile.dart index 3d34bf0b..2f764676 100644 --- a/Frontend/lib/mih_packages/mzansi_wallet/package_tiles/mih_wallet_tile.dart +++ b/Frontend/lib/mih_packages/mzansi_wallet/package_tiles/mih_wallet_tile.dart @@ -3,6 +3,7 @@ import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_ import 'package:mzansi_innovation_hub/mih_objects/app_user.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:mzansi_innovation_hub/mih_objects/arguments.dart'; class MihWalletTile extends StatefulWidget { final AppUser signedInUser; @@ -25,7 +26,7 @@ class _MihWalletTileState extends State { onTap: () { Navigator.of(context).pushNamed( '/mzansi-wallet', - arguments: widget.signedInUser, + arguments: WalletArguments(widget.signedInUser, 0), ); }, appName: "Mzansi Wallet", diff --git a/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_card_favourites.dart b/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_card_favourites.dart new file mode 100644 index 00000000..483ae255 --- /dev/null +++ b/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_card_favourites.dart @@ -0,0 +1,124 @@ +import 'package:flutter/material.dart'; +import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_mzansi_wallet_apis.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_single_child_scroll.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih-app_tool_body.dart'; +import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; +import 'package:mzansi_innovation_hub/mih_objects/app_user.dart'; +import 'package:mzansi_innovation_hub/mih_objects/loyalty_card.dart'; +import 'package:mzansi_innovation_hub/mih_packages/mzansi_wallet/builder/build_loyalty_card_list.dart'; + +class MihCardFavourites extends StatefulWidget { + final AppUser signedInUser; + const MihCardFavourites({ + super.key, + required this.signedInUser, + }); + + @override + State createState() => _MihCardFavouritesState(); +} + +class _MihCardFavouritesState extends State { + late Future> cardList; + List listOfCards = []; + + @override + void initState() { + super.initState(); + cardList = MIHMzansiWalletApis.getFavouriteLoyaltyCards( + widget.signedInUser.app_id, + ); + } + + @override + Widget build(BuildContext context) { + return MihAppToolBody( + borderOn: true, + bodyItem: getBody(), + ); + } + + Widget getBody() { + return Stack( + children: [ + MihSingleChildScroll( + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Favourites", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: MzanziInnovationHub.of(context)! + .theme + .secondaryColor(), + ), + ), + ], + ), + Divider( + color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + FutureBuilder( + future: cardList, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center( + child: Mihloadingcircle(), + ); + } else if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + listOfCards = snapshot.data!; + // searchShop(); + return BuildLoyaltyCardList( + cardList: listOfCards, + signedInUser: widget.signedInUser, + navIndex: 0, + ); + } else { + return const Center( + child: Text("Error Loading Loyalty Cards"), + ); + } + }, + ), + ], + ), + ), + // Positioned( + // right: 0, + // bottom: 0, + // child: MihFloatingMenu( + // animatedIcon: AnimatedIcons.menu_close, + // children: [ + // SpeedDialChild( + // child: Icon( + // Icons.add, + // color: + // MzanziInnovationHub.of(context)!.theme.primaryColor(), + // ), + // label: "Add Loyalty Card", + // labelBackgroundColor: + // MzanziInnovationHub.of(context)!.theme.successColor(), + // labelStyle: TextStyle( + // color: + // MzanziInnovationHub.of(context)!.theme.primaryColor(), + // fontWeight: FontWeight.bold, + // ), + // backgroundColor: + // MzanziInnovationHub.of(context)!.theme.successColor(), + // onTap: () { + // // addCardWindow(context); + // }, + // ) + // ]), + // ) + ], + ); + } +} diff --git a/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart b/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart index 5e0a7c1b..fe9de9ea 100644 --- a/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart +++ b/Frontend/lib/mih_packages/mzansi_wallet/package_tools/mih_cards.dart @@ -201,6 +201,9 @@ class _MihCardsState extends State { widget.signedInUser.app_id, shopController.text, cardNumberController.text, + "", + 0, + 1, context, ); } @@ -314,6 +317,7 @@ class _MihCardsState extends State { return BuildLoyaltyCardList( cardList: searchShopName.value, signedInUser: widget.signedInUser, + navIndex: 1, ); }, ); diff --git a/Frontend/lib/mih_router/routeGenerator.dart b/Frontend/lib/mih_router/routeGenerator.dart index 95fb7df6..5a687d3e 100644 --- a/Frontend/lib/mih_router/routeGenerator.dart +++ b/Frontend/lib/mih_router/routeGenerator.dart @@ -188,12 +188,12 @@ class RouteGenerator { // /mzansi wallet case '/mzansi-wallet': - if (args is AppUser) { + if (args is WalletArguments) { //print("route generator: $args"); return MaterialPageRoute( settings: settings, builder: (_) => MihWallet( - signedInUser: args, + arguments: args, ), // MzansiWallet( // signedInUser: args,