Merge branch 'main' of bitbucket.org:venbainformationtechnology/ts-tat
This commit is contained in:
commit
29eedb3162
@ -14,6 +14,7 @@ import '../../routes/custom_drawer.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import '../../utils/pagination.dart';
|
||||
import '../../widgets/custom_breadcrumb_navigation.dart';
|
||||
import 'costCenterDetails.dart';
|
||||
|
||||
class CostCenterList extends StatefulWidget {
|
||||
@ -279,14 +280,31 @@ class CostCenterListState extends State<CostCenterList> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Cost Center Details',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 16 : 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
Container(
|
||||
child: BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Organization Settings',
|
||||
tooltip: 'Go To Organization Settings',
|
||||
onTap: (context) {
|
||||
context.go("/OrganizationSettings");
|
||||
}
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: 'Cost Center Details',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Text(
|
||||
// 'Cost Center Details',
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 16 : 14,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
|
||||
@ -14,6 +14,7 @@ import '../../routes/custom_drawer.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import '../../utils/pagination.dart';
|
||||
import '../../widgets/custom_breadcrumb_navigation.dart';
|
||||
import 'departmentDetails.dart';
|
||||
|
||||
class DepartmentList extends StatefulWidget {
|
||||
@ -278,14 +279,31 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Department Details',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 16 : 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
Container(
|
||||
child: BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Organization Settings',
|
||||
tooltip: 'Go To Organization Settings',
|
||||
onTap: (context) {
|
||||
context.go("/OrganizationSettings");
|
||||
}
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: 'Department Details',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Text(
|
||||
// 'Department Details',
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 16 : 14,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
|
||||
@ -14,6 +14,7 @@ import '../../routes/custom_drawer.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import '../../utils/pagination.dart';
|
||||
import '../../widgets/custom_breadcrumb_navigation.dart';
|
||||
import '../../widgets/popup_userList_action.dart';
|
||||
import 'forexDetails.dart';
|
||||
|
||||
@ -448,14 +449,31 @@ class ForexDataListState extends State<ForexDataList> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Perdiem Amount Details',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 16 : 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
Container(
|
||||
child: BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Organization Settings',
|
||||
tooltip: 'Go To Organization Settings',
|
||||
onTap: (context) {
|
||||
context.go("/OrganizationSettings");
|
||||
}
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: 'Perdiem Amount Details',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Text(
|
||||
// 'Perdiem Amount Details',
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 16 : 14,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
|
||||
@ -13,6 +13,7 @@ import '../../routes/custom_drawer.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import '../../utils/pagination.dart';
|
||||
import '../../widgets/custom_breadcrumb_navigation.dart';
|
||||
import 'groupDetails.dart';
|
||||
|
||||
class GroupList extends StatefulWidget {
|
||||
@ -297,14 +298,32 @@ class _GroupListState extends State<GroupList> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Group',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 16 : 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
Container(
|
||||
child: BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Organization Settings',
|
||||
tooltip: 'Go To Organization Settings',
|
||||
onTap: (context) {
|
||||
context.go("/OrganizationSettings");
|
||||
}
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: 'Group ',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Text(
|
||||
// 'Group',
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 16 : 14,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// ),
|
||||
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
|
||||
@ -14,6 +14,7 @@ import '../../routes/custom_drawer.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import '../../utils/pagination.dart';
|
||||
import '../../widgets/custom_breadcrumb_navigation.dart';
|
||||
import '../../widgets/popup_userList_action.dart';
|
||||
import 'hotelsDetails.dart';
|
||||
|
||||
@ -329,14 +330,31 @@ class HotelsDataListState extends State<HotelsDataList> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Hotel Details',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 16 : 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
Container(
|
||||
child: BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Organization Settings',
|
||||
tooltip: 'Go To Organization Settings',
|
||||
onTap: (context) {
|
||||
context.go("/OrganizationSettings");
|
||||
}
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: 'Hotel Details',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Text(
|
||||
// 'Hotel Details',
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 16 : 14,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
|
||||
@ -39,6 +39,7 @@ import '../../routes/custom_appBar.dart';
|
||||
import '../../routes/custom_drawer.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import '../../widgets/custom_breadcrumb_navigation.dart';
|
||||
import '../../widgets/custom_user_travel.dart';
|
||||
import 'dialog_placeholders.dart';
|
||||
|
||||
@ -535,6 +536,30 @@ class TemplateForexState extends State<TemplateForex> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
|
||||
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
child: BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Organization Settings',
|
||||
tooltip: 'Go To Organization Settings',
|
||||
onTap: (context) {
|
||||
context.go("/OrganizationSettings");
|
||||
}
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: 'Forex',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Text(
|
||||
formatTemplateName(templateName),
|
||||
style: GoogleFonts.poppins(
|
||||
|
||||
@ -17,6 +17,7 @@ import '../../routes/custom_appBar.dart';
|
||||
import '../../routes/custom_drawer.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import '../../widgets/custom_breadcrumb_navigation.dart';
|
||||
|
||||
class OrgSetUp extends StatefulWidget {
|
||||
@override
|
||||
@ -574,17 +575,37 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
selectedOrg != null && selectedOrg!.isNotEmpty
|
||||
? "Update Organization"
|
||||
: "Create Organization",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w500,
|
||||
Container(
|
||||
child: BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Organization Settings',
|
||||
tooltip: 'Go To Organization Settings',
|
||||
onTap: (context) {
|
||||
context.go("/OrganizationSettings");
|
||||
}
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: selectedOrg != null && selectedOrg!.isNotEmpty
|
||||
? "Update Organization"
|
||||
: "Create Organization",
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Text(
|
||||
// selectedOrg != null && selectedOrg!.isNotEmpty
|
||||
// ? "Update Organization"
|
||||
// : "Create Organization",
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: 15,
|
||||
// fontWeight: FontWeight.w500,
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -13,6 +13,7 @@ import '../../routes/custom_drawer.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import '../../utils/pagination.dart';
|
||||
import '../../widgets/custom_breadcrumb_navigation.dart';
|
||||
|
||||
class PolicyList extends StatefulWidget {
|
||||
@override
|
||||
@ -334,14 +335,31 @@ class _PolicyListState extends State<PolicyList> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Policy',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 16 : 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
Container(
|
||||
child: BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Organization Settings',
|
||||
tooltip: 'Go To Organization Settings',
|
||||
onTap: (context) {
|
||||
context.go("/OrganizationSettings");
|
||||
}
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: 'Policy',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Text(
|
||||
// 'Policy',
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 16 : 14,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
|
||||
@ -17,6 +17,7 @@ import '../../routes/custom_drawer.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import '../../utils/pagination.dart';
|
||||
import '../../widgets/custom_breadcrumb_navigation.dart';
|
||||
import '../../widgets/custom_text_field.dart';
|
||||
|
||||
class AdvancePurchase extends StatefulWidget {
|
||||
@ -426,278 +427,55 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// ------------------- First Row -------------------
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'Advance Purchase',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 16 : 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child:
|
||||
isDesktop
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: handleDownload,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"Excel",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Icon(
|
||||
Icons.file_present_outlined,
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// SizedBox(width: 10),
|
||||
// ElevatedButton(
|
||||
// style: ElevatedButton.styleFrom(
|
||||
// backgroundColor: Color(0xFF114D8B),
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
// side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
// ),
|
||||
// padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// // Your PDF export logic here
|
||||
// },
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Text(
|
||||
// "PDF",
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 13 : 11,
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: 8),
|
||||
// Icon(Icons.picture_as_pdf_outlined, size: 15, color: Colors.white),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
buildTitle(isDesktop),
|
||||
Spacer(),
|
||||
buildExports(isDesktop)
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildTitle(isDesktop),
|
||||
SizedBox(height: 8),
|
||||
buildExports(isDesktop)
|
||||
],
|
||||
)
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
|
||||
// ------------------- Second Row -------------------
|
||||
Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text( "From Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["from_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
firstDate: DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
if (pickedDate != null) {
|
||||
textControllers["from_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["from_date"],
|
||||
controller: textControllers["from_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: const Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child:
|
||||
isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildFromDateField(isDesktop),
|
||||
Spacer(),
|
||||
buildToDateField(isDesktop),
|
||||
Spacer(), // Space after Last Name
|
||||
buildSearchButton(isDesktop),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildFromDateField(isDesktop),
|
||||
SizedBox(height: 8), // Vertical space
|
||||
buildToDateField(isDesktop),
|
||||
SizedBox(height: 8),
|
||||
buildSearchButton(isDesktop),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["from_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["from_date"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text( "To Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["to_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final fromDateText =
|
||||
textControllers["from_date"]?.text;
|
||||
DateTime? mintoDate;
|
||||
if (fromDateText != null && fromDateText.isNotEmpty) {
|
||||
mintoDate = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).parse(fromDateText);
|
||||
}
|
||||
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: mintoDate ?? DateTime.now(),
|
||||
firstDate: mintoDate ?? DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
|
||||
if (pickedDate != null) {
|
||||
textControllers["to_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["to_date"],
|
||||
controller: textControllers["to_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["to_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["to_date"]!,
|
||||
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||
maxLines: 2, // Allow it to wrap onto two lines
|
||||
overflow:
|
||||
TextOverflow
|
||||
.ellipsis, // Add ellipsis if it still overflows
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10, left: 4),
|
||||
child: SizedBox(
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
foregroundColor: Colors.white,
|
||||
disabledBackgroundColor: Color(0xFF114D8B),
|
||||
disabledForegroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
handleSubmit();
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
Text(
|
||||
"Search",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(Icons.search, size: 15, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
|
||||
// ------------------- Third Row -------------------
|
||||
@ -1611,4 +1389,300 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildTitle(bool isDesktop){
|
||||
return // Left side: Breadcrumb inside a Container (optional)
|
||||
Container(
|
||||
child: BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Report List',
|
||||
tooltip: 'Go To Report List',
|
||||
onTap: (context) {
|
||||
// Navigator.pushNamed(context, '/report');
|
||||
context.go("/report");
|
||||
}
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: 'Advance Purchase',
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildExports(bool isDesktop){
|
||||
return Row(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: handleDownload,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"Excel",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Icon(
|
||||
Icons.file_present_outlined,
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// SizedBox(width: 10),
|
||||
// ElevatedButton(
|
||||
// style: ElevatedButton.styleFrom(
|
||||
// backgroundColor: Color(0xFF114D8B),
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
// side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
// ),
|
||||
// padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// // Your PDF export logic here
|
||||
// },
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Text(
|
||||
// "PDF",
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 13 : 11,
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: 8),
|
||||
// Icon(Icons.picture_as_pdf_outlined, size: 15, color: Colors.white),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
Widget buildFromDateField(bool isDesktop) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text( "From Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["from_date"] ?? false,
|
||||
// isDesktop: isDesktop ? MediaQuery.of(context).size.height * 0.51 : 200,
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
firstDate: DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
initialEntryMode: DatePickerEntryMode.calendarOnly,
|
||||
);
|
||||
if (pickedDate != null) {
|
||||
textControllers["from_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["from_date"],
|
||||
controller: textControllers["from_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: const Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["from_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["from_date"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Widget buildToDateField(bool isDesktop) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text( "To Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["to_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final fromDateText =
|
||||
textControllers["from_date"]?.text;
|
||||
DateTime? mintoDate;
|
||||
if (fromDateText != null && fromDateText.isNotEmpty) {
|
||||
mintoDate = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).parse(fromDateText);
|
||||
}
|
||||
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: mintoDate ?? DateTime.now(),
|
||||
initialEntryMode: DatePickerEntryMode.calendarOnly,
|
||||
firstDate: mintoDate ?? DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
|
||||
if (pickedDate != null) {
|
||||
textControllers["to_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["to_date"],
|
||||
controller: textControllers["to_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["to_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["to_date"]!,
|
||||
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||
maxLines: 2, // Allow it to wrap onto two lines
|
||||
overflow:
|
||||
TextOverflow
|
||||
.ellipsis, // Add ellipsis if it still overflows
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildSearchButton(bool isDesktop) {
|
||||
return
|
||||
Padding(
|
||||
padding: isDesktop
|
||||
? const EdgeInsets.only(top: 22)
|
||||
: EdgeInsets.zero,
|
||||
child: SizedBox(
|
||||
// width: isDesktop ? null : MediaQuery.of(context).size.width * 0.5, // don't delete
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
foregroundColor: Colors.white,
|
||||
disabledBackgroundColor: Color(0xFF114D8B),
|
||||
disabledForegroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
handleSubmit();
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
Text(
|
||||
"Search",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(Icons.search, size: 15, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ import '../../routes/custom_drawer.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import '../../utils/pagination.dart';
|
||||
import '../../widgets/custom_breadcrumb_navigation.dart';
|
||||
import '../../widgets/custom_text_field.dart';
|
||||
|
||||
class GuestHouse extends StatefulWidget {
|
||||
@ -445,252 +446,55 @@ class _GuestHouseState extends State<GuestHouse>
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// ------------------- First Row -------------------
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'Guest House',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 16 : 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
// ------------------- First Row -------------------
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child:
|
||||
isDesktop
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: handleDownload,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"Excel",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Icon(
|
||||
Icons.file_present_outlined,
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
buildTitle(isDesktop),
|
||||
Spacer(),
|
||||
buildExports(isDesktop)
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildTitle(isDesktop),
|
||||
SizedBox(height: 8),
|
||||
buildExports(isDesktop)
|
||||
],
|
||||
)
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
|
||||
// ------------------- Second Row -------------------
|
||||
Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"From Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["from_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
firstDate: DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
if (pickedDate != null) {
|
||||
textControllers["from_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["from_date"],
|
||||
controller: textControllers["from_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: const Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["from_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["from_date"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"To Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["to_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final fromDateText =
|
||||
textControllers["from_date"]?.text;
|
||||
DateTime? mintoDate;
|
||||
if (fromDateText != null && fromDateText.isNotEmpty) {
|
||||
mintoDate = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).parse(fromDateText);
|
||||
}
|
||||
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: mintoDate ?? DateTime.now(),
|
||||
firstDate: mintoDate ?? DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
|
||||
if (pickedDate != null) {
|
||||
textControllers["to_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["to_date"],
|
||||
controller: textControllers["to_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["to_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["to_date"]!,
|
||||
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||
maxLines: 2, // Allow it to wrap onto two lines
|
||||
overflow:
|
||||
TextOverflow
|
||||
.ellipsis, // Add ellipsis if it still overflows
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10, left: 4),
|
||||
child: SizedBox(
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
foregroundColor: Colors.white,
|
||||
disabledBackgroundColor: Color(0xFF114D8B),
|
||||
disabledForegroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
handleSubmit();
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
Text(
|
||||
"Search",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(Icons.search, size: 15, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child:
|
||||
isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildFromDateField(isDesktop),
|
||||
Spacer(),
|
||||
buildToDateField(isDesktop),
|
||||
Spacer(), // Space after Last Name
|
||||
buildSearchButton(isDesktop),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildFromDateField(isDesktop),
|
||||
SizedBox(height: 8), // Vertical space
|
||||
buildToDateField(isDesktop),
|
||||
SizedBox(height: 8),
|
||||
buildSearchButton(isDesktop),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
|
||||
@ -1718,4 +1522,297 @@ class _GuestHouseState extends State<GuestHouse>
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildTitle(bool isDesktop){
|
||||
return // Left side: Breadcrumb inside a Container (optional)
|
||||
Container(
|
||||
child: BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Report List',
|
||||
tooltip: 'Go To Report List',
|
||||
onTap: (context) {
|
||||
// Navigator.pushNamed(context, '/report');
|
||||
context.go("/report");
|
||||
}
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: 'Guest House',
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildExports(bool isDesktop){
|
||||
return Row(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: handleDownload,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"Excel",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Icon(
|
||||
Icons.file_present_outlined,
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// SizedBox(width: 10),
|
||||
// ElevatedButton(
|
||||
// style: ElevatedButton.styleFrom(
|
||||
// backgroundColor: Color(0xFF114D8B),
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
// side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
// ),
|
||||
// padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// // Your PDF export logic here
|
||||
// },
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Text(
|
||||
// "PDF",
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 13 : 11,
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: 8),
|
||||
// Icon(Icons.picture_as_pdf_outlined, size: 15, color: Colors.white),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
Widget buildFromDateField(bool isDesktop) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text( "From Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["from_date"] ?? false,
|
||||
// isDesktop: isDesktop ? MediaQuery.of(context).size.height * 0.51 : 200,
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
firstDate: DateTime(2000),
|
||||
initialEntryMode: DatePickerEntryMode.calendarOnly,
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
if (pickedDate != null) {
|
||||
textControllers["from_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["from_date"],
|
||||
controller: textControllers["from_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: const Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["from_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["from_date"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildToDateField(bool isDesktop) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text( "To Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["to_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final fromDateText =
|
||||
textControllers["from_date"]?.text;
|
||||
DateTime? mintoDate;
|
||||
if (fromDateText != null && fromDateText.isNotEmpty) {
|
||||
mintoDate = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).parse(fromDateText);
|
||||
}
|
||||
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: mintoDate ?? DateTime.now(),
|
||||
firstDate: mintoDate ?? DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
|
||||
if (pickedDate != null) {
|
||||
textControllers["to_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["to_date"],
|
||||
controller: textControllers["to_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["to_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["to_date"]!,
|
||||
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||
maxLines: 2, // Allow it to wrap onto two lines
|
||||
overflow:
|
||||
TextOverflow
|
||||
.ellipsis, // Add ellipsis if it still overflows
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildSearchButton(bool isDesktop) {
|
||||
return
|
||||
Padding(
|
||||
padding: isDesktop
|
||||
? const EdgeInsets.only(top: 22)
|
||||
: EdgeInsets.zero,
|
||||
child: SizedBox(
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
foregroundColor: Colors.white,
|
||||
disabledBackgroundColor: Color(0xFF114D8B),
|
||||
disabledForegroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
handleSubmit();
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
Text(
|
||||
"Search",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(Icons.search, size: 15, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ import '../../routes/custom_drawer.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import '../../utils/pagination.dart';
|
||||
import '../../widgets/custom_breadcrumb_navigation.dart';
|
||||
import '../../widgets/custom_text_field.dart';
|
||||
|
||||
class MISair extends StatefulWidget {
|
||||
@ -443,279 +444,55 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// ------------------- First Row -------------------
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'MIS Air Report ',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 16 : 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
// ------------------- First Row -------------------
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child:
|
||||
isDesktop
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: handleDownload,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"Excel",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Icon(
|
||||
Icons.file_present_outlined,
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// SizedBox(width: 10),
|
||||
// ElevatedButton(
|
||||
// style: ElevatedButton.styleFrom(
|
||||
// backgroundColor: Color(0xFF114D8B),
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
// side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
// ),
|
||||
// padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// // Your PDF export logic here
|
||||
// },
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Text(
|
||||
// "PDF",
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 13 : 11,
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: 8),
|
||||
// Icon(Icons.picture_as_pdf_outlined, size: 15, color: Colors.white),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
buildTitle(isDesktop),
|
||||
Spacer(),
|
||||
buildExports(isDesktop)
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildTitle(isDesktop),
|
||||
SizedBox(height: 8),
|
||||
buildExports(isDesktop)
|
||||
],
|
||||
)
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
|
||||
// ------------------- Second Row -------------------
|
||||
Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"From Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["from_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
firstDate: DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
if (pickedDate != null) {
|
||||
textControllers["from_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["from_date"],
|
||||
controller: textControllers["from_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: const Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["from_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["from_date"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"To Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["to_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final fromDateText =
|
||||
textControllers["from_date"]?.text;
|
||||
DateTime? mintoDate;
|
||||
if (fromDateText != null && fromDateText.isNotEmpty) {
|
||||
mintoDate = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).parse(fromDateText);
|
||||
}
|
||||
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: mintoDate ?? DateTime.now(),
|
||||
firstDate: mintoDate ?? DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
|
||||
if (pickedDate != null) {
|
||||
textControllers["to_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["to_date"],
|
||||
controller: textControllers["to_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["to_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["to_date"]!,
|
||||
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||
maxLines: 2, // Allow it to wrap onto two lines
|
||||
overflow:
|
||||
TextOverflow
|
||||
.ellipsis, // Add ellipsis if it still overflows
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10, left: 4),
|
||||
child: SizedBox(
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
foregroundColor: Colors.white,
|
||||
disabledBackgroundColor: Color(0xFF114D8B),
|
||||
disabledForegroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
handleSubmit();
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
Text(
|
||||
"Search",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(Icons.search, size: 15, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child:
|
||||
isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildFromDateField(isDesktop),
|
||||
Spacer(),
|
||||
buildToDateField(isDesktop),
|
||||
Spacer(), // Space after Last Name
|
||||
buildSearchButton(isDesktop),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildFromDateField(isDesktop),
|
||||
SizedBox(height: 8), // Vertical space
|
||||
buildToDateField(isDesktop),
|
||||
SizedBox(height: 8),
|
||||
buildSearchButton(isDesktop),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
|
||||
@ -1733,4 +1510,296 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
|
||||
),
|
||||
);
|
||||
}
|
||||
Widget buildTitle(bool isDesktop){
|
||||
return // Left side: Breadcrumb inside a Container (optional)
|
||||
Container(
|
||||
child: BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Report List',
|
||||
tooltip: 'Go To Report List',
|
||||
onTap: (context) {
|
||||
// Navigator.pushNamed(context, '/report');
|
||||
context.go("/report");
|
||||
}
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: 'MIS Air Report ',
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
Widget buildExports(bool isDesktop){
|
||||
return Row(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: handleDownload,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"Excel",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Icon(
|
||||
Icons.file_present_outlined,
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// SizedBox(width: 10),
|
||||
// ElevatedButton(
|
||||
// style: ElevatedButton.styleFrom(
|
||||
// backgroundColor: Color(0xFF114D8B),
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
// side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
// ),
|
||||
// padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// // Your PDF export logic here
|
||||
// },
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Text(
|
||||
// "PDF",
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 13 : 11,
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: 8),
|
||||
// Icon(Icons.picture_as_pdf_outlined, size: 15, color: Colors.white),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
Widget buildFromDateField(bool isDesktop) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text( "From Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["from_date"] ?? false,
|
||||
// isDesktop: isDesktop ? MediaQuery.of(context).size.height * 0.51 : 200,
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
initialEntryMode: DatePickerEntryMode.calendarOnly,
|
||||
firstDate: DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
if (pickedDate != null) {
|
||||
textControllers["from_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["from_date"],
|
||||
controller: textControllers["from_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: const Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["from_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["from_date"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildToDateField(bool isDesktop) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text( "To Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["to_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final fromDateText =
|
||||
textControllers["from_date"]?.text;
|
||||
DateTime? mintoDate;
|
||||
if (fromDateText != null && fromDateText.isNotEmpty) {
|
||||
mintoDate = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).parse(fromDateText);
|
||||
}
|
||||
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: mintoDate ?? DateTime.now(),
|
||||
firstDate: mintoDate ?? DateTime(2000),
|
||||
initialEntryMode: DatePickerEntryMode.calendarOnly,
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
|
||||
if (pickedDate != null) {
|
||||
textControllers["to_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["to_date"],
|
||||
controller: textControllers["to_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["to_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["to_date"]!,
|
||||
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||
maxLines: 2, // Allow it to wrap onto two lines
|
||||
overflow:
|
||||
TextOverflow
|
||||
.ellipsis, // Add ellipsis if it still overflows
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildSearchButton(bool isDesktop) {
|
||||
return
|
||||
Padding(
|
||||
padding: isDesktop
|
||||
? const EdgeInsets.only(top: 22)
|
||||
: EdgeInsets.zero,
|
||||
child: SizedBox(
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
foregroundColor: Colors.white,
|
||||
disabledBackgroundColor: Color(0xFF114D8B),
|
||||
disabledForegroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
handleSubmit();
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
Text(
|
||||
"Search",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(Icons.search, size: 15, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ import '../../routes/custom_drawer.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import '../../utils/pagination.dart';
|
||||
import '../../widgets/custom_breadcrumb_navigation.dart';
|
||||
import '../../widgets/custom_text_field.dart';
|
||||
|
||||
class MISforex extends StatefulWidget {
|
||||
@ -388,279 +389,55 @@ class _MISforexState extends State<MISforex>
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// ------------------- First Row -------------------
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'MIS Forex Report',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 16 : 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
// ------------------- First Row -------------------
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child:
|
||||
isDesktop
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: handleDownload,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"Excel",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Icon(
|
||||
Icons.file_present_outlined,
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// SizedBox(width: 10),
|
||||
// ElevatedButton(
|
||||
// style: ElevatedButton.styleFrom(
|
||||
// backgroundColor: Color(0xFF114D8B),
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
// side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
// ),
|
||||
// padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// // Your PDF export logic here
|
||||
// },
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Text(
|
||||
// "PDF",
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 13 : 11,
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: 8),
|
||||
// Icon(Icons.picture_as_pdf_outlined, size: 15, color: Colors.white),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
buildTitle(isDesktop),
|
||||
Spacer(),
|
||||
buildExports(isDesktop)
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildTitle(isDesktop),
|
||||
SizedBox(height: 8),
|
||||
buildExports(isDesktop)
|
||||
],
|
||||
)
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
|
||||
// ------------------- Second Row -------------------
|
||||
Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"From Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["from_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
firstDate: DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
if (pickedDate != null) {
|
||||
textControllers["from_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["from_date"],
|
||||
controller: textControllers["from_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: const Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["from_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["from_date"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"To Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["to_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final fromDateText =
|
||||
textControllers["from_date"]?.text;
|
||||
DateTime? mintoDate;
|
||||
if (fromDateText != null && fromDateText.isNotEmpty) {
|
||||
mintoDate = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).parse(fromDateText);
|
||||
}
|
||||
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: mintoDate ?? DateTime.now(),
|
||||
firstDate: mintoDate ?? DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
|
||||
if (pickedDate != null) {
|
||||
textControllers["to_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["to_date"],
|
||||
controller: textControllers["to_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["to_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["to_date"]!,
|
||||
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||
maxLines: 2, // Allow it to wrap onto two lines
|
||||
overflow:
|
||||
TextOverflow
|
||||
.ellipsis, // Add ellipsis if it still overflows
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10, left: 4),
|
||||
child: SizedBox(
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
foregroundColor: Colors.white,
|
||||
disabledBackgroundColor: Color(0xFF114D8B),
|
||||
disabledForegroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
handleSubmit();
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
Text(
|
||||
"Search",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(Icons.search, size: 15, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child:
|
||||
isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildFromDateField(isDesktop),
|
||||
Spacer(),
|
||||
buildToDateField(isDesktop),
|
||||
Spacer(), // Space after Last Name
|
||||
buildSearchButton(isDesktop),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildFromDateField(isDesktop),
|
||||
SizedBox(height: 8), // Vertical space
|
||||
buildToDateField(isDesktop),
|
||||
SizedBox(height: 8),
|
||||
buildSearchButton(isDesktop),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
|
||||
@ -1055,4 +832,296 @@ class _MISforexState extends State<MISforex>
|
||||
),
|
||||
);
|
||||
}
|
||||
Widget buildTitle(bool isDesktop){
|
||||
return // Left side: Breadcrumb inside a Container (optional)
|
||||
Container(
|
||||
child: BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Report List',
|
||||
tooltip: 'Go To Report List',
|
||||
onTap: (context) {
|
||||
// Navigator.pushNamed(context, '/report');
|
||||
context.go("/report");
|
||||
}
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: 'MIS Forex Report ',
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
Widget buildExports(bool isDesktop){
|
||||
return Row(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: handleDownload,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"Excel",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Icon(
|
||||
Icons.file_present_outlined,
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// SizedBox(width: 10),
|
||||
// ElevatedButton(
|
||||
// style: ElevatedButton.styleFrom(
|
||||
// backgroundColor: Color(0xFF114D8B),
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
// side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
// ),
|
||||
// padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// // Your PDF export logic here
|
||||
// },
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Text(
|
||||
// "PDF",
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 13 : 11,
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: 8),
|
||||
// Icon(Icons.picture_as_pdf_outlined, size: 15, color: Colors.white),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
Widget buildFromDateField(bool isDesktop) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text( "From Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["from_date"] ?? false,
|
||||
// isDesktop: isDesktop ? MediaQuery.of(context).size.height * 0.51 : 200,
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
initialEntryMode: DatePickerEntryMode.calendarOnly,
|
||||
firstDate: DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
if (pickedDate != null) {
|
||||
textControllers["from_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["from_date"],
|
||||
controller: textControllers["from_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: const Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["from_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["from_date"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildToDateField(bool isDesktop) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text( "To Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["to_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final fromDateText =
|
||||
textControllers["from_date"]?.text;
|
||||
DateTime? mintoDate;
|
||||
if (fromDateText != null && fromDateText.isNotEmpty) {
|
||||
mintoDate = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).parse(fromDateText);
|
||||
}
|
||||
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
initialEntryMode: DatePickerEntryMode.calendarOnly,
|
||||
firstDate: mintoDate ?? DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
|
||||
if (pickedDate != null) {
|
||||
textControllers["to_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["to_date"],
|
||||
controller: textControllers["to_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["to_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["to_date"]!,
|
||||
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||
maxLines: 2, // Allow it to wrap onto two lines
|
||||
overflow:
|
||||
TextOverflow
|
||||
.ellipsis, // Add ellipsis if it still overflows
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildSearchButton(bool isDesktop) {
|
||||
return
|
||||
Padding(
|
||||
padding: isDesktop
|
||||
? const EdgeInsets.only(top: 22)
|
||||
: EdgeInsets.zero,
|
||||
child: SizedBox(
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
foregroundColor: Colors.white,
|
||||
disabledBackgroundColor: Color(0xFF114D8B),
|
||||
disabledForegroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
handleSubmit();
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
Text(
|
||||
"Search",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(Icons.search, size: 15, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ import '../../routes/custom_drawer.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import '../../utils/pagination.dart';
|
||||
import '../../widgets/custom_breadcrumb_navigation.dart';
|
||||
import '../../widgets/custom_text_field.dart';
|
||||
|
||||
class MIShotel extends StatefulWidget {
|
||||
@ -433,260 +434,54 @@ class _MIShotelState extends State<MIShotel>
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// ------------------- First Row -------------------
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'Mis Hotel Report',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 16 : 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child:
|
||||
isDesktop
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
),
|
||||
onPressed: handleDownload,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"Excel",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Icon(Icons.file_present_outlined, size: 15, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
// SizedBox(width: 10),
|
||||
// ElevatedButton(
|
||||
// style: ElevatedButton.styleFrom(
|
||||
// backgroundColor: Color(0xFF114D8B),
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
// side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
// ),
|
||||
// padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// // Your PDF export logic here
|
||||
// },
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Text(
|
||||
// "PDF",
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 13 : 11,
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: 8),
|
||||
// Icon(Icons.picture_as_pdf_outlined, size: 15, color: Colors.white),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
buildTitle(isDesktop),
|
||||
Spacer(),
|
||||
buildExports(isDesktop)
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildTitle(isDesktop),
|
||||
SizedBox(height: 8),
|
||||
buildExports(isDesktop)
|
||||
],
|
||||
)
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
|
||||
// ------------------- Second Row -------------------
|
||||
Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"From Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["from_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
firstDate: DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
if (pickedDate != null) {
|
||||
textControllers["from_date"]?.text =
|
||||
DateFormat('dd-MM-yyyy').format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["from_date"],
|
||||
controller: textControllers["from_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||
suffixIcon: const Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["from_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["from_date"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"To Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["to_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final fromDateText = textControllers["from_date"]?.text;
|
||||
DateTime? mintoDate;
|
||||
if (fromDateText != null && fromDateText.isNotEmpty) {
|
||||
mintoDate = DateFormat('dd-MM-yyyy').parse(fromDateText);
|
||||
}
|
||||
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: mintoDate ?? DateTime.now(),
|
||||
firstDate: mintoDate ?? DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
|
||||
if (pickedDate != null) {
|
||||
textControllers["to_date"]?.text =
|
||||
DateFormat('dd-MM-yyyy').format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["to_date"],
|
||||
controller: textControllers["to_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["to_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["to_date"]!,
|
||||
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||
maxLines: 2, // Allow it to wrap onto two lines
|
||||
overflow:
|
||||
TextOverflow.ellipsis, // Add ellipsis if it still overflows
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10, left: 4),
|
||||
child : SizedBox(
|
||||
child: ElevatedButton(
|
||||
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
foregroundColor: Colors.white,
|
||||
disabledBackgroundColor: Color(0xFF114D8B),
|
||||
disabledForegroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: () {handleSubmit();},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
Text(
|
||||
"Search",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(
|
||||
Icons.search,
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child:
|
||||
isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildFromDateField(isDesktop),
|
||||
Spacer(),
|
||||
buildToDateField(isDesktop),
|
||||
Spacer(), // Space after Last Name
|
||||
buildSearchButton(isDesktop),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildFromDateField(isDesktop),
|
||||
SizedBox(height: 8), // Vertical space
|
||||
buildToDateField(isDesktop),
|
||||
SizedBox(height: 8),
|
||||
buildSearchButton(isDesktop),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
|
||||
@ -1302,4 +1097,296 @@ class _MIShotelState extends State<MIShotel>
|
||||
),
|
||||
);
|
||||
}
|
||||
Widget buildTitle(bool isDesktop){
|
||||
return // Left side: Breadcrumb inside a Container (optional)
|
||||
Container(
|
||||
child: BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Report List',
|
||||
tooltip: 'Go To Report List',
|
||||
onTap: (context) {
|
||||
// Navigator.pushNamed(context, '/report');
|
||||
context.go("/report");
|
||||
}
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: 'MIS Hotel Report ',
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
Widget buildExports(bool isDesktop){
|
||||
return Row(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: handleDownload,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"Excel",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Icon(
|
||||
Icons.file_present_outlined,
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// SizedBox(width: 10),
|
||||
// ElevatedButton(
|
||||
// style: ElevatedButton.styleFrom(
|
||||
// backgroundColor: Color(0xFF114D8B),
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
// side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
// ),
|
||||
// padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// // Your PDF export logic here
|
||||
// },
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Text(
|
||||
// "PDF",
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 13 : 11,
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: 8),
|
||||
// Icon(Icons.picture_as_pdf_outlined, size: 15, color: Colors.white),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
Widget buildFromDateField(bool isDesktop) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text( "From Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["from_date"] ?? false,
|
||||
// isDesktop: isDesktop ? MediaQuery.of(context).size.height * 0.51 : 200,
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
initialEntryMode: DatePickerEntryMode.calendarOnly,
|
||||
firstDate: DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
if (pickedDate != null) {
|
||||
textControllers["from_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["from_date"],
|
||||
controller: textControllers["from_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: const Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["from_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["from_date"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildToDateField(bool isDesktop) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text( "To Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["to_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final fromDateText =
|
||||
textControllers["from_date"]?.text;
|
||||
DateTime? mintoDate;
|
||||
if (fromDateText != null && fromDateText.isNotEmpty) {
|
||||
mintoDate = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).parse(fromDateText);
|
||||
}
|
||||
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: mintoDate ?? DateTime.now(),
|
||||
initialEntryMode: DatePickerEntryMode.calendarOnly,
|
||||
firstDate: mintoDate ?? DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
|
||||
if (pickedDate != null) {
|
||||
textControllers["to_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["to_date"],
|
||||
controller: textControllers["to_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["to_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["to_date"]!,
|
||||
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||
maxLines: 2, // Allow it to wrap onto two lines
|
||||
overflow:
|
||||
TextOverflow
|
||||
.ellipsis, // Add ellipsis if it still overflows
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildSearchButton(bool isDesktop) {
|
||||
return
|
||||
Padding(
|
||||
padding: isDesktop
|
||||
? const EdgeInsets.only(top: 22)
|
||||
: EdgeInsets.zero,
|
||||
child: SizedBox(
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
foregroundColor: Colors.white,
|
||||
disabledBackgroundColor: Color(0xFF114D8B),
|
||||
disabledForegroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
handleSubmit();
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
Text(
|
||||
"Search",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(Icons.search, size: 15, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -139,13 +139,12 @@ class _ReportListState extends State<ReportList> {
|
||||
'label': 'MIS Forex Report',
|
||||
'description': 'View MIS Forex Report',
|
||||
},
|
||||
|
||||
{
|
||||
'value': '/guestHouseReport',
|
||||
'icon': Icons.home_work,
|
||||
'label': 'Guest House Report',
|
||||
'description': 'View Guest House Report',
|
||||
},
|
||||
// {
|
||||
// 'value': '/guestHouseReport',
|
||||
// 'icon': Icons.home_work,
|
||||
// 'label': 'Guest House Report',
|
||||
// 'description': 'View Guest House Report',
|
||||
// },
|
||||
];
|
||||
|
||||
return Container(
|
||||
@ -178,20 +177,8 @@ class _ReportListState extends State<ReportList> {
|
||||
color: Colors.white,
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
if (item['value'] as String ==
|
||||
"/forexTexmplate") {
|
||||
final data =
|
||||
await apiService.getForexTemplate();
|
||||
print("ForexId -- $data");
|
||||
|
||||
context.go(
|
||||
'/templateForex',
|
||||
extra: {'templateData': data},
|
||||
);
|
||||
} else {
|
||||
final route = item['value'] as String;
|
||||
context.go(route);
|
||||
}
|
||||
},
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(12),
|
||||
|
||||
@ -17,6 +17,7 @@ import '../../routes/custom_drawer.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import '../../utils/pagination.dart';
|
||||
import '../../widgets/custom_breadcrumb_navigation.dart';
|
||||
import '../../widgets/custom_text_field.dart';
|
||||
|
||||
class ServicesAnalysis extends StatefulWidget {
|
||||
@ -429,252 +430,55 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// ------------------- First Row -------------------
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'Service Analysis Report',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 16 : 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
// ------------------- First Row -------------------
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child:
|
||||
isDesktop
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: handleDownload,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"Excel",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Icon(
|
||||
Icons.file_present_outlined,
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
buildTitle(isDesktop),
|
||||
Spacer(),
|
||||
buildExports(isDesktop)
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildTitle(isDesktop),
|
||||
SizedBox(height: 8),
|
||||
buildExports(isDesktop)
|
||||
],
|
||||
)
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
|
||||
// ------------------- Second Row -------------------
|
||||
Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"From Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["from_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
firstDate: DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
if (pickedDate != null) {
|
||||
textControllers["from_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["from_date"],
|
||||
controller: textControllers["from_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: const Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["from_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["from_date"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"To Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["to_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final fromDateText =
|
||||
textControllers["from_date"]?.text;
|
||||
DateTime? mintoDate;
|
||||
if (fromDateText != null && fromDateText.isNotEmpty) {
|
||||
mintoDate = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).parse(fromDateText);
|
||||
}
|
||||
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: mintoDate ?? DateTime.now(),
|
||||
firstDate: mintoDate ?? DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
|
||||
if (pickedDate != null) {
|
||||
textControllers["to_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["to_date"],
|
||||
controller: textControllers["to_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["to_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["to_date"]!,
|
||||
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||
maxLines: 2, // Allow it to wrap onto two lines
|
||||
overflow:
|
||||
TextOverflow
|
||||
.ellipsis, // Add ellipsis if it still overflows
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10, left: 4),
|
||||
child: SizedBox(
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
foregroundColor: Colors.white,
|
||||
disabledBackgroundColor: Color(0xFF114D8B),
|
||||
disabledForegroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
handleSubmit();
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
Text(
|
||||
"Search",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(Icons.search, size: 15, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
Container(
|
||||
color: Colors.white,
|
||||
child:
|
||||
isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildFromDateField(isDesktop),
|
||||
Spacer(),
|
||||
buildToDateField(isDesktop),
|
||||
Spacer(), // Space after Last Name
|
||||
buildSearchButton(isDesktop),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildFromDateField(isDesktop),
|
||||
SizedBox(height: 8), // Vertical space
|
||||
buildToDateField(isDesktop),
|
||||
SizedBox(height: 8),
|
||||
buildSearchButton(isDesktop),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
|
||||
@ -1412,4 +1216,298 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildTitle(bool isDesktop){
|
||||
return // Left side: Breadcrumb inside a Container (optional)
|
||||
Container(
|
||||
child: BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Report List',
|
||||
tooltip: 'Go To Report List',
|
||||
onTap: (context) {
|
||||
// Navigator.pushNamed(context, '/report');
|
||||
context.go("/report");
|
||||
}
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: 'Service Analysis Report',
|
||||
),
|
||||
],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildExports(bool isDesktop){
|
||||
return Row(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: handleDownload,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"Excel",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Icon(
|
||||
Icons.file_present_outlined,
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// SizedBox(width: 10),
|
||||
// ElevatedButton(
|
||||
// style: ElevatedButton.styleFrom(
|
||||
// backgroundColor: Color(0xFF114D8B),
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
// side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
// ),
|
||||
// padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// // Your PDF export logic here
|
||||
// },
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Text(
|
||||
// "PDF",
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 13 : 11,
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: 8),
|
||||
// Icon(Icons.picture_as_pdf_outlined, size: 15, color: Colors.white),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
Widget buildFromDateField(bool isDesktop) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text( "From Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["from_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
initialEntryMode: DatePickerEntryMode.calendarOnly,
|
||||
firstDate: DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
if (pickedDate != null) {
|
||||
textControllers["from_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["from_date"],
|
||||
controller: textControllers["from_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: const Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["from_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["from_date"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildToDateField(bool isDesktop) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text( "To Date *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: focusStates["to_date"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
final fromDateText =
|
||||
textControllers["from_date"]?.text;
|
||||
DateTime? mintoDate;
|
||||
if (fromDateText != null && fromDateText.isNotEmpty) {
|
||||
mintoDate = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).parse(fromDateText);
|
||||
}
|
||||
|
||||
final pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: mintoDate ?? DateTime.now(),
|
||||
initialEntryMode: DatePickerEntryMode.calendarOnly,
|
||||
firstDate: mintoDate ?? DateTime(2000),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
|
||||
if (pickedDate != null) {
|
||||
textControllers["to_date"]?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
).format(pickedDate);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: focusNodes["to_date"],
|
||||
controller: textControllers["to_date"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 16,
|
||||
),
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["to_date"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["to_date"]!,
|
||||
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||
maxLines: 2, // Allow it to wrap onto two lines
|
||||
overflow:
|
||||
TextOverflow
|
||||
.ellipsis, // Add ellipsis if it still overflows
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildSearchButton(bool isDesktop) {
|
||||
return
|
||||
Padding(
|
||||
padding: isDesktop
|
||||
? const EdgeInsets.only(top: 22)
|
||||
: EdgeInsets.zero,
|
||||
child: SizedBox(
|
||||
width: isDesktop ? null : double.infinity,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF114D8B),
|
||||
foregroundColor: Colors.white,
|
||||
disabledBackgroundColor: Color(0xFF114D8B),
|
||||
disabledForegroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
handleSubmit();
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
Text(
|
||||
"Search",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(Icons.search, size: 15, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ import '../../routes/custom_drawer.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import '../../utils/pagination.dart';
|
||||
import '../../widgets/custom_breadcrumb_navigation.dart';
|
||||
import 'travellerDetails.dart';
|
||||
|
||||
class TravellerList extends StatefulWidget {
|
||||
@ -286,14 +287,32 @@ class TravellerListState extends State<TravellerList> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Traveller Details',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 16 : 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
// Left side: Breadcrumb inside a Container (optional)
|
||||
Container(
|
||||
child: BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Organization Settings',
|
||||
tooltip: 'Go To Organization Settings',
|
||||
onTap: (context) {
|
||||
context.go("/OrganizationSettings");
|
||||
}
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: 'Traveller Details',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Text(
|
||||
// 'Traveller Details',
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 16 : 14,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
|
||||
@ -26,6 +26,7 @@ import '../../../config/apiUrl.dart';
|
||||
import '../../../routes/custom_appBar.dart';
|
||||
import '../../../routes/custom_drawer.dart';
|
||||
import '../../../services/apiService.dart';
|
||||
import '../../../widgets/custom_breadcrumb_navigation.dart';
|
||||
import '../../../widgets/custom_text_field.dart';
|
||||
import '../../../widgets/custom_text_forex.dart';
|
||||
import '../../../widgets/custom_user_form.dart';
|
||||
@ -1349,14 +1350,39 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
apiselectedUser != null ? "Profile" : "Create New User",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 15 : 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
apiselectedUser != null
|
||||
? Text( "Profile",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 15 : 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
child: BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Users',
|
||||
tooltip: 'Go To Users',
|
||||
onTap: (context) {
|
||||
context.go("/listUser");
|
||||
}
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: 'Create New User',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Text(
|
||||
// apiselectedUser != null ? "Profile" : "Create New User",
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 15 : 12,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// ),
|
||||
// if (isEditProfile)
|
||||
// IconButton(
|
||||
// icon: Icon(
|
||||
|
||||
162
lib/widgets/custom_breadcrumb_navigation.dart
Normal file
162
lib/widgets/custom_breadcrumb_navigation.dart
Normal file
@ -0,0 +1,162 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
/// Data model for a breadcrumb item.
|
||||
class BreadcrumbItem {
|
||||
final String title;
|
||||
final void Function(BuildContext)? onTap;
|
||||
final String? tooltip;
|
||||
|
||||
BreadcrumbItem({
|
||||
required this.title,
|
||||
this.onTap,
|
||||
this.tooltip,
|
||||
});
|
||||
}
|
||||
|
||||
/// Breadcrumb UI widget
|
||||
class BreadcrumbNavigation extends StatelessWidget {
|
||||
final List<BreadcrumbItem> breadcrumbItems;
|
||||
final bool isDesktop;
|
||||
|
||||
const BreadcrumbNavigation({
|
||||
super.key,
|
||||
required this.breadcrumbItems,
|
||||
required this.isDesktop,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Wrap(
|
||||
crossAxisAlignment: WrapCrossAlignment.center, // Align text + arrows
|
||||
children: List.generate(breadcrumbItems.length * 2 - 1, (index) {
|
||||
if (index.isEven) {
|
||||
final int itemIndex = index ~/ 2;
|
||||
final item = breadcrumbItems[itemIndex];
|
||||
final bool isLast = itemIndex == breadcrumbItems.length - 1;
|
||||
|
||||
// If last item or no tap handler, show as plain black text without tooltip/click
|
||||
if (isLast || item.onTap == null) {
|
||||
return Text(
|
||||
item.title,
|
||||
style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 16 : 14,
|
||||
// fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// If clickable, wrap with GestureDetector + Tooltip + MouseRegion
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: Tooltip(
|
||||
message: item.tooltip ?? item.title,
|
||||
child: GestureDetector(
|
||||
onTap: () => item.onTap!(context),
|
||||
child: Text(
|
||||
item.title,
|
||||
style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 16 : 14,
|
||||
// fontWeight: FontWeight.w600,
|
||||
color: Colors.black54,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Arrow between items
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||
child: Align(
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
">",
|
||||
style: TextStyle(
|
||||
color: Colors.black54,
|
||||
fontSize: isDesktop ? 16 : 14,
|
||||
height: 1.2,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:google_fonts/google_fonts.dart';
|
||||
//
|
||||
// class BreadcrumbItem {
|
||||
// final String title;
|
||||
// final void Function(BuildContext)? onTap;
|
||||
// final String? tooltip;
|
||||
//
|
||||
// BreadcrumbItem({
|
||||
// required this.title,
|
||||
// this.onTap,
|
||||
// this.tooltip,
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// class BreadcrumbNavigation extends StatelessWidget {
|
||||
// final List<BreadcrumbItem> breadcrumbItems;
|
||||
// final bool isDesktop;
|
||||
//
|
||||
// const BreadcrumbNavigation({
|
||||
// super.key,
|
||||
// required this.breadcrumbItems,
|
||||
// required this.isDesktop,
|
||||
// });
|
||||
//
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// return Wrap(
|
||||
// crossAxisAlignment: WrapCrossAlignment.center, // Ensures vertical alignment
|
||||
// children: List.generate(breadcrumbItems.length * 2 - 1, (index) {
|
||||
// if (index.isEven) {
|
||||
// final int itemIndex = index ~/ 2;
|
||||
// final item = breadcrumbItems[itemIndex];
|
||||
// final bool isLast = itemIndex == breadcrumbItems.length - 1;
|
||||
//
|
||||
// return Tooltip(
|
||||
// message: item.tooltip ?? item.title,
|
||||
// child: GestureDetector(
|
||||
// onTap: isLast || item.onTap == null
|
||||
// ? null
|
||||
// : () => item.onTap!(context), // pass context
|
||||
// child: Text( item.title,
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: isDesktop ? 16 : 14,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: isLast ? Colors.black : Colors.black54,
|
||||
// decoration: TextDecoration.none,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// } else {
|
||||
// // Arrow between items, centered vertically
|
||||
// return Padding(
|
||||
// padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||
// child: Align(
|
||||
// alignment: Alignment.center,
|
||||
// child: Text(" > ",
|
||||
// style: TextStyle(
|
||||
// color: Colors.black54,
|
||||
// fontSize: isDesktop ? 16 : 14,
|
||||
// height: 1.2, // Aligns better with text
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
Loading…
Reference in New Issue
Block a user