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

17-09

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