diff --git a/lib/Screens/policy/policy.dart b/lib/Screens/policy/policy.dart index 53df327..8d36fa3 100644 --- a/lib/Screens/policy/policy.dart +++ b/lib/Screens/policy/policy.dart @@ -40,7 +40,7 @@ class Policy extends StatefulWidget { class _PolicyState extends State { final GlobalKey policyCriteriaKey = - GlobalKey(); + GlobalKey(); final ApiService apiService = ApiService(); @@ -82,22 +82,22 @@ class _PolicyState extends State { Map get policyData { List> policyDetails = - policy_details!.where((service) { - // Only check these specific fields for emptiness - final fieldsToCheck = [ - 'cost', - 'class', - 'a1_action', - 'a2_action', - 'a3_action', - ]; + policy_details!.where((service) { + // Only check these specific fields for emptiness + final fieldsToCheck = [ + 'cost', + 'class', + 'a1_action', + 'a2_action', + 'a3_action', + ]; - // If any of the important fields has a value, keep it - return fieldsToCheck.any((field) { - final value = service[field]; - return value != null && value.toString().trim().isNotEmpty; - }); - }).toList(); + // If any of the important fields has a value, keep it + return fieldsToCheck.any((field) { + final value = service[field]; + return value != null && value.toString().trim().isNotEmpty; + }); + }).toList(); Map data = { @@ -181,14 +181,14 @@ class _PolicyState extends State { setState(() { layoutColor = - layoutString != null - ? Color(int.parse(layoutString)) - : Colors.redAccent; + layoutString != null + ? Color(int.parse(layoutString)) + : Colors.redAccent; bodyColor = - bodyStringColor != null - ? Color(int.parse(bodyStringColor)) - : Colors.white; + bodyStringColor != null + ? Color(int.parse(bodyStringColor)) + : Colors.white; }); } @@ -220,9 +220,9 @@ class _PolicyState extends State { try { List decoded = json.decode(rawServices); List> formatted = - decoded - .map((e) => {"service_id": e['service_id'].toString()}) - .toList(); + decoded + .map((e) => {"service_id": e['service_id'].toString()}) + .toList(); setState(() { selectedOrgServiceIds = formatted; @@ -247,7 +247,7 @@ class _PolicyState extends State { await loadOrgSelectedAlServices(); final selectedIds = - selectedOrgServiceIds.map((e) => e['service_id']).toSet(); + selectedOrgServiceIds.map((e) => e['service_id']).toSet(); if (widget.policy != null) { final details = List>.from( @@ -260,12 +260,12 @@ class _PolicyState extends State { // pr int("UUFiltered Selected Services - $details"); final filtered = - selectedAllServices! - .where( - (service) => - selectedIds.contains(service['service_id'].toString()), - ) - .toList(); + selectedAllServices! + .where( + (service) => + selectedIds.contains(service['service_id'].toString()), + ) + .toList(); setState(() { ServicesChoosed = filtered; @@ -290,11 +290,11 @@ class _PolicyState extends State { List>.from(decoded) .map( (service) => { - 'service_id': service['service_id'].toString(), - 'name': service['name'].toString(), - 'order': service['order'].toString(), - }, - ) + 'service_id': service['service_id'].toString(), + 'name': service['name'].toString(), + 'order': service['order'].toString(), + }, + ) .toList(); }); @@ -304,12 +304,12 @@ class _PolicyState extends State { print("Filtered Selected Services Added to Policy: $ServicesChoosed"); } else { final filtered = - selectedAllServices! - .where( - (service) => - selectedIds.contains(service['service_id'].toString()), - ) - .toList(); + selectedAllServices! + .where( + (service) => + selectedIds.contains(service['service_id'].toString()), + ) + .toList(); print("ServicesChoosedYY: $ServicesChoosed"); setState(() { @@ -324,12 +324,12 @@ class _PolicyState extends State { ServicesChoosed! .map( (service) => { - 'service_id': service['service_id'].toString(), - 'name': - service['name'].toString(), // ✅ no space before 'name' - 'order': service['order'].toString(), - }, - ) + 'service_id': service['service_id'].toString(), + 'name': + service['name'].toString(), // ✅ no space before 'name' + 'order': service['order'].toString(), + }, + ) .toList(); }); @@ -408,7 +408,7 @@ class _PolicyState extends State { if (domestic != "1" && international != "1") { errorMessages["trip_type"] = - "Required"; // "Please select Domestic or International."; + "Required"; // "Please select Domestic or International."; } // Validate at least one policy_detail with valid content @@ -430,7 +430,7 @@ class _PolicyState extends State { if (!hasAtLeastOneDetail) { errorMessages["policy_details"] = - "Required"; // "At least one valid policy detail is required."; + "Required"; // "At least one valid policy detail is required."; } return errorMessages.isEmpty; @@ -496,16 +496,16 @@ class _PolicyState extends State { drawer: CustomDrawer(isDesktop: false), body: Padding( padding: - isDesktop - ? EdgeInsets.symmetric( - horizontal: - MediaQuery.of(context).size.width * - 0.1, // 30% of screen width as horizontal padding - vertical: - MediaQuery.of(context).size.height * - 0, // 5% of screen height as vertical padding - ) - : EdgeInsets.all(8), + isDesktop + ? EdgeInsets.symmetric( + horizontal: + MediaQuery.of(context).size.width * + 0.1, // 30% of screen width as horizontal padding + vertical: + MediaQuery.of(context).size.height * + 0, // 5% of screen height as vertical padding + ) + : EdgeInsets.all(8), child: Column( children: [ Expanded( @@ -591,15 +591,15 @@ class _PolicyState extends State { color: Colors.white, padding: const EdgeInsets.all(8.0), child: - isDesktop - ? Row( - mainAxisAlignment: MainAxisAlignment.end, - children: _buildSubmit(isDesktop), - ) - : Row( - mainAxisAlignment: MainAxisAlignment.center, - children: _buildSubmit(isDesktop), - ), + isDesktop + ? Row( + mainAxisAlignment: MainAxisAlignment.end, + children: _buildSubmit(isDesktop), + ) + : Row( + mainAxisAlignment: MainAxisAlignment.center, + children: _buildSubmit(isDesktop), + ), ), ], ), @@ -612,9 +612,9 @@ class _PolicyState extends State { // ? EdgeInsets.all(10.0) // : EdgeInsets.only(left: 20.0, bottom: 20.0, top: 10.0, right: 20.0), height: - isDesktop - ? MediaQuery.of(context).size.height * 0.98 - : MediaQuery.of(context).size.height, + isDesktop + ? MediaQuery.of(context).size.height * 0.98 + : MediaQuery.of(context).size.height, // decoration: BoxDecoration( // border: isDesktop // ? Border.all( @@ -663,23 +663,23 @@ class _PolicyState extends State { Container( padding: isDesktop ? const EdgeInsets.only(left: 35) : null, child: - isDesktop - ? Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded(child: _buildPolicyNameField(isDesktop)), - Spacer(), - Expanded(child: _buildPolicyTypeField(isDesktop)), - ], - ) - : Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _buildPolicyNameField(isDesktop), - SizedBox(height: 20), - _buildPolicyTypeField(isDesktop), - ], - ), + isDesktop + ? Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded(child: _buildPolicyNameField(isDesktop)), + Spacer(), + Expanded(child: _buildPolicyTypeField(isDesktop)), + ], + ) + : Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildPolicyNameField(isDesktop), + SizedBox(height: 20), + _buildPolicyTypeField(isDesktop), + ], + ), ), SizedBox(height: 10), Divider(thickness: 0.1, color: Colors.grey), @@ -692,66 +692,66 @@ class _PolicyState extends State { ], isDesktop ? Padding( - padding: const EdgeInsets.only(left: 30.0, right: 98.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Approval Criteria", - style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Color(0xFF575A74), - ), - ), - Text( - "Service Priority", - style: GoogleFonts.poppins( - fontSize: 12, - fontWeight: FontWeight.w600, - color: Color(0xFF575A74), - ), - ), - ], + padding: const EdgeInsets.only(left: 30.0, right: 98.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Approval Criteria", + style: GoogleFonts.poppins( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xFF575A74), + ), ), - ) + Text( + "Service Priority", + style: GoogleFonts.poppins( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xFF575A74), + ), + ), + ], + ), + ) : SizedBox.shrink(), isDesktop ? Container( - // color: Colors.yellow.shade50, - height: MediaQuery.of(context).size.height * 0.54, - child: SingleChildScrollView( - scrollDirection: Axis.vertical, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, + // color: Colors.yellow.shade50, + height: MediaQuery.of(context).size.height * 0.54, + child: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( children: [ - Column( - children: [ - _buildPolicyOrdering(isDesktop), - _buildPolicyCategory(isDesktop), - ], - ), - Column(children: [_buildPolicyCategoryList(isDesktop)]), + _buildPolicyOrdering(isDesktop), + _buildPolicyCategory(isDesktop), ], ), - ), - ) + Column(children: [_buildPolicyCategoryList(isDesktop)]), + ], + ), + ), + ) : Expanded( - child: Container( - child: SingleChildScrollView( - scrollDirection: Axis.vertical, - child: Column( - children: [ - _buildPolicyCategoryList(isDesktop), - _buildPolicyOrdering(isDesktop), - _buildPolicyCategory(isDesktop), - ], - ), - ), + child: Container( + child: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: Column( + children: [ + _buildPolicyCategoryList(isDesktop), + _buildPolicyOrdering(isDesktop), + _buildPolicyCategory(isDesktop), + ], ), ), + ), + ), // isDesktop // ? Expanded( // child: Row( @@ -864,28 +864,28 @@ class _PolicyState extends State { border: Border.all(color: Colors.blueGrey.shade100, width: 0.35), ), child: - isDesktop - ? Padding( - padding: const EdgeInsets.all(10.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.start, - children: [_buildPolicySubCategoryList(isDesktop)], - ), - ) - : Column( - children: [ - Container( - // color: Colors.amber, - child: _buildPolicySubCategoryList(isDesktop), - // child: Text("FAta"), - // child: Row( - // mainAxisAlignment: MainAxisAlignment.start, - // children: [_buildPolicySubCategoryList(isDesktop)], - // ), - ), - ], - ), + isDesktop + ? Padding( + padding: const EdgeInsets.all(10.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [_buildPolicySubCategoryList(isDesktop)], + ), + ) + : Column( + children: [ + Container( + // color: Colors.amber, + child: _buildPolicySubCategoryList(isDesktop), + // child: Text("FAta"), + // child: Row( + // mainAxisAlignment: MainAxisAlignment.start, + // children: [_buildPolicySubCategoryList(isDesktop)], + // ), + ), + ], + ), ); } @@ -1042,21 +1042,21 @@ class _PolicyState extends State { width: isDesktop ? MediaQuery.of(context).size.width * 0.62 : null, // width: isDesktop ? MediaQuery.of(context).size.width * 0.75 : null, child: - isDesktop - ? Container( - // color: Colors.amber, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [_buildPolicyServiceOrdering(isDesktop)], - ), - ) - : Container( - // color: Colors.amber, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [_buildPolicyServiceOrdering(isDesktop)], - ), - ), + isDesktop + ? Container( + // color: Colors.amber, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [_buildPolicyServiceOrdering(isDesktop)], + ), + ) + : Container( + // color: Colors.amber, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [_buildPolicyServiceOrdering(isDesktop)], + ), + ), ); } @@ -1067,11 +1067,11 @@ class _PolicyState extends State { // Sort services by 'order' ServicesChoosed!.sort( - (a, b) => (a['order'] ?? 0).compareTo(b['order'] ?? 0), + (a, b) => (a['order'] ?? 0).compareTo(b['order'] ?? 0), ); List services = - ServicesChoosed!.map((service) => service['name'].toString()).toList(); + ServicesChoosed!.map((service) => service['name'].toString()).toList(); return Container( child: SingleChildScrollView( @@ -1079,104 +1079,104 @@ class _PolicyState extends State { child: Flex( direction: Axis.horizontal, children: - services.asMap().entries.map((entry) { - int index = entry.key + 1; - String service = entry.value; - String serviceId = index.toString(); - bool isSelected = - selectedServiceIndex.value == index.toString(); + services.asMap().entries.map((entry) { + int index = entry.key + 1; + String service = entry.value; + String serviceId = index.toString(); + bool isSelected = + selectedServiceIndex.value == index.toString(); - return SizedBox( - // width: isDesktop ? 40 : null, - height: - isDesktop - ? max( - (MediaQuery.of(context).size.height * 0.075), - 10, - ) - : 45, + return SizedBox( + // width: isDesktop ? 40 : null, + height: + isDesktop + ? max( + (MediaQuery.of(context).size.height * 0.075), + 10, + ) + : 45, - // max((MediaQuery.of(context).size.height * 0.09), 10) - child: GestureDetector( - onTap: () { - print("Selected Services - $service - $index"); - setState(() { - selectedServiceIndex.value = index.toString(); - selectedService = service; + // max((MediaQuery.of(context).size.height * 0.09), 10) + child: GestureDetector( + onTap: () { + print("Selected Services - $service - $index"); + setState(() { + selectedServiceIndex.value = index.toString(); + selectedService = service; - print( - " selectedServiceIndex.value - ${selectedServiceIndex.value}", - ); + print( + " selectedServiceIndex.value - ${selectedServiceIndex.value}", + ); - // policyCriteriaKey.currentState?.fieldForPolicy(); - // policyCriteriaKey.currentState - // ?.addOrUpdatePolicy(selectedServiceIndex.value); - print("policyselectedService - $selectedService"); - if (selectedService == "Flight" || - selectedService == "Train" || selectedService == "Accomodation") { - showClass = true; - showCost = false; - int serviceCode = selectedService == "Flight" ? 1 : 2; - print("policyselectedService1 - $selectedService"); - policyCriteriaKey.currentState - ?.fetchTrainFlightClass(); - } - // else if (selectedService == "Accommodation") { - // showClass = true; - // showCost = false; - // } - else { - showClass = false; - showCost = false; - } - }); - }, - child: Container( - margin: const EdgeInsets.all(5), - padding: - isDesktop - ? const EdgeInsets.all(8) - : const EdgeInsets.symmetric( - horizontal: 8, - vertical: 3, - ), - alignment: Alignment.center, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - service, - style: GoogleFonts.poppins( - color: - isSelected - ? const Color(0xFF114D8B) - : Colors.black87, - fontSize: 13, - fontWeight: - isSelected - ? FontWeight.bold - : FontWeight.w500, - decoration: - TextDecoration - .none, // remove built-in underline - ), - ), - if (isSelected) - const SizedBox( - height: 1, - ), // spacing between text and underline - if (isSelected) - Container( - height: 2, - width: 30, // or based on text width - color: const Color(0xFF114D8B), - ), - ], - ), - ), + // policyCriteriaKey.currentState?.fieldForPolicy(); + // policyCriteriaKey.currentState + // ?.addOrUpdatePolicy(selectedServiceIndex.value); + print("policyselectedService - $selectedService"); + if (selectedService == "Flight" || + selectedService == "Train" || selectedService == "Accomodation") { + showClass = true; + showCost = false; + int serviceCode = selectedService == "Flight" ? 1 : 2; + print("policyselectedService1 - $selectedService"); + policyCriteriaKey.currentState + ?.fetchTrainFlightClass(); + } + // else if (selectedService == "Accommodation") { + // showClass = true; + // showCost = false; + // } + else { + showClass = false; + showCost = false; + } + }); + }, + child: Container( + margin: const EdgeInsets.all(5), + padding: + isDesktop + ? const EdgeInsets.all(8) + : const EdgeInsets.symmetric( + horizontal: 8, + vertical: 3, ), - ); - }).toList(), + alignment: Alignment.center, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + service, + style: GoogleFonts.poppins( + color: + isSelected + ? const Color(0xFF114D8B) + : Colors.black87, + fontSize: 13, + fontWeight: + isSelected + ? FontWeight.bold + : FontWeight.w500, + decoration: + TextDecoration + .none, // remove built-in underline + ), + ), + if (isSelected) + const SizedBox( + height: 1, + ), // spacing between text and underline + if (isSelected) + Container( + height: 2, + width: 30, // or based on text width + color: const Color(0xFF114D8B), + ), + ], + ), + ), + ), + ); + }).toList(), ), ), ); @@ -1200,7 +1200,7 @@ class _PolicyState extends State { } List services = - ServicesChoosed!.map((service) => service['name'].toString()).toList(); + ServicesChoosed!.map((service) => service['name'].toString()).toList(); return Expanded( child: SingleChildScrollView( @@ -1208,88 +1208,88 @@ class _PolicyState extends State { child: Flex( direction: isDesktop ? Axis.vertical : Axis.horizontal, children: - services.asMap().entries.map((entry) { - int index = entry.key + 1; - String service = entry.value; - bool isSelected = - selectedServiceIndex.value == index.toString(); + services.asMap().entries.map((entry) { + int index = entry.key + 1; + String service = entry.value; + bool isSelected = + selectedServiceIndex.value == index.toString(); - return SizedBox( - width: isDesktop ? 180 : null, - height: - isDesktop - ? max( - (MediaQuery.of(context).size.height * 0.075), - 10, - ) - : 45, + return SizedBox( + width: isDesktop ? 180 : null, + height: + isDesktop + ? max( + (MediaQuery.of(context).size.height * 0.075), + 10, + ) + : 45, - // max((MediaQuery.of(context).size.height * 0.09), 10) - child: GestureDetector( - onTap: () { - print("Selected Services - $service - $index"); - setState(() { - // selectedServiceIndex.value = index.toString(); - // selectedService = service; - // - // if (selectedService == "Flight" || - // selectedService == "Train") { - // showClass = true; - // showCost = true; - // int serviceCode = selectedService == "Flight" ? 1 : 2; - // policyCriteriaKey.currentState?.fetchTrainFlightClass(); - // } else if (selectedService == "Accommodation") { - // showClass = true; - // showCost = false; - // } else { - // showClass = false; - // showCost = false; - // } - }); - }, - child: Container( - margin: EdgeInsets.all(5), - padding: - isDesktop - ? EdgeInsets.all(8) - : EdgeInsets.only( - top: 3, - bottom: 3, - left: 8, - right: 8, - ), - decoration: BoxDecoration( - // color: Colors.blue, - color: isSelected ? Color(0xFF114D8B) : Colors.white, - // : Color(0xFFEBEBF7), - borderRadius: BorderRadius.circular(8), - border: Border.all( - color: Colors.white, // Light grey border - width: 1, - ), - boxShadow: [ - BoxShadow( - color: Colors.grey.withAlpha(90), // Shadow color - blurRadius: 1, // Blur radius - spreadRadius: 1, // Spread radius - offset: Offset(0, 1), // Shadow position - ), - ], - ), - alignment: Alignment.center, - child: Text( - service, - style: GoogleFonts.poppins( - color: isSelected ? Colors.white : Colors.black87, - fontSize: 13, - fontWeight: - isSelected ? FontWeight.bold : FontWeight.w100, - ), + // max((MediaQuery.of(context).size.height * 0.09), 10) + child: GestureDetector( + onTap: () { + print("Selected Services - $service - $index"); + setState(() { + // selectedServiceIndex.value = index.toString(); + // selectedService = service; + // + // if (selectedService == "Flight" || + // selectedService == "Train") { + // showClass = true; + // showCost = true; + // int serviceCode = selectedService == "Flight" ? 1 : 2; + // policyCriteriaKey.currentState?.fetchTrainFlightClass(); + // } else if (selectedService == "Accommodation") { + // showClass = true; + // showCost = false; + // } else { + // showClass = false; + // showCost = false; + // } + }); + }, + child: Container( + margin: EdgeInsets.all(5), + padding: + isDesktop + ? EdgeInsets.all(8) + : EdgeInsets.only( + top: 3, + bottom: 3, + left: 8, + right: 8, + ), + decoration: BoxDecoration( + // color: Colors.blue, + color: isSelected ? Color(0xFF114D8B) : Colors.white, + // : Color(0xFFEBEBF7), + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: Colors.white, // Light grey border + width: 1, + ), + boxShadow: [ + BoxShadow( + color: Colors.grey.withAlpha(90), // Shadow color + blurRadius: 1, // Blur radius + spreadRadius: 1, // Spread radius + offset: Offset(0, 1), // Shadow position ), + ], + ), + alignment: Alignment.center, + child: Text( + service, + style: GoogleFonts.poppins( + color: isSelected ? Colors.white : Colors.black87, + fontSize: 13, + fontWeight: + isSelected ? FontWeight.bold : FontWeight.w100, ), ), - ); - }).toList(), + ), + ), + ); + }).toList(), ), ), ); @@ -1366,14 +1366,14 @@ class _PolicyState extends State { borderRadius: BorderRadius.circular(4), // Rounded rectangle border: Border.all( color: - _selectedTripType == "1" ? Colors.green : Colors.black, + _selectedTripType == "1" ? Colors.green : Colors.black, width: _selectedTripType == "1" ? 2 : 1, ), ), child: - _selectedTripType == "1" - ? Icon(Icons.rectangle, size: 8, color: Colors.green) - : null, // Add checkmark if selected + _selectedTripType == "1" + ? Icon(Icons.rectangle, size: 8, color: Colors.green) + : null, // Add checkmark if selected ), ), ], @@ -1422,14 +1422,14 @@ class _PolicyState extends State { borderRadius: BorderRadius.circular(4), // Rounded rectangle border: Border.all( color: - _selectedTripType == "2" ? Colors.green : Colors.black, + _selectedTripType == "2" ? Colors.green : Colors.black, width: _selectedTripType == "2" ? 2 : 1, ), ), child: - _selectedTripType == "2" - ? Icon(Icons.rectangle, size: 8, color: Colors.green) - : null, // Add checkmark if selected + _selectedTripType == "2" + ? Icon(Icons.rectangle, size: 8, color: Colors.green) + : null, // Add checkmark if selected ), ), ], @@ -1474,17 +1474,17 @@ class _PolicyState extends State { SizedBox(width: 20), MouseRegion( cursor: - isViewMode - ? SystemMouseCursors.forbidden - : SystemMouseCursors.click, + isViewMode + ? SystemMouseCursors.forbidden + : SystemMouseCursors.click, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: - isViewMode ? layoutColor : layoutColor, // Keep original color + isViewMode ? layoutColor : layoutColor, // Keep original color foregroundColor: - isViewMode ? Colors.white : Colors.white, // Keep original color + isViewMode ? Colors.white : Colors.white, // Keep original color disabledBackgroundColor: - layoutColor, // Ensure color remains when disabled + layoutColor, // Ensure color remains when disabled disabledForegroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), @@ -1493,7 +1493,7 @@ class _PolicyState extends State { padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), ), onPressed: - isViewMode ? null : handleSubmit, // Disable when in view mode + isViewMode ? null : handleSubmit, // Disable when in view mode child: Text("Submit", style: GoogleFonts.poppins(fontSize: 10)), ), ), @@ -1565,4 +1565,4 @@ class _PolicyState extends State { ), ]; } -} +} \ No newline at end of file diff --git a/lib/Screens/policy/policyCriteria.dart b/lib/Screens/policy/policyCriteria.dart index 6e4545f..085c588 100644 --- a/lib/Screens/policy/policyCriteria.dart +++ b/lib/Screens/policy/policyCriteria.dart @@ -65,6 +65,7 @@ class PolicyCriteriaState extends State { Map FirstExceptionalApproverAction = {}; Map SecondExceptionalApproverAction = {}; Map ThirdExceptionalApproverAction = {}; + Map FourthExceptionalApproverAction = {}; Map SelectedParallelExceptionalProcess = {}; Map FirstAmendApproverAction = {}; @@ -137,7 +138,7 @@ class PolicyCriteriaState extends State { // Step 2: Collect existing service_ids from policyData final existingServiceIds = - policyData?.map((e) => e['service_id'].toString()).toSet(); + policyData?.map((e) => e['service_id'].toString()).toSet(); // Step 3: Loop through all service definitions for (var service in services) { @@ -157,7 +158,8 @@ class PolicyCriteriaState extends State { FirstExceptionalApproverAction.putIfAbsent(id, () => "None"); SecondExceptionalApproverAction.putIfAbsent(id, () => "None"); ThirdExceptionalApproverAction.putIfAbsent(id, () => "None"); - SelectedParallelExceptionalProcess.putIfAbsent(id, () => "3"); + FourthExceptionalApproverAction.putIfAbsent(id, () => "None"); + SelectedParallelExceptionalProcess.putIfAbsent(id, () => "4"); FirstAmendApproverAction.putIfAbsent(id, () => "None"); SecondAmendApproverAction.putIfAbsent(id, () => "None"); @@ -176,8 +178,9 @@ class PolicyCriteriaState extends State { "a1_exceptional_action": FirstExceptionalApproverAction[id], "a2_exceptional_action": SecondExceptionalApproverAction[id], "a3_exceptional_action": ThirdExceptionalApproverAction[id], + "a4_exceptional_action": FourthExceptionalApproverAction[id], "exceptional_parallel_process_from": - SelectedParallelExceptionalProcess[id], + SelectedParallelExceptionalProcess[id], "a1_amendment_action": FirstAmendApproverAction[id], "a2_amendment_action": SecondAmendApproverAction[id], "a3_amendment_action": ThirdAmendApproverAction[id], @@ -215,6 +218,8 @@ class PolicyCriteriaState extends State { item['a2_exceptional_action']?.toString(); ThirdExceptionalApproverAction[serviceId] = item['a3_exceptional_action']?.toString(); + FourthExceptionalApproverAction[serviceId] = + item['a4_exceptional_action']?.toString(); SelectedParallelExceptionalProcess[serviceId] = item['exceptional_parallel_process_from']?.toString() ?? "3"; @@ -254,7 +259,7 @@ class PolicyCriteriaState extends State { print("addOrUpdatePolicyserviceId - $serviceId"); // 1. First, find existing item if any final existingIndex = policyData!.indexWhere( - (item) => item["service_id"] == serviceId, + (item) => item["service_id"] == serviceId, ); Map data = { @@ -269,13 +274,14 @@ class PolicyCriteriaState extends State { "a1_exceptional_action": FirstExceptionalApproverAction[serviceId], "a2_exceptional_action": SecondExceptionalApproverAction[serviceId], "a3_exceptional_action": ThirdExceptionalApproverAction[serviceId], + "a4_exceptional_action": FourthExceptionalApproverAction[serviceId], "exceptional_parallel_process_from": - SelectedParallelExceptionalProcess[serviceId], + SelectedParallelExceptionalProcess[serviceId], "a1_amendment_action": FirstAmendApproverAction[serviceId], "a2_amendment_action": SecondAmendApproverAction[serviceId], "a3_amendment_action": ThirdAmendApproverAction[serviceId], "amendment_parallel_process_from": - SelectedParallelAmendProcess[serviceId], + SelectedParallelAmendProcess[serviceId], "created_by": widget.userId, }; @@ -290,6 +296,7 @@ class PolicyCriteriaState extends State { final ae1 = FirstExceptionalApproverAction[serviceId]; final ae2 = SecondExceptionalApproverAction[serviceId]; final ae3 = ThirdExceptionalApproverAction[serviceId]; + final ae4 = FourthExceptionalApproverAction[serviceId]; final aa1 = FirstAmendApproverAction[serviceId]; final aa2 = SecondAmendApproverAction[serviceId]; @@ -302,17 +309,17 @@ class PolicyCriteriaState extends State { bool allActionsNull = a1 == null && a2 == null && a3 == null; bool someActionsMissing = [a1, a2, a3].where((a) => a != null).length > 0 && - [a1, a2, a3].where((a) => a == null).length > 0; + [a1, a2, a3].where((a) => a == null).length > 0; bool allExceptionalActionsNull = ae1 == null && ae2 == null && ae3 == null; bool someExceptionalActionsMissing = [ae1, ae2, ae3].where((a) => a != null).length > 0 && - [ae1, ae2, ae3].where((a) => a == null).length > 0; + [ae1, ae2, ae3].where((a) => a == null).length > 0; bool allAmendActionsNull = aa1 == null && aa2 == null && aa3 == null; bool someAmendActionsMissing = [aa1, aa2, aa3].where((a) => a != null).length > 0 && - [aa1, aa2, aa3].where((a) => a == null).length > 0; + [aa1, aa2, aa3].where((a) => a == null).length > 0; if (someActionsMissing) { validationErrors[serviceId] = "All 3 approver actions must be selected."; @@ -320,12 +327,12 @@ class PolicyCriteriaState extends State { } if (someExceptionalActionsMissing) { validationErrors[serviceId] = - "All 3 exceptional approver actions must be selected."; + "All 3 exceptional approver actions must be selected."; return; } if (someAmendActionsMissing) { validationErrors[serviceId] = - "All 3 amendment approver actions must be selected."; + "All 3 amendment approver actions must be selected."; return; } @@ -463,7 +470,8 @@ class PolicyCriteriaState extends State { FirstExceptionalApproverAction.putIfAbsent(ServiceId!, () => "None"); SecondExceptionalApproverAction.putIfAbsent(ServiceId!, () => "None"); ThirdExceptionalApproverAction.putIfAbsent(ServiceId!, () => "None"); - SelectedParallelExceptionalProcess.putIfAbsent(ServiceId!, () => "3"); + FourthExceptionalApproverAction.putIfAbsent(ServiceId!, () => "None"); + SelectedParallelExceptionalProcess.putIfAbsent(ServiceId!, () => "4"); FirstAmendApproverAction.putIfAbsent(ServiceId!, () => "None"); SecondAmendApproverAction.putIfAbsent(ServiceId!, () => "None"); @@ -505,9 +513,9 @@ class PolicyCriteriaState extends State { widget.isDesktop ? SizedBox(height: 1) : SizedBox(height: 1), Padding( padding: - widget.isDesktop - ? const EdgeInsets.only(left: 0.0) - : const EdgeInsets.only(left: 0), + widget.isDesktop + ? const EdgeInsets.only(left: 0.0) + : const EdgeInsets.only(left: 0), child: Row( children: [ Container( @@ -519,27 +527,27 @@ class PolicyCriteriaState extends State { right: 5, ), child: - widget.isDesktop - ? Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - if (widget.isClass) - buildClassWidget(widget.isDesktop), - SizedBox(width: 45), - if (widget.isCost!) - buildCostWidget(widget.isDesktop), - ], - ) - : Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (widget.isClass!) - buildClassWidget(widget.isDesktop), - SizedBox(height: 10), - if (widget.isCost!) - buildCostWidget(widget.isDesktop), - ], - ), + widget.isDesktop + ? Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (widget.isClass) + buildClassWidget(widget.isDesktop), + SizedBox(width: 45), + if (widget.isCost!) + buildCostWidget(widget.isDesktop), + ], + ) + : Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (widget.isClass!) + buildClassWidget(widget.isDesktop), + SizedBox(height: 10), + if (widget.isCost!) + buildCostWidget(widget.isDesktop), + ], + ), ), ], ), @@ -577,13 +585,13 @@ class PolicyCriteriaState extends State { Container( // color: Colors.yellow, width: - widget.isDesktop - ? MediaQuery.of(context).size.width * 0.18 - : 600, + widget.isDesktop + ? MediaQuery.of(context).size.width * 0.18 + : 600, height: - widget.isDesktop - ? MediaQuery.of(context).size.height * 0.56 - : null, + widget.isDesktop + ? MediaQuery.of(context).size.height * 0.56 + : null, child: Column( children: [ Container( @@ -602,9 +610,9 @@ class PolicyCriteriaState extends State { ), child: Row( mainAxisAlignment: - widget.isDesktop - ? MainAxisAlignment.spaceAround - : MainAxisAlignment.spaceBetween, + widget.isDesktop + ? MainAxisAlignment.spaceAround + : MainAxisAlignment.spaceBetween, children: [ Expanded( flex: 3, @@ -652,11 +660,11 @@ class PolicyCriteriaState extends State { border: Border( right: BorderSide( color: - Colors - .blueGrey - .shade50, // Change this to your desired color + Colors + .blueGrey + .shade50, // Change this to your desired color width: - 1.0, // Change this to your desired width + 1.0, // Change this to your desired width ), ), ), @@ -680,9 +688,9 @@ class PolicyCriteriaState extends State { Spacer(), CustomTextFieldUserWrapper( width: - MediaQuery.of( - context, - ).size.width * + MediaQuery.of( + context, + ).size.width * 0.12, isFocused: false, isDesktop: widget.isDesktop, @@ -690,38 +698,38 @@ class PolicyCriteriaState extends State { height: 35, child: DropdownSearch( selectedItem: - FirstApproverAction[ServiceId], + FirstApproverAction[ServiceId], // enabled: !isViewMode, popupProps: PopupProps.menu( // showSearchBox: true, fit: - FlexFit - .loose, // Allows flexible height + FlexFit + .loose, // Allows flexible height constraints: BoxConstraints( maxHeight: 250, ), itemBuilder: ( - context, - item, - isSelected, + context, + item, + isSelected, ) => Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 16.0, - vertical: 8.0, - ), - child: Text( - item, - style: GoogleFonts.poppins( - fontSize: - 12, // 👈 Smaller text size here - color: - Colors - .black, // You can customize this - ), - ), + padding: + const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 8.0, + ), + child: Text( + item, + style: GoogleFonts.poppins( + fontSize: + 12, // 👈 Smaller text size here + color: + Colors + .black, // You can customize this ), + ), + ), ), items: [ "Approval", @@ -729,29 +737,29 @@ class PolicyCriteriaState extends State { "None", ], dropdownDecoratorProps: - DropDownDecoratorProps( - dropdownSearchDecoration: - InputDecoration( - border: - InputBorder.none, - contentPadding: - EdgeInsets.symmetric( - horizontal: 1, - vertical: 5, - ), - ), + DropDownDecoratorProps( + dropdownSearchDecoration: + InputDecoration( + border: + InputBorder.none, + contentPadding: + EdgeInsets.symmetric( + horizontal: 1, + vertical: 5, ), + ), + ), dropdownBuilder: ( - context, - selectedItem, + context, + selectedItem, ) => Text( - selectedItem ?? "Select", - style: GoogleFonts.poppins( - fontSize: 12, - color: Color(0xFF114D8B), - ), - ), + selectedItem ?? "Select", + style: GoogleFonts.poppins( + fontSize: 12, + color: Color(0xFF114D8B), + ), + ), onChanged: (String? newValue) { setState(() { @@ -774,7 +782,7 @@ class PolicyCriteriaState extends State { onTap: () { setState(() { SelectedParallelProcess[ServiceId!] = - "1"; + "1"; }); print( @@ -788,10 +796,10 @@ class PolicyCriteriaState extends State { shape: BoxShape.circle, border: Border.all( color: - (SelectedParallelProcess[ServiceId] == - "1") - ? Colors.green - : Colors.grey, + (SelectedParallelProcess[ServiceId] == + "1") + ? Colors.green + : Colors.grey, width: 2, ), ), @@ -799,10 +807,10 @@ class PolicyCriteriaState extends State { Icons.check_circle, size: 20, color: - (SelectedParallelProcess[ServiceId] == - "1") - ? Colors.green - : Colors.grey, + (SelectedParallelProcess[ServiceId] == + "1") + ? Colors.green + : Colors.grey, // color: Colors.grey, ), ), @@ -825,9 +833,9 @@ class PolicyCriteriaState extends State { Spacer(), CustomTextFieldUserWrapper( width: - MediaQuery.of( - context, - ).size.width * + MediaQuery.of( + context, + ).size.width * 0.12, isFocused: false, isDesktop: widget.isDesktop, @@ -835,38 +843,38 @@ class PolicyCriteriaState extends State { height: 35, child: DropdownSearch( selectedItem: - SecondApproverAction[ServiceId], + SecondApproverAction[ServiceId], // enabled: !isViewMode, popupProps: PopupProps.menu( // showSearchBox: true, fit: - FlexFit - .loose, // Allows flexible height + FlexFit + .loose, // Allows flexible height constraints: BoxConstraints( maxHeight: 250, ), itemBuilder: ( - context, - item, - isSelected, + context, + item, + isSelected, ) => Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 16.0, - vertical: 8.0, - ), - child: Text( - item, - style: TextStyle( - fontSize: - 12, // 👈 Smaller text size here - color: - Colors - .black, // You can customize this - ), - ), + padding: + const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 8.0, + ), + child: Text( + item, + style: TextStyle( + fontSize: + 12, // 👈 Smaller text size here + color: + Colors + .black, // You can customize this ), + ), + ), ), items: [ "Approval", @@ -874,29 +882,29 @@ class PolicyCriteriaState extends State { "None", ], dropdownDecoratorProps: - DropDownDecoratorProps( - dropdownSearchDecoration: - InputDecoration( - border: - InputBorder.none, - contentPadding: - EdgeInsets.symmetric( - horizontal: 1, - vertical: 5, - ), - ), + DropDownDecoratorProps( + dropdownSearchDecoration: + InputDecoration( + border: + InputBorder.none, + contentPadding: + EdgeInsets.symmetric( + horizontal: 1, + vertical: 5, ), + ), + ), dropdownBuilder: ( - context, - selectedItem, + context, + selectedItem, ) => Text( - selectedItem ?? "Select", - style: GoogleFonts.poppins( - fontSize: 12, - color: Color(0xFF114D8B), - ), - ), + selectedItem ?? "Select", + style: GoogleFonts.poppins( + fontSize: 12, + color: Color(0xFF114D8B), + ), + ), onChanged: (String? newValue) { setState(() { @@ -919,7 +927,7 @@ class PolicyCriteriaState extends State { onTap: () { setState(() { SelectedParallelProcess[ServiceId!] = - "2"; + "2"; }); print( @@ -933,12 +941,12 @@ class PolicyCriteriaState extends State { shape: BoxShape.circle, border: Border.all( color: - ((SelectedParallelProcess[ServiceId] == - "1") || - (SelectedParallelProcess[ServiceId] == - "2")) - ? Colors.green - : Colors.grey, + ((SelectedParallelProcess[ServiceId] == + "1") || + (SelectedParallelProcess[ServiceId] == + "2")) + ? Colors.green + : Colors.grey, width: 2, ), ), @@ -946,12 +954,12 @@ class PolicyCriteriaState extends State { Icons.check_circle, size: 20, color: - ((SelectedParallelProcess[ServiceId] == - "1") || - (SelectedParallelProcess[ServiceId] == - "2")) - ? Colors.green - : Colors.grey, + ((SelectedParallelProcess[ServiceId] == + "1") || + (SelectedParallelProcess[ServiceId] == + "2")) + ? Colors.green + : Colors.grey, // color: Colors.grey, ), ), @@ -973,9 +981,9 @@ class PolicyCriteriaState extends State { Spacer(), CustomTextFieldUserWrapper( width: - MediaQuery.of( - context, - ).size.width * + MediaQuery.of( + context, + ).size.width * 0.12, isFocused: false, isDesktop: widget.isDesktop, @@ -983,38 +991,38 @@ class PolicyCriteriaState extends State { height: 35, child: DropdownSearch( selectedItem: - ThirdApproverAction[ServiceId], + ThirdApproverAction[ServiceId], // enabled: !isViewMode, popupProps: PopupProps.menu( // showSearchBox: true, fit: - FlexFit - .loose, // Allows flexible height + FlexFit + .loose, // Allows flexible height constraints: BoxConstraints( maxHeight: 250, ), itemBuilder: ( - context, - item, - isSelected, + context, + item, + isSelected, ) => Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 16.0, - vertical: 8.0, - ), - child: Text( - item, - style: GoogleFonts.poppins( - fontSize: - 12, // 👈 Smaller text size here - color: - Colors - .black, // You can customize this - ), - ), + padding: + const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 8.0, + ), + child: Text( + item, + style: GoogleFonts.poppins( + fontSize: + 12, // 👈 Smaller text size here + color: + Colors + .black, // You can customize this ), + ), + ), ), items: [ "Approval", @@ -1022,28 +1030,28 @@ class PolicyCriteriaState extends State { "None", ], dropdownDecoratorProps: - DropDownDecoratorProps( - dropdownSearchDecoration: - InputDecoration( - border: - InputBorder.none, - contentPadding: - EdgeInsets.symmetric( - horizontal: 1, - vertical: 5, - ), - ), + DropDownDecoratorProps( + dropdownSearchDecoration: + InputDecoration( + border: + InputBorder.none, + contentPadding: + EdgeInsets.symmetric( + horizontal: 1, + vertical: 5, ), + ), + ), dropdownBuilder: (context, selectedItem) => - // Center-align selected item - Text( - selectedItem ?? "Select", - style: GoogleFonts.poppins( - fontSize: 12, - color: Color(0xFF114D8B), - ), - ), + // Center-align selected item + Text( + selectedItem ?? "Select", + style: GoogleFonts.poppins( + fontSize: 12, + color: Color(0xFF114D8B), + ), + ), onChanged: (String? newValue) { setState(() { @@ -1066,7 +1074,7 @@ class PolicyCriteriaState extends State { onTap: () { setState(() { SelectedParallelProcess[ServiceId!] = - "3"; + "3"; }); print( "SelectedParallelProcess - $SelectedParallelProcess[ServiceId]", @@ -1079,14 +1087,14 @@ class PolicyCriteriaState extends State { shape: BoxShape.circle, border: Border.all( color: - ((SelectedParallelProcess[ServiceId] == - "1") || - (SelectedParallelProcess[ServiceId] == - "2") || - (SelectedParallelProcess[ServiceId] == - "3")) - ? Colors.green - : Colors.grey, + ((SelectedParallelProcess[ServiceId] == + "1") || + (SelectedParallelProcess[ServiceId] == + "2") || + (SelectedParallelProcess[ServiceId] == + "3")) + ? Colors.green + : Colors.grey, width: 2, ), ), @@ -1094,14 +1102,14 @@ class PolicyCriteriaState extends State { Icons.check_circle, size: 20, color: - ((SelectedParallelProcess[ServiceId] == - "1") || - (SelectedParallelProcess[ServiceId] == - "2") || - (SelectedParallelProcess[ServiceId] == - "3")) - ? Colors.green - : Colors.grey, + ((SelectedParallelProcess[ServiceId] == + "1") || + (SelectedParallelProcess[ServiceId] == + "2") || + (SelectedParallelProcess[ServiceId] == + "3")) + ? Colors.green + : Colors.grey, // color: Colors.grey, ), ), @@ -1124,13 +1132,13 @@ class PolicyCriteriaState extends State { children: [ Container( width: - widget.isDesktop - ? MediaQuery.of(context).size.width * 0.18 - : 600, + widget.isDesktop + ? MediaQuery.of(context).size.width * 0.18 + : 600, height: - widget.isDesktop - ? MediaQuery.of(context).size.height * 0.56 - : null, + widget.isDesktop + ? MediaQuery.of(context).size.height * 0.56 + : null, child: Column( children: [ Container( @@ -1149,9 +1157,9 @@ class PolicyCriteriaState extends State { ), child: Row( mainAxisAlignment: - widget.isDesktop - ? MainAxisAlignment.spaceAround - : MainAxisAlignment.spaceBetween, + widget.isDesktop + ? MainAxisAlignment.spaceAround + : MainAxisAlignment.spaceBetween, children: [ Expanded( flex: 3, @@ -1199,11 +1207,11 @@ class PolicyCriteriaState extends State { border: Border( right: BorderSide( color: - Colors - .blueGrey - .shade50, // Change this to your desired color + Colors + .blueGrey + .shade50, // Change this to your desired color width: - 1.0, // Change this to your desired width + 1.0, // Change this to your desired width ), ), ), @@ -1226,9 +1234,9 @@ class PolicyCriteriaState extends State { Spacer(), CustomTextFieldUserWrapper( width: - MediaQuery.of( - context, - ).size.width * + MediaQuery.of( + context, + ).size.width * 0.12, isFocused: false, isDesktop: widget.isDesktop, @@ -1236,38 +1244,38 @@ class PolicyCriteriaState extends State { height: 35, child: DropdownSearch( selectedItem: - FirstExceptionalApproverAction[ServiceId], + FirstExceptionalApproverAction[ServiceId], // enabled: !isViewMode, popupProps: PopupProps.menu( // showSearchBox: true, fit: - FlexFit - .loose, // Allows flexible height + FlexFit + .loose, // Allows flexible height constraints: BoxConstraints( maxHeight: 250, ), itemBuilder: ( - context, - item, - isSelected, + context, + item, + isSelected, ) => Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 16.0, - vertical: 8.0, - ), - child: Text( - item, - style: GoogleFonts.poppins( - fontSize: - 12, // 👈 Smaller text size here - color: - Colors - .black, // You can customize this - ), - ), + padding: + const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 8.0, + ), + child: Text( + item, + style: GoogleFonts.poppins( + fontSize: + 12, // 👈 Smaller text size here + color: + Colors + .black, // You can customize this ), + ), + ), ), items: [ "Approval", @@ -1275,29 +1283,29 @@ class PolicyCriteriaState extends State { "None", ], dropdownDecoratorProps: - DropDownDecoratorProps( - dropdownSearchDecoration: - InputDecoration( - border: - InputBorder.none, - contentPadding: - EdgeInsets.symmetric( - horizontal: 1, - vertical: 5, - ), - ), + DropDownDecoratorProps( + dropdownSearchDecoration: + InputDecoration( + border: + InputBorder.none, + contentPadding: + EdgeInsets.symmetric( + horizontal: 1, + vertical: 5, ), + ), + ), dropdownBuilder: ( - context, - selectedItem, + context, + selectedItem, ) => Text( - selectedItem ?? "Select", - style: GoogleFonts.poppins( - fontSize: 12, - color: Color(0xFF114D8B), - ), - ), + selectedItem ?? "Select", + style: GoogleFonts.poppins( + fontSize: 12, + color: Color(0xFF114D8B), + ), + ), onChanged: (String? newValue) { setState(() { @@ -1320,7 +1328,7 @@ class PolicyCriteriaState extends State { onTap: () { setState(() { SelectedParallelExceptionalProcess[ServiceId!] = - "1"; + "1"; }); print( @@ -1334,10 +1342,10 @@ class PolicyCriteriaState extends State { shape: BoxShape.circle, border: Border.all( color: - (SelectedParallelExceptionalProcess[ServiceId] == - "1") - ? Colors.green - : Colors.grey, + (SelectedParallelExceptionalProcess[ServiceId] == + "1") + ? Colors.green + : Colors.grey, width: 2, ), ), @@ -1345,10 +1353,10 @@ class PolicyCriteriaState extends State { Icons.check_circle, size: 20, color: - (SelectedParallelExceptionalProcess[ServiceId] == - "1") - ? Colors.green - : Colors.grey, + (SelectedParallelExceptionalProcess[ServiceId] == + "1") + ? Colors.green + : Colors.grey, // color: Colors.grey, ), ), @@ -1371,9 +1379,9 @@ class PolicyCriteriaState extends State { Spacer(), CustomTextFieldUserWrapper( width: - MediaQuery.of( - context, - ).size.width * + MediaQuery.of( + context, + ).size.width * 0.12, isFocused: false, isDesktop: widget.isDesktop, @@ -1381,38 +1389,38 @@ class PolicyCriteriaState extends State { height: 35, child: DropdownSearch( selectedItem: - SecondExceptionalApproverAction[ServiceId], + SecondExceptionalApproverAction[ServiceId], // enabled: !isViewMode, popupProps: PopupProps.menu( // showSearchBox: true, fit: - FlexFit - .loose, // Allows flexible height + FlexFit + .loose, // Allows flexible height constraints: BoxConstraints( maxHeight: 250, ), itemBuilder: ( - context, - item, - isSelected, + context, + item, + isSelected, ) => Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 16.0, - vertical: 8.0, - ), - child: Text( - item, - style: TextStyle( - fontSize: - 12, // 👈 Smaller text size here - color: - Colors - .black, // You can customize this - ), - ), + padding: + const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 8.0, + ), + child: Text( + item, + style: TextStyle( + fontSize: + 12, // 👈 Smaller text size here + color: + Colors + .black, // You can customize this ), + ), + ), ), items: [ "Approval", @@ -1420,29 +1428,29 @@ class PolicyCriteriaState extends State { "None", ], dropdownDecoratorProps: - DropDownDecoratorProps( - dropdownSearchDecoration: - InputDecoration( - border: - InputBorder.none, - contentPadding: - EdgeInsets.symmetric( - horizontal: 1, - vertical: 5, - ), - ), + DropDownDecoratorProps( + dropdownSearchDecoration: + InputDecoration( + border: + InputBorder.none, + contentPadding: + EdgeInsets.symmetric( + horizontal: 1, + vertical: 5, ), + ), + ), dropdownBuilder: ( - context, - selectedItem, + context, + selectedItem, ) => Text( - selectedItem ?? "Select", - style: GoogleFonts.poppins( - fontSize: 12, - color: Color(0xFF114D8B), - ), - ), + selectedItem ?? "Select", + style: GoogleFonts.poppins( + fontSize: 12, + color: Color(0xFF114D8B), + ), + ), onChanged: (String? newValue) { setState(() { @@ -1465,7 +1473,7 @@ class PolicyCriteriaState extends State { onTap: () { setState(() { SelectedParallelExceptionalProcess[ServiceId!] = - "2"; + "2"; }); print( @@ -1479,12 +1487,12 @@ class PolicyCriteriaState extends State { shape: BoxShape.circle, border: Border.all( color: - ((SelectedParallelExceptionalProcess[ServiceId] == - "1") || - (SelectedParallelExceptionalProcess[ServiceId] == - "2")) - ? Colors.green - : Colors.grey, + ((SelectedParallelExceptionalProcess[ServiceId] == + "1") || + (SelectedParallelExceptionalProcess[ServiceId] == + "2")) + ? Colors.green + : Colors.grey, width: 2, ), ), @@ -1492,12 +1500,12 @@ class PolicyCriteriaState extends State { Icons.check_circle, size: 20, color: - ((SelectedParallelExceptionalProcess[ServiceId] == - "1") || - (SelectedParallelExceptionalProcess[ServiceId] == - "2")) - ? Colors.green - : Colors.grey, + ((SelectedParallelExceptionalProcess[ServiceId] == + "1") || + (SelectedParallelExceptionalProcess[ServiceId] == + "2")) + ? Colors.green + : Colors.grey, // color: Colors.grey, ), ), @@ -1519,9 +1527,9 @@ class PolicyCriteriaState extends State { Spacer(), CustomTextFieldUserWrapper( width: - MediaQuery.of( - context, - ).size.width * + MediaQuery.of( + context, + ).size.width * 0.12, isFocused: false, isDesktop: widget.isDesktop, @@ -1529,38 +1537,38 @@ class PolicyCriteriaState extends State { height: 35, child: DropdownSearch( selectedItem: - ThirdExceptionalApproverAction[ServiceId], + ThirdExceptionalApproverAction[ServiceId], // enabled: !isViewMode, popupProps: PopupProps.menu( // showSearchBox: true, fit: - FlexFit - .loose, // Allows flexible height + FlexFit + .loose, // Allows flexible height constraints: BoxConstraints( maxHeight: 250, ), itemBuilder: ( - context, - item, - isSelected, + context, + item, + isSelected, ) => Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 16.0, - vertical: 8.0, - ), - child: Text( - item, - style: GoogleFonts.poppins( - fontSize: - 12, // 👈 Smaller text size here - color: - Colors - .black, // You can customize this - ), - ), + padding: + const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 8.0, + ), + child: Text( + item, + style: GoogleFonts.poppins( + fontSize: + 12, // 👈 Smaller text size here + color: + Colors + .black, // You can customize this ), + ), + ), ), items: [ "Approval", @@ -1568,28 +1576,28 @@ class PolicyCriteriaState extends State { "None", ], dropdownDecoratorProps: - DropDownDecoratorProps( - dropdownSearchDecoration: - InputDecoration( - border: - InputBorder.none, - contentPadding: - EdgeInsets.symmetric( - horizontal: 1, - vertical: 5, - ), - ), + DropDownDecoratorProps( + dropdownSearchDecoration: + InputDecoration( + border: + InputBorder.none, + contentPadding: + EdgeInsets.symmetric( + horizontal: 1, + vertical: 5, ), + ), + ), dropdownBuilder: (context, selectedItem) => - // Center-align selected item - Text( - selectedItem ?? "Select", - style: GoogleFonts.poppins( - fontSize: 12, - color: Color(0xFF114D8B), - ), - ), + // Center-align selected item + Text( + selectedItem ?? "Select", + style: GoogleFonts.poppins( + fontSize: 12, + color: Color(0xFF114D8B), + ), + ), onChanged: (String? newValue) { setState(() { @@ -1612,7 +1620,7 @@ class PolicyCriteriaState extends State { onTap: () { setState(() { SelectedParallelExceptionalProcess[ServiceId!] = - "3"; + "3"; }); print( "SelectedParallelExceptionalProcess - $SelectedParallelExceptionalProcess[ServiceId]", @@ -1625,14 +1633,14 @@ class PolicyCriteriaState extends State { shape: BoxShape.circle, border: Border.all( color: - ((SelectedParallelExceptionalProcess[ServiceId] == - "1") || - (SelectedParallelExceptionalProcess[ServiceId] == - "2") || - (SelectedParallelExceptionalProcess[ServiceId] == - "3")) - ? Colors.green - : Colors.grey, + ((SelectedParallelExceptionalProcess[ServiceId] == + "1") || + (SelectedParallelExceptionalProcess[ServiceId] == + "2") || + (SelectedParallelExceptionalProcess[ServiceId] == + "3")) + ? Colors.green + : Colors.grey, width: 2, ), ), @@ -1640,14 +1648,168 @@ class PolicyCriteriaState extends State { Icons.check_circle, size: 20, color: - ((SelectedParallelExceptionalProcess[ServiceId] == - "1") || - (SelectedParallelExceptionalProcess[ServiceId] == - "2") || - (SelectedParallelExceptionalProcess[ServiceId] == - "3")) - ? Colors.green - : Colors.grey, + ((SelectedParallelExceptionalProcess[ServiceId] == + "1") || + (SelectedParallelExceptionalProcess[ServiceId] == + "2") || + (SelectedParallelExceptionalProcess[ServiceId] == + "3")) + ? Colors.green + : Colors.grey, + // color: Colors.grey, + ), + ), + ), + ], + ), + ), + Container( + padding: const EdgeInsets.all(10), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text( + "A4", + style: GoogleFonts.poppins( + fontSize: 13, + ), + ), + Spacer(), + CustomTextFieldUserWrapper( + width: + MediaQuery.of( + context, + ).size.width * + 0.12, + isFocused: false, + isDesktop: widget.isDesktop, + child: SizedBox( + height: 35, + child: DropdownSearch( + selectedItem: + FourthExceptionalApproverAction[ServiceId], + // enabled: !isViewMode, + popupProps: PopupProps.menu( + // showSearchBox: true, + fit: + FlexFit + .loose, // Allows flexible height + constraints: BoxConstraints( + maxHeight: 250, + ), + itemBuilder: + ( + context, + item, + isSelected, + ) => Padding( + padding: + const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 8.0, + ), + child: Text( + item, + style: GoogleFonts.poppins( + fontSize: + 12, // 👈 Smaller text size here + color: + Colors + .black, // You can customize this + ), + ), + ), + ), + items: [ + "Approval", + "Notification", + "None", + ], + dropdownDecoratorProps: + DropDownDecoratorProps( + dropdownSearchDecoration: + InputDecoration( + border: + InputBorder.none, + contentPadding: + EdgeInsets.symmetric( + horizontal: 1, + vertical: 5, + ), + ), + ), + dropdownBuilder: + (context, selectedItem) => + // Center-align selected item + Text( + selectedItem ?? "Select", + style: GoogleFonts.poppins( + fontSize: 12, + color: Color(0xFF114D8B), + ), + ), + + onChanged: (String? newValue) { + setState(() { + // Find the country_code based on selected country_name + FourthExceptionalApproverAction[ServiceId!] = + newValue; + + // print("selectedUserType - $selectedUserType"); + + // if (selectedCountry!.isNotEmpty) { + // errorMessages.remove("country_code"); + // } + }); + }, + ), + ), + ), + Spacer(), + GestureDetector( + onTap: () { + setState(() { + SelectedParallelExceptionalProcess[ServiceId!] = + "4"; + }); + print( + "SelectedParallelExceptionalProcess - $SelectedParallelExceptionalProcess[ServiceId]", + ); + }, + child: Container( + height: 25, + width: 25, + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: + ((SelectedParallelExceptionalProcess[ServiceId] == + "1") || + (SelectedParallelExceptionalProcess[ServiceId] == + "2") || + (SelectedParallelExceptionalProcess[ServiceId] == + "3") || + (SelectedParallelExceptionalProcess[ServiceId] == + "4")) + ? Colors.green + : Colors.grey, + width: 2, + ), + ), + child: Icon( + Icons.check_circle, + size: 20, + color: + ((SelectedParallelExceptionalProcess[ServiceId] == + "1") || + (SelectedParallelExceptionalProcess[ServiceId] == + "2") || + (SelectedParallelExceptionalProcess[ServiceId] == + "3") || + (SelectedParallelExceptionalProcess[ServiceId] == + "4")) + ? Colors.green + : Colors.grey, // color: Colors.grey, ), ), @@ -1670,13 +1832,13 @@ class PolicyCriteriaState extends State { Container( //color: Colors.grey.shade100, width: - widget.isDesktop - ? MediaQuery.of(context).size.width * 0.18 - : 600, + widget.isDesktop + ? MediaQuery.of(context).size.width * 0.18 + : 600, height: - widget.isDesktop - ? MediaQuery.of(context).size.height * 0.56 - : null, + widget.isDesktop + ? MediaQuery.of(context).size.height * 0.56 + : null, child: Column( children: [ Container( @@ -1695,9 +1857,9 @@ class PolicyCriteriaState extends State { ), child: Row( mainAxisAlignment: - widget.isDesktop - ? MainAxisAlignment.spaceAround - : MainAxisAlignment.spaceBetween, + widget.isDesktop + ? MainAxisAlignment.spaceAround + : MainAxisAlignment.spaceBetween, children: [ Expanded( flex: 3, @@ -1760,9 +1922,9 @@ class PolicyCriteriaState extends State { Spacer(), CustomTextFieldUserWrapper( width: - MediaQuery.of( - context, - ).size.width * + MediaQuery.of( + context, + ).size.width * 0.12, isFocused: false, isDesktop: widget.isDesktop, @@ -1770,38 +1932,38 @@ class PolicyCriteriaState extends State { height: 35, child: DropdownSearch( selectedItem: - FirstAmendApproverAction[ServiceId], + FirstAmendApproverAction[ServiceId], // enabled: !isViewMode, popupProps: PopupProps.menu( // showSearchBox: true, fit: - FlexFit - .loose, // Allows flexible height + FlexFit + .loose, // Allows flexible height constraints: BoxConstraints( maxHeight: 250, ), itemBuilder: ( - context, - item, - isSelected, + context, + item, + isSelected, ) => Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 16.0, - vertical: 8.0, - ), - child: Text( - item, - style: GoogleFonts.poppins( - fontSize: - 12, // 👈 Smaller text size here - color: - Colors - .black, // You can customize this - ), - ), + padding: + const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 8.0, + ), + child: Text( + item, + style: GoogleFonts.poppins( + fontSize: + 12, // 👈 Smaller text size here + color: + Colors + .black, // You can customize this ), + ), + ), ), items: [ "Approval", @@ -1809,29 +1971,29 @@ class PolicyCriteriaState extends State { "None", ], dropdownDecoratorProps: - DropDownDecoratorProps( - dropdownSearchDecoration: - InputDecoration( - border: - InputBorder.none, - contentPadding: - EdgeInsets.symmetric( - horizontal: 1, - vertical: 5, - ), - ), + DropDownDecoratorProps( + dropdownSearchDecoration: + InputDecoration( + border: + InputBorder.none, + contentPadding: + EdgeInsets.symmetric( + horizontal: 1, + vertical: 5, ), + ), + ), dropdownBuilder: ( - context, - selectedItem, + context, + selectedItem, ) => Text( - selectedItem ?? "Select", - style: GoogleFonts.poppins( - fontSize: 12, - color: Color(0xFF114D8B), - ), - ), + selectedItem ?? "Select", + style: GoogleFonts.poppins( + fontSize: 12, + color: Color(0xFF114D8B), + ), + ), onChanged: (String? newValue) { setState(() { @@ -1854,7 +2016,7 @@ class PolicyCriteriaState extends State { onTap: () { setState(() { SelectedParallelAmendProcess[ServiceId!] = - "1"; + "1"; }); print( @@ -1868,10 +2030,10 @@ class PolicyCriteriaState extends State { shape: BoxShape.circle, border: Border.all( color: - (SelectedParallelAmendProcess[ServiceId] == - "1") - ? Colors.green - : Colors.grey, + (SelectedParallelAmendProcess[ServiceId] == + "1") + ? Colors.green + : Colors.grey, width: 2, ), ), @@ -1879,10 +2041,10 @@ class PolicyCriteriaState extends State { Icons.check_circle, size: 20, color: - (SelectedParallelAmendProcess[ServiceId] == - "1") - ? Colors.green - : Colors.grey, + (SelectedParallelAmendProcess[ServiceId] == + "1") + ? Colors.green + : Colors.grey, // color: Colors.grey, ), ), @@ -1905,9 +2067,9 @@ class PolicyCriteriaState extends State { Spacer(), CustomTextFieldUserWrapper( width: - MediaQuery.of( - context, - ).size.width * + MediaQuery.of( + context, + ).size.width * 0.12, isFocused: false, isDesktop: widget.isDesktop, @@ -1915,38 +2077,38 @@ class PolicyCriteriaState extends State { height: 35, child: DropdownSearch( selectedItem: - SecondAmendApproverAction[ServiceId], + SecondAmendApproverAction[ServiceId], // enabled: !isViewMode, popupProps: PopupProps.menu( // showSearchBox: true, fit: - FlexFit - .loose, // Allows flexible height + FlexFit + .loose, // Allows flexible height constraints: BoxConstraints( maxHeight: 250, ), itemBuilder: ( - context, - item, - isSelected, + context, + item, + isSelected, ) => Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 16.0, - vertical: 8.0, - ), - child: Text( - item, - style: TextStyle( - fontSize: - 12, // 👈 Smaller text size here - color: - Colors - .black, // You can customize this - ), - ), + padding: + const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 8.0, + ), + child: Text( + item, + style: TextStyle( + fontSize: + 12, // 👈 Smaller text size here + color: + Colors + .black, // You can customize this ), + ), + ), ), items: [ "Approval", @@ -1954,29 +2116,29 @@ class PolicyCriteriaState extends State { "None", ], dropdownDecoratorProps: - DropDownDecoratorProps( - dropdownSearchDecoration: - InputDecoration( - border: - InputBorder.none, - contentPadding: - EdgeInsets.symmetric( - horizontal: 1, - vertical: 5, - ), - ), + DropDownDecoratorProps( + dropdownSearchDecoration: + InputDecoration( + border: + InputBorder.none, + contentPadding: + EdgeInsets.symmetric( + horizontal: 1, + vertical: 5, ), + ), + ), dropdownBuilder: ( - context, - selectedItem, + context, + selectedItem, ) => Text( - selectedItem ?? "Select", - style: GoogleFonts.poppins( - fontSize: 12, - color: Color(0xFF114D8B), - ), - ), + selectedItem ?? "Select", + style: GoogleFonts.poppins( + fontSize: 12, + color: Color(0xFF114D8B), + ), + ), onChanged: (String? newValue) { setState(() { @@ -1999,7 +2161,7 @@ class PolicyCriteriaState extends State { onTap: () { setState(() { SelectedParallelAmendProcess[ServiceId!] = - "2"; + "2"; }); print( @@ -2013,12 +2175,12 @@ class PolicyCriteriaState extends State { shape: BoxShape.circle, border: Border.all( color: - ((SelectedParallelAmendProcess[ServiceId] == - "1") || - (SelectedParallelAmendProcess[ServiceId] == - "2")) - ? Colors.green - : Colors.grey, + ((SelectedParallelAmendProcess[ServiceId] == + "1") || + (SelectedParallelAmendProcess[ServiceId] == + "2")) + ? Colors.green + : Colors.grey, width: 2, ), ), @@ -2026,12 +2188,12 @@ class PolicyCriteriaState extends State { Icons.check_circle, size: 20, color: - ((SelectedParallelAmendProcess[ServiceId] == - "1") || - (SelectedParallelAmendProcess[ServiceId] == - "2")) - ? Colors.green - : Colors.grey, + ((SelectedParallelAmendProcess[ServiceId] == + "1") || + (SelectedParallelAmendProcess[ServiceId] == + "2")) + ? Colors.green + : Colors.grey, // color: Colors.grey, ), ), @@ -2053,9 +2215,9 @@ class PolicyCriteriaState extends State { Spacer(), CustomTextFieldUserWrapper( width: - MediaQuery.of( - context, - ).size.width * + MediaQuery.of( + context, + ).size.width * 0.12, isFocused: false, isDesktop: widget.isDesktop, @@ -2063,38 +2225,38 @@ class PolicyCriteriaState extends State { height: 35, child: DropdownSearch( selectedItem: - ThirdAmendApproverAction[ServiceId], + ThirdAmendApproverAction[ServiceId], // enabled: !isViewMode, popupProps: PopupProps.menu( // showSearchBox: true, fit: - FlexFit - .loose, // Allows flexible height + FlexFit + .loose, // Allows flexible height constraints: BoxConstraints( maxHeight: 250, ), itemBuilder: ( - context, - item, - isSelected, + context, + item, + isSelected, ) => Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 16.0, - vertical: 8.0, - ), - child: Text( - item, - style: GoogleFonts.poppins( - fontSize: - 12, // 👈 Smaller text size here - color: - Colors - .black, // You can customize this - ), - ), + padding: + const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 8.0, + ), + child: Text( + item, + style: GoogleFonts.poppins( + fontSize: + 12, // 👈 Smaller text size here + color: + Colors + .black, // You can customize this ), + ), + ), ), items: [ "Approval", @@ -2102,28 +2264,28 @@ class PolicyCriteriaState extends State { "None", ], dropdownDecoratorProps: - DropDownDecoratorProps( - dropdownSearchDecoration: - InputDecoration( - border: - InputBorder.none, - contentPadding: - EdgeInsets.symmetric( - horizontal: 1, - vertical: 5, - ), - ), + DropDownDecoratorProps( + dropdownSearchDecoration: + InputDecoration( + border: + InputBorder.none, + contentPadding: + EdgeInsets.symmetric( + horizontal: 1, + vertical: 5, ), + ), + ), dropdownBuilder: (context, selectedItem) => - // Center-align selected item - Text( - selectedItem ?? "Select", - style: GoogleFonts.poppins( - fontSize: 12, - color: Color(0xFF114D8B), - ), - ), + // Center-align selected item + Text( + selectedItem ?? "Select", + style: GoogleFonts.poppins( + fontSize: 12, + color: Color(0xFF114D8B), + ), + ), onChanged: (String? newValue) { setState(() { @@ -2146,7 +2308,7 @@ class PolicyCriteriaState extends State { onTap: () { setState(() { SelectedParallelAmendProcess[ServiceId!] = - "3"; + "3"; }); print( "SelectedParallelAmendProcess - $SelectedParallelAmendProcess[ServiceId]", @@ -2159,14 +2321,14 @@ class PolicyCriteriaState extends State { shape: BoxShape.circle, border: Border.all( color: - ((SelectedParallelAmendProcess[ServiceId] == - "1") || - (SelectedParallelAmendProcess[ServiceId] == - "2") || - (SelectedParallelAmendProcess[ServiceId] == - "3")) - ? Colors.green - : Colors.grey, + ((SelectedParallelAmendProcess[ServiceId] == + "1") || + (SelectedParallelAmendProcess[ServiceId] == + "2") || + (SelectedParallelAmendProcess[ServiceId] == + "3")) + ? Colors.green + : Colors.grey, width: 2, ), ), @@ -2174,14 +2336,14 @@ class PolicyCriteriaState extends State { Icons.check_circle, size: 20, color: - ((SelectedParallelAmendProcess[ServiceId] == - "1") || - (SelectedParallelAmendProcess[ServiceId] == - "2") || - (SelectedParallelAmendProcess[ServiceId] == - "3")) - ? Colors.green - : Colors.grey, + ((SelectedParallelAmendProcess[ServiceId] == + "1") || + (SelectedParallelAmendProcess[ServiceId] == + "2") || + (SelectedParallelAmendProcess[ServiceId] == + "3")) + ? Colors.green + : Colors.grey, // color: Colors.grey, ), ), @@ -2216,11 +2378,11 @@ class PolicyCriteriaState extends State { if (ServiceIndxId != null) { purposeList = - (ServiceIndxId == "1") - ? (apiDataForClass?['flight_class'] ?? []) - : (ServiceIndxId == "2") - ? (apiDataForClass?['hotel_class'] ?? []) - : (apiDataForClass?['train_class'] ?? []); + (ServiceIndxId == "1") + ? (apiDataForClass?['flight_class'] ?? []) + : (ServiceIndxId == "2") + ? (apiDataForClass?['hotel_class'] ?? []) + : (apiDataForClass?['train_class'] ?? []); } String textLabel = "Class"; if (ServiceIndxId != null) { @@ -2238,14 +2400,14 @@ class PolicyCriteriaState extends State { }); List> dropdownItems = - purposeList - .map( - (item) => DropdownMenuItem( - value: item['dropdown_key'], - child: Text(item['dropdown_value']), - ), - ) - .toList(); + purposeList + .map( + (item) => DropdownMenuItem( + value: item['dropdown_key'], + child: Text(item['dropdown_value']), + ), + ) + .toList(); print("CLASS 2 - "); @@ -2340,96 +2502,96 @@ class PolicyCriteriaState extends State { height: 40, width: double.infinity, child: - ServiceId != null && (isLoading || dropdownItems.isEmpty) - ? const Center(child: CircularProgressIndicator()) - : DropdownSearch>( - key: - classAction[ServiceId!] == null - ? UniqueKey() - : ValueKey(classAction[ServiceId!]), - items: purposeList.cast>(), + ServiceId != null && (isLoading || dropdownItems.isEmpty) + ? const Center(child: CircularProgressIndicator()) + : DropdownSearch>( + key: + classAction[ServiceId!] == null + ? UniqueKey() + : ValueKey(classAction[ServiceId!]), + items: purposeList.cast>(), - // selectedItem: purposeList.firstWhere( - // (item) => item['dropdown_key'] == selectedClass, - // orElse: () => {}, - // ), - selectedItem: - classAction[ServiceId!] != null - ? purposeList.firstWhere( - (item) => - item['dropdown_key'] == - classAction[ServiceId!], - orElse: () => {}, - ) - : null, - itemAsString: (item) => item['dropdown_value'] ?? '', - popupProps: PopupProps.menu( - showSearchBox: false, - fit: FlexFit.loose, - menuProps: const MenuProps( - backgroundColor: Colors.white, - ), - itemBuilder: (context, item, isSelected) { - final bool isNotAllowed = - item['is_allowed'] == 'No'; - return Padding( - padding: const EdgeInsets.symmetric( - horizontal: 10, - vertical: 5, - ), - child: Text( - item['dropdown_value'] ?? '', - style: GoogleFonts.poppins( - fontSize: 12, - color: - isNotAllowed - ? Colors.redAccent - : Colors.black, - ), - ), - ); - }, - ), - dropdownDecoratorProps: const DropDownDecoratorProps( - dropdownSearchDecoration: InputDecoration( - border: InputBorder.none, - contentPadding: EdgeInsets.symmetric( - horizontal: 10, - vertical: 10, - ), - ), - ), - dropdownBuilder: (context, selectedItem) { - if (selectedItem == null || selectedItem.isEmpty) { - return Text( - "Select ", - style: GoogleFonts.poppins( - color: Colors.grey, - fontSize: 13, - ), - ); - } - return Text( - selectedItem['dropdown_value'] ?? '', - style: GoogleFonts.poppins( - fontSize: 12, - color: Colors.black, - ), - ); - }, - onChanged: - purposeList.isNotEmpty - ? (Map? newValue) async { - setState(() { - classAction[ServiceId!] = - newValue?['dropdown_key']; - print( - "Selected Purpose: ${classAction[ServiceId!]}", - ); - }); - } - : null, + // selectedItem: purposeList.firstWhere( + // (item) => item['dropdown_key'] == selectedClass, + // orElse: () => {}, + // ), + selectedItem: + classAction[ServiceId!] != null + ? purposeList.firstWhere( + (item) => + item['dropdown_key'] == + classAction[ServiceId!], + orElse: () => {}, + ) + : null, + itemAsString: (item) => item['dropdown_value'] ?? '', + popupProps: PopupProps.menu( + showSearchBox: false, + fit: FlexFit.loose, + menuProps: const MenuProps( + backgroundColor: Colors.white, + ), + itemBuilder: (context, item, isSelected) { + final bool isNotAllowed = + item['is_allowed'] == 'No'; + return Padding( + padding: const EdgeInsets.symmetric( + horizontal: 10, + vertical: 5, ), + child: Text( + item['dropdown_value'] ?? '', + style: GoogleFonts.poppins( + fontSize: 12, + color: + isNotAllowed + ? Colors.redAccent + : Colors.black, + ), + ), + ); + }, + ), + dropdownDecoratorProps: const DropDownDecoratorProps( + dropdownSearchDecoration: InputDecoration( + border: InputBorder.none, + contentPadding: EdgeInsets.symmetric( + horizontal: 10, + vertical: 10, + ), + ), + ), + dropdownBuilder: (context, selectedItem) { + if (selectedItem == null || selectedItem.isEmpty) { + return Text( + "Select ", + style: GoogleFonts.poppins( + color: Colors.grey, + fontSize: 13, + ), + ); + } + return Text( + selectedItem['dropdown_value'] ?? '', + style: GoogleFonts.poppins( + fontSize: 12, + color: Colors.black, + ), + ); + }, + onChanged: + purposeList.isNotEmpty + ? (Map? newValue) async { + setState(() { + classAction[ServiceId!] = + newValue?['dropdown_key']; + print( + "Selected Purpose: ${classAction[ServiceId!]}", + ); + }); + } + : null, + ), ), ), ], @@ -2483,4 +2645,4 @@ class PolicyCriteriaState extends State { ], ); } -} +} \ No newline at end of file diff --git a/lib/Screens/userManagement/create_user/create_user.dart b/lib/Screens/userManagement/create_user/create_user.dart index ef5cf1b..88829d1 100644 --- a/lib/Screens/userManagement/create_user/create_user.dart +++ b/lib/Screens/userManagement/create_user/create_user.dart @@ -102,6 +102,7 @@ class _CreateUserFormDetialsState extends State { String? selectedSecondApprover; String? selectedThirdApprover; String? selectedSubstituteApprover; + String? selectedExceptionalApprover; String? selectedFileNames; Uint8List? passportDocumentBytes; @@ -174,6 +175,7 @@ class _CreateUserFormDetialsState extends State { "first_approver": selectedFirstApprover, "second_approver": selectedSecondApprover, "third_approver": selectedThirdApprover, + "exceptional_approver" : selectedExceptionalApprover, "delegated_to_user_id": selectedSubstituteApprover, // "passport_number": controllers["passportNumber"]?.text, // "place_of_issue": controllers["placeOfIssue"]?.text, @@ -292,6 +294,11 @@ class _CreateUserFormDetialsState extends State { apiselectedUser?["third_approver"]?.toString() ?? ""; } + if (apiselectedUser?["exceptional_approver"] != null) { + selectedExceptionalApprover = + apiselectedUser?["exceptional_approver"]?.toString() ?? ""; + } + if (apiselectedUser?["delegated_to_user_id"] != null) { print( "UPDADele- ${apiselectedUser?["delegated_to_user_id"]?.toString()}", @@ -814,6 +821,7 @@ class _CreateUserFormDetialsState extends State { Map data = userDetials; + print("userDetials ====> $userDetials"); if (!isValidData(data)) { print("USERDETAILS : $userDetials"); print("Validation Failed: Required fields are missing."); @@ -1447,6 +1455,7 @@ class _CreateUserFormDetialsState extends State { selectedFirstApprover: selectedFirstApprover, selectedSecondApprover: selectedSecondApprover, selectedThirdApprover: selectedThirdApprover, + selectedExceptionalApprover: selectedExceptionalApprover, selectedSubstituteApprover: selectedSubstituteApprover, onLevelChanged: (gender) { setState(() { @@ -1473,6 +1482,11 @@ class _CreateUserFormDetialsState extends State { selectedThirdApprover = role; }); }, + onExceptionalApproverChanged: (role) { + setState(() { + selectedExceptionalApprover = role; + }); + }, onFirstSubsApproverChanged: (role) { setState(() { selectedSubstituteApprover = role; diff --git a/lib/Screens/userManagement/create_user/office_details.dart b/lib/Screens/userManagement/create_user/office_details.dart index 7457a87..e258e21 100644 --- a/lib/Screens/userManagement/create_user/office_details.dart +++ b/lib/Screens/userManagement/create_user/office_details.dart @@ -23,6 +23,7 @@ class OfficeDetails extends StatefulWidget { final ValueChanged? onSecondApproverChanged; final ValueChanged? onThirdApproverChanged; final ValueChanged? onFirstSubsApproverChanged; + final ValueChanged? onExceptionalApproverChanged; final String? selectedLevel; final String? selectedDepartment; @@ -30,6 +31,7 @@ class OfficeDetails extends StatefulWidget { final String? selectedSecondApprover; final String? selectedThirdApprover; final String? selectedSubstituteApprover; + final String? selectedExceptionalApprover; const OfficeDetails({ Key? key, @@ -48,6 +50,8 @@ class OfficeDetails extends StatefulWidget { this.onSecondApproverChanged, this.onThirdApproverChanged, this.selectedSubstituteApprover, + this.selectedExceptionalApprover, + this.onExceptionalApproverChanged, this.onFirstSubsApproverChanged, this.userIdApi, }) : super(key: key); @@ -94,6 +98,7 @@ class _OfficeDetailsState extends State { String? selectedSecondApprover; String? selectedThirdApprover; String? selectedSubstituteApprover; + String? selectedExceptionalApprover; String? selectedFileNames; Uint8List? passportDocumentBytes; @@ -125,6 +130,7 @@ class _OfficeDetailsState extends State { "firstApproval", "secondApproval", "thirdApproval", + "exceptional_approver", "employeeCode", "dateOfIssue", "dateOfExpiry", @@ -151,6 +157,7 @@ class _OfficeDetailsState extends State { selectedSecondApprover = widget.selectedSecondApprover; selectedThirdApprover = widget.selectedThirdApprover; selectedSubstituteApprover = widget.selectedSubstituteApprover; + selectedExceptionalApprover = widget.selectedExceptionalApprover; fetchDepartment(); fetchUsers(); @@ -307,6 +314,8 @@ class _OfficeDetailsState extends State { if (widget.isDesktop) SizedBox(height: 10), _buildSecondRow(widget.isDesktop), if (widget.isDesktop) SizedBox(height: 10), + _buildThirdRow(widget.isDesktop), + if (widget.isDesktop) SizedBox(height: 10), Divider(thickness: 0.2, color: Colors.blueGrey.shade100), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -321,7 +330,7 @@ class _OfficeDetailsState extends State { ], ), SizedBox(height: 15), - _buildThirdRow(widget.isDesktop), + _buildFourthRow(widget.isDesktop), ], ), ); @@ -384,6 +393,28 @@ class _OfficeDetailsState extends State { } Widget _buildThirdRow(bool isDesktop) { + return Container( + color: Colors.white, + child: + widget.isDesktop + ? Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + buildExceptionApprover(isDesktop), + Spacer(), + ], + ) + : Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + buildExceptionApprover(isDesktop), + SizedBox(height: 8), // Vertical space + ], + ), + ); + } + + Widget _buildFourthRow(bool isDesktop) { return Container( color: Colors.white, child: @@ -1185,6 +1216,130 @@ class _OfficeDetailsState extends State { ); } + Widget buildExceptionApprover(bool isDesktop) { + return Container( + color: Colors.white, + // child: Expanded( + // Allow first column to take available space + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Exceptional Approver", + style: GoogleFonts.poppins( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Color(0xFF575A74), + ), + ), + SizedBox(height: 5), + CustomTextFieldUserWrapper( + isFocused: false, + isDesktop: isDesktop, + child: SizedBox( + height: 40, + child: + apiUserData == null + ? Center( + child: Transform.scale( + scale: 0.5, + child: CircularProgressIndicator(), + ), + ) + : DropdownSearch( + selectedItem: userMap[selectedExceptionalApprover], + enabled: !widget.isViewMode, + popupProps: PopupProps.menu( + showSearchBox: true, + fit: FlexFit.loose, // Allows flexible height + menuProps: const MenuProps( + backgroundColor: Colors.white, + ), + itemBuilder: + (context, item, isSelected) => Container( + padding: EdgeInsets.symmetric( + horizontal: 10, + vertical: 6, + ), + child: Text( + item, + style: GoogleFonts.poppins( + fontSize: 11.5, + ), + ), + ), + constraints: BoxConstraints(maxHeight: 250), + searchFieldProps: TextFieldProps( + decoration: InputDecoration( + hintText: "Search User...", + contentPadding: EdgeInsets.symmetric( + horizontal: 10, + ), + ), + ), + ), + items: + apiUserData!.map((user) { + return "${user['first_name']} ${user['last_name']}"; + }).toList(), + dropdownDecoratorProps: DropDownDecoratorProps( + dropdownSearchDecoration: InputDecoration( + border: InputBorder.none, + contentPadding: EdgeInsets.symmetric( + horizontal: 1, + ), + ), + ), + dropdownBuilder: + (context, selectedItem) => Align( + // Center-align selected item + alignment: Alignment.centerLeft, + child: Text( + selectedItem ?? "Select", + style: GoogleFonts.poppins( + fontSize: 12, + ), + ), + ), + + onChanged: (String? newValue) { + if (newValue == null) return; + + final approverId = + userMap.entries + .firstWhere( + (entry) => entry.value == newValue, + ) + .key; + + setState(() { + selectedExceptionalApprover = approverId; + }); + + widget.onExceptionalApproverChanged?.call( + approverId, + ); // ✅ not newValue, but approverId + }, + ), + ), + ), + ], + ), + ], + ), + ], + ), + + // ), + ); + } + + Widget buildApproverSubstitute1(bool isDesktop) { return Container( color: Colors.white, @@ -1246,7 +1401,7 @@ class _OfficeDetailsState extends State { ), ), ), - constraints: BoxConstraints(maxHeight: 250), + constraints: BoxConstraints(maxHeight: 133), searchFieldProps: TextFieldProps( decoration: InputDecoration( hintText: "Search User...", diff --git a/lib/data/models/plan.dart b/lib/data/models/plan.dart index 882e330..9ce1b73 100644 --- a/lib/data/models/plan.dart +++ b/lib/data/models/plan.dart @@ -46,36 +46,36 @@ class Plan { factory Plan.fromJson(Map json) { print('Parsing Plan from JSON: $json'); return Plan( - planId: json['plan_id']!.toString(), - employeeCode: json['employee_code']!.toString(), - tripTitle: json['trip_title']!.toString(), - tripType: json['trip_type_value']!.toString(), + planId: json['plan_id']?.toString() ?? "", + employeeCode: json['employee_code']?.toString() ?? "", + tripTitle: json['trip_title']?.toString() ?? "", + tripType: json['trip_type_value']?.toString() ?? "", approver_status: json["approver_status"] == null ? '' - : json['approver_status']!.toString(), + : json['approver_status']?.toString() ?? "", status: json['status'] == "0" ? "Inactive" : "Active", - costCenter: json['cost_center_value']!.toString(), - functionalDepartment: json['functional_department_value']!.toString(), - purposeOfTravel: json['purpose_of_travel_value']!.toString(), - soNumber: json['so_number']!.toString(), - description: json['description']!.toString(), - isBillable: json['is_billable_value']!.toString(), - userName: json["user_name"]!.toString(), + costCenter: json['cost_center_value']?.toString() ?? "" , + functionalDepartment: json['functional_department_value']?.toString() ?? "", + purposeOfTravel: json['purpose_of_travel_value']?.toString() ?? "", + soNumber: json['so_number']?.toString() ?? "", + description: json['description']?.toString() ?? "", + isBillable: json['is_billable_value']?.toString() ?? "", + userName: json["user_name"]?.toString() ?? "", travellerName: json["traveller_name"] == null ? '' - : json["traveller_name"]!.toString(), + : json["traveller_name"]?.toString() ?? "", approverName: json["approver_name"] == null ? '' - : json["approver_name"]!.toString(), - statusValue: json["status_value"]!.toString(), - createdOn: json["created_on"], + : json["approver_name"]?.toString() ?? "", + statusValue: json["status_value"]?.toString() ?? "", + createdOn: json["created_on"]?.toString() ?? "", approverId: - json["approver_id"] == null ? '' : json['approver_id']!.toString(), + json["approver_id"] == null ? '' : json['approver_id']?.toString() ?? "", delegaterId: - json["delegater_id"] == null ? '' : json['delegater_id']!.toString(), + json["delegater_id"] == null ? '' : json['delegater_id']?.toString() ?? "", ); } }