Merge pull request #7 from yaso-meth/New-Tile-Mzansi-Wallet
New-Tile-Mzansi-Wallet
BIN
Frontend/images/loyalty_cards/Clicks_Club.png
Normal file
|
After Width: | Height: | Size: 108 KiB |
BIN
Frontend/images/loyalty_cards/bb_club.png
Normal file
|
After Width: | Height: | Size: 134 KiB |
BIN
Frontend/images/loyalty_cards/dischem_benefit.png
Normal file
|
After Width: | Height: | Size: 121 KiB |
BIN
Frontend/images/loyalty_cards/pnp_smart.png
Normal file
|
After Width: | Height: | Size: 206 KiB |
BIN
Frontend/images/loyalty_cards/spar_rewards.png
Normal file
|
After Width: | Height: | Size: 129 KiB |
BIN
Frontend/images/loyalty_cards/wrewards.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
Frontend/images/loyalty_cards/xtraSavings.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
178
Frontend/lib/mih_apis/mih_mzansi_wallet_apis.dart
Normal file
@@ -0,0 +1,178 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:Mzansi_Innovation_Hub/mih_objects/app_user.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';
|
||||
// import '../mih_components/mih_pop_up_messages/mih_success_message.dart';
|
||||
// import '../mih_env/env.dart';
|
||||
// import '../mih_objects/app_user.dart';
|
||||
// import '../mih_objects/arguments.dart';
|
||||
// import '../mih_objects/business.dart';
|
||||
// import '../mih_objects/business_user.dart';
|
||||
// import '../mih_objects/notification.dart';
|
||||
// import '../mih_objects/patient_access.dart';
|
||||
// import '../mih_objects/patient_queue.dart';
|
||||
// import '../mih_objects/patients.dart';
|
||||
import 'package:supertokens_flutter/http.dart' as http;
|
||||
|
||||
import '../mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||
import '../mih_components/mih_pop_up_messages/mih_success_message.dart';
|
||||
import '../mih_env/env.dart';
|
||||
|
||||
class MIHMzansiWalletApis {
|
||||
final baseAPI = AppEnviroment.baseApiUrl;
|
||||
|
||||
/// This function is used to fetch a list of loyalty cards for a user.
|
||||
///
|
||||
/// Patameters: app_id .
|
||||
///
|
||||
/// Returns List<PatientQueue>.
|
||||
static Future<List<MIHLoyaltyCard>> getLoyaltyCards(
|
||||
String app_id,
|
||||
) async {
|
||||
//print("Patien manager page: $endpoint");
|
||||
final response = await http.get(Uri.parse(
|
||||
"${AppEnviroment.baseApiUrl}/mzasni-wallet/loyalty-cards/$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<MIHLoyaltyCard> patientQueue = List<MIHLoyaltyCard>.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:-
|
||||
/// AppUser signedInUser,
|
||||
/// int idloyalty_cards,
|
||||
/// BuildContext context,
|
||||
///
|
||||
/// Returns VOID (TRIGGERS NOTIGICATIOPN ON SUCCESS)
|
||||
static Future<void> deleteLoyaltyCardAPICall(
|
||||
AppUser signedInUser,
|
||||
int idloyalty_cards,
|
||||
BuildContext context,
|
||||
) async {
|
||||
var response = await http.delete(
|
||||
Uri.parse(
|
||||
"${AppEnviroment.baseApiUrl}/mzasni-wallet/loyalty-cards/delete/"),
|
||||
headers: <String, String>{
|
||||
"Content-Type": "application/json; charset=UTF-8"
|
||||
},
|
||||
body: jsonEncode(<String, dynamic>{"idloyalty_cards": idloyalty_cards}),
|
||||
);
|
||||
//print("Here4");
|
||||
//print(response.statusCode);
|
||||
if (response.statusCode == 200) {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed(
|
||||
'/mzansi-wallet',
|
||||
arguments: signedInUser,
|
||||
);
|
||||
String message =
|
||||
"The note has been deleted successfully. This means it will no longer be visible on your and cannot be used for future appointments.";
|
||||
successPopUp(message, context);
|
||||
} else {
|
||||
internetConnectionPopUp(context);
|
||||
}
|
||||
}
|
||||
|
||||
/// This function is used to add a lopyalty card to users mzansi wallet.
|
||||
///
|
||||
/// Patameters:-
|
||||
/// AppUser signedInUser,
|
||||
/// String app_id,
|
||||
/// String shop_name,
|
||||
/// String card_number,
|
||||
/// BuildContext context,
|
||||
///
|
||||
/// Returns VOID (TRIGGERS SUCCESS pop up)
|
||||
static Future<void> addLoyaltyCardAPICall(
|
||||
AppUser signedInUser,
|
||||
String app_id,
|
||||
String shop_name,
|
||||
String card_number,
|
||||
BuildContext context,
|
||||
) async {
|
||||
var response = await http.post(
|
||||
Uri.parse(
|
||||
"${AppEnviroment.baseApiUrl}/mzasni-wallet/loyalty-cards/insert/"),
|
||||
headers: <String, String>{
|
||||
"Content-Type": "application/json; charset=UTF-8"
|
||||
},
|
||||
body: jsonEncode(<String, dynamic>{
|
||||
"app_id": app_id,
|
||||
"shop_name": shop_name,
|
||||
"card_number": card_number,
|
||||
}),
|
||||
);
|
||||
if (response.statusCode == 201) {
|
||||
// Navigator.pushNamed(context, '/patient-manager/patient',
|
||||
// arguments: widget.signedInUser);
|
||||
String message =
|
||||
"Your $shop_name Loyalty Card was successfully added to you Mzansi Wallet.";
|
||||
Navigator.pop(context);
|
||||
Navigator.pop(context);
|
||||
Navigator.of(context).pushNamed(
|
||||
'/mzansi-wallet',
|
||||
arguments: signedInUser,
|
||||
);
|
||||
// Navigator.pop(context);
|
||||
// setState(() {
|
||||
// dateController.text = "";
|
||||
// timeController.text = "";
|
||||
// });
|
||||
// Navigator.of(context).pushNamed(
|
||||
// '/patient-manager',
|
||||
// arguments: BusinessArguments(
|
||||
// widget.arguments.signedInUser,
|
||||
// widget.arguments.businessUser,
|
||||
// widget.arguments.business,
|
||||
// ),
|
||||
// );
|
||||
successPopUp(message, context);
|
||||
} else {
|
||||
internetConnectionPopUp(context);
|
||||
}
|
||||
}
|
||||
|
||||
//================== POP UPS ==========================================================================
|
||||
|
||||
static void internetConnectionPopUp(BuildContext context) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return const MIHErrorMessage(
|
||||
errorType: "Internet Connection",
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static void successPopUp(String message, BuildContext context) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return MIHSuccessMessage(
|
||||
successType: "Success",
|
||||
successMessage: message,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ class MIHDropdownField extends StatefulWidget {
|
||||
final String hintText;
|
||||
final bool required;
|
||||
final List<String> dropdownOptions;
|
||||
final void Function(String?)? onSelect;
|
||||
// final void Function(String?)? onSelect;
|
||||
final bool editable;
|
||||
|
||||
const MIHDropdownField({
|
||||
@@ -16,7 +16,7 @@ class MIHDropdownField extends StatefulWidget {
|
||||
required this.dropdownOptions,
|
||||
required this.required,
|
||||
required this.editable,
|
||||
this.onSelect,
|
||||
// this.onSelect,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -59,6 +59,7 @@ class _MIHDropdownFieldState extends State<MIHDropdownField> {
|
||||
setState(() {
|
||||
startup = false;
|
||||
});
|
||||
// widget.onSelect;
|
||||
}
|
||||
|
||||
String? get _errorText {
|
||||
@@ -124,10 +125,8 @@ class _MIHDropdownFieldState extends State<MIHDropdownField> {
|
||||
errorText: _errorText,
|
||||
|
||||
focusNode: _focus,
|
||||
onSelected: (_) {
|
||||
setState(() {
|
||||
startup = false;
|
||||
});
|
||||
onSelected: (selected) {
|
||||
_onFocusChange();
|
||||
// if (widget.editable == false) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
31
Frontend/lib/mih_objects/loyalty_card.dart
Normal file
@@ -0,0 +1,31 @@
|
||||
class MIHLoyaltyCard {
|
||||
final int idloyalty_cards;
|
||||
final String app_id;
|
||||
final String shop_name;
|
||||
final String card_number;
|
||||
|
||||
const MIHLoyaltyCard({
|
||||
required this.idloyalty_cards,
|
||||
required this.app_id,
|
||||
required this.shop_name,
|
||||
required this.card_number,
|
||||
});
|
||||
|
||||
factory MIHLoyaltyCard.fromJson(Map<String, dynamic> json) {
|
||||
return switch (json) {
|
||||
{
|
||||
"idloyalty_cards": int idloyalty_cards,
|
||||
"app_id": String app_id,
|
||||
"shop_name": String shop_name,
|
||||
"card_number": String card_number,
|
||||
} =>
|
||||
MIHLoyaltyCard(
|
||||
idloyalty_cards: idloyalty_cards,
|
||||
app_id: app_id,
|
||||
shop_name: shop_name,
|
||||
card_number: card_number,
|
||||
),
|
||||
_ => throw const FormatException('Failed to load loyalty card objects'),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -137,6 +137,29 @@ class _MIHHomeState extends State<MIHHome> {
|
||||
p: getPrim(),
|
||||
s: getSec(),
|
||||
));
|
||||
tileList.add(MIHTile(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(
|
||||
'/mzansi-wallet',
|
||||
arguments: widget.signedInUser,
|
||||
);
|
||||
},
|
||||
tileName: "Mzansi Wallet",
|
||||
tileIcon: Center(
|
||||
child: FaIcon(
|
||||
FontAwesomeIcons.wallet,
|
||||
color: getSec(),
|
||||
size: 200,
|
||||
),
|
||||
),
|
||||
// Icon(
|
||||
// Icons.info_outline,
|
||||
// color: getSec(),
|
||||
// size: 230,
|
||||
// ),
|
||||
p: getPrim(),
|
||||
s: getSec(),
|
||||
));
|
||||
tileList.add(MIHTile(
|
||||
videoID: "NUDdoWrbXNc",
|
||||
onTap: () {
|
||||
@@ -206,6 +229,7 @@ class _MIHHomeState extends State<MIHHome> {
|
||||
p: getPrim(),
|
||||
s: getSec(),
|
||||
));
|
||||
|
||||
tileList.add(MIHTile(
|
||||
videoID: "hbKhlmY_56U",
|
||||
onTap: () {
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
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_objects/app_user.dart';
|
||||
import 'package:Mzansi_Innovation_Hub/mih_objects/loyalty_card.dart';
|
||||
import 'package:Mzansi_Innovation_Hub/mih_packages/mzansi_wallet/components/mih_card_display.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:syncfusion_flutter_barcodes/barcodes.dart';
|
||||
|
||||
class BuildLoyaltyCardList extends StatefulWidget {
|
||||
final AppUser signedInUser;
|
||||
final List<MIHLoyaltyCard> cardList;
|
||||
const BuildLoyaltyCardList({
|
||||
super.key,
|
||||
required this.signedInUser,
|
||||
required this.cardList,
|
||||
});
|
||||
|
||||
@override
|
||||
State<BuildLoyaltyCardList> createState() => _BuildLoyaltyCardListState();
|
||||
}
|
||||
|
||||
class _BuildLoyaltyCardListState extends State<BuildLoyaltyCardList> {
|
||||
void viewCardWindow(int index) {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (context) => MIHWindow(
|
||||
fullscreen: false,
|
||||
windowTitle: widget.cardList[index].shop_name.toUpperCase(),
|
||||
windowTools: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
MIHMzansiWalletApis.deleteLoyaltyCardAPICall(
|
||||
widget.signedInUser,
|
||||
widget.cardList[index].idloyalty_cards,
|
||||
context,
|
||||
);
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.delete,
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
),
|
||||
],
|
||||
onWindowTapClose: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
windowBody: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
MihCardDisplay(
|
||||
shopName: widget.cardList[index].shop_name, height: 250),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
SizedBox(
|
||||
height: 150,
|
||||
child:
|
||||
SfBarcodeGenerator(value: widget.cardList[index].card_number),
|
||||
),
|
||||
Text(
|
||||
"Card Number: ${widget.cardList[index].card_number}",
|
||||
style: TextStyle(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (widget.cardList.isNotEmpty) {
|
||||
return ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return Divider(
|
||||
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
);
|
||||
},
|
||||
itemCount: widget.cardList.length,
|
||||
itemBuilder: (context, index) {
|
||||
return ListTile(
|
||||
title: MihCardDisplay(
|
||||
shopName: widget.cardList[index].shop_name, height: 200),
|
||||
// subtitle: Text(
|
||||
// "Card Number: ${widget.cardList[index].card_number}",
|
||||
// style: TextStyle(
|
||||
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
// ),
|
||||
// ),
|
||||
// trailing: Icon(
|
||||
// Icons.arrow_forward,
|
||||
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
// ),
|
||||
onTap: () {
|
||||
viewCardWindow(index);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.only(top: 25.0),
|
||||
child: Center(
|
||||
child: Text(
|
||||
"No Cards Available",
|
||||
style: TextStyle(fontSize: 25, color: Colors.grey),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MihCardDisplay extends StatefulWidget {
|
||||
final String shopName;
|
||||
final double height;
|
||||
const MihCardDisplay({
|
||||
super.key,
|
||||
required this.shopName,
|
||||
required this.height,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MihCardDisplay> createState() => _MihCardDisplayState();
|
||||
}
|
||||
|
||||
class _MihCardDisplayState extends State<MihCardDisplay> {
|
||||
Widget displayLoyaltyCard() {
|
||||
switch (widget.shopName.toLowerCase()) {
|
||||
case "best before":
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: widget.height,
|
||||
child: Image.asset('images/loyalty_cards/bb_club.png'),
|
||||
),
|
||||
],
|
||||
);
|
||||
case "checkers":
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: widget.height,
|
||||
child: Image.asset('images/loyalty_cards/xtraSavings.png'),
|
||||
),
|
||||
],
|
||||
);
|
||||
case "clicks":
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: widget.height,
|
||||
child: Image.asset('images/loyalty_cards/Clicks_Club.png'),
|
||||
),
|
||||
],
|
||||
);
|
||||
case "dis-chem":
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: widget.height,
|
||||
child: Image.asset('images/loyalty_cards/dischem_benefit.png'),
|
||||
),
|
||||
],
|
||||
);
|
||||
case "pick n pay":
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: widget.height,
|
||||
child: Image.asset('images/loyalty_cards/pnp_smart.png'),
|
||||
),
|
||||
],
|
||||
);
|
||||
case "spar":
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: widget.height,
|
||||
child: Image.asset('images/loyalty_cards/spar_rewards.png'),
|
||||
),
|
||||
],
|
||||
);
|
||||
case "woolworths":
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: widget.height,
|
||||
child: Image.asset('images/loyalty_cards/wrewards.png'),
|
||||
),
|
||||
],
|
||||
);
|
||||
default:
|
||||
return const SizedBox(
|
||||
height: 150,
|
||||
//child: Placeholder(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return displayLoyaltyCard();
|
||||
}
|
||||
}
|
||||
237
Frontend/lib/mih_packages/mzansi_wallet/loyalty_cards.dart
Normal file
@@ -0,0 +1,237 @@
|
||||
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_inputs_and_buttons/mih_button.dart';
|
||||
import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
|
||||
import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart';
|
||||
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_window.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';
|
||||
import 'package:Mzansi_Innovation_Hub/mih_packages/mzansi_wallet/components/mih_card_display.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:simple_barcode_scanner/simple_barcode_scanner.dart';
|
||||
|
||||
class LoyaltyCards extends StatefulWidget {
|
||||
final AppUser signedInUser;
|
||||
const LoyaltyCards({
|
||||
super.key,
|
||||
required this.signedInUser,
|
||||
});
|
||||
|
||||
@override
|
||||
State<LoyaltyCards> createState() => _LoyaltyCardsState();
|
||||
}
|
||||
|
||||
class _LoyaltyCardsState extends State<LoyaltyCards> {
|
||||
final TextEditingController shopController = TextEditingController();
|
||||
final TextEditingController cardNumberController = TextEditingController();
|
||||
late Future<List<MIHLoyaltyCard>> cardList;
|
||||
//bool showSelectedCardType = false;
|
||||
final ValueNotifier<String> shopName = ValueNotifier("");
|
||||
|
||||
void addCardWindow() {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (context) => MIHWindow(
|
||||
fullscreen: false,
|
||||
windowTitle: "Add New Loyalty Card",
|
||||
windowTools: const [
|
||||
SizedBox(width: 35),
|
||||
// IconButton(
|
||||
// onPressed: () {
|
||||
// //Delete card API Call
|
||||
// },
|
||||
// icon: Icon(
|
||||
// Icons.delete,
|
||||
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
onWindowTapClose: () {
|
||||
shopController.clear();
|
||||
cardNumberController.clear();
|
||||
shopName.value = "";
|
||||
Navigator.pop(context);
|
||||
},
|
||||
windowBody: [
|
||||
MIHDropdownField(
|
||||
controller: shopController,
|
||||
hintText: "Shop Name",
|
||||
dropdownOptions: const [
|
||||
"Best Before",
|
||||
"Checkers",
|
||||
"Clicks",
|
||||
"Dis-Chem",
|
||||
"Pick n Pay",
|
||||
"Spar",
|
||||
"Woolworths"
|
||||
],
|
||||
required: true,
|
||||
editable: true,
|
||||
),
|
||||
ValueListenableBuilder(
|
||||
valueListenable: shopName,
|
||||
builder: (BuildContext context, String value, Widget? child) {
|
||||
return Visibility(
|
||||
visible: value != "",
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 10),
|
||||
MihCardDisplay(shopName: shopName.value, height: 200),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Flexible(
|
||||
child: MIHTextField(
|
||||
controller: cardNumberController,
|
||||
hintText: "Card Number",
|
||||
editable: true,
|
||||
required: true,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
MIHButton(
|
||||
onTap: () async {
|
||||
String? res = await SimpleBarcodeScanner.scanBarcode(
|
||||
context,
|
||||
barcodeAppBar: const BarcodeAppBar(
|
||||
appBarTitle: 'Scan Barcode',
|
||||
centerTitle: false,
|
||||
enableBackButton: true,
|
||||
backButtonIcon: Icon(Icons.arrow_back),
|
||||
),
|
||||
isShowFlashIcon: true,
|
||||
delayMillis: 500,
|
||||
cameraFace: CameraFace.back,
|
||||
scanFormat: ScanFormat.ALL_FORMATS,
|
||||
);
|
||||
setState(() {
|
||||
cardNumberController.text = res as String;
|
||||
});
|
||||
},
|
||||
buttonText: "Scan",
|
||||
buttonColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
textColor:
|
||||
MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
SizedBox(
|
||||
width: 300,
|
||||
height: 50,
|
||||
child: MIHButton(
|
||||
onTap: () {
|
||||
MIHMzansiWalletApis.addLoyaltyCardAPICall(
|
||||
widget.signedInUser,
|
||||
widget.signedInUser.app_id,
|
||||
shopController.text,
|
||||
cardNumberController.text,
|
||||
context,
|
||||
);
|
||||
},
|
||||
buttonText: "Add",
|
||||
buttonColor:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void shopSelected() {
|
||||
if (shopController.text.isNotEmpty) {
|
||||
shopName.value = shopController.text;
|
||||
} else {
|
||||
shopName.value = "";
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
cardNumberController.dispose();
|
||||
shopController.dispose();
|
||||
shopController.removeListener(shopSelected);
|
||||
shopName.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
cardList = MIHMzansiWalletApis.getLoyaltyCards(widget.signedInUser.app_id);
|
||||
shopController.addListener(shopSelected);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder(
|
||||
future: cardList,
|
||||
builder: (context, snapshot) {
|
||||
//print(snapshot.connectionState);
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const Center(
|
||||
child: Mihloadingcircle(),
|
||||
);
|
||||
} else if (snapshot.connectionState == ConnectionState.done &&
|
||||
snapshot.hasData) {
|
||||
final cardList = snapshot.data!;
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
"Loyalty Cards",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 25,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: MzanziInnovationHub.of(context)!
|
||||
.theme
|
||||
.secondaryColor(),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.add_card),
|
||||
alignment: Alignment.topRight,
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
|
||||
onPressed: () {
|
||||
addCardWindow();
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
Divider(
|
||||
color:
|
||||
MzanziInnovationHub.of(context)!.theme.secondaryColor()),
|
||||
const SizedBox(height: 10),
|
||||
BuildLoyaltyCardList(
|
||||
cardList: cardList,
|
||||
signedInUser: widget.signedInUser,
|
||||
)
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return const Center(
|
||||
child: Text("Error Loading Loyalty Cards"),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
178
Frontend/lib/mih_packages/mzansi_wallet/mzansi_wallet.dart
Normal file
@@ -0,0 +1,178 @@
|
||||
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_action.dart';
|
||||
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_body.dart';
|
||||
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_header.dart';
|
||||
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_layout_builder.dart';
|
||||
import 'package:Mzansi_Innovation_Hub/mih_objects/app_user.dart';
|
||||
import 'package:Mzansi_Innovation_Hub/mih_packages/mzansi_wallet/loyalty_cards.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MzansiWallet extends StatefulWidget {
|
||||
final AppUser signedInUser;
|
||||
const MzansiWallet({
|
||||
super.key,
|
||||
required this.signedInUser,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MzansiWallet> createState() => _MzansiWalletState();
|
||||
}
|
||||
|
||||
class _MzansiWalletState extends State<MzansiWallet> {
|
||||
int _selectedIndex = 0;
|
||||
|
||||
MIHAction getActionButton() {
|
||||
return MIHAction(
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
iconSize: 35,
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).popAndPushNamed(
|
||||
'/',
|
||||
arguments: true,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
MIHHeader getHeader() {
|
||||
return const MIHHeader(
|
||||
headerAlignment: MainAxisAlignment.center,
|
||||
headerItems: [
|
||||
Text(
|
||||
"",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 25,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
MIHHeader getSecAction() {
|
||||
return MIHHeader(
|
||||
headerAlignment: MainAxisAlignment.end,
|
||||
headerItems: [
|
||||
//============ Patient Details ================
|
||||
Visibility(
|
||||
visible: _selectedIndex != 0,
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_selectedIndex = 0;
|
||||
});
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.card_membership,
|
||||
size: 35,
|
||||
),
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: _selectedIndex == 0,
|
||||
child: IconButton.filled(
|
||||
iconSize: 35,
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_selectedIndex = 0;
|
||||
});
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.card_membership,
|
||||
),
|
||||
),
|
||||
),
|
||||
//============ Patient Notes ================
|
||||
// Visibility(
|
||||
// visible: _selectedIndex != 1,
|
||||
// child: IconButton(
|
||||
// onPressed: () {
|
||||
// setState(() {
|
||||
// _selectedIndex = 1;
|
||||
// });
|
||||
// },
|
||||
// icon: const Icon(
|
||||
// Icons.article_outlined,
|
||||
// size: 35,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// Visibility(
|
||||
// visible: _selectedIndex == 1,
|
||||
// child: IconButton.filled(
|
||||
// onPressed: () {
|
||||
// setState(() {
|
||||
// _selectedIndex = 1;
|
||||
// });
|
||||
// },
|
||||
// icon: const Icon(
|
||||
// Icons.article_outlined,
|
||||
// size: 35,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// //============ Patient Files ================
|
||||
// Visibility(
|
||||
// visible: _selectedIndex != 2,
|
||||
// child: IconButton(
|
||||
// onPressed: () {
|
||||
// setState(() {
|
||||
// _selectedIndex = 2;
|
||||
// });
|
||||
// },
|
||||
// icon: const Icon(
|
||||
// Icons.file_present,
|
||||
// size: 35,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// Visibility(
|
||||
// visible: _selectedIndex == 2,
|
||||
// child: IconButton.filled(
|
||||
// onPressed: () {
|
||||
// setState(() {
|
||||
// _selectedIndex = 2;
|
||||
// });
|
||||
// },
|
||||
// icon: const Icon(
|
||||
// Icons.file_present,
|
||||
// size: 35,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
MIHBody getBody() {
|
||||
return MIHBody(
|
||||
borderOn: true,
|
||||
bodyItems: [showSelection(_selectedIndex)],
|
||||
);
|
||||
}
|
||||
|
||||
Widget showSelection(int index) {
|
||||
if (index == 0) {
|
||||
return LoyaltyCards(signedInUser: widget.signedInUser);
|
||||
} else if (index == 1) {
|
||||
return const Placeholder();
|
||||
} else {
|
||||
return const Placeholder();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MIHLayoutBuilder(
|
||||
actionButton: getActionButton(),
|
||||
header: getHeader(),
|
||||
secondaryActionButton: getSecAction(),
|
||||
body: getBody(),
|
||||
actionDrawer: null,
|
||||
secondaryActionDrawer: null,
|
||||
bottomNavBar: null,
|
||||
pullDownToRefresh: false,
|
||||
onPullDown: () async {},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -46,11 +46,12 @@ class _AddPatientState extends State<AddPatient> {
|
||||
|
||||
final baseAPI = AppEnviroment.baseApiUrl;
|
||||
late int futureDocOfficeId;
|
||||
late bool medRequired;
|
||||
//late bool medRequired;
|
||||
final ValueNotifier<bool> medRequired = ValueNotifier(false);
|
||||
final FocusNode _focusNode = FocusNode();
|
||||
|
||||
bool isFieldsFilled() {
|
||||
if (medRequired) {
|
||||
if (medRequired.value) {
|
||||
if (idController.text.isEmpty ||
|
||||
fnameController.text.isEmpty ||
|
||||
lnameController.text.isEmpty ||
|
||||
@@ -151,13 +152,9 @@ class _AddPatientState extends State<AddPatient> {
|
||||
void isRequired() {
|
||||
//print("listerner triggered");
|
||||
if (medAidController.text == "Yes") {
|
||||
setState(() {
|
||||
medRequired = true;
|
||||
});
|
||||
medRequired.value = true;
|
||||
} else {
|
||||
setState(() {
|
||||
medRequired = false;
|
||||
});
|
||||
medRequired.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,54 +232,59 @@ class _AddPatientState extends State<AddPatient> {
|
||||
controller: medAidController,
|
||||
hintText: "Medical Aid",
|
||||
editable: true,
|
||||
onSelect: (_) {
|
||||
isRequired();
|
||||
},
|
||||
// onSelect: (_) {
|
||||
// isRequired();
|
||||
// },
|
||||
required: true,
|
||||
dropdownOptions: const ["Yes", "No"],
|
||||
),
|
||||
Visibility(
|
||||
visible: medRequired,
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 10.0),
|
||||
MIHDropdownField(
|
||||
controller: medMainMemController,
|
||||
hintText: "Main Member",
|
||||
editable: medRequired,
|
||||
required: medRequired,
|
||||
dropdownOptions: const ["Yes", "No"],
|
||||
ValueListenableBuilder(
|
||||
valueListenable: medRequired,
|
||||
builder: (BuildContext context, bool value, Widget? child) {
|
||||
return Visibility(
|
||||
visible: value,
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 10.0),
|
||||
MIHDropdownField(
|
||||
controller: medMainMemController,
|
||||
hintText: "Main Member",
|
||||
editable: value,
|
||||
required: value,
|
||||
dropdownOptions: const ["Yes", "No"],
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHTextField(
|
||||
controller: medNoController,
|
||||
hintText: "Medical Aid No.",
|
||||
editable: value,
|
||||
required: value,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHTextField(
|
||||
controller: medAidCodeController,
|
||||
hintText: "Medical Aid Code",
|
||||
editable: value,
|
||||
required: value,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHTextField(
|
||||
controller: medNameController,
|
||||
hintText: "Medical Aid Name",
|
||||
editable: value,
|
||||
required: value,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHTextField(
|
||||
controller: medSchemeController,
|
||||
hintText: "Medical Aid Scheme",
|
||||
editable: value,
|
||||
required: value,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHTextField(
|
||||
controller: medNoController,
|
||||
hintText: "Medical Aid No.",
|
||||
editable: medRequired,
|
||||
required: medRequired,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHTextField(
|
||||
controller: medAidCodeController,
|
||||
hintText: "Medical Aid Code",
|
||||
editable: medRequired,
|
||||
required: medRequired,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHTextField(
|
||||
controller: medNameController,
|
||||
hintText: "Medical Aid Name",
|
||||
editable: medRequired,
|
||||
required: medRequired,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHTextField(
|
||||
controller: medSchemeController,
|
||||
hintText: "Medical Aid Scheme",
|
||||
editable: medRequired,
|
||||
required: medRequired,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 30.0),
|
||||
SizedBox(
|
||||
@@ -372,6 +374,8 @@ class _AddPatientState extends State<AddPatient> {
|
||||
medSchemeController.dispose();
|
||||
addressController.dispose();
|
||||
medAidController.dispose();
|
||||
medAidCodeController.removeListener(isRequired);
|
||||
medRequired.dispose();
|
||||
medMainMemController.dispose();
|
||||
medAidCodeController.dispose();
|
||||
_focusNode.dispose();
|
||||
|
||||
@@ -53,7 +53,8 @@ class _EditPatientState extends State<EditPatient> {
|
||||
|
||||
late int futureDocOfficeId;
|
||||
late String userEmail;
|
||||
late bool medRequired;
|
||||
// bool medRequired = false;
|
||||
final ValueNotifier<bool> medRequired = ValueNotifier(false);
|
||||
|
||||
late double width;
|
||||
late double height;
|
||||
@@ -324,7 +325,7 @@ class _EditPatientState extends State<EditPatient> {
|
||||
}
|
||||
|
||||
bool isFieldsFilled() {
|
||||
if (medRequired) {
|
||||
if (medRequired.value) {
|
||||
if (idController.text.isEmpty ||
|
||||
fnameController.text.isEmpty ||
|
||||
lnameController.text.isEmpty ||
|
||||
@@ -357,15 +358,13 @@ class _EditPatientState extends State<EditPatient> {
|
||||
}
|
||||
|
||||
void isRequired() {
|
||||
//print("listerner triggered");
|
||||
print("listerner triggered");
|
||||
if (medAidController.text == "Yes") {
|
||||
setState(() {
|
||||
medRequired = true;
|
||||
});
|
||||
medRequired.value = true;
|
||||
} else if (medAidController.text == "No") {
|
||||
medRequired.value = false;
|
||||
} else {
|
||||
setState(() {
|
||||
medRequired = false;
|
||||
});
|
||||
//print("here");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,63 +455,68 @@ class _EditPatientState extends State<EditPatient> {
|
||||
MIHDropdownField(
|
||||
controller: medAidController,
|
||||
hintText: "Medical Aid",
|
||||
onSelect: (selected) {
|
||||
if (selected == "Yes") {
|
||||
setState(() {
|
||||
medRequired = true;
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
medRequired = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
// onSelect: (selected) {
|
||||
// if (selected == "Yes") {
|
||||
// setState(() {
|
||||
// medRequired = true;
|
||||
// });
|
||||
// } else {
|
||||
// setState(() {
|
||||
// medRequired = false;
|
||||
// });
|
||||
// }
|
||||
// },
|
||||
editable: true,
|
||||
required: true,
|
||||
dropdownOptions: const ["Yes", "No"],
|
||||
),
|
||||
Visibility(
|
||||
visible: medRequired,
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 10.0),
|
||||
MIHDropdownField(
|
||||
controller: medMainMemController,
|
||||
hintText: "Main Member.",
|
||||
editable: medRequired,
|
||||
required: medRequired,
|
||||
dropdownOptions: const ["Yes", "No"],
|
||||
ValueListenableBuilder(
|
||||
valueListenable: medRequired,
|
||||
builder: (BuildContext context, bool value, Widget? child) {
|
||||
return Visibility(
|
||||
visible: value,
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 10.0),
|
||||
MIHDropdownField(
|
||||
controller: medMainMemController,
|
||||
hintText: "Main Member.",
|
||||
editable: value,
|
||||
required: value,
|
||||
dropdownOptions: const ["Yes", "No"],
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHTextField(
|
||||
controller: medNoController,
|
||||
hintText: "Medical Aid No.",
|
||||
editable: value,
|
||||
required: value,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHTextField(
|
||||
controller: medAidCodeController,
|
||||
hintText: "Medical Aid Code",
|
||||
editable: value,
|
||||
required: value,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHTextField(
|
||||
controller: medNameController,
|
||||
hintText: "Medical Aid Name",
|
||||
editable: value,
|
||||
required: value,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHTextField(
|
||||
controller: medSchemeController,
|
||||
hintText: "Medical Aid Scheme",
|
||||
editable: value,
|
||||
required: value,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHTextField(
|
||||
controller: medNoController,
|
||||
hintText: "Medical Aid No.",
|
||||
editable: medRequired,
|
||||
required: medRequired,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHTextField(
|
||||
controller: medAidCodeController,
|
||||
hintText: "Medical Aid Code",
|
||||
editable: medRequired,
|
||||
required: medRequired,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHTextField(
|
||||
controller: medNameController,
|
||||
hintText: "Medical Aid Name",
|
||||
editable: medRequired,
|
||||
required: medRequired,
|
||||
),
|
||||
const SizedBox(height: 10.0),
|
||||
MIHTextField(
|
||||
controller: medSchemeController,
|
||||
hintText: "Medical Aid Scheme",
|
||||
editable: medRequired,
|
||||
required: medRequired,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 30.0),
|
||||
SizedBox(
|
||||
@@ -535,7 +539,7 @@ class _EditPatientState extends State<EditPatient> {
|
||||
|
||||
void submitForm() {
|
||||
if (isFieldsFilled()) {
|
||||
if (!medRequired) {
|
||||
if (!medRequired.value) {
|
||||
setState(() {
|
||||
medMainMemController.text = "";
|
||||
medNoController.text = "";
|
||||
@@ -611,8 +615,10 @@ class _EditPatientState extends State<EditPatient> {
|
||||
medSchemeController.dispose();
|
||||
addressController.dispose();
|
||||
medAidController.dispose();
|
||||
medAidCodeController.removeListener(isRequired);
|
||||
medMainMemController.dispose();
|
||||
medAidCodeController.dispose();
|
||||
medRequired.dispose();
|
||||
_focusNode.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
@@ -622,29 +628,19 @@ class _EditPatientState extends State<EditPatient> {
|
||||
getLoginUserEmail();
|
||||
medAidController.addListener(isRequired);
|
||||
setState(() {
|
||||
idController.value = TextEditingValue(text: widget.selectedPatient.id_no);
|
||||
fnameController.value =
|
||||
TextEditingValue(text: widget.selectedPatient.first_name);
|
||||
lnameController.value =
|
||||
TextEditingValue(text: widget.selectedPatient.last_name);
|
||||
cellController.value =
|
||||
TextEditingValue(text: widget.selectedPatient.cell_no);
|
||||
emailController.value =
|
||||
TextEditingValue(text: widget.selectedPatient.email);
|
||||
medNameController.value =
|
||||
TextEditingValue(text: widget.selectedPatient.medical_aid_name);
|
||||
medNoController.value =
|
||||
TextEditingValue(text: widget.selectedPatient.medical_aid_no);
|
||||
medSchemeController.value =
|
||||
TextEditingValue(text: widget.selectedPatient.medical_aid_scheme);
|
||||
addressController.value =
|
||||
TextEditingValue(text: widget.selectedPatient.address);
|
||||
medAidController.value =
|
||||
TextEditingValue(text: widget.selectedPatient.medical_aid);
|
||||
medMainMemController.value = TextEditingValue(
|
||||
text: widget.selectedPatient.medical_aid_main_member);
|
||||
medAidCodeController.value =
|
||||
TextEditingValue(text: widget.selectedPatient.medical_aid_code);
|
||||
idController.text = widget.selectedPatient.id_no;
|
||||
fnameController.text = widget.selectedPatient.first_name;
|
||||
lnameController.text = widget.selectedPatient.last_name;
|
||||
cellController.text = widget.selectedPatient.cell_no;
|
||||
emailController.text = widget.selectedPatient.email;
|
||||
medNameController.text = widget.selectedPatient.medical_aid_name;
|
||||
medNoController.text = widget.selectedPatient.medical_aid_no;
|
||||
medSchemeController.text = widget.selectedPatient.medical_aid_scheme;
|
||||
addressController.text = widget.selectedPatient.address;
|
||||
medAidController.text = widget.selectedPatient.medical_aid;
|
||||
medMainMemController.text =
|
||||
widget.selectedPatient.medical_aid_main_member;
|
||||
medAidCodeController.text = widget.selectedPatient.medical_aid_code;
|
||||
});
|
||||
|
||||
super.initState();
|
||||
|
||||
@@ -275,81 +275,5 @@ class _PatientViewState extends State<PatientView> {
|
||||
onPullDown: () async {},
|
||||
),
|
||||
);
|
||||
// return Scaffold(
|
||||
// body: SafeArea(
|
||||
// child: SingleChildScrollView(
|
||||
// child: Stack(
|
||||
// children: [
|
||||
// Container(
|
||||
// width: width,
|
||||
// height: height,
|
||||
// padding: const EdgeInsets.symmetric(
|
||||
// vertical: 10.0, horizontal: 15.0),
|
||||
// child: Column(
|
||||
// mainAxisSize: MainAxisSize.max,
|
||||
// children: [
|
||||
// Row(
|
||||
// crossAxisAlignment: CrossAxisAlignment.end,
|
||||
// mainAxisAlignment: MainAxisAlignment.end,
|
||||
// children: [
|
||||
// IconButton(
|
||||
// onPressed: () {
|
||||
// setState(() {
|
||||
// _selectedIndex = 0;
|
||||
// });
|
||||
// },
|
||||
// icon: const Icon(
|
||||
// Icons.perm_identity,
|
||||
// size: 35,
|
||||
// ),
|
||||
// ),
|
||||
// IconButton(
|
||||
// onPressed: () {
|
||||
// setState(() {
|
||||
// _selectedIndex = 1;
|
||||
// });
|
||||
// },
|
||||
// icon: const Icon(
|
||||
// Icons.article_outlined,
|
||||
// size: 35,
|
||||
// ),
|
||||
// ),
|
||||
// IconButton(
|
||||
// onPressed: () {
|
||||
// setState(() {
|
||||
// _selectedIndex = 2;
|
||||
// });
|
||||
// },
|
||||
// icon: const Icon(
|
||||
// Icons.file_present,
|
||||
// size: 35,
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// const SizedBox(
|
||||
// height: 10.0,
|
||||
// ),
|
||||
// showSelection(_selectedIndex),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// Positioned(
|
||||
// top: 10,
|
||||
// left: 5,
|
||||
// width: 50,
|
||||
// height: 50,
|
||||
// child: IconButton(
|
||||
// onPressed: () {
|
||||
// Navigator.of(context).pop();
|
||||
// },
|
||||
// icon: const Icon(Icons.arrow_back),
|
||||
// ),
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:Mzansi_Innovation_Hub/mih_packages/mzansi_wallet/mzansi_wallet.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../mih_components/mih_layout/mih_print_prevew.dart';
|
||||
import '../mih_components/mih_pop_up_messages/mih_notification_message.dart';
|
||||
@@ -70,6 +71,7 @@ class RouteGenerator {
|
||||
settings: settings, builder: (_) => const ForgotPassword());
|
||||
//http://mzansi-innovation-hub.co.za/auth/reset-password
|
||||
//===============================================================
|
||||
|
||||
//About MIH
|
||||
case '/about':
|
||||
return MaterialPageRoute(
|
||||
@@ -157,6 +159,20 @@ class RouteGenerator {
|
||||
return _errorRoute();
|
||||
//===============================================================
|
||||
|
||||
// /mzansi wallet
|
||||
case '/mzansi-wallet':
|
||||
if (args is AppUser) {
|
||||
//print("route generator: $args");
|
||||
return MaterialPageRoute(
|
||||
settings: settings,
|
||||
builder: (_) => MzansiWallet(
|
||||
signedInUser: args,
|
||||
),
|
||||
);
|
||||
}
|
||||
return _errorRoute();
|
||||
//===============================================================
|
||||
|
||||
// Access Review Page
|
||||
case '/access-review':
|
||||
if (args is AppUser) {
|
||||
|
||||
@@ -426,10 +426,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_plugin_android_lifecycle
|
||||
sha256: "9ee02950848f61c4129af3d6ec84a1cfc0e47931abc746b03e7a3bc3e8ff6eda"
|
||||
sha256: "9b78450b89f059e96c9ebb355fa6b3df1d6b330436e0b885fb49594c41721398"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.22"
|
||||
version: "2.0.23"
|
||||
flutter_swipe_detector:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -832,6 +832,54 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
permission_handler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler
|
||||
sha256: "18bf33f7fefbd812f37e72091a15575e72d5318854877e0e4035a24ac1113ecb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "11.3.1"
|
||||
permission_handler_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_android
|
||||
sha256: "71bbecfee799e65aff7c744761a57e817e73b738fedf62ab7afd5593da21f9f1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "12.0.13"
|
||||
permission_handler_apple:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_apple
|
||||
sha256: e6f6d73b12438ef13e648c4ae56bd106ec60d17e90a59c4545db6781229082a0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.4.5"
|
||||
permission_handler_html:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_html
|
||||
sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.3+5"
|
||||
permission_handler_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_platform_interface
|
||||
sha256: e9c8eadee926c4532d0305dff94b85bf961f16759c3af791486613152af4b4f9
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2.3"
|
||||
permission_handler_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_windows
|
||||
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.1"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1016,6 +1064,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
simple_barcode_scanner:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: simple_barcode_scanner
|
||||
sha256: "993c4b0e22bbe6cf127f8e0001574fd54015b90e0698a058ec9fdb2fdf84bc55"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.5"
|
||||
simple_gesture_detector:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1125,6 +1181,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.1"
|
||||
syncfusion_flutter_barcodes:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: syncfusion_flutter_barcodes
|
||||
sha256: "5e65d005474caadfc48e0ecc5142da06f401900036631674a610a202b270be9d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "26.2.10"
|
||||
syncfusion_flutter_core:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -1361,10 +1425,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062
|
||||
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
version: "1.1.0"
|
||||
web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1413,6 +1477,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.16.2"
|
||||
webview_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webview_windows
|
||||
sha256: "47fcad5875a45db29dbb5c9e6709bf5c88dcc429049872701343f91ed7255730"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.0"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1478,5 +1550,5 @@ packages:
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
sdks:
|
||||
dart: ">=3.5.0 <3.6.0"
|
||||
dart: ">=3.5.3 <3.6.0"
|
||||
flutter: ">=3.24.0"
|
||||
|
||||
@@ -61,6 +61,8 @@ dependencies:
|
||||
table_calendar: ^3.1.2
|
||||
flutter_swipe_detector: ^2.0.0
|
||||
youtube_player_iframe: ^5.2.0
|
||||
syncfusion_flutter_barcodes: ^26.2.10
|
||||
simple_barcode_scanner: ^0.2.5
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
@@ -90,6 +92,7 @@ flutter:
|
||||
# To add assets to your application, add an assets section, like this:
|
||||
assets:
|
||||
- images/
|
||||
- images/loyalty_cards/
|
||||
# - images/a_dot_ham.jpeg
|
||||
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
|
||||
@@ -9,9 +9,11 @@
|
||||
#include <app_links/app_links_plugin_c_api.h>
|
||||
#include <firebase_core/firebase_core_plugin_c_api.h>
|
||||
#include <geolocator_windows/geolocator_windows.h>
|
||||
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||
#include <printing/printing_plugin.h>
|
||||
#include <syncfusion_pdfviewer_windows/syncfusion_pdfviewer_windows_plugin.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
#include <webview_windows/webview_windows_plugin.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
AppLinksPluginCApiRegisterWithRegistrar(
|
||||
@@ -20,10 +22,14 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
|
||||
GeolocatorWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("GeolocatorWindows"));
|
||||
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
|
||||
PrintingPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("PrintingPlugin"));
|
||||
SyncfusionPdfviewerWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("SyncfusionPdfviewerWindowsPlugin"));
|
||||
UrlLauncherWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||
WebviewWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("WebviewWindowsPlugin"));
|
||||
}
|
||||
|
||||
@@ -6,9 +6,11 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
||||
app_links
|
||||
firebase_core
|
||||
geolocator_windows
|
||||
permission_handler_windows
|
||||
printing
|
||||
syncfusion_pdfviewer_windows
|
||||
url_launcher_windows
|
||||
webview_windows
|
||||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
|
||||
@@ -24,6 +24,14 @@ def dbDataAccessConnect():
|
||||
database="data_access"
|
||||
)
|
||||
|
||||
def dbMzansiWalletConnect():
|
||||
return mysql.connector.connect(
|
||||
host="mysqldb",
|
||||
user="root",
|
||||
passwd="C@rtoon1995",
|
||||
database="mzansi_wallet"
|
||||
)
|
||||
|
||||
def dbAllConnect():
|
||||
return mysql.connector.connect(
|
||||
host="mysqldb",
|
||||
|
||||
@@ -14,6 +14,7 @@ import routers.business_user as business_user
|
||||
import routers.business as business
|
||||
import routers.access_request as access_request
|
||||
import routers.patient_access as patient_access
|
||||
import routers.mzansi_wallet as mzansi_wallet
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.middleware import Middleware
|
||||
from supertokens_python import get_all_cors_headers
|
||||
@@ -86,6 +87,7 @@ app.include_router(medicine.router)
|
||||
app.include_router(business_user.router)
|
||||
app.include_router(business.router)
|
||||
app.include_router(notifications.router)
|
||||
app.include_router(mzansi_wallet.router)
|
||||
|
||||
# Check if server is up
|
||||
@app.get("/", tags=["Server Check"])
|
||||
|
||||
138
backend/routers/mzansi_wallet.py
Normal file
@@ -0,0 +1,138 @@
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from datetime import date
|
||||
#from ..database import dbConnection
|
||||
import database
|
||||
#SuperToken Auth from front end
|
||||
from supertokens_python.recipe.session.framework.fastapi import verify_session
|
||||
from supertokens_python.recipe.session import SessionContainer
|
||||
from fastapi import Depends
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
class LoyaltyCardDeleteRequest(BaseModel):
|
||||
idloyalty_cards: int
|
||||
|
||||
class MzansiWalletInsertRequest(BaseModel):
|
||||
app_id: str
|
||||
shop_name: str
|
||||
card_number: str
|
||||
|
||||
# class patientNoteUpdateRequest(BaseModel):
|
||||
# idpatient_notes: int
|
||||
# note_name: str
|
||||
# note_text: str
|
||||
# doc_office: str
|
||||
# doctor: str
|
||||
# patient_id: int
|
||||
|
||||
# Get List of all loyalty cards by user
|
||||
@router.get("/mzasni-wallet/loyalty-cards/{app_id}", tags=["Mzansi Wallet"])
|
||||
async def read_all_loyalty_cards_by_app_id(app_id: str, session: SessionContainer = Depends(verify_session())): # , session: SessionContainer = Depends(verify_session())
|
||||
db = database.dbConnection.dbMzansiWalletConnect()
|
||||
cursor = db.cursor()
|
||||
query = "SELECT * FROM loyalty_cards where app_id = %s ORDER BY shop_name Asc"
|
||||
cursor.execute(query, (app_id,))
|
||||
items = [
|
||||
{
|
||||
"idloyalty_cards": item[0],
|
||||
"app_id": item[1],
|
||||
"shop_name": item[2],
|
||||
"card_number": item[3],
|
||||
}
|
||||
for item in cursor.fetchall()
|
||||
]
|
||||
cursor.close()
|
||||
db.close()
|
||||
return items
|
||||
|
||||
# Get List of all notes by patient
|
||||
# @router.get("/notes/patients-docOffice/", tags="patients_notes")
|
||||
# async def read_all_patientsby(itemRequest: noteRequest, session: SessionContainer = Depends(verify_session())):
|
||||
# db = database.dbConnection.dbPatientManagerConnect()
|
||||
# cursor = db.cursor()
|
||||
# query = "select patient_notes.idpatient_notes, patient_notes.note_name, patient_notes.note_text, patient_notes.patient_id, patient_notes.insert_date, patients.doc_office_id "
|
||||
# query += "from patient_manager.patient_notes "
|
||||
# query += "inner join patient_manager.patients "
|
||||
# query += "on patient_notes.patient_id = patients.idpatients "
|
||||
# query += "where patient_notes.patient_id = %s and patients.doc_office_id = %s"
|
||||
# cursor.execute(query, (itemRequest.patientID, itemRequest.DocOfficeID,))
|
||||
# items = [
|
||||
# {
|
||||
# "idpatient_notes": item[0],
|
||||
# "note_name": item[1],
|
||||
# "note_text": item[2],
|
||||
# "insert_date": item[3],
|
||||
# }
|
||||
# for item in cursor.fetchall()
|
||||
# ]
|
||||
# cursor.close()
|
||||
# db.close()
|
||||
# return items
|
||||
|
||||
# Insert loyalty cards into table
|
||||
@router.post("/mzasni-wallet/loyalty-cards/insert/", tags=["Mzansi Wallet"], status_code=201)
|
||||
async def insert_loyalty_card(itemRequest : MzansiWalletInsertRequest): #, session: SessionContainer = Depends(verify_session())
|
||||
db = database.dbConnection.dbMzansiWalletConnect()
|
||||
cursor = db.cursor()
|
||||
query = "insert into loyalty_cards "
|
||||
query += "(app_id, shop_name, card_number) "
|
||||
query += "values (%s, %s, %s)"
|
||||
notetData = (itemRequest.app_id,
|
||||
itemRequest.shop_name,
|
||||
itemRequest.card_number,
|
||||
)
|
||||
try:
|
||||
cursor.execute(query, notetData)
|
||||
except Exception as error:
|
||||
print(error)
|
||||
raise HTTPException(status_code=404, detail="Failed to Create Record")
|
||||
# return {"message": error}
|
||||
db.commit()
|
||||
cursor.close()
|
||||
db.close()
|
||||
return {"message": "Successfully Created Record"}
|
||||
|
||||
# Delete loyalty cards on table
|
||||
@router.delete("/mzasni-wallet/loyalty-cards/delete/", tags=["Mzansi Wallet"])
|
||||
async def Delete_loyalty_card(itemRequest : LoyaltyCardDeleteRequest, session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session())
|
||||
# today = date.today()
|
||||
db = database.dbConnection.dbMzansiWalletConnect()
|
||||
cursor = db.cursor()
|
||||
query = "delete from loyalty_cards "
|
||||
query += "where idloyalty_cards=%s"
|
||||
# notetData = (itemRequest.idpatient_notes)
|
||||
try:
|
||||
cursor.execute(query, (str(itemRequest.idloyalty_cards),))
|
||||
except Exception as error:
|
||||
print(error)
|
||||
raise HTTPException(status_code=404, detail="Failed to Delete Record")
|
||||
#return {"query": query, "message": error}
|
||||
db.commit()
|
||||
cursor.close()
|
||||
db.close()
|
||||
return {"message": "Successfully deleted Record"}
|
||||
|
||||
# Update Patient note on table
|
||||
# @router.put("/notes/update/", tags="patients_notes")
|
||||
# async def UpdatePatient(itemRequest : patientNoteUpdateRequest, session: SessionContainer = Depends(verify_session())):
|
||||
# today = date.today()
|
||||
# db = database.dbConnection.dbPatientManagerConnect()
|
||||
# cursor = db.cursor()
|
||||
# query = "update patient_notes "
|
||||
# query += "set note_name=%s, note_text=%s, patient_id=%s, insert_date=%s "
|
||||
# query += "where idpatient_notes=%s"
|
||||
# notetData = (itemRequest.note_name,
|
||||
# itemRequest.note_text,
|
||||
# itemRequest.patient_id,
|
||||
# today,
|
||||
# itemRequest.idpatient_notes)
|
||||
# try:
|
||||
# cursor.execute(query, notetData)
|
||||
# except Exception as error:
|
||||
# raise HTTPException(status_code=404, detail="Failed to Update Record")
|
||||
# #return {"query": query, "message": error}
|
||||
# db.commit()
|
||||
# cursor.close()
|
||||
# db.close()
|
||||
# return {"message": "Successfully Updated Record"}
|
||||