Commit 7210793a authored by Sai Srinivas's avatar Sai Srinivas
Browse files

17-09

parent 185e0896
......@@ -187,20 +187,20 @@ class _PaymentrequestionlistdetailsState
Widget _scaffold(BuildContext context) {
return Consumer<Requesitionlidtdetailsprovider>(
builder: (context, provider, child) {
var req_det = provider.requestsDetails;
var reqDet = provider.requestsDetails;
isLevel1Finalized = [
"Level 1 Approved",
"Level 1 Rejected",
"Level 1 approved",
"Level 1 rejected",
].contains(req_det.status);
].contains(reqDet.status);
isLevel2Finalized = [
"Level 2 Approved",
"Level 2 Rejected",
"Level 2 approved",
"Level 2 rejected",
].contains(req_det.status);
].contains(reqDet.status);
if (widget.mode == "apr_lvl1") {
shouldShowButtons = !isLevel1Finalized;
} else if (widget.mode == "apr_lvl2") {
......@@ -210,14 +210,14 @@ class _PaymentrequestionlistdetailsState
"Requested",
"Level 1 Approved",
"Level 1 approved",
].contains(req_det.status);
].contains(reqDet.status);
} else if (widget.mode == "process") {
shouldShowButtons = [
"Level 2 Approved",
"Level 2 approved",
].contains(req_det.status);
].contains(reqDet.status);
} else if (widget.mode == "self_apr_lvl2") {
shouldShowButtons = ["Requested"].contains(req_det.status);
shouldShowButtons = ["Requested"].contains(reqDet.status);
}
return Scaffold(
resizeToAvoidBottomInset: true,
......@@ -262,9 +262,9 @@ class _PaymentrequestionlistdetailsState
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
req_det.accountName == ""
reqDet.accountName == ""
? "-"
: req_det.accountName ?? "-",
: reqDet.accountName ?? "-",
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 14,
......@@ -272,9 +272,9 @@ class _PaymentrequestionlistdetailsState
),
),
Text(
req_det.amount == ""
reqDet.amount == ""
? "-"
: "₹${req_det.amount}",
: "₹${reqDet.amount}",
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 14,
......@@ -298,7 +298,7 @@ class _PaymentrequestionlistdetailsState
),
child: Center(
child: Text(
req_det.status ?? "-",
reqDet.status ?? "-",
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: "JakartaMedium",
......@@ -314,7 +314,7 @@ class _PaymentrequestionlistdetailsState
Divider(thickness: 0.5, color: Color(0xFFD7D7D7)),
...List.generate(provider.subHeadings.length, (j) {
if (provider.Headings[j] == "Attachment" &&
req_det.attachmentViewFileName == "") {
reqDet.attachmentViewFileName == "") {
return SizedBox.shrink();
}
return Container(
......@@ -343,11 +343,11 @@ class _PaymentrequestionlistdetailsState
builder:
(context) => Fileviewer(
fileName:
req_det
reqDet
.attachmentViewFileName ??
"",
fileUrl:
req_det
reqDet
.attachmentDirFilePath ??
"",
),
......@@ -667,21 +667,21 @@ class _PaymentrequestionlistdetailsState
Widget _scaffold1(BuildContext context) {
return Consumer<Requesitionlidtdetailsprovider>(
builder: (context, provider, child) {
var req_det = provider.requestsDetails;
var pay_det = provider.paymentsDetails;
var reqDet = provider.requestsDetails;
var payDet = provider.paymentsDetails;
isLevel1Finalized = [
"Level 1 Approved",
"Level 1 Rejected",
"Level 1 approved",
"Level 1 rejected",
].contains(req_det.status);
].contains(reqDet.status);
isLevel2Finalized = [
"Level 2 Approved",
"Level 2 Rejected",
"Level 2 approved",
"Level 2 rejected",
].contains(req_det.status);
].contains(reqDet.status);
if (widget.mode == "apr_lvl1") {
shouldShowButtons = !isLevel1Finalized;
} else if (widget.mode == "apr_lvl2") {
......@@ -691,14 +691,14 @@ class _PaymentrequestionlistdetailsState
"Requested",
"Level 1 Approved",
"Level 1 approved",
].contains(req_det.status);
].contains(reqDet.status);
} else if (widget.mode == "process") {
shouldShowButtons = [
"Level 2 Approved",
"Level 2 approved",
].contains(req_det.status);
].contains(reqDet.status);
} else if (widget.mode == "self_apr_lvl2") {
shouldShowButtons = ["Requested"].contains(req_det.status);
shouldShowButtons = ["Requested"].contains(reqDet.status);
}
final headings2 = [
......@@ -709,11 +709,11 @@ class _PaymentrequestionlistdetailsState
"Requested Date",
];
final subHeadings2 = [
req_det.proposedAccount ?? "-",
req_det.requestingPurpose ?? "-",
req_det.requestedAmount ?? "-",
req_det.amount ?? "-",
req_det.date ?? "-",
reqDet.proposedAccount ?? "-",
reqDet.requestingPurpose ?? "-",
reqDet.requestedAmount ?? "-",
reqDet.amount ?? "-",
reqDet.date ?? "-",
];
final headings3 = [
......@@ -726,12 +726,12 @@ class _PaymentrequestionlistdetailsState
"Attachment",
];
final subHeadings3 = [
pay_det.accountName ?? "-",
pay_det.paymentAccountName ?? "-",
pay_det.mode ?? "-",
pay_det.paymentEmployeeName ?? "-",
req_det.amount ?? "-",
req_det.date ?? "-",
payDet.accountName ?? "-",
payDet.paymentAccountName ?? "-",
payDet.mode ?? "-",
payDet.paymentEmployeeName ?? "-",
reqDet.amount ?? "-",
reqDet.date ?? "-",
"View",
];
final headings4 = [
......@@ -743,12 +743,12 @@ class _PaymentrequestionlistdetailsState
"UPI ID",
];
final subHeadings4 = [
pay_det.bankName ?? "-",
pay_det.bankAccountHolderName ?? "-",
pay_det.bankAccountNumber ?? "-",
pay_det.bankBranchName ?? "-",
pay_det.bankIfscCode ?? "-",
pay_det.bankUpiId ?? "-",
payDet.bankName ?? "-",
payDet.bankAccountHolderName ?? "-",
payDet.bankAccountNumber ?? "-",
payDet.bankBranchName ?? "-",
payDet.bankIfscCode ?? "-",
payDet.bankUpiId ?? "-",
];
final headings5 = [
"Level 1 Approved By",
......@@ -757,15 +757,15 @@ class _PaymentrequestionlistdetailsState
"Level 2 Remarks",
];
final subHeadings5 = [
req_det.level1Employee ?? "-",
req_det.level1ApprovalRemarks ?? "-",
req_det.level2Employee ?? "-",
req_det.level2ApprovalRemarks ?? "-",
reqDet.level1Employee ?? "-",
reqDet.level1ApprovalRemarks ?? "-",
reqDet.level2Employee ?? "-",
reqDet.level2ApprovalRemarks ?? "-",
];
final headings6 = ["Note", "Created Employee"];
final subHeadings6 = [
req_det.description ?? "-",
req_det.createdEmployee ?? "-",
reqDet.description ?? "-",
reqDet.createdEmployee ?? "-",
];
final sections = [
......@@ -873,9 +873,9 @@ class _PaymentrequestionlistdetailsState
bottom: 4,
),
child: Text(
req_det.accountName == ""
reqDet.accountName == ""
? "-"
: req_det.accountName ?? "-",
: reqDet.accountName ?? "-",
style: TextStyle(
decoration: TextDecoration.underline,
decorationStyle:
......@@ -890,9 +890,9 @@ class _PaymentrequestionlistdetailsState
),
),
Text(
req_det.amount == ""
reqDet.amount == ""
? "-"
: "₹${req_det.amount}",
: "₹${reqDet.amount}",
style: TextStyle(
fontFamily: "JakartaRegular",
fontSize: 14,
......@@ -912,16 +912,16 @@ class _PaymentrequestionlistdetailsState
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: getDecorationColor(req_det.status ?? "-"),
color: getDecorationColor(reqDet.status ?? "-"),
),
child: Center(
child: Text(
getText(req_det.status ?? "-"),
getText(reqDet.status ?? "-"),
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 14,
color: getTextColor(req_det.status),
color: getTextColor(reqDet.status),
),
),
),
......@@ -972,7 +972,7 @@ class _PaymentrequestionlistdetailsState
Column(
children: List.generate(headings.length, (j) {
if (provider.Headings[j] == "Attachment" &&
req_det.attachmentViewFileName == "") {
reqDet.attachmentViewFileName == "") {
return SizedBox.shrink();
}
return Container(
......@@ -1004,11 +1004,11 @@ class _PaymentrequestionlistdetailsState
context,
) => Fileviewer(
fileName:
req_det
reqDet
.attachmentViewFileName ??
"",
fileUrl:
req_det
reqDet
.attachmentDirFilePath ??
"",
),
......@@ -1446,8 +1446,7 @@ class _PaymentrequestionlistdetailsState
provider.selectedID = value.id!;
provider.selectedValue = value.name!;
print(
"hfjkshfg" +
provider.selectedID.toString(),
"hfjkshfg${provider.selectedID}",
);
}
}
......@@ -2151,16 +2150,9 @@ class _PaymentrequestionlistdetailsState
child: Consumer<Requesitionlidtdetailsprovider>(
builder: (context, provider, child) {
// Fallback UI if provider data is not ready
if (provider.paymentsAccounts == null) {
return Center(child: CircularProgressIndicator());
}
return Padding(
padding: EdgeInsets.only(
bottom:
MediaQuery.of(
context,
).viewInsets.bottom,
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: Container(
// Constrain the height to avoid overflow
......@@ -2261,7 +2253,8 @@ class _PaymentrequestionlistdetailsState
provider
.selectedPaymentAccounts,
onChanged: (
PaymentAccounts? value,
PaymentAccounts?
value,
) {
if (value != null &&
provider
......@@ -2301,7 +2294,8 @@ class _PaymentrequestionlistdetailsState
EdgeInsets.symmetric(
horizontal:
10,
vertical: 8,
vertical:
8,
),
hintText:
'Search account...',
......@@ -2342,7 +2336,8 @@ class _PaymentrequestionlistdetailsState
ddtheme
.buttonStyleData,
iconStyleData:
ddtheme.iconStyleData,
ddtheme
.iconStyleData,
menuItemStyleData:
ddtheme
.menuItemStyleData,
......@@ -2433,7 +2428,9 @@ class _PaymentrequestionlistdetailsState
decoration: BoxDecoration(
color: Color(0xFFE6F6FF),
borderRadius:
BorderRadius.circular(12),
BorderRadius.circular(
12,
),
border: Border.all(
color: AppColors.app_blue,
width: 0.5,
......@@ -2445,14 +2442,16 @@ class _PaymentrequestionlistdetailsState
style: TextStyle(
fontFamily:
"JakartaMedium",
color: AppColors.app_blue,
color:
AppColors.app_blue,
),
),
),
),
),
if (provider.imagePicked == 1 &&
provider.imagePath != null) ...[
provider.imagePath !=
null) ...[
Padding(
padding:
const EdgeInsets.symmetric(
......@@ -2477,8 +2476,8 @@ class _PaymentrequestionlistdetailsState
InkResponse(
onTap: () {
setState(() {
provider.imagePicked =
0;
provider
.imagePicked = 0;
provider.imagePath =
null;
provider.imageFilePath =
......@@ -2645,10 +2644,7 @@ class _PaymentrequestionlistdetailsState
builder: (context, provider, child) {
return Padding(
padding: EdgeInsets.only(
bottom:
MediaQuery.of(
context,
).viewInsets.bottom,
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: Container(
constraints: BoxConstraints(
......@@ -2680,7 +2676,8 @@ class _PaymentrequestionlistdetailsState
),
textControllerWidget(
context,
provider.editPaymentRequestedEditableAmountController,
provider
.editPaymentRequestedEditableAmountController,
"Approved Amount",
"Enter Approved Amount",
(p0) {
......@@ -2704,7 +2701,8 @@ class _PaymentrequestionlistdetailsState
provider.editPaymentProcessLoading
? null
: () {
provider.editPaymentProcessLoading = true;
provider.editPaymentProcessLoading =
true;
provider.editProcessedPaymentAmountAPIFunction(
context,
......@@ -2731,7 +2729,9 @@ class _PaymentrequestionlistdetailsState
: Text(
"Submit",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white),
style: TextStyle(
color: Colors.white,
),
),
),
),
......@@ -2801,7 +2801,7 @@ class _PaymentrequestionlistdetailsState
Navigator.of(context).pop(false);
provider.imgFromGallery(context);
},
child: Container(
child: SizedBox(
height: 35,
child: Text("Select photo from gallery"),
),
......@@ -2812,7 +2812,7 @@ class _PaymentrequestionlistdetailsState
Navigator.of(context).pop(false);
provider.imgFromCamera(context);
},
child: Container(
child: SizedBox(
height: 35,
child: Text("Capture photo from camera"),
),
......
......@@ -97,7 +97,7 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> {
"${widget.pageTitleName}",
provider.resetForm,
SizedBox.shrink(),
0xFFFFFFFF
0xFFFFFFFF,
),
body: Scrollbar(
thumbVisibility: false,
......@@ -107,7 +107,8 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> {
decoration: BoxDecoration(
color: AppColors.white,
borderRadius: BorderRadius.circular(20),
),margin: EdgeInsets.only(top: 10,left: 10,right: 10),
),
margin: EdgeInsets.only(top: 10, left: 10, right: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
......@@ -124,8 +125,7 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> {
overflow: TextOverflow.ellipsis,
),
items: [
...provider.receiptAccounts
.map(
...provider.receiptAccounts.map(
(accs) => DropdownMenuItem<Accounts>(
value: accs,
child: Text(
......@@ -134,8 +134,7 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> {
overflow: TextOverflow.ellipsis,
),
),
)
.toList(),
),
],
value: provider.selectreceiptAccounts,
onChanged: (Accounts? value) {
......@@ -148,8 +147,7 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> {
provider.receiptAccountId = value.id!;
provider.receiptAccountValue = value.name!;
print(
"hfjkshfg" +
provider.receiptAccountId.toString(),
"hfjkshfg${provider.receiptAccountId}",
);
}
}
......@@ -161,10 +159,12 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> {
searchInnerWidget: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller: provider.accountSearchController,
controller:
provider.accountSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding: const EdgeInsets.symmetric(
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
......@@ -176,7 +176,9 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> {
),
),
searchMatchFn: (item, searchValue) {
return item.value?.name?.toLowerCase().contains(
return item.value?.name
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
......@@ -233,17 +235,17 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> {
if (provider
.receiptPaymentAccounts
.isNotEmpty) {
provider.selectreceiptPaymentAccounts = value;
provider.selectreceiptPaymentAccounts =
value;
print(
"Selected Complaint Type: ${value.name}, ID: ${value.id}",
);
provider.receiptPaymentAccountsID = value.id!;
provider.receiptPaymentAccountsID =
value.id!;
provider.receiptPaymentAccountsValue =
value.name!;
print(
"hfjkshfg" +
provider.receiptPaymentAccountsID
.toString(),
"hfjkshfg${provider.receiptPaymentAccountsID}",
);
}
}
......@@ -259,7 +261,8 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> {
provider.paymentAccountSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding: const EdgeInsets.symmetric(
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
......@@ -271,7 +274,9 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> {
),
),
searchMatchFn: (item, searchValue) {
return item.value?.name?.toLowerCase().contains(
return item.value?.name
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
......@@ -281,7 +286,8 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> {
),
onMenuStateChange: (isOpen) {
if (!isOpen) {
provider.paymentAccountSearchController.clear();
provider.paymentAccountSearchController
.clear();
}
},
buttonStyleData: ddtheme.buttonStyleData,
......@@ -412,9 +418,7 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> {
provider.receiptPaymentModesValues =
value.name!;
print(
"hfjkshfg" +
provider.receiptPaymentModesID
.toString(),
"hfjkshfg${provider.receiptPaymentModesID}",
);
}
}
......@@ -774,7 +778,7 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> {
Navigator.of(context).pop(false);
provider.imgFromGallery(context);
},
child: Container(
child: SizedBox(
height: 35,
child: Text("Select photo from gallery"),
),
......@@ -785,7 +789,7 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> {
Navigator.of(context).pop(false);
provider.imgFromCamera(context);
},
child: Container(
child: SizedBox(
height: 35,
child: Text("Capture photo from camera"),
),
......
......@@ -96,13 +96,13 @@ class _DirectpaymentrequesitionlistState
return Scaffold(
resizeToAvoidBottomInset: true,
backgroundColor: AppColors.scaffold_bg_color,
appBar: appbarNew(context, "${widget.pageTitleName}",0xFFFFFFFF),
appBar: appbarNew(context, widget.pageTitleName, 0xFFFFFFFF),
body: Scrollbar(
thumbVisibility: false,
child: SingleChildScrollView(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
margin: EdgeInsets.only(top: 10,left: 10,right: 10),
margin: EdgeInsets.only(top: 10, left: 10, right: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
......@@ -149,8 +149,7 @@ class _DirectpaymentrequesitionlistState
provider.directAccountId = value.id!;
provider.directAccountValue = value.name!;
print(
"hfjkshfg" +
provider.directAccountId.toString(),
"hfjkshfg${provider.directAccountId}",
);
}
}
......@@ -162,10 +161,12 @@ class _DirectpaymentrequesitionlistState
searchInnerWidget: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller: provider.accountSearchController,
controller:
provider.accountSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding: const EdgeInsets.symmetric(
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
......@@ -177,7 +178,9 @@ class _DirectpaymentrequesitionlistState
),
),
searchMatchFn: (item, searchValue) {
return item.value?.name?.toLowerCase().contains(
return item.value?.name
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
......@@ -222,7 +225,9 @@ class _DirectpaymentrequesitionlistState
value: accs,
child: Text(
accs.name ?? '',
style: const TextStyle(fontSize: 14),
style: const TextStyle(
fontSize: 14,
),
overflow: TextOverflow.ellipsis,
),
),
......@@ -231,18 +236,20 @@ class _DirectpaymentrequesitionlistState
value: provider.selectDirectPaymentAccounts,
onChanged: (DirectPaymentAccounts? value) {
if (value != null) {
if (provider.directPaymentAccounts.isNotEmpty) {
provider.selectDirectPaymentAccounts = value;
if (provider
.directPaymentAccounts
.isNotEmpty) {
provider.selectDirectPaymentAccounts =
value;
print(
"Selected Complaint Type: ${value.name}, ID: ${value.id}",
);
provider.directPaymentAccountsID = value.id!;
provider.directPaymentAccountsID =
value.id!;
provider.directPaymentAccountsValue =
value.name!;
print(
"hfjkshfg" +
provider.directPaymentAccountsID
.toString(),
"hfjkshfg${provider.directPaymentAccountsID}",
);
}
}
......@@ -258,7 +265,8 @@ class _DirectpaymentrequesitionlistState
provider.paymentAccountSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding: const EdgeInsets.symmetric(
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
......@@ -270,7 +278,9 @@ class _DirectpaymentrequesitionlistState
),
),
searchMatchFn: (item, searchValue) {
return item.value?.name?.toLowerCase().contains(
return item.value?.name
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
......@@ -280,7 +290,8 @@ class _DirectpaymentrequesitionlistState
),
onMenuStateChange: (isOpen) {
if (!isOpen) {
provider.paymentAccountSearchController.clear();
provider.paymentAccountSearchController
.clear();
}
},
buttonStyleData: ddtheme.buttonStyleData,
......@@ -387,8 +398,9 @@ class _DirectpaymentrequesitionlistState
items:
provider.directPaymentModes
.map(
(paymenents) =>
DropdownMenuItem<DirectPaymentModes>(
(paymenents) => DropdownMenuItem<
DirectPaymentModes
>(
value: paymenents,
child: Text(
paymenents.name ?? '',
......@@ -412,9 +424,7 @@ class _DirectpaymentrequesitionlistState
provider.directPaymentModesValues =
value.name!;
print(
"hfjkshfg" +
provider.directPaymentModesID
.toString(),
"hfjkshfg${provider.directPaymentModesID}",
);
}
}
......@@ -615,7 +625,7 @@ class _DirectpaymentrequesitionlistState
),
),
],
SizedBox(height: 20,)
SizedBox(height: 20),
],
),
),
......@@ -773,7 +783,7 @@ class _DirectpaymentrequesitionlistState
Navigator.of(context).pop(false);
provider.imgFromGallery(context);
},
child: Container(
child: SizedBox(
height: 35,
child: Text("Select photo from gallery"),
),
......@@ -784,7 +794,7 @@ class _DirectpaymentrequesitionlistState
Navigator.of(context).pop(false);
provider.imgFromCamera(context);
},
child: Container(
child: SizedBox(
height: 35,
child: Text("Capture photo from camera"),
),
......
......@@ -228,7 +228,8 @@ class _FinancedashboardState extends State<Financedashboard> {
child: InkResponse(
onTap: () async {
HapticFeedback.selectionClick();
var navigate;
Allpaymentrequesitionlistsbymodes
navigate;
navigate = Allpaymentrequesitionlistsbymodes(
mode: approvalModes[co],
pageTitleName:
......
......@@ -88,11 +88,11 @@ class _PaymentdetailspaymentrequisitionState
Widget _scaffold(BuildContext context) {
return Consumer<Paymentrequisitionpaymentslistprovider>(
builder: (context, provider, child) {
var payment_det = provider.paymentDetails;
var paymentDet = provider.paymentDetails;
final headings1 = ["From Account", "Created Employee"];
final subHeadings1 = [
payment_det.paymentAccountName ?? "-",
payment_det.paymentEmployeeName ?? "-",
paymentDet.paymentAccountName ?? "-",
paymentDet.paymentEmployeeName ?? "-",
];
final headings2 = [
"Bank Name",
......@@ -103,12 +103,12 @@ class _PaymentdetailspaymentrequisitionState
"UPI ID",
];
final subHeadings2 = [
payment_det.bankName ?? "-",
payment_det.bankAccountHolderName ?? "-",
payment_det.bankAccountNumber ?? "-",
payment_det.bankBranchName ?? "-",
payment_det.bankIfscCode ?? "-",
payment_det.bankUpiId ?? "-",
paymentDet.bankName ?? "-",
paymentDet.bankAccountHolderName ?? "-",
paymentDet.bankAccountNumber ?? "-",
paymentDet.bankBranchName ?? "-",
paymentDet.bankIfscCode ?? "-",
paymentDet.bankUpiId ?? "-",
];
final headings3 = [
"Payment Mode",
......@@ -117,10 +117,10 @@ class _PaymentdetailspaymentrequisitionState
"Payment Date",
];
final subHeadings3 = [
payment_det.mode ?? "-",
payment_det.paymentReferenceNumber ?? "-",
paymentDet.mode ?? "-",
paymentDet.paymentReferenceNumber ?? "-",
"View",
payment_det.paymentDate ?? "-",
paymentDet.paymentDate ?? "-",
];
final sections = [
......@@ -194,7 +194,7 @@ class _PaymentdetailspaymentrequisitionState
MaterialPageRoute(
builder:
(context) => Accountslistdetails(
accountID: payment_det.accountId,
accountID: paymentDet.accountId,
),
),
);
......@@ -204,7 +204,7 @@ class _PaymentdetailspaymentrequisitionState
vertical: 6,
),
child: Text(
payment_det.accountName ?? "-",
paymentDet.accountName ?? "-",
style: TextStyle(
decoration: TextDecoration.underline,
decorationColor: AppColors.grey_thick,
......@@ -219,7 +219,7 @@ class _PaymentdetailspaymentrequisitionState
),
),
Text(
"₹${payment_det.amount}",
"₹${paymentDet.amount}",
style: TextStyle(
fontFamily: "JakartaRegular",
fontSize: 14,
......@@ -243,7 +243,7 @@ class _PaymentdetailspaymentrequisitionState
),
child: Center(
child: Text(
payment_det.refType ?? "-",
paymentDet.refType ?? "-",
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: "JakartaMedium",
......@@ -316,23 +316,27 @@ class _PaymentdetailspaymentrequisitionState
),
Expanded(
child: InkResponse(
onTap: [
onTap:
[
"Attachment",
"From Account",
"Created Employee",
].contains(headings[j]) ? () {
switch(headings[j]){
].contains(headings[j])
? () {
switch (headings[j]) {
case "Attachment":
Navigator.push(
context,
MaterialPageRoute(
builder:
(context) => Fileviewer(
(
context,
) => Fileviewer(
fileName:
payment_det
paymentDet
.attachmentViewFileName!,
fileUrl:
payment_det
paymentDet
.attachmentDirFilePath!,
),
),
......@@ -343,8 +347,12 @@ class _PaymentdetailspaymentrequisitionState
context,
MaterialPageRoute(
builder:
(context) => Accountslistdetails(
accountID: payment_det.paymentAccountId,
(
context,
) => Accountslistdetails(
accountID:
paymentDet
.paymentAccountId,
),
),
);
......@@ -354,15 +362,19 @@ class _PaymentdetailspaymentrequisitionState
context,
MaterialPageRoute(
builder:
(context) => Accountslistdetails(
accountID: payment_det.createdEmployeeId,
(
context,
) => Accountslistdetails(
accountID:
paymentDet
.createdEmployeeId,
),
),
);
break;
}
} : null,
}
: null,
child: Padding(
padding: EdgeInsets.only(
top: 2.5,
......@@ -395,7 +407,8 @@ class _PaymentdetailspaymentrequisitionState
.solid
: TextDecorationStyle
.solid,
decorationColor: [
decorationColor:
[
"From Account",
"Created Employee",
].contains(headings[j])
......@@ -470,7 +483,7 @@ class _PaymentdetailspaymentrequisitionState
Widget _scaffold1(BuildContext context) {
return Consumer<Paymentrequisitionpaymentslistprovider>(
builder: (context, provider, child) {
var payment_det = provider.paymentDetails;
var paymentDet = provider.paymentDetails;
return Scaffold(
resizeToAvoidBottomInset: true,
......@@ -510,7 +523,7 @@ class _PaymentdetailspaymentrequisitionState
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
payment_det.accountName ?? "-",
paymentDet.accountName ?? "-",
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 14,
......@@ -518,7 +531,7 @@ class _PaymentdetailspaymentrequisitionState
),
),
Text(
"₹${payment_det.amount}",
"₹${paymentDet.amount}",
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 14,
......@@ -542,7 +555,7 @@ class _PaymentdetailspaymentrequisitionState
),
child: Center(
child: Text(
payment_det.refType ?? "-",
paymentDet.refType ?? "-",
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: "JakartaMedium",
......@@ -558,7 +571,7 @@ class _PaymentdetailspaymentrequisitionState
Divider(thickness: 0.5, color: Color(0xFFD7D7D7)),
...List.generate(provider.subHeadings.length, (j) {
if (provider.Headings[j] == "Attachment" &&
payment_det.attachmentViewFileName == "") {
paymentDet.attachmentViewFileName == "") {
return SizedBox.shrink();
}
return Container(
......@@ -586,10 +599,10 @@ class _PaymentdetailspaymentrequisitionState
builder:
(context) => Fileviewer(
fileName:
payment_det
paymentDet
.attachmentViewFileName!,
fileUrl:
payment_det
paymentDet
.attachmentDirFilePath!,
),
),
......
import 'dart:io';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart';
......@@ -13,7 +12,6 @@ import '../../Utils/app_colors.dart';
import '../../Utils/commonServices.dart';
import '../../Utils/commonWidgets.dart';
import '../commonDateRangeFilter.dart';
import 'FileViewer.dart';
class Paymentlistpaymentrequisition extends StatefulWidget {
final String pageTitleName;
......@@ -66,7 +64,6 @@ class _PaymentlistpaymentrequisitionState
super.dispose();
}
@override
Widget build(BuildContext context) {
switch (_source.keys.toList()[0]) {
......@@ -146,10 +143,11 @@ class _PaymentlistpaymentrequisitionState
),
],
),
0xFFFFFFFF
0xFFFFFFFF,
),
backgroundColor: AppColors.scaffold_bg_color,
body: provider.isLoading
body:
provider.isLoading
? Center(
child: CircularProgressIndicator.adaptive(
valueColor: AlwaysStoppedAnimation<Color>(
......@@ -163,15 +161,16 @@ class _PaymentlistpaymentrequisitionState
thumbVisibility: false,
child: ListView.builder(
controller: _scrollController,
itemCount: requestLists.length +
(provider.hasMoreData ? 1 : 0),
itemCount:
requestLists.length + (provider.hasMoreData ? 1 : 0),
itemBuilder: (context, index) {
if (index == requestLists.length) {
return provider.isLoadingMore
? const Padding(
padding: EdgeInsets.all(16),
child: Center(
child: CircularProgressIndicator()),
child: CircularProgressIndicator(),
),
)
: const SizedBox.shrink();
}
......@@ -186,14 +185,12 @@ class _PaymentlistpaymentrequisitionState
builder:
(context) =>
Paymentdetailspaymentrequisition(
pageName:
widget.pageTitleName,
pageName: widget.pageTitleName,
paymentRequestId:
requestLists[index].id,
),
settings: RouteSettings(
name:
"Paymentdetailspaymentrequisition",
name: "Paymentdetailspaymentrequisition",
),
),
);
......@@ -229,7 +226,7 @@ class _PaymentlistpaymentrequisitionState
padding: EdgeInsets.all(3.0),
decoration: BoxDecoration(
color: AppColors.requested_bg_color,
shape: BoxShape.circle
shape: BoxShape.circle,
),
child: SvgPicture.asset(
"assets/svg/finance/rupee_ic.svg",
......@@ -282,11 +279,8 @@ class _PaymentlistpaymentrequisitionState
),
),
),
],
),
],
),
),
......
......@@ -85,12 +85,12 @@ class _PaymentreceiptdetailsState extends State<Paymentreceiptdetails> {
Widget _scaffold(BuildContext context) {
return Consumer<Paymentreceiptsprovider>(
builder: (context, provider, child) {
var payment_det = provider.receiptDetails;
var paymentDet = provider.receiptDetails;
final headings1 = ["Payment Mode", "Receipt Date"];
final subHeadings1 = [
payment_det.requestMode ?? "-",
payment_det.receiptDate ?? "-",
paymentDet.requestMode ?? "-",
paymentDet.receiptDate ?? "-",
];
final headings2 = [
"Bank Name",
......@@ -101,17 +101,17 @@ class _PaymentreceiptdetailsState extends State<Paymentreceiptdetails> {
"UPI ID",
];
final subHeadings2 = [
payment_det.bankName ?? "-",
payment_det.bankAccountHolderName ?? "-",
payment_det.bankAccountNumber ?? "-",
payment_det.bankBranchName ?? "-",
payment_det.bankIfscCode ?? "-",
payment_det.bankUpiId ?? "-",
paymentDet.bankName ?? "-",
paymentDet.bankAccountHolderName ?? "-",
paymentDet.bankAccountNumber ?? "-",
paymentDet.bankBranchName ?? "-",
paymentDet.bankIfscCode ?? "-",
paymentDet.bankUpiId ?? "-",
];
final headings3 = ["Note", "Created Employee"];
final subHeadings3 = [
payment_det.description ?? "-",
payment_det.createdEmployee ?? "-",
paymentDet.description ?? "-",
paymentDet.createdEmployee ?? "-",
];
final sections = [
......@@ -189,7 +189,10 @@ class _PaymentreceiptdetailsState extends State<Paymentreceiptdetails> {
MaterialPageRoute(
builder:
(context) => Accountslistdetails(
accountID: provider.receiptDetails.accountId,
accountID:
provider
.receiptDetails
.accountId,
),
),
);
......@@ -199,7 +202,7 @@ class _PaymentreceiptdetailsState extends State<Paymentreceiptdetails> {
vertical: 6,
),
child: Text(
payment_det.receipientAccount ?? "-",
paymentDet.receipientAccount ?? "-",
style: TextStyle(
decoration: TextDecoration.underline,
decorationColor: AppColors.grey_thick,
......@@ -214,7 +217,7 @@ class _PaymentreceiptdetailsState extends State<Paymentreceiptdetails> {
),
),
Text(
"₹${payment_det.amount}",
"₹${paymentDet.amount}",
style: TextStyle(
fontFamily: "JakartaRegular",
fontSize: 14,
......@@ -351,7 +354,7 @@ class _PaymentreceiptdetailsState extends State<Paymentreceiptdetails> {
Widget _scaffold1(BuildContext context) {
return Consumer<Paymentreceiptsprovider>(
builder: (context, provider, child) {
var payment_det = provider.receiptDetails;
var paymentDet = provider.receiptDetails;
return Scaffold(
resizeToAvoidBottomInset: true,
......@@ -392,7 +395,7 @@ class _PaymentreceiptdetailsState extends State<Paymentreceiptdetails> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
payment_det.receipientAccount ?? "-",
paymentDet.receipientAccount ?? "-",
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 14,
......@@ -400,7 +403,7 @@ class _PaymentreceiptdetailsState extends State<Paymentreceiptdetails> {
),
),
Text(
"₹${payment_det.amount}",
"₹${paymentDet.amount}",
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 14,
......@@ -416,7 +419,7 @@ class _PaymentreceiptdetailsState extends State<Paymentreceiptdetails> {
Divider(thickness: 0.5, color: Color(0xFFD7D7D7)),
...List.generate(provider.subHeadings.length, (j) {
if (provider.Headings[j] == "Attachment" &&
payment_det.attachmentViewFileName == "") {
paymentDet.attachmentViewFileName == "") {
return SizedBox.shrink();
}
return Container(
......@@ -444,10 +447,10 @@ class _PaymentreceiptdetailsState extends State<Paymentreceiptdetails> {
builder:
(context) => Fileviewer(
fileName:
payment_det
paymentDet
.attachmentViewFileName!,
fileUrl:
payment_det
paymentDet
.attachmentDirFilePath!,
),
),
......
import 'dart:io';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart';
......@@ -15,7 +14,6 @@ import '../../Utils/app_colors.dart';
import '../../Utils/commonServices.dart';
import '../../Utils/commonWidgets.dart';
import '../commonDateRangeFilter.dart';
import 'FileViewer.dart';
class Paymentreceiptlist extends StatefulWidget {
final String pageTitleName;
......@@ -63,7 +61,6 @@ class _PaymentreceiptlistState extends State<Paymentreceiptlist> {
super.dispose();
}
@override
Widget build(BuildContext context) {
switch (_source.keys.toList()[0]) {
......@@ -147,7 +144,8 @@ class _PaymentreceiptlistState extends State<Paymentreceiptlist> {
0xFFFFFFFF,
),
backgroundColor: AppColors.scaffold_bg_color,
body: provider.isLoading
body:
provider.isLoading
? Center(
child: CircularProgressIndicator.adaptive(
valueColor: AlwaysStoppedAnimation<Color>(
......@@ -168,7 +166,8 @@ class _PaymentreceiptlistState extends State<Paymentreceiptlist> {
? const Padding(
padding: EdgeInsets.all(16),
child: Center(
child: CircularProgressIndicator()),
child: CircularProgressIndicator(),
),
)
: const SizedBox.shrink();
}
......@@ -183,8 +182,7 @@ class _PaymentreceiptlistState extends State<Paymentreceiptlist> {
builder:
(context) => Paymentreceiptdetails(
pageName: widget.pageTitleName,
paymentRequestId:
requestLists[index].id,
paymentRequestId: requestLists[index].id,
),
settings: RouteSettings(
name: "Paymentreceiptdetails",
......
......@@ -41,7 +41,7 @@ class _SubmitpaymentrequestionlistsbymodeState
Dropdowntheme ddtheme = Dropdowntheme();
List<FocusNode> focusNodes = List.generate(11, (index) => FocusNode());
GlobalKey _globalKey = GlobalKey();
final GlobalKey _globalKey = GlobalKey();
ScrollController scrollcontroller = ScrollController();
@override
......@@ -63,7 +63,7 @@ class _SubmitpaymentrequestionlistsbymodeState
if (widget.mode == "self" && provider.accounts.length == 1) {
provider.selectedAccount = provider.accounts.first;
provider.accountId = provider.accounts.first.id!;
} else if (widget.mode == "other" && provider.accounts != null) {
} else if (widget.mode == "other") {
if (widget.accountId != null) {
provider.selectedAccount = provider.accounts.firstWhereOrNull(
(element) => element.id == widget.accountId,
......@@ -72,11 +72,11 @@ class _SubmitpaymentrequestionlistsbymodeState
print("sdsd,al;,al${provider.selectedAccount!.name}");
provider.accountId =
provider.accounts
.firstWhere((e) => e.id == widget.accountId)!
.firstWhere((e) => e.id == widget.accountId)
.id!;
provider.accountValue =
provider.accounts
.firstWhere((e) => e.id == widget.accountId)!
.firstWhere((e) => e.id == widget.accountId)
.name!;
}
}
......@@ -115,7 +115,6 @@ class _SubmitpaymentrequestionlistsbymodeState
autofill(res) {
print("auto");
var provider = Provider.of<Requestionlistprovider>(context, listen: false);
if (provider.accounts != null) {
provider.selectedAccount = provider.accounts.firstWhereOrNull(
(element) => element.id == res,
);
......@@ -124,7 +123,6 @@ class _SubmitpaymentrequestionlistsbymodeState
provider.accountValue =
provider.accounts.firstWhere((e) => e.id == res).name!;
}
}
Future<bool> _onBackPressed(BuildContext context) async {
Navigator.pop(context, true);
......@@ -178,14 +176,14 @@ class _SubmitpaymentrequestionlistsbymodeState
backgroundColor: AppColors.scaffold_bg_color,
appBar: appbar2New(
context,
"${widget.pageTitleName}",
widget.pageTitleName,
provider.resetForm,
SizedBox(width: 0),
0xFFFFFFFF
0xFFFFFFFF,
),
body: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
margin: EdgeInsets.only(top: 10,left: 10,right: 10),
margin: EdgeInsets.only(top: 10, left: 10, right: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
......@@ -235,8 +233,7 @@ class _SubmitpaymentrequestionlistsbymodeState
);
provider.accountId = value.id!;
print(
"hfjkshfg" +
provider.accountId.toString(),
"hfjkshfg${provider.accountId}",
);
provider
.paymentRequestionBankDetailsAPIFunction(
......@@ -303,7 +300,7 @@ class _SubmitpaymentrequestionlistsbymodeState
),
),
);
print("return Response: ${res}");
print("return Response: $res");
if (res != true) {
provider.addPaymentRequestionViewAPI(
context,
......@@ -371,12 +368,9 @@ class _SubmitpaymentrequestionlistsbymodeState
onChanged: (String? value) {
if (value != null) {
provider.selectReqPurpose = value;
print("Selected Complaint Type: ${value},");
print("Selected Complaint Type: $value,");
print(
"hfjkshfg" +
provider.selectReqPurpose.toString(),
);
print("hfjkshfg${provider.selectReqPurpose}");
}
},
buttonStyleData: ddtheme.buttonStyleData,
......@@ -473,16 +467,13 @@ class _SubmitpaymentrequestionlistsbymodeState
);
provider.paymentModeId = value.id!;
provider.paymentModeValue = value.name!;
print(
"hfjkshfg" +
provider.paymentModeId.toString(),
);
print("hfjkshfg${provider.paymentModeId}");
if ([
"Cheque",
"RTGS",
"IMPS",
"NEFT",
"UPI"
"UPI",
].contains(provider.paymentModeValue)) {
WidgetsBinding.instance
.addPostFrameCallback((_) {
......@@ -554,10 +545,7 @@ class _SubmitpaymentrequestionlistsbymodeState
value.id!;
provider.selectedApprovalEmployeeValue =
value.name!;
print(
"hfjkshfg" +
provider.paymentModeId.toString(),
);
print("hfjkshfg${provider.paymentModeId}");
}
}
},
......@@ -648,8 +636,6 @@ class _SubmitpaymentrequestionlistsbymodeState
"IMPS",
"NEFT",
].contains(provider.paymentModeValue)) ...[
textControllerWidget(
context,
provider.bankNameController,
......@@ -748,7 +734,7 @@ class _SubmitpaymentrequestionlistsbymodeState
),
errorWidget(context, provider.UPIError),
SizedBox(height: 20,)
SizedBox(height: 20),
],
],
),
......@@ -851,7 +837,7 @@ class _SubmitpaymentrequestionlistsbymodeState
Navigator.of(context).pop(false);
provider.imgFromGallery(context);
},
child: Container(
child: SizedBox(
height: 35,
child: Text("Select photo from gallery"),
),
......@@ -862,7 +848,7 @@ class _SubmitpaymentrequestionlistsbymodeState
Navigator.of(context).pop(false);
provider.imgFromCamera(context);
},
child: Container(
child: SizedBox(
height: 35,
child: Text("Capture photo from camera"),
),
......
......@@ -20,7 +20,6 @@ class Complainthistory extends StatefulWidget {
}
class _ComplainthistoryState extends State<Complainthistory> {
Map _source = {ConnectivityResult.mobile: true};
final MyConnectivity _connectivity = MyConnectivity.instance;
......@@ -48,6 +47,7 @@ class _ComplainthistoryState extends State<Complainthistory> {
);
});
}
@override
void dispose() {
// TODO: implement dispose
......@@ -68,13 +68,14 @@ class _ComplainthistoryState extends State<Complainthistory> {
default:
connection = 'Offline';
}
return connection=="Online"?Consumer<Generatordetailsprovider>(
return connection == "Online"
? Consumer<Generatordetailsprovider>(
builder: (context, provider, child) {
return WillPopScope(
onWillPop: () => onBackPressed(context),
child: SafeArea(
top: false,
bottom: Platform.isIOS?false:true,
bottom: Platform.isIOS ? false : true,
child: Scaffold(
resizeToAvoidBottomInset: true,
appBar: appbar(context, "Complaint History"),
......@@ -93,12 +94,16 @@ class _ComplainthistoryState extends State<Complainthistory> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(left: 8.0,top: 5.0),
padding: const EdgeInsets.only(
left: 8.0,
top: 5.0,
),
child: Text(
"${provider.complaintListOther[l].compRegdate}",
style: TextStyle(
fontSize:14,
color: Color(0xFF818181)),
fontSize: 14,
color: Color(0xFF818181),
),
),
),
Container(
......@@ -121,10 +126,18 @@ class _ComplainthistoryState extends State<Complainthistory> {
];
final values = [
provider.complaintListOther[l].techName,
provider.complaintListOther[l].compType,
provider.complaintListOther[l].compStatus,
provider.complaintListOther[l].createdBy,
provider
.complaintListOther[l]
.techName,
provider
.complaintListOther[l]
.compType,
provider
.complaintListOther[l]
.compStatus,
provider
.complaintListOther[l]
.createdBy,
];
return Container(
padding: EdgeInsets.symmetric(
......@@ -132,14 +145,15 @@ class _ComplainthistoryState extends State<Complainthistory> {
vertical: 6,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Expanded(
child: SizedBox(
child: Text(
"${headings[jndex]}",
headings[jndex],
style: TextStyle(
fontSize: 14
fontSize: 14,
),
),
),
......@@ -149,9 +163,8 @@ class _ComplainthistoryState extends State<Complainthistory> {
child: Text(
"${values[jndex]}",
style: TextStyle(
fontSize:14,
fontSize: 14,
color: Color(
0xFF818181,
),
),
......@@ -180,6 +193,7 @@ class _ComplainthistoryState extends State<Complainthistory> {
),
);
},
):NoNetwork(context);
)
: NoNetwork(context);
}
}
......@@ -877,7 +877,10 @@ class _GeneratordetailsState extends State<Generatordetails> {
vertical: 10,
),
child: Text(
"${provider.scheduleList[lp].status ?? "-"}",
provider
.scheduleList[lp]
.status ??
"-",
textAlign:
TextAlign.center,
style: TextStyle(
......@@ -1194,7 +1197,10 @@ class _GeneratordetailsState extends State<Generatordetails> {
vertical: 10,
),
child: Text(
"${provider.complaintsList[lp].openStatus ?? "-"}",
provider
.complaintsList[lp]
.openStatus ??
"-",
textAlign:
TextAlign.center,
style: TextStyle(
......@@ -1956,7 +1962,7 @@ class _GeneratordetailsState extends State<Generatordetails> {
Expanded(
child: SizedBox(
child: Text(
"${headings[jndex]}",
headings[jndex],
style: TextStyle(
fontSize: 14,
),
......@@ -2081,7 +2087,7 @@ class _GeneratordetailsState extends State<Generatordetails> {
Expanded(
child: SizedBox(
child: Text(
"${headings[jndex]}",
headings[jndex],
style: TextStyle(
fontSize: 14,
),
......@@ -2622,7 +2628,7 @@ class _TagLocationScreenState extends State<TagLocationScreen> {
Navigator.of(context).pop(false);
provider.imgFromCamera();
},
child: Container(
child: SizedBox(
height: 35,
child: Text("Capture photo from camera"),
),
......
......@@ -323,14 +323,11 @@ class _RegistercomplaintState extends State<Registercomplaint> {
"Selected Complaint Type: ${value.name}, ID: ${value.id}",
);
provider.selectedType =
value?.name;
value.name;
provider.selectedTypeId =
value?.id;
value.id;
print(
"hfjkshfg" +
provider
.selectedTypeId
.toString(),
"hfjkshfg${provider.selectedTypeId}",
);
}
}
......
......@@ -4,7 +4,6 @@ import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:generp/Notifiers/GeneratorDetailsProvider.dart';
import 'package:generp/Utils/commonServices.dart';
import 'package:generp/services/api_calling.dart';
import 'package:provider/provider.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
......
......@@ -11,7 +11,7 @@ import '../../Utils/app_colors.dart';
import '../../Utils/dropdownTheme.dart';
class AddLiveAttendanceScreen extends StatefulWidget {
const AddLiveAttendanceScreen({Key? key}) : super(key: key);
const AddLiveAttendanceScreen({super.key});
@override
State<AddLiveAttendanceScreen> createState() =>
......@@ -63,8 +63,10 @@ class _AddLiveAttendanceScreenState extends State<AddLiveAttendanceScreen> {
final coords = "${position.latitude},${position.longitude}";
// Convert to address for display
final placemarks =
await placemarkFromCoordinates(position.latitude, position.longitude);
final placemarks = await placemarkFromCoordinates(
position.latitude,
position.longitude,
);
String displayAddress;
if (placemarks.isNotEmpty) {
......@@ -81,10 +83,9 @@ class _AddLiveAttendanceScreenState extends State<AddLiveAttendanceScreen> {
});
}
// Add this field at the top of your State class:
// Add this field at the top of your State class:
String? _rawCoordinates;
Future<String> getCurrentLocation() async {
try {
LocationPermission permission = await Geolocator.checkPermission();
......@@ -99,10 +100,13 @@ class _AddLiveAttendanceScreenState extends State<AddLiveAttendanceScreen> {
}
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
desiredAccuracy: LocationAccuracy.high,
);
List<Placemark> placemarks =
await placemarkFromCoordinates(position.latitude, position.longitude);
List<Placemark> placemarks = await placemarkFromCoordinates(
position.latitude,
position.longitude,
);
if (placemarks.isNotEmpty) {
Placemark place = placemarks.first;
......@@ -127,8 +131,9 @@ class _AddLiveAttendanceScreenState extends State<AddLiveAttendanceScreen> {
title: const Text('Camera'),
onTap: () async {
Navigator.of(context).pop();
final XFile? image =
await picker.pickImage(source: ImageSource.camera);
final XFile? image = await picker.pickImage(
source: ImageSource.camera,
);
if (image != null) {
setState(() => proofFile = image);
}
......@@ -139,8 +144,9 @@ class _AddLiveAttendanceScreenState extends State<AddLiveAttendanceScreen> {
title: const Text('Gallery'),
onTap: () async {
Navigator.of(context).pop();
final XFile? image =
await picker.pickImage(source: ImageSource.gallery);
final XFile? image = await picker.pickImage(
source: ImageSource.gallery,
);
if (image != null) {
setState(() => proofFile = image);
}
......@@ -182,7 +188,10 @@ class _AddLiveAttendanceScreenState extends State<AddLiveAttendanceScreen> {
setState(() => isSubmitting = true);
final provider = Provider.of<Attendancelistprovider>(context, listen: false);
final provider = Provider.of<Attendancelistprovider>(
context,
listen: false,
);
await provider.addAttendanceRequest(
context,
......@@ -197,8 +206,7 @@ class _AddLiveAttendanceScreenState extends State<AddLiveAttendanceScreen> {
checkOutTime:
selectedType == "Check Out" ? TimeOfDay.now().format(context) : null,
checkOutLoc: selectedType == "Check Out" ? locationController.text : null,
checkOutProof:
selectedType == "Check Out" ? File(proofFile!.path) : null,
checkOutProof: selectedType == "Check Out" ? File(proofFile!.path) : null,
note: descriptionController.text,
);
......@@ -259,11 +267,14 @@ class _AddLiveAttendanceScreenState extends State<AddLiveAttendanceScreen> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/// Type Dropdown
const Text("Type",
const Text(
"Type",
style: TextStyle(
fontSize: 15,
fontFamily: "JakartaMedium",
fontWeight: FontWeight.w500)),
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 6),
Container(
padding: const EdgeInsets.symmetric(horizontal: 2),
......@@ -280,19 +291,25 @@ class _AddLiveAttendanceScreenState extends State<AddLiveAttendanceScreen> {
style: TextStyle(
fontSize: 15,
fontFamily: "JakartaMedium",
fontWeight: FontWeight.w400),
fontWeight: FontWeight.w400,
),
),
value: selectedType,
items: types
.map((e) => DropdownMenuItem<String>(
items:
types
.map(
(e) => DropdownMenuItem<String>(
value: e,
child: Text(
e,
style: const TextStyle(
fontSize: 14, fontFamily: "JakartaMedium"),
fontSize: 14,
fontFamily: "JakartaMedium",
),
overflow: TextOverflow.ellipsis,
),
))
),
)
.toList(),
onChanged: (val) => setState(() => selectedType = val),
iconStyleData: ddtheme.iconStyleData,
......@@ -302,21 +319,27 @@ class _AddLiveAttendanceScreenState extends State<AddLiveAttendanceScreen> {
),
if (typeError != null) ...[
const SizedBox(height: 4),
Text(typeError!,
Text(
typeError!,
style: const TextStyle(
color: Colors.red,
fontSize: 13,
fontFamily: "JakartaMedium")),
fontFamily: "JakartaMedium",
),
),
],
const SizedBox(height: 16),
/// Location
Text(locationHeading,
Text(
locationHeading,
style: const TextStyle(
fontSize: 15,
fontFamily: "JakartaMedium",
fontWeight: FontWeight.w500)),
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 6),
TextField(
controller: locationController,
......@@ -324,21 +347,27 @@ class _AddLiveAttendanceScreenState extends State<AddLiveAttendanceScreen> {
),
if (locationError != null) ...[
const SizedBox(height: 4),
Text(locationError!,
Text(
locationError!,
style: const TextStyle(
color: Colors.red,
fontSize: 13,
fontFamily: "JakartaMedium")),
fontFamily: "JakartaMedium",
),
),
],
const SizedBox(height: 16),
/// Description
Text(descriptionHeading,
Text(
descriptionHeading,
style: const TextStyle(
fontSize: 15,
fontFamily: "JakartaMedium",
fontWeight: FontWeight.w500)),
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 6),
TextField(
controller: descriptionController,
......@@ -374,11 +403,14 @@ class _AddLiveAttendanceScreenState extends State<AddLiveAttendanceScreen> {
),
if (proofError != null) ...[
const SizedBox(height: 4),
Text(proofError!,
Text(
proofError!,
style: const TextStyle(
color: Colors.red,
fontSize: 13,
fontFamily: "JakartaMedium")),
fontFamily: "JakartaMedium",
),
),
],
if (proofFile != null) ...[
......@@ -388,16 +420,21 @@ class _AddLiveAttendanceScreenState extends State<AddLiveAttendanceScreen> {
const Icon(Icons.check_circle, color: Colors.green),
const SizedBox(width: 8),
Expanded(
child: Text("Attached: ${proofFile!.name}",
child: Text(
"Attached: ${proofFile!.name}",
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontFamily: "JakartaMedium", fontSize: 14))),
fontFamily: "JakartaMedium",
fontSize: 14,
),
),
),
IconButton(
icon: const Icon(Icons.close, color: Colors.red),
onPressed: () => setState(() => proofFile = null),
),
],
)
),
],
const SizedBox(height: 24),
......@@ -405,19 +442,25 @@ class _AddLiveAttendanceScreenState extends State<AddLiveAttendanceScreen> {
/// Submit Button
InkResponse(
onTap:
isSubmitEnabled && !isSubmitting ? () => submitAttendance(context) : null,
isSubmitEnabled && !isSubmitting
? () => submitAttendance(context)
: null,
child: Container(
height: 48,
alignment: Alignment.center,
decoration: BoxDecoration(
color: isSubmitEnabled
color:
isSubmitEnabled
? AppColors.app_blue
: Colors.grey.shade400,
borderRadius: BorderRadius.circular(12),
),
child: isSubmitting
child:
isSubmitting
? const CircularProgressIndicator(
color: Colors.white, strokeWidth: 2)
color: Colors.white,
strokeWidth: 2,
)
: const Text(
"Submit",
style: TextStyle(
......
......@@ -51,8 +51,14 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
// Errors
String? dateError, typeError;
String? checkInTimeError, checkInLocError, checkInDescError, checkInProofError;
String? checkOutTimeError, checkOutLocError, checkOutDescError, checkOutProofError;
String? checkInTimeError,
checkInLocError,
checkInDescError,
checkInProofError;
String? checkOutTimeError,
checkOutLocError,
checkOutDescError,
checkOutProofError;
// In your Attendancelistprovider class
CommonResponse? get addResponse => addResponse;
......@@ -132,10 +138,13 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
}
Position pos = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
desiredAccuracy: LocationAccuracy.high,
);
List<Placemark> placemarks =
await placemarkFromCoordinates(pos.latitude, pos.longitude);
List<Placemark> placemarks = await placemarkFromCoordinates(
pos.latitude,
pos.longitude,
);
if (placemarks.isNotEmpty) {
Placemark p = placemarks.first;
......@@ -147,9 +156,14 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
}
}
Future<void> _pickTime(TextEditingController controller, bool isCheckIn) async {
final TimeOfDay? picked =
await showTimePicker(context: context, initialTime: TimeOfDay.now());
Future<void> _pickTime(
TextEditingController controller,
bool isCheckIn,
) async {
final TimeOfDay? picked = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
);
if (picked != null) {
controller.text = picked.format(context);
// Clear error when time is selected
......@@ -177,16 +191,19 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
leading: const Icon(Icons.camera_alt),
title: const Text("Capture photo from camera"),
onTap: () async {
final XFile? file =
await picker.pickImage(source: ImageSource.camera);
final XFile? file = await picker.pickImage(
source: ImageSource.camera,
);
if (file != null) {
setState(() {
if (isCheckIn) {
checkInProof = file;
if (checkInProofError != null) setState(() => checkInProofError = null);
if (checkInProofError != null)
setState(() => checkInProofError = null);
} else {
checkOutProof = file;
if (checkOutProofError != null) setState(() => checkOutProofError = null);
if (checkOutProofError != null)
setState(() => checkOutProofError = null);
}
});
}
......@@ -197,16 +214,19 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
leading: const Icon(Icons.photo_library),
title: const Text("Select photo from gallery"),
onTap: () async {
final XFile? file =
await picker.pickImage(source: ImageSource.gallery);
final XFile? file = await picker.pickImage(
source: ImageSource.gallery,
);
if (file != null) {
setState(() {
if (isCheckIn) {
checkInProof = file;
if (checkInProofError != null) setState(() => checkInProofError = null);
if (checkInProofError != null)
setState(() => checkInProofError = null);
} else {
checkOutProof = file;
if (checkOutProofError != null) setState(() => checkOutProofError = null);
if (checkOutProofError != null)
setState(() => checkOutProofError = null);
}
});
}
......@@ -224,17 +244,24 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
// Reset errors first
dateError = null;
typeError = null;
checkInTimeError = checkInLocError = checkInDescError = checkInProofError = null;
checkOutTimeError = checkOutLocError = checkOutDescError = checkOutProofError = null;
checkInTimeError =
checkInLocError = checkInDescError = checkInProofError = null;
checkOutTimeError =
checkOutLocError = checkOutDescError = checkOutProofError = null;
final provider = Provider.of<Attendancelistprovider>(context, listen: false);
final provider = Provider.of<Attendancelistprovider>(
context,
listen: false,
);
// --- Date Validation (allow today, yesterday, day before yesterday) ---
if (provider.dateController.text.isEmpty) {
dateError = "Please select a date";
} else {
try {
final enteredDate = DateFormat("dd MMM yyyy").parse(provider.dateController.text);
final enteredDate = DateFormat(
"dd MMM yyyy",
).parse(provider.dateController.text);
provider.setSelectedDate(enteredDate);
final today = DateTime.now();
......@@ -242,14 +269,16 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
final dayBeforeYesterday = today.subtract(const Duration(days: 2));
// Normalize dates (ignore time part)
bool isValid = enteredDate.year == today.year &&
bool isValid =
enteredDate.year == today.year &&
enteredDate.month == today.month &&
(enteredDate.day == today.day ||
enteredDate.day == yesterday.day ||
enteredDate.day == dayBeforeYesterday.day);
if (!isValid) {
dateError = "Date must be today, yesterday, or the day before yesterday";
dateError =
"Date must be today, yesterday, or the day before yesterday";
}
} catch (e) {
dateError = "Invalid date format (use dd MMM yyyy)";
......@@ -263,18 +292,26 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
// --- Check In Validations ---
if (selectedType == "Check In" || selectedType == "Check In/Out") {
if (checkInTime.text.isEmpty) checkInTimeError = "Please select check-in time";
if (checkInLocation.text.isEmpty) checkInLocError = "Please enter check-in location";
if (checkInDescription.text.isEmpty) checkInDescError = "Please enter description";
if (checkInProof == null) checkInProofError = "Please attach check-in proof";
if (checkInTime.text.isEmpty)
checkInTimeError = "Please select check-in time";
if (checkInLocation.text.isEmpty)
checkInLocError = "Please enter check-in location";
if (checkInDescription.text.isEmpty)
checkInDescError = "Please enter description";
if (checkInProof == null)
checkInProofError = "Please attach check-in proof";
}
// --- Check Out Validations ---
if (selectedType == "Check Out" || selectedType == "Check In/Out") {
if (checkOutTime.text.isEmpty) checkOutTimeError = "Please select check-out time";
if (checkOutLocation.text.isEmpty) checkOutLocError = "Please enter check-out location";
if (checkOutDescription.text.isEmpty) checkOutDescError = "Please enter description";
if (checkOutProof == null) checkOutProofError = "Please attach check-out proof";
if (checkOutTime.text.isEmpty)
checkOutTimeError = "Please select check-out time";
if (checkOutLocation.text.isEmpty)
checkOutLocError = "Please enter check-out location";
if (checkOutDescription.text.isEmpty)
checkOutDescError = "Please enter description";
if (checkOutProof == null)
checkOutProofError = "Please attach check-out proof";
}
// --- Stop if any error ---
......@@ -288,7 +325,7 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
checkOutTimeError,
checkOutLocError,
checkOutDescError,
checkOutProofError
checkOutProofError,
].any((e) => e != null)) {
setState(() {}); // refresh UI to show error messages
return;
......@@ -297,12 +334,14 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
// --- Format date for server ---
String formattedDate = "";
try {
final parsedDate = DateFormat("dd MMM yyyy").parse(provider.dateController.text);
final parsedDate = DateFormat(
"dd MMM yyyy",
).parse(provider.dateController.text);
formattedDate = DateFormat("yyyy-MM-dd").format(parsedDate);
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Error formatting date: $e")),
);
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text("Error formatting date: $e")));
return;
}
......@@ -340,7 +379,8 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
context,
process: "Manual",
type: selectedType!,
loc: selectedType == "Check In"
loc:
selectedType == "Check In"
? checkInLocation.text
: selectedType == "Check Out"
? checkOutLocation.text
......@@ -358,7 +398,12 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
// --- Response handling ---
if (provider.addResponse != null && provider.addResponse!.error == "0") {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(provider.addResponse!.message ?? "Attendance Submitted Successfully")),
SnackBar(
content: Text(
provider.addResponse!.message ??
"Attendance Submitted Successfully",
),
),
);
// Reset fields
......@@ -377,11 +422,13 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
_fetchInitialLocation();
} else {
String errorMessage = provider.errorMessage ?? "Failed to submit attendance";
String errorMessage =
provider.errorMessage ?? "Failed to submit attendance";
if (errorMessage.contains("Check In is not Available")) {
errorMessage = "Cannot submit Check Out without a Check In record for this date";
errorMessage =
"Cannot submit Check Out without a Check In record for this date";
}
if (errorMessage.contains("2")){
if (errorMessage.contains("2")) {
errorMessage = "Only One manual Request can be added in a month !";
}
......@@ -474,11 +521,14 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
child: DropdownButton2<String>(
isExpanded: true,
hint: const Text("Select Type"),
items: types
.map((e) => DropdownMenuItem(
items:
types
.map(
(e) => DropdownMenuItem(
value: e,
child: Text(e),
))
),
)
.toList(),
value: selectedType,
onChanged: (val) {
......@@ -500,9 +550,11 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
),
errorWidget(context, typeError),
if (selectedType == "Check In" || selectedType == "Check In/Out")
if (selectedType == "Check In" ||
selectedType == "Check In/Out")
_buildSection("Check In"),
if (selectedType == "Check Out" || selectedType == "Check In/Out")
if (selectedType == "Check Out" ||
selectedType == "Check In/Out")
_buildSection("Check Out"),
SizedBox(height: 80),
......@@ -520,7 +572,8 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
color: AppColors.app_blue,
borderRadius: BorderRadius.circular(15),
),
child: provider.isSubmitting
child:
provider.isSubmitting
? CircularProgressIndicator.adaptive(
valueColor: AlwaysStoppedAnimation(AppColors.white),
)
......@@ -642,11 +695,14 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
icon: const Icon(Icons.close, color: Colors.red, size: 18),
onPressed: () {
setState(() {
if (isCheckIn) checkInProof = null;
else checkOutProof = null;
if (isCheckIn) {
checkInProof = null;
} else {
checkOutProof = null;
}
});
},
)
),
],
),
errorWidget(context, proofError),
......@@ -661,9 +717,6 @@ Widget errorWidget(BuildContext context, String? error) {
return Padding(
padding: const EdgeInsets.only(bottom: 8, left: 4),
child: Text(
error,
style: const TextStyle(color: Colors.red, fontSize: 12),
),
child: Text(error, style: const TextStyle(color: Colors.red, fontSize: 12)),
);
}
......@@ -74,7 +74,10 @@ class _AddBillScreenState extends State<AddBillScreen> {
});
Future.microtask(() {
final provider = Provider.of<TourExpensesProvider>(context, listen: false);
final provider = Provider.of<TourExpensesProvider>(
context,
listen: false,
);
provider.fetchTourExpensesAddView(context, "0"); // fresh bill
});
}
......@@ -97,13 +100,21 @@ class _AddBillScreenState extends State<AddBillScreen> {
// Function to validate all fields
bool validateFields() {
String? newPlaceError = placeController.text.isEmpty ? "Place of visit is required" : null;
String? newDaAmountError = selectedDAAmount == null ? "DA Amount is required" : null;
String? newTourTypeError = selectedTourType == null ? "Tour Type is required" : null;
String? newTourDateError = Provider.of<TourExpensesProvider>(context, listen: false).dateController.text.isEmpty
String? newPlaceError =
placeController.text.isEmpty ? "Place of visit is required" : null;
String? newDaAmountError =
selectedDAAmount == null ? "DA Amount is required" : null;
String? newTourTypeError =
selectedTourType == null ? "Tour Type is required" : null;
String? newTourDateError =
Provider.of<TourExpensesProvider>(
context,
listen: false,
).dateController.text.isEmpty
? "Tour Date is required"
: null;
String? newNoteError = noteController.text.isEmpty ? "Note is required" : null;
String? newNoteError =
noteController.text.isEmpty ? "Note is required" : null;
// Only update if there are actual changes to avoid unnecessary rebuilds
if (placeError != newPlaceError ||
......@@ -129,7 +140,20 @@ class _AddBillScreenState extends State<AddBillScreen> {
// Format date to "02 Sep 2025" format
String _formatDate(DateTime date) {
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
const months = [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec',
];
return '${date.day.toString().padLeft(2, '0')} ${months[date.month - 1]} ${date.year}';
}
......@@ -150,11 +174,15 @@ class _AddBillScreenState extends State<AddBillScreen> {
? WillPopScope(
onWillPop: () => _onBackPressed(context),
child: SafeArea(
top: false, bottom: true, child: _scaffold(context)),
top: false,
bottom: true,
child: _scaffold(context),
),
)
: _scaffold(context)
: NoNetwork(context);
}
Future<File?> pickImage(BuildContext context) async {
final ImagePicker picker = ImagePicker();
......@@ -168,7 +196,9 @@ class _AddBillScreenState extends State<AddBillScreen> {
leading: const Icon(Icons.photo_library),
title: const Text('Pick from Gallery'),
onTap: () async {
final picked = await picker.pickImage(source: ImageSource.gallery);
final picked = await picker.pickImage(
source: ImageSource.gallery,
);
Navigator.pop(ctx, picked != null ? File(picked.path) : null);
},
),
......@@ -176,7 +206,9 @@ class _AddBillScreenState extends State<AddBillScreen> {
leading: const Icon(Icons.camera_alt),
title: const Text('Take a Photo'),
onTap: () async {
final picked = await picker.pickImage(source: ImageSource.camera);
final picked = await picker.pickImage(
source: ImageSource.camera,
);
Navigator.pop(ctx, picked != null ? File(picked.path) : null);
},
),
......@@ -192,7 +224,11 @@ class _AddBillScreenState extends State<AddBillScreen> {
builder: (context, provider, _) {
if (provider.isLoading) {
return Scaffold(
body: Container(child: Center(child: CircularProgressIndicator(color: Colors.blue)),),
body: Container(
child: Center(
child: CircularProgressIndicator(color: Colors.blue),
),
),
);
}
if (provider.errorMessage != null) {
......@@ -266,21 +302,27 @@ class _AddBillScreenState extends State<AddBillScreen> {
style: TextStyle(fontSize: 14),
overflow: TextOverflow.ellipsis,
),
items: provider.daAmountList
.map((item) => DropdownMenuItem<String>(
items:
provider.daAmountList
.map(
(item) => DropdownMenuItem<String>(
value: item,
child: Text(
item,
style: const TextStyle(fontSize: 14),
style: const TextStyle(
fontSize: 14,
),
overflow: TextOverflow.ellipsis,
),
))
),
)
.toList(),
value: selectedDAAmount,
onChanged: (String? value) {
setState(() {
selectedDAAmount = value;
if (daAmountError != null) daAmountError = null;
if (daAmountError != null)
daAmountError = null;
});
},
buttonStyleData: ddtheme.buttonStyleData,
......@@ -306,21 +348,27 @@ class _AddBillScreenState extends State<AddBillScreen> {
style: TextStyle(fontSize: 14),
overflow: TextOverflow.ellipsis,
),
items: provider.tourTypeList
.map((item) => DropdownMenuItem<String>(
items:
provider.tourTypeList
.map(
(item) => DropdownMenuItem<String>(
value: item,
child: Text(
item,
style: const TextStyle(fontSize: 14),
style: const TextStyle(
fontSize: 14,
),
overflow: TextOverflow.ellipsis,
),
))
),
)
.toList(),
value: selectedTourType,
onChanged: (String? value) {
setState(() {
selectedTourType = value;
if (tourTypeError != null) tourTypeError = null;
if (tourTypeError != null)
tourTypeError = null;
});
},
buttonStyleData: ddtheme.buttonStyleData,
......@@ -337,7 +385,10 @@ class _AddBillScreenState extends State<AddBillScreen> {
TextWidget(context, "Tour Date"),
GestureDetector(
onTap: () async {
final d = await provider.showDatePickerDialog(context, isFromDate: true);
final d = await provider.showDatePickerDialog(
context,
isFromDate: true,
);
if (d != null) {
provider.dateController.text = _formatDate(d);
if (tourDateError != null) {
......@@ -362,7 +413,9 @@ class _AddBillScreenState extends State<AddBillScreen> {
fontSize: 14,
),
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(horizontal: 15),
contentPadding: EdgeInsets.symmetric(
horizontal: 15,
),
),
),
),
......@@ -393,7 +446,9 @@ class _AddBillScreenState extends State<AddBillScreen> {
const SizedBox(height: 16),
/// Travel Expenses Section
sectionHeader("Travel Expenses", onAddTap: () {
sectionHeader(
"Travel Expenses",
onAddTap: () {
showAddTravelExpenseSheet(
context,
travelExpenses,
......@@ -401,11 +456,15 @@ class _AddBillScreenState extends State<AddBillScreen> {
provider.travelTypeList,
travelImages,
);
}),
if (travelExpenses.isNotEmpty) travelExpenseList(travelExpenses),
},
),
if (travelExpenses.isNotEmpty)
travelExpenseList(travelExpenses),
/// Hotel Expenses Section
sectionHeader("Hotel Expenses", onAddTap: () {
sectionHeader(
"Hotel Expenses",
onAddTap: () {
showAddHotelExpenseSheet(
context,
hotelExpenses,
......@@ -413,11 +472,15 @@ class _AddBillScreenState extends State<AddBillScreen> {
provider,
hotelImages,
);
}),
if (hotelExpenses.isNotEmpty) hotelExpenseList(hotelExpenses),
},
),
if (hotelExpenses.isNotEmpty)
hotelExpenseList(hotelExpenses),
/// Other Expenses Section
sectionHeader("Other Expenses", onAddTap: () {
sectionHeader(
"Other Expenses",
onAddTap: () {
showAddOtherExpenseSheet(
context,
otherExpenses,
......@@ -425,8 +488,10 @@ class _AddBillScreenState extends State<AddBillScreen> {
provider,
otherImages,
);
}),
if (otherExpenses.isNotEmpty) otherExpenseList(otherExpenses),
},
),
if (otherExpenses.isNotEmpty)
otherExpenseList(otherExpenses),
const SizedBox(height: 80),
],
......@@ -434,7 +499,8 @@ class _AddBillScreenState extends State<AddBillScreen> {
),
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButtonLocation:
FloatingActionButtonLocation.centerFloat,
bottomNavigationBar: InkResponse(
onTap: () async {
// Validate all fields first
......@@ -443,22 +509,35 @@ class _AddBillScreenState extends State<AddBillScreen> {
}
String formattedDate = "";
final provider = Provider.of<TourExpensesProvider>(context, listen: false);
final provider = Provider.of<TourExpensesProvider>(
context,
listen: false,
);
tourDateError = null;
final parsedDate = DateFormat("dd MMM yyyy").parse(provider.dateController.text);
final parsedDate = DateFormat(
"dd MMM yyyy",
).parse(provider.dateController.text);
formattedDate = DateFormat("yyyy-MM-dd").format(parsedDate);
final success = await provider.addTourBill(
context: context,
placeOfVisit: placeController.text,
daAmount: selectedDAAmount ?? "",
tourType: selectedTourType ?? "",
tourDate: formattedDate,
travelExpenses: travelExpenses.map((e) => e.map((k, v) => MapEntry(k, v as dynamic))).toList(),
hotelExpenses: hotelExpenses.map((e) => e.map((k, v) => MapEntry(k, v as dynamic))).toList(),
otherExpenses: otherExpenses.map((e) => e.map((k, v) => MapEntry(k, v as dynamic))).toList(),
travelExpenses:
travelExpenses
.map((e) => e.map((k, v) => MapEntry(k, v as dynamic)))
.toList(),
hotelExpenses:
hotelExpenses
.map((e) => e.map((k, v) => MapEntry(k, v as dynamic)))
.toList(),
otherExpenses:
otherExpenses
.map((e) => e.map((k, v) => MapEntry(k, v as dynamic)))
.toList(),
travelImages: travelImages,
hotelImages: hotelImages,
otherImages: otherImages,
......@@ -468,12 +547,18 @@ class _AddBillScreenState extends State<AddBillScreen> {
print("image================== $travelImages");
if (success) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Tour Bill Submitted Successfully")),
const SnackBar(
content: Text("Tour Bill Submitted Successfully"),
),
);
Navigator.pop(context, true);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(provider.errorMessage ?? "Failed to submit bill")),
SnackBar(
content: Text(
provider.errorMessage ?? "Failed to submit bill",
),
),
);
}
},
......@@ -505,11 +590,14 @@ class _AddBillScreenState extends State<AddBillScreen> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, style: TextStyle(
Text(
title,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
fontFamily: "JakartaMedium",
)),
),
),
const SizedBox(height: 6),
Container(
height: 45,
......@@ -525,11 +613,14 @@ class _AddBillScreenState extends State<AddBillScreen> {
children: [
Icon(Icons.add, color: Colors.blue),
SizedBox(width: 6),
Text("Add Expenses", style: TextStyle(
Text(
"Add Expenses",
style: TextStyle(
color: Colors.blue,
fontSize: 14,
fontFamily: "JakartaMedium",
)),
),
),
],
),
),
......@@ -559,7 +650,6 @@ class _AddBillScreenState extends State<AddBillScreen> {
}
}
Widget travelExpenseList(List<Map<String, String>> items) {
return Container(
height: 90,
......@@ -795,14 +885,16 @@ class _AddBillScreenState extends State<AddBillScreen> {
}
Future<File?> pickFile() async {
FilePickerResult? result = await FilePicker.platform.pickFiles(type: FileType.any);
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.any,
);
if (result != null && result.files.isNotEmpty) {
return File(result.files.single.path!);
}
return null;
}
// --- Travel Expense BottomSheet ---
// --- Travel Expense BottomSheet ---
Future<void> showAddTravelExpenseSheet(
BuildContext context,
List<Map<String, String>> travelExpenses,
......@@ -856,11 +948,16 @@ class _AddBillScreenState extends State<AddBillScreen> {
// Function to validate fields and show errors if needed
bool validateFields() {
String? newFromError = fromController.text.isEmpty ? "From is required" : null;
String? newToError = toController.text.isEmpty ? "To is required" : null;
String? newTypeError = selectedTravelType == null ? "Please select type" : null;
String? newFareError = fareController.text.isEmpty ? "Fare is required" : null;
String? newBillError = billFile == null ? "Attach bill required" : null;
String? newFromError =
fromController.text.isEmpty ? "From is required" : null;
String? newToError =
toController.text.isEmpty ? "To is required" : null;
String? newTypeError =
selectedTravelType == null ? "Please select type" : null;
String? newFareError =
fareController.text.isEmpty ? "Fare is required" : null;
String? newBillError =
billFile == null ? "Attach bill required" : null;
// Only update if there are actual changes to avoid unnecessary rebuilds
if (fromError != newFromError ||
......@@ -884,7 +981,8 @@ class _AddBillScreenState extends State<AddBillScreen> {
newBillError == null;
}
Widget errorText(String? msg) => msg == null
Widget errorText(String? msg) =>
msg == null
? const SizedBox()
: Padding(
padding: const EdgeInsets.only(top: 4, left: 4),
......@@ -894,13 +992,16 @@ class _AddBillScreenState extends State<AddBillScreen> {
color: Colors.red,
fontSize: 12,
fontFamily: "JakartaMedium",
)
),
),
);
return SafeArea(
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
margin: const EdgeInsets.symmetric(
horizontal: 15,
vertical: 10,
),
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
......@@ -962,7 +1063,7 @@ class _AddBillScreenState extends State<AddBillScreen> {
TextWidget(context, "Travel Type"),
DropdownButtonHideUnderline(
child: Container(
child: SizedBox(
width: double.infinity,
child: DropdownButton2<String>(
isExpanded: true,
......@@ -971,17 +1072,20 @@ class _AddBillScreenState extends State<AddBillScreen> {
style: TextStyle(
fontSize: 14,
color: Color(0xFFB4BEC0),
)
),
items: travelTypes.map((t) =>
DropdownMenuItem(
),
items:
travelTypes
.map(
(t) => DropdownMenuItem(
value: t,
child: Text(
t,
style: TextStyle(fontSize: 14),
),
),
)
)
).toList(),
.toList(),
value: selectedTravelType,
onChanged: (val) {
updateState(() {
......@@ -992,7 +1096,10 @@ class _AddBillScreenState extends State<AddBillScreen> {
buttonStyleData: ButtonStyleData(
height: 50,
width: double.infinity,
padding: const EdgeInsets.only(left: 14, right: 14),
padding: const EdgeInsets.only(
left: 14,
right: 14,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(14),
color: AppColors.text_field_color,
......@@ -1008,8 +1115,10 @@ class _AddBillScreenState extends State<AddBillScreen> {
offset: const Offset(0, -5),
scrollbarTheme: ScrollbarThemeData(
radius: const Radius.circular(40),
thickness: MaterialStateProperty.all<double>(6),
thumbVisibility: MaterialStateProperty.all<bool>(true),
thickness: WidgetStateProperty.all<double>(6),
thumbVisibility: WidgetStateProperty.all<bool>(
true,
),
),
),
),
......@@ -1054,11 +1163,16 @@ class _AddBillScreenState extends State<AddBillScreen> {
decoration: BoxDecoration(
color: Color(0xFFE6F6FF),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColors.app_blue, width: 0.5),
border: Border.all(
color: AppColors.app_blue,
width: 0.5,
),
),
child: Center(
child: Text(
billFile == null ? "Attach Bill" : "Bill Attached",
billFile == null
? "Attach Bill"
: "Bill Attached",
style: TextStyle(
fontFamily: "JakartaMedium",
color: AppColors.app_blue,
......@@ -1078,7 +1192,7 @@ class _AddBillScreenState extends State<AddBillScreen> {
Expanded(
flex: 5,
child: Text(
"${billFile!.path.split('/').last}",
billFile!.path.split('/').last,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
......@@ -1091,7 +1205,8 @@ class _AddBillScreenState extends State<AddBillScreen> {
Expanded(
flex: 1,
child: InkResponse(
onTap: () => updateState(() => billFile = null),
onTap:
() => updateState(() => billFile = null),
child: SvgPicture.asset(
"assets/svg/ic_close.svg",
width: 15,
......@@ -1101,7 +1216,7 @@ class _AddBillScreenState extends State<AddBillScreen> {
),
],
),
)
),
],
const SizedBox(height: 20),
......@@ -1149,7 +1264,7 @@ class _AddBillScreenState extends State<AddBillScreen> {
);
}
// --- Hotel Expense BottomSheet ---
// --- Hotel Expense BottomSheet ---
Future<void> showAddHotelExpenseSheet(
BuildContext context,
List<Map<String, String>> hotelExpenses,
......@@ -1197,12 +1312,16 @@ class _AddBillScreenState extends State<AddBillScreen> {
// Function to validate fields and show errors
bool validateFields() {
String? newHotelError = hotelController.text.isEmpty ? "Hotel name required" : null;
String? newFromDateError = fromDate == null ? "From date required" : null;
String? newToDateError = toDate == null ? "To date required" : null;
String? newAmountError = amountController.text.isEmpty ? "Amount required" : null;
String? newBillError = billFile == null ? "Attach bill required" : null;
String? newHotelError =
hotelController.text.isEmpty ? "Hotel name required" : null;
String? newFromDateError =
fromDate == null ? "From date required" : null;
String? newToDateError =
toDate == null ? "To date required" : null;
String? newAmountError =
amountController.text.isEmpty ? "Amount required" : null;
String? newBillError =
billFile == null ? "Attach bill required" : null;
if (hotelError != newHotelError ||
fromDateError != newFromDateError ||
......@@ -1225,7 +1344,8 @@ class _AddBillScreenState extends State<AddBillScreen> {
newBillError == null;
}
Widget errorText(String? msg) => msg == null
Widget errorText(String? msg) =>
msg == null
? const SizedBox()
: Padding(
padding: const EdgeInsets.only(top: 4, left: 4),
......@@ -1241,7 +1361,10 @@ class _AddBillScreenState extends State<AddBillScreen> {
return SafeArea(
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
margin: const EdgeInsets.symmetric(
horizontal: 15,
vertical: 10,
),
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
......@@ -1293,11 +1416,15 @@ class _AddBillScreenState extends State<AddBillScreen> {
Expanded(
child: GestureDetector(
onTap: () async {
final d = await provider.showDatePickerDialog(context, isFromDate: true);
final d = await provider.showDatePickerDialog(
context,
isFromDate: true,
);
if (d != null) {
updateState(() {
fromDate = d;
if (fromDateError != null) fromDateError = null;
if (fromDateError != null)
fromDateError = null;
});
}
},
......@@ -1311,10 +1438,15 @@ class _AddBillScreenState extends State<AddBillScreen> {
child: Text(
fromDate == null
? "From Date"
: DateFormat("dd MMM yyyy").format(fromDate!),
: DateFormat(
"dd MMM yyyy",
).format(fromDate!),
style: TextStyle(
fontSize: 14,
color: fromDate == null ? Color(0xFFB4BEC0) : Colors.black,
color:
fromDate == null
? Color(0xFFB4BEC0)
: Colors.black,
fontFamily: "JakartaMedium",
),
),
......@@ -1326,7 +1458,10 @@ class _AddBillScreenState extends State<AddBillScreen> {
Expanded(
child: GestureDetector(
onTap: () async {
final d = await provider.showDatePickerDialog(context, isFromDate: false);
final d = await provider.showDatePickerDialog(
context,
isFromDate: false,
);
if (d != null) {
updateState(() {
toDate = d;
......@@ -1344,14 +1479,18 @@ class _AddBillScreenState extends State<AddBillScreen> {
child: Text(
toDate == null
? "To Date"
: DateFormat("dd MMM yyyy").format(toDate!),
: DateFormat(
"dd MMM yyyy",
).format(toDate!),
style: TextStyle(
fontSize: 14,
color: toDate == null ? Color(0xFFB4BEC0) : Colors.black,
color:
toDate == null
? Color(0xFFB4BEC0)
: Colors.black,
fontFamily: "JakartaMedium",
),
),
),
),
),
......@@ -1398,11 +1537,16 @@ class _AddBillScreenState extends State<AddBillScreen> {
decoration: BoxDecoration(
color: Color(0xFFE6F6FF),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColors.app_blue, width: 0.5),
border: Border.all(
color: AppColors.app_blue,
width: 0.5,
),
),
child: Center(
child: Text(
billFile == null ? "Attach Bill" : "Bill Attached",
billFile == null
? "Attach Bill"
: "Bill Attached",
style: TextStyle(
fontFamily: "JakartaMedium",
color: AppColors.app_blue,
......@@ -1419,16 +1563,22 @@ class _AddBillScreenState extends State<AddBillScreen> {
const Icon(Icons.check_circle, color: Colors.green),
const SizedBox(width: 8),
Expanded(
child: Text("Attached: ${billFile!.path.split('/').last}",
child: Text(
"Attached: ${billFile!.path.split('/').last}",
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontFamily: "JakartaMedium", fontSize: 14))),
fontFamily: "JakartaMedium",
fontSize: 14,
),
),
),
IconButton(
icon: const Icon(Icons.close, color: Colors.red),
onPressed: () => updateState(() => billFile = null),
onPressed:
() => updateState(() => billFile = null),
),
],
)
),
],
const SizedBox(height: 20),
......@@ -1476,7 +1626,7 @@ class _AddBillScreenState extends State<AddBillScreen> {
);
}
// --- Other Expense BottomSheet ---
// --- Other Expense BottomSheet ---
Future<void> showAddOtherExpenseSheet(
BuildContext context,
List<Map<String, String>> otherExpenses,
......@@ -1524,10 +1674,12 @@ class _AddBillScreenState extends State<AddBillScreen> {
// Function to validate fields and show errors
bool validateFields() {
String? newDateError = date == null ? "Date required" : null;
String? newTitleError = titleController.text.isEmpty ? "Title required" : null;
String? newAmountError = amountController.text.isEmpty ? "Amount required" : null;
String? newBillError = billFile == null ? "Attach bill required" : null;
String? newTitleError =
titleController.text.isEmpty ? "Title required" : null;
String? newAmountError =
amountController.text.isEmpty ? "Amount required" : null;
String? newBillError =
billFile == null ? "Attach bill required" : null;
if (dateError != newDateError ||
titleError != newTitleError ||
......@@ -1547,7 +1699,8 @@ class _AddBillScreenState extends State<AddBillScreen> {
newBillError == null;
}
Widget errorText(String? msg) => msg == null
Widget errorText(String? msg) =>
msg == null
? const SizedBox()
: Padding(
padding: const EdgeInsets.only(top: 4, left: 4),
......@@ -1563,7 +1716,10 @@ class _AddBillScreenState extends State<AddBillScreen> {
return SafeArea(
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
margin: const EdgeInsets.symmetric(
horizontal: 15,
vertical: 10,
),
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
......@@ -1584,7 +1740,10 @@ class _AddBillScreenState extends State<AddBillScreen> {
TextWidget(context, "Date"),
GestureDetector(
onTap: () async {
final d = await provider.showDatePickerDialog(context, isFromDate: false);
final d = await provider.showDatePickerDialog(
context,
isFromDate: false,
);
if (d != null) {
updateState(() {
date = d;
......@@ -1600,7 +1759,10 @@ class _AddBillScreenState extends State<AddBillScreen> {
),
child: Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 14, horizontal: 12),
padding: const EdgeInsets.symmetric(
vertical: 14,
horizontal: 12,
),
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(16),
......@@ -1611,7 +1773,10 @@ class _AddBillScreenState extends State<AddBillScreen> {
: DateFormat("dd MMM yyyy").format(date!),
style: TextStyle(
fontSize: 14,
color: date == null ? const Color(0xFFB4BEC0) : Colors.black,
color:
date == null
? const Color(0xFFB4BEC0)
: Colors.black,
fontFamily: "JakartaMedium",
),
),
......@@ -1678,11 +1843,16 @@ class _AddBillScreenState extends State<AddBillScreen> {
decoration: BoxDecoration(
color: Color(0xFFE6F6FF),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColors.app_blue, width: 0.5),
border: Border.all(
color: AppColors.app_blue,
width: 0.5,
),
),
child: Center(
child: Text(
billFile == null ? "Attach Bill" : "Bill Attached",
billFile == null
? "Attach Bill"
: "Bill Attached",
style: TextStyle(
fontFamily: "JakartaMedium",
color: AppColors.app_blue,
......@@ -1702,7 +1872,7 @@ class _AddBillScreenState extends State<AddBillScreen> {
Expanded(
flex: 5,
child: Text(
"${billFile!.path.split('/').last}",
billFile!.path.split('/').last,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
......@@ -1715,7 +1885,8 @@ class _AddBillScreenState extends State<AddBillScreen> {
Expanded(
flex: 1,
child: InkResponse(
onTap: () => updateState(() => billFile = null),
onTap:
() => updateState(() => billFile = null),
child: SvgPicture.asset(
"assets/svg/ic_close.svg",
width: 15,
......@@ -1725,7 +1896,7 @@ class _AddBillScreenState extends State<AddBillScreen> {
),
],
),
)
),
],
const SizedBox(height: 20),
......
......@@ -14,7 +14,11 @@ import '../finance/FileViewer.dart';
class AttendanceRequestDetailScreen extends StatefulWidget {
final String mode;
final attendanceListId;
const AttendanceRequestDetailScreen({super.key, required this.attendanceListId, required this.mode});
const AttendanceRequestDetailScreen({
super.key,
required this.attendanceListId,
required this.mode,
});
@override
State<AttendanceRequestDetailScreen> createState() =>
......@@ -23,8 +27,7 @@ class AttendanceRequestDetailScreen extends StatefulWidget {
class _AttendanceRequestDetailScreenState
extends State<AttendanceRequestDetailScreen> {
bool _actionSubmitted = false;
final bool _actionSubmitted = false;
late AttendanceDetailsProvider provider;
@override
......@@ -32,8 +35,12 @@ class _AttendanceRequestDetailScreenState
return SafeArea(
top: false,
child: ChangeNotifierProvider(
create: (_) =>
AttendanceDetailsProvider()..fetchAttendanceRequestDetail(context, widget.attendanceListId),
create:
(_) =>
AttendanceDetailsProvider()..fetchAttendanceRequestDetail(
context,
widget.attendanceListId,
),
child: Consumer<AttendanceDetailsProvider>(
builder: (context, provider, child) {
// Get screen dimensions for responsive scaling
......@@ -42,7 +49,9 @@ class _AttendanceRequestDetailScreenState
// Scale factors based on screen size
final scaleFactor = screenWidth / 360; // Base width for scaling
final textScaleFactor = MediaQuery.of(context).textScaleFactor.clamp(1.0, 1.2);
final textScaleFactor = MediaQuery.of(
context,
).textScaleFactor.clamp(1.0, 1.2);
return Scaffold(
appBar: AppBar(
......@@ -80,7 +89,9 @@ class _AttendanceRequestDetailScreenState
body: Builder(
builder: (context) {
if (provider.isLoading) {
return const Center(child: CircularProgressIndicator(color: Colors.blue,));
return const Center(
child: CircularProgressIndicator(color: Colors.blue),
);
}
// if (provider.errorMessage != null) {
// return Center(child: Text(provider.errorMessage!));
......@@ -90,10 +101,10 @@ class _AttendanceRequestDetailScreenState
}
final details = provider.response!.requestDetails!;
final checkInTime = details.status == "Requested" ? "--" : details.checkInTime;
final checkInTime =
details.status == "Requested"
? "--"
: details.checkInTime;
/// scr
return SingleChildScrollView(
......@@ -102,7 +113,9 @@ class _AttendanceRequestDetailScreenState
children: [
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16 * scaleFactor),
borderRadius: BorderRadius.circular(
16 * scaleFactor,
),
),
elevation: 0,
child: Padding(
......@@ -111,11 +124,18 @@ class _AttendanceRequestDetailScreenState
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.only(bottom: 0.5 * scaleFactor),
padding: EdgeInsets.symmetric(horizontal: 2.5 * scaleFactor, vertical: 12 * scaleFactor),
margin: EdgeInsets.only(
bottom: 0.5 * scaleFactor,
),
padding: EdgeInsets.symmetric(
horizontal: 2.5 * scaleFactor,
vertical: 12 * scaleFactor,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12 * scaleFactor),
borderRadius: BorderRadius.circular(
12 * scaleFactor,
),
),
child: Row(
children: [
......@@ -125,7 +145,9 @@ class _AttendanceRequestDetailScreenState
width: 44 * scaleFactor,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: const Color(0xFFEDF8FF), // icon bg
color: const Color(
0xFFEDF8FF,
), // icon bg
),
child: Center(
child: SvgPicture.asset(
......@@ -147,10 +169,12 @@ class _AttendanceRequestDetailScreenState
Text(
details.type ?? "-",
style: TextStyle(
decoration: TextDecoration.underline,
decoration:
TextDecoration.underline,
decorationStyle:
TextDecorationStyle.dotted,
decorationColor: AppColors.grey_thick,
decorationColor:
AppColors.grey_thick,
height: 1.2,
fontFamily: "JakartaRegular",
fontSize: 14,
......@@ -177,8 +201,12 @@ class _AttendanceRequestDetailScreenState
horizontal: 12 * scaleFactor,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6 * scaleFactor),
color: getDecorationColor(details.status)
borderRadius: BorderRadius.circular(
6 * scaleFactor,
),
color: getDecorationColor(
details.status,
),
),
child: Center(
child: Text(
......@@ -186,7 +214,9 @@ class _AttendanceRequestDetailScreenState
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w600,
color: getTextColor(details.status.toString()),
color: getTextColor(
details.status.toString(),
),
),
),
),
......@@ -196,49 +226,162 @@ class _AttendanceRequestDetailScreenState
),
// Employee Details
_buildSectionHeader("Employee Details", scaleFactor),
_buildDetailTile("Employee Name", details.employeeName, scaleFactor),
_buildDetailTile("Created Employee", details.createdEmpName, scaleFactor),
_buildSectionHeader(
"Employee Details",
scaleFactor,
),
_buildDetailTile(
"Employee Name",
details.employeeName,
scaleFactor,
),
_buildDetailTile(
"Created Employee",
details.createdEmpName,
scaleFactor,
),
// Check In/Out
_buildSectionHeader("Check In/Out Details", scaleFactor),
_buildDate_TimeTile("Check In Date & Time", details.date, details.checkInTime, scaleFactor),
_buildDate_TimeTile("Check Out Date & Time", details.date, details.checkOutTime, scaleFactor),
_buildSectionHeader(
"Check In/Out Details",
scaleFactor,
),
_buildDate_TimeTile(
"Check In Date & Time",
details.date,
details.checkInTime,
scaleFactor,
),
_buildDate_TimeTile(
"Check Out Date & Time",
details.date,
details.checkOutTime,
scaleFactor,
),
_buildDetailTile("Original Check In", checkInTime, scaleFactor),
_buildDetailTile(
"Original Check In",
checkInTime,
scaleFactor,
),
_buildDetailTile("Original Check Out", "--", scaleFactor),
_buildDetailTile("Original Check In Location", details.checkInLocation, scaleFactor),
_buildDetailTile("Original Check Out Location", details.checkOutLocation, scaleFactor),
buildLocationTile("Location", details.location, scaleFactor),
_buildDetailTile(
"Original Check Out",
"--",
scaleFactor,
),
_buildDetailTile(
"Original Check In Location",
details.checkInLocation,
scaleFactor,
),
_buildDetailTile(
"Original Check Out Location",
details.checkOutLocation,
scaleFactor,
),
buildLocationTile(
"Location",
details.location,
scaleFactor,
),
// Proofs
if ((details.checkInProofDirFilePath != null && details.checkInProofDirFilePath!.isNotEmpty) ||
(details.checkOutProofDirFilePath != null && details.checkOutProofDirFilePath!.isNotEmpty)) ...[
if ((details.checkInProofDirFilePath != null &&
details
.checkInProofDirFilePath!
.isNotEmpty) ||
(details.checkOutProofDirFilePath != null &&
details
.checkOutProofDirFilePath!
.isNotEmpty)) ...[
_buildSectionHeader("Proofs", scaleFactor),
if (details.checkInProofDirFilePath != null && details.checkInProofDirFilePath!.isNotEmpty)
_buildProofLink(context, "Check In Proof", details.checkInProofDirFilePath, scaleFactor),
if (details.checkOutProofDirFilePath != null && details.checkOutProofDirFilePath!.isNotEmpty)
_buildProofLink(context, "Check Out Proof", details.checkOutProofDirFilePath, scaleFactor),
if (details.checkInProofDirFilePath != null &&
details
.checkInProofDirFilePath!
.isNotEmpty)
_buildProofLink(
context,
"Check In Proof",
details.checkInProofDirFilePath,
scaleFactor,
),
if (details.checkOutProofDirFilePath !=
null &&
details
.checkOutProofDirFilePath!
.isNotEmpty)
_buildProofLink(
context,
"Check Out Proof",
details.checkOutProofDirFilePath,
scaleFactor,
),
],
// Remarks & Approvals
_buildSectionHeader("Remarks & Approvals", scaleFactor),
_buildDetailTile("Level 1 Approved By", details.level1EmpName, scaleFactor),
_buildDetailTile("Level 2 Approved By", details.level2EmpName, scaleFactor),
_buildDetailTile("Level 1 Remark", details.level1Remarks, scaleFactor),
_buildDetailTile("Level 2 Remark", details.level2Remarks, scaleFactor),
_buildSectionHeader(
"Remarks & Approvals",
scaleFactor,
),
_buildDetailTile(
"Level 1 Approved By",
details.level1EmpName,
scaleFactor,
),
_buildDetailTile(
"Level 2 Approved By",
details.level2EmpName,
scaleFactor,
),
_buildDetailTile(
"Level 1 Remark",
details.level1Remarks,
scaleFactor,
),
_buildDetailTile(
"Level 2 Remark",
details.level2Remarks,
scaleFactor,
),
///remain data
_buildSectionHeader("Other Details", scaleFactor),
_buildDetailTile("Check In Type", details.checkInType, scaleFactor),
_buildDetailTile("Check Out Type", details.chechOutType, scaleFactor),
_buildDetailTile("Check Out Time", details.checkOutTime, scaleFactor),
_buildSectionHeader(
"Other Details",
scaleFactor,
),
_buildDetailTile(
"Check In Type",
details.checkInType,
scaleFactor,
),
_buildDetailTile(
"Check Out Type",
details.chechOutType,
scaleFactor,
),
_buildDetailTile(
"Check Out Time",
details.checkOutTime,
scaleFactor,
),
// Attendance Info
_buildDetailTile("ID", details.id, scaleFactor),
_buildDetailTile("Attendance Type", details.attendanceType, scaleFactor),
_buildDetailTile("Note", details.note, scaleFactor),
_buildDetailTile("Created Datetime", details.requestedDatetime, scaleFactor),
_buildDetailTile(
"Attendance Type",
details.attendanceType,
scaleFactor,
),
_buildDetailTile(
"Note",
details.note,
scaleFactor,
),
_buildDetailTile(
"Created Datetime",
details.requestedDatetime,
scaleFactor,
),
],
),
),
......@@ -249,22 +392,25 @@ class _AttendanceRequestDetailScreenState
);
},
),
bottomNavigationBar: (widget.mode == "apr_lvl1"
&& !_actionSubmitted
&& provider.response?.requestDetails?.status != "Level 1 Approved"
&& provider.response?.requestDetails?.status != "Rejected")
bottomNavigationBar:
(widget.mode == "apr_lvl1" &&
!_actionSubmitted &&
provider.response?.requestDetails?.status !=
"Level 1 Approved" &&
provider.response?.requestDetails?.status !=
"Rejected")
? Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xffFFFFFF),
Color(0x00FFFFFF),
],
colors: [Color(0xffFFFFFF), Color(0x00FFFFFF)],
),
),
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 6,
),
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
height: 61,
child: Column(
children: [
......@@ -278,16 +424,24 @@ class _AttendanceRequestDetailScreenState
context: context,
actionType: "Reject",
onSubmit: (remark) {
provider.rejectApproveAttendanceRequest(
provider
.rejectApproveAttendanceRequest(
context,
mode: widget.mode,
type: "Rejected",
remarks: remark,
id: provider.response!.requestDetails!.id!,
id:
provider
.response!
.requestDetails!
.id!,
);
},
).then((_) {
provider.fetchAttendanceRequestDetail(context, widget.attendanceListId); // or setState(() {}) if needed
provider.fetchAttendanceRequestDetail(
context,
widget.attendanceListId,
); // or setState(() {}) if needed
});
},
child: Container(
......@@ -296,9 +450,12 @@ class _AttendanceRequestDetailScreenState
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
SvgPicture.asset("assets/svg/finance/level_reject_ic.svg"),
SvgPicture.asset(
"assets/svg/finance/level_reject_ic.svg",
),
const SizedBox(width: 6),
const Text("Reject"),
],
......@@ -322,16 +479,24 @@ class _AttendanceRequestDetailScreenState
context: context,
actionType: "Approve",
onSubmit: (remark) async {
await provider.rejectApproveAttendanceRequest(
await provider
.rejectApproveAttendanceRequest(
context,
mode: widget.mode,
type: "Approved",
remarks: remark,
id: provider.response!.requestDetails!.id!,
id:
provider
.response!
.requestDetails!
.id!,
);
},
).then((_) {
provider.fetchAttendanceRequestDetail(context, widget.attendanceListId); // or setState(() {}) if needed
provider.fetchAttendanceRequestDetail(
context,
widget.attendanceListId,
); // or setState(() {}) if needed
});
},
......@@ -341,9 +506,12 @@ class _AttendanceRequestDetailScreenState
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
SvgPicture.asset("assets/svg/finance/level_approve_ic.svg"),
SvgPicture.asset(
"assets/svg/finance/level_approve_ic.svg",
),
const SizedBox(width: 6),
const Text("Approve"),
],
......@@ -353,15 +521,16 @@ class _AttendanceRequestDetailScreenState
),
],
),
SizedBox(height: 0,)
SizedBox(height: 0),
],
),
)
: const SizedBox.shrink(),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked,
);
},
)
),
),
);
}
......@@ -391,7 +560,9 @@ class _AttendanceRequestDetailScreenState
bool validateFields() {
String? newRemarkError =
remarkController.text.trim().isEmpty ? "Remark required" : null;
remarkController.text.trim().isEmpty
? "Remark required"
: null;
if (remarkError != newRemarkError) {
updateState(() {
......@@ -401,7 +572,8 @@ class _AttendanceRequestDetailScreenState
return newRemarkError == null;
}
Widget errorText(String? msg) => msg == null
Widget errorText(String? msg) =>
msg == null
? const SizedBox()
: Padding(
padding: const EdgeInsets.only(top: 4, left: 4),
......@@ -417,7 +589,10 @@ class _AttendanceRequestDetailScreenState
return SafeArea(
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
margin: const EdgeInsets.symmetric(
horizontal: 15,
vertical: 10,
),
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
......@@ -463,11 +638,15 @@ class _AttendanceRequestDetailScreenState
decoration: InputDecoration(
hintText: "Enter your remark here...",
hintStyle: TextStyle(
color: Colors.grey.shade500, // Customize this color
color:
Colors.grey.shade500, // Customize this color
fontSize: 14, // Optional: tweak font size
),
border: InputBorder.none,
contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
contentPadding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 12,
),
),
),
),
......@@ -510,7 +689,9 @@ class _AttendanceRequestDetailScreenState
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Request submitted successfully"),
content: Text(
"Request submitted successfully",
),
backgroundColor: Colors.green,
behavior: SnackBarBehavior.floating,
),
......@@ -534,7 +715,6 @@ class _AttendanceRequestDetailScreenState
),
),
),
),
],
),
......@@ -549,7 +729,6 @@ class _AttendanceRequestDetailScreenState
);
}
/// Reusable Row Widget for details
Widget _buildDetailTile(String label, String? value, double scaleFactor) {
return Padding(
......@@ -569,17 +748,14 @@ class _AttendanceRequestDetailScreenState
),
),
),
SizedBox(width: 4,),
SizedBox(width: 4),
// Value
Expanded(
flex: 5, // take remaining width
child: Text(
value ?? "-",
style: const TextStyle(
fontSize: 14,
color: Color(0xFF818181),
),
style: const TextStyle(fontSize: 14, color: Color(0xFF818181)),
softWrap: true,
overflow: TextOverflow.visible, // wrap instead of clipping
),
......@@ -589,14 +765,14 @@ class _AttendanceRequestDetailScreenState
);
}
/// for location
/// Location Tile
Widget buildLocationTile(String label, String? value, double scaleFactor) {
return FutureBuilder<String>(
future: getReadableLocation(value),
builder: (context, snapshot) {
final locationText = snapshot.connectionState == ConnectionState.done
final locationText =
snapshot.connectionState == ConnectionState.done
? (snapshot.data ?? value ?? "-")
: value ?? "-";
......@@ -624,9 +800,13 @@ class _AttendanceRequestDetailScreenState
child: GestureDetector(
onTap: () async {
final uri = Uri.parse(
"https://www.google.com/maps/search/?api=1&query=$value");
"https://www.google.com/maps/search/?api=1&query=$value",
);
if (await canLaunchUrl(uri)) {
await launchUrl(uri, mode: LaunchMode.externalApplication);
await launchUrl(
uri,
mode: LaunchMode.externalApplication,
);
}
},
child: Text(
......@@ -673,7 +853,7 @@ class _AttendanceRequestDetailScreenState
place.locality, // e.g. "Hyderabad"
place.administrativeArea, // e.g. "Telangana"
place.postalCode, // e.g. "500038"
place.country // e.g. "India"
place.country, // e.g. "India"
].where((e) => e != null && e.isNotEmpty).join(", ");
return address;
......@@ -682,9 +862,13 @@ class _AttendanceRequestDetailScreenState
}
}
/// for date and time
Widget _buildDate_TimeTile(String label, String? date, String? time, double scaleFactor) {
Widget _buildDate_TimeTile(
String label,
String? date,
String? time,
double scaleFactor,
) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 6 * scaleFactor),
child: Row(
......@@ -702,7 +886,7 @@ class _AttendanceRequestDetailScreenState
),
),
),
SizedBox(width: 4,),
SizedBox(width: 4),
// Value (date + time)
Expanded(
......@@ -723,7 +907,6 @@ class _AttendanceRequestDetailScreenState
);
}
Widget _buildSectionHeader(String title, double scaleFactor) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 9 * scaleFactor),
......@@ -731,10 +914,7 @@ class _AttendanceRequestDetailScreenState
children: [
Text(
title,
style: TextStyle(
fontSize: 14,
fontFamily: "JakartaSemiBold",
),
style: TextStyle(fontSize: 14, fontFamily: "JakartaSemiBold"),
),
SizedBox(width: 10 * scaleFactor),
Expanded(
......@@ -752,7 +932,12 @@ class _AttendanceRequestDetailScreenState
}
/// Proof section (image/file path)
Widget _buildProofLink(BuildContext context, String label, String? filePath, double scaleFactor) {
Widget _buildProofLink(
BuildContext context,
String label,
String? filePath,
double scaleFactor,
) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 6 * scaleFactor),
child: Row(
......@@ -770,7 +955,8 @@ class _AttendanceRequestDetailScreenState
),
Expanded(
flex: 0,
child: filePath != null
child:
filePath != null
? InkWell(
onTap: () {
print("++++++++++++++++ImageUrel: $filePath");
......@@ -778,15 +964,9 @@ class _AttendanceRequestDetailScreenState
context,
MaterialPageRoute(
builder:
(
context,
) => Fileviewer(
fileName:
filePath ??
"",
fileUrl:
filePath ??
"",
(context) => Fileviewer(
fileName: filePath ?? "",
fileUrl: filePath ?? "",
),
),
);
......@@ -799,7 +979,7 @@ class _AttendanceRequestDetailScreenState
fontStyle: FontStyle.normal,
fontFamily: "Plus Jakarta Sans",
fontWeight: FontWeight.w400,
decoration: TextDecoration.underline
decoration: TextDecoration.underline,
),
),
)
......
......@@ -18,7 +18,7 @@ import 'AddLiveAttendance.dart';
class AttendanceListScreen extends StatefulWidget {
final mode;
const AttendanceListScreen({super.key,required this.mode});
const AttendanceListScreen({super.key, required this.mode});
@override
State<AttendanceListScreen> createState() => _AttendanceListScreenState();
......@@ -36,9 +36,9 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
@override
Widget build(BuildContext context) {
String _truncate(String text, int maxLength) {
String truncate(String text, int maxLength) {
if (text.length <= maxLength) return text;
return text.substring(0, maxLength).trim() + '...';
return '${text.substring(0, maxLength).trim()}...';
}
return SafeArea(
......@@ -54,7 +54,10 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
builder: (context, child) {
return Consumer<Attendancelistprovider>(
builder: (context, provider, child) {
final requestProvider = Provider.of<AttendanceDetailsProvider>(context, listen: false);
final requestProvider = Provider.of<AttendanceDetailsProvider>(
context,
listen: false,
);
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
......@@ -83,16 +86,21 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
actions: [
InkResponse(
onTap: () async {
final result = await CommonFilter2().showFilterBottomSheet(context);
final result = await CommonFilter2()
.showFilterBottomSheet(context);
if (result != null) {
final provider = Provider.of<Attendancelistprovider>(context, listen: false);
final provider = Provider.of<Attendancelistprovider>(
context,
listen: false,
);
provider.updateFiltersFromSheet(
widget.mode,
context,
type: result['type'] ?? "All",
selectedValue: result['selectedValue'] ?? "This Month",
selectedValue:
result['selectedValue'] ?? "This Month",
customRange: result['dateRange'],
);
}
......@@ -104,8 +112,6 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
),
const SizedBox(width: 20),
],
),
backgroundColor: const Color(0xFFF6F6F8),
body: Column(
......@@ -141,7 +147,11 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
child: Builder(
builder: (context) {
if (provider.isLoading) {
return const Center(child: CircularProgressIndicator(color: Colors.blue));
return const Center(
child: CircularProgressIndicator(
color: Colors.blue,
),
);
}
// if (provider.errorMessage != null) {
// return Center(child: Text(provider.errorMessage!));
......@@ -151,7 +161,10 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
return const Center(
child: Text(
"No attendance records found",
style: TextStyle(fontSize: 16, color: Colors.grey),
style: TextStyle(
fontSize: 16,
color: Colors.grey,
),
),
);
}
......@@ -163,59 +176,84 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
itemBuilder: (context, index) {
final item = list[index];
final canSwipe = widget.mode == "apr_lvl1" &&
final canSwipe =
widget.mode == "apr_lvl1" &&
item.status != "Level 1 Approved" &&
item.status != "Rejected";
final homeProvider = Provider.of<HomescreenNotifier>(context, listen: false);
final homeProvider =
Provider.of<HomescreenNotifier>(
context,
listen: false,
);
return Slidable(
key: ValueKey(item.id),
// Left swipe (Reject)
startActionPane: canSwipe
startActionPane:
canSwipe
? ActionPane(
motion: const ScrollMotion(),
dragDismissible: false,
children: [
SlidableAction(
onPressed: (_) {
showRemarkSheet(
context: context,
actionType: "Reject",
onSubmit: (remark) async {
await provider.rejectApproveAttendanceRequest(
session: homeProvider.session,
empId: homeProvider.empId,
await provider
.rejectApproveAttendanceRequest(
session:
homeProvider
.session,
empId:
homeProvider
.empId,
mode: widget.mode,
type: "Rejected",
remarks: remark,
id: item.id ?? "0",
);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Attendance request rejected successfully.")),
ScaffoldMessenger.of(
context,
).showSnackBar(
const SnackBar(
content: Text(
"Attendance request rejected successfully.",
),
),
);
// refresh list
provider.fetchAttendanceRequests(context, widget.mode);
provider
.fetchAttendanceRequests(
context,
widget.mode,
);
},
).then((_) {
provider.fetchAttendanceRequests(context, widget.mode); // or setState(() {}) if needed
provider.fetchAttendanceRequests(
context,
widget.mode,
); // or setState(() {}) if needed
});
},
backgroundColor: const Color(0xFFFFE5E5),
foregroundColor: const Color(0xFFEF3739),
backgroundColor: const Color(
0xFFFFE5E5,
),
foregroundColor: const Color(
0xFFEF3739,
),
icon: Icons.clear,
label: 'Reject',
),
],
)
: null,
// Right swipe (Approve)
endActionPane: canSwipe
endActionPane:
canSwipe
? ActionPane(
motion: const ScrollMotion(),
dragDismissible: false,
......@@ -226,9 +264,14 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
context: context,
actionType: "Approve",
onSubmit: (remark) async {
await provider.rejectApproveAttendanceRequest(
session: homeProvider.session,
empId: homeProvider.empId,
await provider
.rejectApproveAttendanceRequest(
session:
homeProvider
.session,
empId:
homeProvider
.empId,
mode: widget.mode,
type: "Approved",
remarks: remark,
......@@ -236,12 +279,22 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
);
},
).then((_) {
provider.fetchAttendanceRequests(context, widget.mode);
provider
.fetchAttendanceRequests(
context,
widget.mode,
);
});
print("######################################");
print(
"######################################",
);
},
backgroundColor: const Color(0xFFE9FFE8),
foregroundColor: const Color(0xFF4CB443),
backgroundColor: const Color(
0xFFE9FFE8,
),
foregroundColor: const Color(
0xFF4CB443,
),
icon: Icons.check,
label: 'Approve',
),
......@@ -255,7 +308,9 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AttendanceRequestDetailScreen(
builder:
(context) =>
AttendanceRequestDetailScreen(
attendanceListId: item.id,
mode: widget.mode,
),
......@@ -263,8 +318,14 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
);
},
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 8.5, vertical: 5),
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8.5),
margin: const EdgeInsets.symmetric(
horizontal: 8.5,
vertical: 5,
),
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 8.5,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
......@@ -284,7 +345,9 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
child: Text(
getText(item.status),
style: TextStyle(
color: _getTextColor(item.status),
color: _getTextColor(
item.status,
),
fontSize: 14,
fontWeight: FontWeight.bold,
),
......@@ -296,11 +359,15 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
/// Middle Section
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
widget.mode == "apr_lvl1"
? _truncate(item.employeeName ?? "-", 20)
? truncate(
item.employeeName ?? "-",
20,
)
: item.type ?? "-",
maxLines: 1,
overflow: TextOverflow.ellipsis,
......@@ -317,18 +384,22 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
? item.type ?? "-"
: item.type ?? "-",
style: TextStyle(
fontFamily: "JakartaRegular",
fontFamily:
"JakartaRegular",
fontSize: 14,
color: AppColors.grey_semi,
color:
AppColors.grey_semi,
),
),
const SizedBox(width: 2),
Text(
" - ${item.date}" ?? "-",
style: TextStyle(
fontFamily: "JakartaRegular",
fontFamily:
"JakartaRegular",
fontSize: 14,
color: AppColors.grey_semi,
color:
AppColors.grey_semi,
),
),
],
......@@ -344,7 +415,10 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 14,
color: (item.attendanceType ?? "").toLowerCase() == "live"
color:
(item.attendanceType ?? "")
.toLowerCase() ==
"live"
? Colors.green
: Colors.orange,
),
......@@ -356,26 +430,26 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
);
},
);
},
),
)
),
],
),
bottomNavigationBar: widget.mode == "apr_lvl1"
bottomNavigationBar:
widget.mode == "apr_lvl1"
? null
: Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
alignment: Alignment.bottomCenter,
height: 61,
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xffFFFFFF),
Color(0x00FFFFFF),
],
colors: [Color(0xffFFFFFF), Color(0x00FFFFFF)],
),
),
child: Row(
......@@ -388,28 +462,41 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddLiveAttendanceScreen(),
builder:
(context) =>
AddLiveAttendanceScreen(),
settings: const RouteSettings(
name: 'AddLiveAttendanceScreen',
),
),
).then((_) {
provider.fetchAttendanceRequests(context, widget.mode);
provider.fetchAttendanceRequests(
context,
widget.mode,
);
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset("assets/svg/hrm/live.svg"),
SvgPicture.asset(
"assets/svg/hrm/live.svg",
),
const SizedBox(width: 10),
Text("Live Request",
style: TextStyle(color: AppColors.semi_black)),
Text(
"Live Request",
style: TextStyle(
color: AppColors.semi_black,
),
),
],
),
),
),
const SizedBox(width: 10),
SvgPicture.asset("assets/svg/crm/vertical_line_ic.svg"),
SvgPicture.asset(
"assets/svg/crm/vertical_line_ic.svg",
),
const SizedBox(width: 10),
Expanded(
child: InkResponse(
......@@ -417,21 +504,33 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const AddManualAttendanceScreen(),
builder:
(context) =>
const AddManualAttendanceScreen(),
settings: const RouteSettings(
name: 'AddManualAttendanceScreen'),
name: 'AddManualAttendanceScreen',
),
),
).then((_) {
provider.fetchAttendanceRequests(context, widget.mode);
provider.fetchAttendanceRequests(
context,
widget.mode,
);
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset("assets/svg/hrm/manual.svg"),
SvgPicture.asset(
"assets/svg/hrm/manual.svg",
),
const SizedBox(width: 10),
Text("Manual Request",
style: TextStyle(color: AppColors.semi_black)),
Text(
"Manual Request",
style: TextStyle(
color: AppColors.semi_black,
),
),
],
),
),
......@@ -439,13 +538,11 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
],
),
),
);
},
);
},
)
),
);
}
......@@ -474,7 +571,9 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
bool validateFields() {
String? newRemarkError =
remarkController.text.trim().isEmpty ? "Remark required" : null;
remarkController.text.trim().isEmpty
? "Remark required"
: null;
if (remarkError != newRemarkError) {
updateState(() {
......@@ -484,7 +583,8 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
return newRemarkError == null;
}
Widget errorText(String? msg) => msg == null
Widget errorText(String? msg) =>
msg == null
? const SizedBox()
: Padding(
padding: const EdgeInsets.only(top: 4, left: 4),
......@@ -500,7 +600,10 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
return SafeArea(
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
margin: const EdgeInsets.symmetric(
horizontal: 15,
vertical: 10,
),
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
......@@ -546,11 +649,15 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
decoration: InputDecoration(
hintText: "Enter your remark here...",
hintStyle: TextStyle(
color: Colors.grey.shade500, // Customize this color
color:
Colors.grey.shade500, // Customize this color
fontSize: 14, // Optional: tweak font size
),
border: InputBorder.none,
contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
contentPadding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 12,
),
),
),
),
......@@ -593,7 +700,9 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Request submitted successfully"),
content: Text(
"Request submitted successfully",
),
backgroundColor: Colors.green,
behavior: SnackBarBehavior.floating,
),
......@@ -617,7 +726,6 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
),
),
),
),
],
),
......@@ -632,8 +740,6 @@ class _AttendanceListScreenState extends State<AttendanceListScreen> {
);
}
/// Avatar color generator
Color _getAvatarColor(value) {
var color = AppColors.approved_bg_color;
......
......@@ -3,11 +3,9 @@ import 'package:flutter_svg/svg.dart';
import 'package:generp/screens/hrm/Attendancelist.dart';
import 'package:provider/provider.dart';
import '../../Utils/app_colors.dart';
import 'AttendanceRequestDetail.dart';
import 'LeaveApplicationScreen.dart';
import 'TourExpensesListScreen.dart';
import 'RewardListScreen.dart';
import 'OrganizationStructureScreen.dart';
import '../../Notifiers/hrmProvider/hrmAccessiblePagesProvider.dart';
import 'oggchart.dart';
......@@ -31,9 +29,12 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
@override
void initState() {
super.initState();
Future.microtask(() =>
Provider.of<HrmAccessiblePagesProvider>(context, listen: false)
.fetchAccessiblePages(context));
Future.microtask(
() => Provider.of<HrmAccessiblePagesProvider>(
context,
listen: false,
).fetchAccessiblePages(context),
);
}
@override
......@@ -122,10 +123,14 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
const SizedBox(height: 32),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 8),
horizontal: 20,
vertical: 8,
),
decoration: BoxDecoration(
border: Border.all(
color: const Color(0xFF1487C9), // border color
color: const Color(
0xFF1487C9,
), // border color
width: 1.2, // thickness of the border
),
color: const Color(0xffEDF8FF),
......@@ -152,9 +157,17 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
const SizedBox(width: 7),
const Text(
"Organization Structure",
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500, fontStyle: FontStyle.normal, fontFamily: "Plus Jakarta Sans"),
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w500,
fontStyle: FontStyle.normal,
fontFamily: "Plus Jakarta Sans",
),
),
const Icon(
Icons.chevron_right,
color: Colors.black54,
),
const Icon(Icons.chevron_right, color: Colors.black54),
],
),
),
......@@ -167,29 +180,42 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
LayoutBuilder(
builder: (context, constraints) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 10),
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 10,
),
child: Consumer<HrmAccessiblePagesProvider>(
builder: (context, provider, child) {
if (provider.isLoading) {
return const Center(
child: CircularProgressIndicator());
child: CircularProgressIndicator(),
);
}
if (provider.errorMessage != null) {
return Center(
child: Text(provider.errorMessage!));
child: Text(provider.errorMessage!),
);
}
final pages = (provider.response?.pagesAccessible ?? [])
.where((page) =>
allowedPages.contains(page.pageName))
final pages =
(provider.response?.pagesAccessible ?? [])
.where(
(page) => allowedPages.contains(
page.pageName,
),
)
.toList();
return GridView.builder(
itemCount: pages.length,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: (constraints.maxWidth / 180).floor().clamp(2, 4),
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: (constraints.maxWidth /
180)
.floor()
.clamp(2, 4),
crossAxisSpacing: 1,
mainAxisSpacing: 2,
childAspectRatio: 1.8,
......@@ -199,10 +225,13 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
return _buildTile(
label: page.pageName ?? "",
subtitle: _getSubtitle(page.pageName ?? ""),
subtitle: _getSubtitle(
page.pageName ?? "",
),
assetIcon: _getIcon(page.pageName ?? ""),
txtColor: const Color(0xff1487C9),
onTap: () => _handleNavigation(
onTap:
() => _handleNavigation(
context,
page.pageName ?? "",
page.mode ?? "",
......@@ -283,7 +312,6 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
),
),
],
),
),
Expanded(
......@@ -311,6 +339,7 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
},
);
}
/// Mapping subtitles
String _getSubtitle(String pageName) {
switch (pageName) {
......@@ -352,11 +381,7 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
}
/// Navigation mapping
void _handleNavigation(
BuildContext context,
String pageName,
String mode,
) {
void _handleNavigation(BuildContext context, String pageName, String mode) {
switch (pageName) {
case "Attendance Request List":
Navigator.push(
......@@ -371,9 +396,7 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LeaveApplicationListScreen(
mode: mode,
),
builder: (context) => LeaveApplicationListScreen(mode: mode),
),
);
break;
......@@ -381,18 +404,14 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
case "Rewards List":
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RewardListScreen(),
),
MaterialPageRoute(builder: (context) => RewardListScreen()),
);
break;
case "Tour Bill List":
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TourExpensesListScreen(),
),
MaterialPageRoute(builder: (context) => TourExpensesListScreen()),
);
break;
......@@ -400,9 +419,7 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LeaveApplicationListScreen(
mode: mode,
),
builder: (context) => LeaveApplicationListScreen(mode: mode),
),
);
break;
......@@ -417,5 +434,4 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
break;
}
}
}
......@@ -15,10 +15,12 @@ class LeaveApplicationListScreen extends StatefulWidget {
const LeaveApplicationListScreen({super.key, required this.mode});
@override
State<LeaveApplicationListScreen> createState() => _LeaveApplicationListScreenState();
State<LeaveApplicationListScreen> createState() =>
_LeaveApplicationListScreenState();
}
class _LeaveApplicationListScreenState extends State<LeaveApplicationListScreen> {
class _LeaveApplicationListScreenState
extends State<LeaveApplicationListScreen> {
// @override
// void initState() {
// super.initState();
......@@ -28,7 +30,6 @@ class _LeaveApplicationListScreenState extends State<LeaveApplicationListScreen>
// });
// }
@override
Widget build(BuildContext context) {
return SafeArea(
......@@ -56,10 +57,14 @@ class _LeaveApplicationListScreenState extends State<LeaveApplicationListScreen>
var cf = Commondaterangefilter();
var result = await cf.showFilterBottomSheet(context);
if (result != null) {
var dateRange = result['dateRange'] as DateTimeRange?;
var dateRange =
result['dateRange'] as DateTimeRange?;
var formatted = result['formatted'] as List<String>;
if (formatted.isNotEmpty) {
provider.setDateRangeFilter("Custom", customRange: dateRange);
provider.setDateRangeFilter(
"Custom",
customRange: dateRange,
);
provider.fetchLeaveApplications(
context,
widget.mode,
......@@ -69,7 +74,10 @@ class _LeaveApplicationListScreenState extends State<LeaveApplicationListScreen>
}
}
},
child: SvgPicture.asset("assets/svg/filter_ic.svg", height: 25),
child: SvgPicture.asset(
"assets/svg/filter_ic.svg",
height: 25,
),
),
],
),
......@@ -110,29 +118,46 @@ class _LeaveApplicationListScreenState extends State<LeaveApplicationListScreen>
child: Builder(
builder: (context) {
if (provider.isLoading) {
return const Center(child: CircularProgressIndicator(color: Colors.blue));
return const Center(
child: CircularProgressIndicator(
color: Colors.blue,
),
);
}
if (provider.errorMessage != null) {
return Center(child: Text(provider.errorMessage!));
}
if (provider.response?.requestList == null ||
provider.response!.requestList!.isEmpty) {
return const Center(child: Text("No leave applications found"));
return const Center(
child: Text("No leave applications found"),
);
}
final list = provider.response!.requestList!;
return ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 10),
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 10,
),
itemCount: list.length,
itemBuilder: (context, index) {
final item = list[index];
// Parse the full string into a DateTime object
DateTime parsedFromDate = DateFormat("dd MMM yyyy, hh:mm a").parse(item.fromPeriod.toString());
String dateFromMonth = DateFormat("dd MMM").format(parsedFromDate);
DateTime parsedFromDate = DateFormat(
"dd MMM yyyy, hh:mm a",
).parse(item.fromPeriod.toString());
String dateFromMonth = DateFormat(
"dd MMM",
).format(parsedFromDate);
// Parse the full string into a DateTime object
DateTime parsedToDate = DateFormat("dd MMM yyyy, hh:mm a").parse(item.toPeriod.toString());
DateTime parsedToDate = DateFormat(
"dd MMM yyyy, hh:mm a",
).parse(item.toPeriod.toString());
String dateToMonth = DateFormat("dd MMM yyyy").format(parsedToDate);
String dateToMonth = DateFormat(
"dd MMM yyyy",
).format(parsedToDate);
return InkWell(
borderRadius: BorderRadius.circular(16),
......@@ -140,21 +165,35 @@ class _LeaveApplicationListScreenState extends State<LeaveApplicationListScreen>
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LeaveApplicationDetailScreen(
leaveRequestId: item.id.toString(),
builder:
(context) =>
LeaveApplicationDetailScreen(
leaveRequestId:
item.id.toString(),
mode: widget.mode,
),
),
).then((_) {
provider.fetchLeaveApplications(context,widget.mode);
provider.fetchLeaveApplications(
context,
widget.mode,
);
});
},
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 8.5, vertical: 5),
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
margin: const EdgeInsets.symmetric(
horizontal: 8.5,
vertical: 5,
),
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 12,
),
decoration: BoxDecoration(
color: Colors.white,//Color(int.parse(item.rowColor!.replaceFirst('#', '0xff'))),
color:
Colors
.white, //Color(int.parse(item.rowColor!.replaceFirst('#', '0xff'))),
borderRadius: BorderRadius.circular(16),
),
child: Row(
......@@ -165,14 +204,18 @@ class _LeaveApplicationListScreenState extends State<LeaveApplicationListScreen>
width: 48,
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: _getStatusBackgroundColor(item.status),
color: _getStatusBackgroundColor(
item.status,
),
shape: BoxShape.circle,
),
child: Center(
child: Text(
_getStatusInitials(item.status),
style: TextStyle(
color: _getStatusTextColor(item.status),
color: _getStatusTextColor(
item.status,
),
fontSize: 14,
fontWeight: FontWeight.bold,
),
......@@ -184,7 +227,8 @@ class _LeaveApplicationListScreenState extends State<LeaveApplicationListScreen>
/// Middle Section - Leave Details
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
widget.mode == "teamleader"
......@@ -204,15 +248,17 @@ class _LeaveApplicationListScreenState extends State<LeaveApplicationListScreen>
Text(
dateFromMonth ?? "-",
style: TextStyle(
fontFamily: "JakartaRegular",
fontFamily:
"JakartaRegular",
fontSize: 14,
color: AppColors.grey_semi,
),
),
Text(
" - ${dateToMonth}" ?? "-",
" - $dateToMonth" ?? "-",
style: TextStyle(
fontFamily: "JakartaRegular",
fontFamily:
"JakartaRegular",
fontSize: 14,
color: AppColors.grey_semi,
),
......@@ -235,10 +281,15 @@ class _LeaveApplicationListScreenState extends State<LeaveApplicationListScreen>
/// Right Status
if (widget.mode == "teamleader")
Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 4,
),
decoration: BoxDecoration(
color: Color(0x00FFFFFF),
borderRadius: BorderRadius.circular(10),
borderRadius: BorderRadius.circular(
10,
),
),
child: Text(
item.leaveType ?? "-",
......@@ -258,14 +309,18 @@ class _LeaveApplicationListScreenState extends State<LeaveApplicationListScreen>
},
),
),
SizedBox(height: 28,)
SizedBox(height: 28),
],
),
bottomNavigationBar: widget.mode == "teamleader"
bottomNavigationBar:
widget.mode == "teamleader"
? null
: Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 10,
),
color: Colors.white,
child: InkResponse(
onTap: () {
......@@ -273,13 +328,21 @@ class _LeaveApplicationListScreenState extends State<LeaveApplicationListScreen>
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ChangeNotifierProvider(
create: (_) => LeaveApplicationListProvider(),
child: AddLeaveRequest(pageTitleName: "Add Leave Request"),
builder:
(_) => ChangeNotifierProvider(
create:
(_) =>
LeaveApplicationListProvider(),
child: AddLeaveRequest(
pageTitleName: "Add Leave Request",
),
),
),
).then((_) {
provider.fetchLeaveApplications(context, widget.mode);
provider.fetchLeaveApplications(
context,
widget.mode,
);
});
// show add bill screen here
......@@ -288,7 +351,10 @@ class _LeaveApplicationListScreenState extends State<LeaveApplicationListScreen>
height: 45,
alignment: Alignment.center,
margin: EdgeInsets.symmetric(horizontal: 14),
padding: EdgeInsets.symmetric(horizontal: 6, vertical: 5),
padding: EdgeInsets.symmetric(
horizontal: 6,
vertical: 5,
),
decoration: BoxDecoration(
color: AppColors.app_blue,
borderRadius: BorderRadius.circular(15),
......@@ -312,11 +378,6 @@ class _LeaveApplicationListScreenState extends State<LeaveApplicationListScreen>
);
}
/// Get status background color
Color _getStatusBackgroundColor(String? status) {
switch (status?.toLowerCase()) {
......@@ -330,7 +391,6 @@ class _LeaveApplicationListScreenState extends State<LeaveApplicationListScreen>
}
}
/// Get status text color
Color _getStatusTextColor(String? status) {
switch (status?.toLowerCase()) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment