Merge pull request #179 from yaso-meth/NEW--nickname-per-loyalty-card

NEW--nickname-per-loyalty-card
This commit is contained in:
yaso-meth
2025-05-22 12:12:31 +02:00
committed by GitHub
7 changed files with 287 additions and 58 deletions

View File

@@ -145,6 +145,7 @@ class MIHMzansiWalletApis {
String card_number,
String favourite,
int priority_index,
String nickname,
int navIndex,
BuildContext context,
) async {
@@ -161,6 +162,7 @@ class MIHMzansiWalletApis {
"card_number": card_number,
"favourite": favourite,
"priority_index": priority_index,
"nickname": nickname,
}),
);
if (response.statusCode == 201) {
@@ -193,6 +195,8 @@ class MIHMzansiWalletApis {
int idloyalty_cards,
String favourite,
int priority_index,
String nickname,
String card_number,
int navIndex,
BuildContext context,
) async {
@@ -207,6 +211,8 @@ class MIHMzansiWalletApis {
"idloyalty_cards": idloyalty_cards,
"favourite": favourite,
"priority_index": priority_index,
"nickname": nickname,
"card_number": card_number,
}),
);
//print("Here4");

View File

@@ -61,7 +61,37 @@ class _MihAppWindowState extends State<MihAppWindow> {
height: 50,
child: Row(
children: [
widget.windowTools != null ? widget.windowTools! : Container(),
Container(
// color: Colors.white,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(25), // Optional: rounds the corners
boxShadow: const [
BoxShadow(
color: Color.fromARGB(
60, 0, 0, 0), // 0.2 opacity = 51 in alpha (255 * 0.2)
spreadRadius: -5,
blurRadius: 5,
offset: Offset(0, 5),
),
],
),
child: IconButton.filled(
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all<Color>(
MzanziInnovationHub.of(context)!.theme.errorColor()),
),
color: MzanziInnovationHub.of(context)!.theme.primaryColor(),
iconSize: 20,
onPressed: () {
widget.onWindowTapClose();
},
icon: const Icon(
Icons.close,
),
),
),
Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 15),
@@ -78,20 +108,7 @@ class _MihAppWindowState extends State<MihAppWindow> {
),
),
),
Container(
// color: Colors.white,
alignment: Alignment.center,
child: IconButton(
iconSize: 35,
onPressed: () {
widget.onWindowTapClose();
},
icon: Icon(
Icons.close,
color: MzanziInnovationHub.of(context)!.theme.errorColor(),
),
),
),
widget.windowTools != null ? widget.windowTools! : Container(),
],
),
);

View File

@@ -5,6 +5,7 @@ class MIHLoyaltyCard {
final String card_number;
final String favourite;
final int priority_index;
final String nickname;
const MIHLoyaltyCard({
required this.idloyalty_cards,
@@ -13,6 +14,7 @@ class MIHLoyaltyCard {
required this.card_number,
required this.favourite,
required this.priority_index,
required this.nickname,
});
factory MIHLoyaltyCard.fromJson(Map<String, dynamic> json) {
@@ -24,6 +26,7 @@ class MIHLoyaltyCard {
"card_number": String card_number,
"favourite": String favourite,
"priority_index": int priority_index,
"nickname": String nickname,
} =>
MIHLoyaltyCard(
idloyalty_cards: idloyalty_cards,
@@ -32,6 +35,7 @@ class MIHLoyaltyCard {
card_number: card_number,
favourite: favourite,
priority_index: priority_index,
nickname: nickname,
),
_ => throw const FormatException('Failed to load loyalty card objects'),
};

View File

@@ -1,9 +1,15 @@
import 'package:flutter_speed_dial/flutter_speed_dial.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_inputs_and_buttons/mih_button.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_number_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_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_package_components/mih_floating_menu.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_delete_message.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.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';
@@ -29,8 +35,104 @@ class BuildLoyaltyCardList extends StatefulWidget {
}
class _BuildLoyaltyCardListState extends State<BuildLoyaltyCardList> {
final TextEditingController _nicknameController = TextEditingController();
final TextEditingController _cardNumberController = TextEditingController();
late int _noFavourites;
void openscanner() async {
Navigator.of(context).pushNamed(
'/scanner',
arguments: _cardNumberController,
);
}
void editCardWindow(BuildContext ctxt, int index) {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => MIHWindow(
fullscreen: false,
windowTitle: "Edit Loyalty Card",
windowTools: const [
SizedBox(width: 35),
],
onWindowTapClose: () {
_cardNumberController.clear();
_nicknameController.clear();
Navigator.pop(context);
},
windowBody: [
MIHTextField(
controller: _nicknameController,
hintText: "Card Title",
editable: true,
required: false,
),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
child: MIHNumberField(
controller: _cardNumberController,
hintText: "Card Number",
editable: true,
required: true,
enableDecimal: false,
),
),
const SizedBox(width: 10),
MIHButton(
onTap: () async {
openscanner();
},
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: () {
if (_cardNumberController.text == "") {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(errorType: "Input Error");
},
);
} else {
MIHMzansiWalletApis.updateLoyaltyCardAPICall(
widget.signedInUser,
widget.cardList[index].idloyalty_cards,
widget.cardList[index].favourite,
widget.cardList[index].priority_index,
_nicknameController.text,
_cardNumberController.text,
0,
ctxt,
);
}
},
buttonText: "Update",
buttonColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
),
),
],
),
);
}
void deleteCardWindow(BuildContext ctxt, int index) {
showDialog(
context: context,
@@ -85,7 +187,9 @@ class _BuildLoyaltyCardListState extends State<BuildLoyaltyCardList> {
widget.cardList[index].idloyalty_cards,
"Yes",
_noFavourites,
0,
widget.cardList[index].nickname,
widget.cardList[index].card_number,
1,
ctxt,
);
},
@@ -139,6 +243,8 @@ class _BuildLoyaltyCardListState extends State<BuildLoyaltyCardList> {
widget.cardList[index].idloyalty_cards,
"",
0,
widget.cardList[index].nickname,
widget.cardList[index].card_number,
0,
ctxt,
);
@@ -175,39 +281,93 @@ class _BuildLoyaltyCardListState extends State<BuildLoyaltyCardList> {
windowTitle: widget.cardList[index].shop_name.toUpperCase(),
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(),
),
Padding(
padding: const EdgeInsets.only(top: 5.0),
child: MihFloatingMenu(
animatedIcon: AnimatedIcons.menu_close,
direction: SpeedDialDirection.down,
children: [
SpeedDialChild(
child: widget.cardList[index].favourite == ""
? Icon(
Icons.favorite,
color: MzanziInnovationHub.of(context)!
.theme
.primaryColor(),
)
: Icon(
Icons.favorite_border,
color: MzanziInnovationHub.of(context)!
.theme
.primaryColor(),
),
label: widget.cardList[index].favourite == ""
? "Add to Favourite"
: "Remove from Favourite",
labelBackgroundColor:
MzanziInnovationHub.of(context)!.theme.successColor(),
labelStyle: TextStyle(
color:
MzanziInnovationHub.of(context)!.theme.primaryColor(),
fontWeight: FontWeight.bold,
),
backgroundColor:
MzanziInnovationHub.of(context)!.theme.successColor(),
onTap: () {
if (widget.cardList[index].favourite == "") {
addToFavCardWindow(context, index);
} else {
removeFromFavCardWindow(context, index);
}
},
),
SpeedDialChild(
child: Icon(
Icons.edit,
color:
MzanziInnovationHub.of(context)!.theme.primaryColor(),
),
label: "Edit Card Details",
labelBackgroundColor:
MzanziInnovationHub.of(context)!.theme.successColor(),
labelStyle: TextStyle(
color:
MzanziInnovationHub.of(context)!.theme.primaryColor(),
fontWeight: FontWeight.bold,
),
backgroundColor:
MzanziInnovationHub.of(context)!.theme.successColor(),
onTap: () {
setState(() {
_cardNumberController.text =
widget.cardList[index].card_number;
_nicknameController.text =
widget.cardList[index].nickname;
});
editCardWindow(context, index);
},
),
SpeedDialChild(
child: Icon(
Icons.delete,
color:
MzanziInnovationHub.of(context)!.theme.primaryColor(),
),
label: "Delete 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: () {
deleteCardWindow(context, index);
},
),
],
),
),
],
@@ -221,7 +381,10 @@ class _BuildLoyaltyCardListState extends State<BuildLoyaltyCardList> {
Container(
width: 500,
child: MihCardDisplay(
shopName: widget.cardList[index].shop_name, height: 250),
shopName: widget.cardList[index].shop_name,
nickname: widget.cardList[index].nickname,
height: 250,
),
),
const SizedBox(height: 20),
Container(
@@ -326,7 +489,10 @@ class _BuildLoyaltyCardListState extends State<BuildLoyaltyCardList> {
itemBuilder: (context, index) {
return GestureDetector(
child: MihCardDisplay(
shopName: widget.cardList[index].shop_name, height: 100),
shopName: widget.cardList[index].shop_name,
nickname: widget.cardList[index].nickname,
height: 100,
),
onTap: () {
viewCardWindow(index);
},

View File

@@ -2,11 +2,13 @@ import 'package:flutter/material.dart';
class MihCardDisplay extends StatefulWidget {
final String shopName;
final String nickname;
final double height;
const MihCardDisplay({
super.key,
required this.shopName,
required this.height,
required this.nickname,
});
@override
@@ -155,6 +157,19 @@ class _MihCardDisplayState extends State<MihCardDisplay> {
@override
Widget build(BuildContext context) {
return displayLoyaltyCard();
return Column(
children: [
displayLoyaltyCard(),
FittedBox(
child: Text(
widget.nickname,
style: const TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
)
],
);
}
}

View File

@@ -5,6 +5,7 @@ import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_
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_number_input.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_inputs_and_buttons/mih_search_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_single_child_scroll.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_layout/mih_window.dart';
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih-app_tool_body.dart';
@@ -31,6 +32,7 @@ class MihCards extends StatefulWidget {
class _MihCardsState extends State<MihCards> {
final TextEditingController shopController = TextEditingController();
final TextEditingController _nicknameController = TextEditingController();
final TextEditingController cardNumberController = TextEditingController();
final TextEditingController cardSearchController = TextEditingController();
late Future<List<MIHLoyaltyCard>> cardList;
@@ -97,6 +99,7 @@ class _MihCardsState extends State<MihCards> {
onWindowTapClose: () {
shopController.clear();
cardNumberController.clear();
_nicknameController.clear();
shopName.value = "";
Navigator.pop(context);
},
@@ -162,13 +165,21 @@ class _MihCardsState extends State<MihCards> {
child: Column(
children: [
const SizedBox(height: 10),
MihCardDisplay(shopName: shopName.value, height: 200),
MihCardDisplay(
shopName: shopName.value, nickname: "", height: 200),
],
),
);
},
),
const SizedBox(height: 10),
MIHTextField(
controller: _nicknameController,
hintText: "Card Title",
editable: true,
required: false,
),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
@@ -218,7 +229,8 @@ class _MihCardsState extends State<MihCards> {
cardNumberController.text,
"",
0,
1,
_nicknameController.text,
0,
context,
);
}
@@ -242,6 +254,7 @@ class _MihCardsState extends State<MihCards> {
cardSearchController.removeListener(searchShop);
cardSearchController.dispose();
searchShopName.dispose();
_nicknameController.dispose();
shopName.dispose();
super.dispose();
}
@@ -332,7 +345,7 @@ class _MihCardsState extends State<MihCards> {
return BuildLoyaltyCardList(
cardList: searchShopName.value,
signedInUser: widget.signedInUser,
navIndex: 1,
navIndex: 0,
);
},
);

View File

@@ -19,11 +19,14 @@ class MzansiWalletInsertRequest(BaseModel):
card_number: str
favourite: str
priority_index: int
nickname: str
class MzansiWalletUpdateRequest(BaseModel):
idloyalty_cards: int
favourite: str
priority_index: int
nickname: str
card_number: str
# class patientNoteUpdateRequest(BaseModel):
# idpatient_notes: int
# note_name: str
@@ -47,6 +50,7 @@ async def read_all_loyalty_cards_by_app_id(app_id: str, session: SessionContaine
"card_number": item[3],
"favourite": item[4],
"priority_index": item[5],
"nickname": item[6],
}
for item in cursor.fetchall()
]
@@ -69,6 +73,7 @@ async def read_favourite_loyalty_cards_by_app_id(app_id: str, session: SessionCo
"card_number": item[3],
"favourite": item[4],
"priority_index": item[5],
"nickname": item[6],
}
for item in cursor.fetchall()
]
@@ -106,13 +111,14 @@ async def insert_loyalty_card(itemRequest : MzansiWalletInsertRequest): #, sessi
db = database.dbConnection.dbMzansiWalletConnect()
cursor = db.cursor()
query = "insert into loyalty_cards "
query += "(app_id, shop_name, card_number, favourite, priority_index) "
query += "values (%s, %s, %s, %s, %s)"
query += "(app_id, shop_name, card_number, favourite, priority_index, nickname) "
query += "values (%s, %s, %s, %s, %s, %s)"
notetData = (itemRequest.app_id,
itemRequest.shop_name,
itemRequest.card_number,
itemRequest.favourite,
itemRequest.priority_index,
itemRequest.nickname,
)
try:
cursor.execute(query, notetData)
@@ -152,10 +158,12 @@ async def UpdatePatient(itemRequest : MzansiWalletUpdateRequest, session: Sessio
db = database.dbConnection.dbMzansiWalletConnect()
cursor = db.cursor()
query = "update loyalty_cards "
query += "set favourite=%s, priority_index=%s "
query += "set favourite=%s, priority_index=%s, nickname=%s, card_number=%s "
query += "where idloyalty_cards=%s"
notetData = (itemRequest.favourite,
itemRequest.priority_index,
itemRequest.nickname,
itemRequest.card_number,
itemRequest.idloyalty_cards,
)
try: