This commit is contained in:
venbaittech 2025-07-22 14:46:43 +05:30
parent 058875d571
commit cf23f4f936
12 changed files with 1580 additions and 1536 deletions

View File

@ -811,11 +811,13 @@ class _ListAllPlansState extends State<ListAllPlans> {
), ),
columns: [ columns: [
DataColumn( DataColumn(
label: Text( label: Expanded(
'S.NO', child: Text(
style: GoogleFonts.poppins( 'S.NO',
fontSize: 13, style: GoogleFonts.poppins(
fontWeight: FontWeight.w600, fontSize: 13,
fontWeight: FontWeight.w600,
),
), ),
), ),
), ),
@ -928,8 +930,11 @@ class _ListAllPlansState extends State<ListAllPlans> {
fontSize: 13, fontSize: 13,
fontFamily: "Inter", fontFamily: "Inter",
), ),
softWrap: true, softWrap: true, // Allows wrapping
overflow: TextOverflow.ellipsis, overflow:
TextOverflow
.visible, // Ensures full display
maxLines: null,
), ),
), ),
DataCell( DataCell(
@ -1251,6 +1256,12 @@ class _ListAllPlansState extends State<ListAllPlans> {
fontWeight: fontWeight:
FontWeight.w500, FontWeight.w500,
), ),
softWrap:
true, // Allows wrapping
overflow:
TextOverflow
.visible, // Ensures full display
maxLines: null,
), ),
], ],
), ),

View File

@ -26,13 +26,15 @@ class MiscellaneousListWidget extends StatelessWidget {
return Padding( return Padding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: Container( child: Container(
margin: const EdgeInsets.only(top: 16.0), // color: Color(0xFFE8F0FC),
margin: const EdgeInsets.only(top: 28.0),
padding: const EdgeInsets.all(10.0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
// Header with title and button // Header with title and button
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
MouseRegion( MouseRegion(
cursor: cursor:
@ -56,10 +58,23 @@ class MiscellaneousListWidget extends StatelessWidget {
// style: TextStyle(fontSize: 13), // style: TextStyle(fontSize: 13),
// ), // ),
// SizedBox(width: 8), // spacing between icon and text // SizedBox(width: 8), // spacing between icon and text
Icon( Container(
Icons.add_circle_sharp, decoration: BoxDecoration(
size: 30, shape: BoxShape.circle,
color: Color(0xFF114D8B), border: Border.all(
color: Color(0xFF114D8B), // Outline color
width: 2, // Outline thickness
),
),
height: 30,
width: 30,
child: Center(
child: Icon(
Icons.add,
size: 20,
color: Colors.black,
),
),
), ),
], ],
), ),
@ -159,7 +174,8 @@ class MiscellaneousListWidget extends StatelessWidget {
getRequestValue(item["special_request"]?.toString()), getRequestValue(item["special_request"]?.toString()),
style: GoogleFonts.poppins( style: GoogleFonts.poppins(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w800, color: Color(0xFF114D8B),
fontWeight: FontWeight.w500,
), ),
), ),
Spacer(), Spacer(),
@ -189,54 +205,67 @@ class MiscellaneousListWidget extends StatelessWidget {
), ),
], ],
), ),
Divider(color: Colors.blueGrey.shade50), // Divider(color: Colors.blueGrey.shade50),
SizedBox(height: 4), SizedBox(height: 10),
isDesktop isDesktop
? Row( ? Row(
children: [ children: [
Expanded( // Expanded(
flex: 2, // flex: 2,
child: Text( // child: Text(
"Special Request", // "Special Request",
style: GoogleFonts.poppins(fontSize: 11), // style: GoogleFonts.poppins(fontSize: 11),
), // ),
), // ),
Expanded( Expanded(
flex: 3, flex: 3,
child: Text( child: Text(
" Comments", "Comments",
style: GoogleFonts.poppins(fontSize: 11), style: GoogleFonts.poppins(
fontSize: 12,
color: Colors.black,
fontWeight: FontWeight.w600,
),
), ),
), ),
], ],
) )
: SizedBox.shrink(), : SizedBox.shrink(),
SizedBox(height: 4),
isDesktop isDesktop
? Row( ? Container(
children: [ // color: Color(0xFFE8F0FC),
Expanded( color: Colors.white,
flex: 2, child: Expanded(
child: Text( child: Row(
getRequestValue( children: [
item["special_request"]?.toString(), // Expanded(
// flex: 2,
// child: Text(
// getRequestValue(
// item["special_request"]?.toString(),
// ),
// style: GoogleFonts.poppins(
// fontSize: 12,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
Container(
// width: MediaQuery.of(context).size.width * 0.6,
// padding: EdgeInsets.all(16),
// color: Color(0xFFE8F0FC),
child: Expanded(
// flex: 1,
child: Text(
item["comments"],
style: GoogleFonts.poppins(fontSize: 11),
),
),
), ),
style: GoogleFonts.poppins( ],
fontSize: 12,
fontWeight: FontWeight.w600,
),
),
), ),
Expanded( ),
flex: 3,
child: Text(
item["comments"],
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w600,
),
),
),
],
) )
: Column( : Column(
children: [ children: [

View File

@ -32,12 +32,10 @@ class _ColorThemePickerWidgetState extends State<ColorThemePickerWidget> {
Color(0xFF027E87), // Blue Shade Color(0xFF027E87), // Blue Shade
Color(0xFF12B24B), // Green Color(0xFF12B24B), // Green
Color(0xFFe30f01), // Emerald Green Color(0xFFe30f01), // Emerald Green
// Color(0xFFef3030), // Emerald Green
Color(0xFFf26157), // Emerald Green Color(0xFFf26157), // Emerald Green
// Color(0xFF2ECC71), // Emerald Green
Color(0xFFFF9800), // Orange Color(0xFFFF9800), // Orange
Color(0xFFE67E22), // Orange 2 Color(0xFF3F51B5), // Orange 2
Color(0xFFBF4C0D), // Orange dark orange 3 Color(0xFF00695C), // Orange dark orange 3
Color(0xFFD9067A), // rose Color(0xFFD9067A), // rose
Color(0xFFc94b92), // rose light Color(0xFFc94b92), // rose light
Color(0xFF9C27B0), // Purple Color(0xFF9C27B0), // Purple
@ -45,31 +43,32 @@ class _ColorThemePickerWidgetState extends State<ColorThemePickerWidget> {
]; ];
final List<Color> layoutSecondaryColors = [ final List<Color> layoutSecondaryColors = [
Color(0xFF00B0FF), // Lighter Blue Color(0xFF82B1FF), // Lighter BlueAccent
Color(0xFF00ACC1), // Teal Blue Color(0xFF4DD0E1), // Lighter Teal
Color(0xFF43A047), // Dark Green Color(0xFF43A047), // Light Green
Color(0xFF27AE60), // Medium Emerald Color(0xFFEF5350), // Lighter Red
Color(0xFFFFC107), // Amber (complementary to orange) Color(0xFFFF8A65), // Coral Peach
Color(0xFFFFA726), // Light orange Color(0xFFFFB74D), // Amber Orange
Color(0xFFE64A19), // Deep Orange Color(0xFF7986CB), // Indigo Soft
Color(0xFFFF4081), // Bright Pink (complementary to rose) Color(0xFF4DB6AC), // Soft Teal
Color(0xFFF06292), // Light Rose
Color(0xFFF48FB1), // Light Pink Color(0xFFF48FB1), // Light Pink
Color(0xFFBA68C8), // Light Purple Color(0xFFBA68C8), // Soft Purple
Color(0xFFAB47BC), // Orchid Purple Color(0xFFDDA0DD), // Plum
]; ];
final List<Color> layoutTertiaryColors = [ final List<Color> layoutTertiaryColors = [
Color(0xFF82B1FF), // Very Light Blue Color(0xFFE3F2FD), // Very Light Blue
Color(0xFF4DD0E1), // Lighter Teal Color(0xFFE0F7FA), // Very Light Teal
Color(0xFF81C784), // Light Green Color(0xFFC8E6C9), // Mint Green
Color(0xFFAAF0D1), // Pastel Mint Color(0xFFFFCDD2), // Light Coral/Red
Color(0xFFFFE0B2), // Pale Orange Color(0xFFFFE0B2), // Peach
Color(0xFFFFCCBC), // Light Orange Peach Color(0xFFFFF3E0), // Lightest Orange
Color(0xFFFFAB91), // Light Coral Color(0xFFFFEBEE), // Very Light Rose
Color(0xFFF8BBD0), // Pastel Rose Color(0xFFFCE4EC), // Pastel Pink
Color(0xFFF8BBD0), // Pastel Pink Color(0xFFF3E5F5), // Light Lavender
Color(0xFFE1BEE7), // Lavender Color(0xFFEDE7F6), // Soft Purple Grey
Color(0xFFD1C4E9), // Light Purple Grey Color(0xFFF8F9FA), // Near-white Neutral
]; ];
// Body colors // Body colors

View File

@ -659,6 +659,8 @@ class CreateNewPlansState extends State<CreateNewPlan> {
} else if (userId.isNotEmpty && userId != "0") { } else if (userId.isNotEmpty && userId != "0") {
print("TestplanUsrId : $userId"); print("TestplanUsrId : $userId");
print("TestplanUsrIdSelf : $selfId"); print("TestplanUsrIdSelf : $selfId");
planUsrId = userId;
print("TestplanUsrId2 : $planUsrId");
_selectedOption = (selfId != userId) ? "Option 2" : "Option 1"; _selectedOption = (selfId != userId) ? "Option 2" : "Option 1";
otherUserName = userName; otherUserName = userName;
} }
@ -3766,7 +3768,9 @@ class CreateNewPlansState extends State<CreateNewPlan> {
reverse: false, // show right-end on overflow reverse: false, // show right-end on overflow
physics: BouncingScrollPhysics(), physics: BouncingScrollPhysics(),
child: ConstrainedBox( child: ConstrainedBox(
constraints: BoxConstraints(minWidth: isDesktop ? MediaQuery.of(context).size.width * 0.5 : 180), constraints: BoxConstraints(
minWidth: isDesktop ? MediaQuery.of(context).size.width * 0.5 : 180,
),
child: IntrinsicWidth( child: IntrinsicWidth(
child: TextField( child: TextField(
controller: _tripTitleController, controller: _tripTitleController,
@ -3786,9 +3790,15 @@ class CreateNewPlansState extends State<CreateNewPlan> {
), ),
floatingLabelBehavior: FloatingLabelBehavior.never, floatingLabelBehavior: FloatingLabelBehavior.never,
border: InputBorder.none, border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(horizontal: 1, vertical: 16), contentPadding: EdgeInsets.symmetric(
horizontal: 1,
vertical: 16,
),
errorText: validationErrors["trip_title"], errorText: validationErrors["trip_title"],
errorStyle: GoogleFonts.poppins(fontSize: 12, color: Colors.red), errorStyle: GoogleFonts.poppins(
fontSize: 12,
color: Colors.red,
),
), ),
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
scrollPhysics: BouncingScrollPhysics(), scrollPhysics: BouncingScrollPhysics(),
@ -3799,7 +3809,6 @@ class CreateNewPlansState extends State<CreateNewPlan> {
); );
} }
Widget _buildApprovalItem(String title, String name) { Widget _buildApprovalItem(String title, String name) {
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,

View File

@ -1,5 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'package:dotted_border/dotted_border.dart';
import 'package:easy_stepper/easy_stepper.dart'; import 'package:easy_stepper/easy_stepper.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:frontend/Screens/itnerary_list/accomodation_list.dart'; import 'package:frontend/Screens/itnerary_list/accomodation_list.dart';
@ -7,6 +8,7 @@ import 'package:frontend/Screens/itnerary_list/bus_list.dart';
import 'package:frontend/Screens/itnerary_list/flight_list.dart'; import 'package:frontend/Screens/itnerary_list/flight_list.dart';
import 'package:frontend/Screens/itnerary_list/taxi_list.dart'; import 'package:frontend/Screens/itnerary_list/taxi_list.dart';
import 'package:frontend/Screens/itnerary_list/train_list.dart'; import 'package:frontend/Screens/itnerary_list/train_list.dart';
import 'package:frontend/utils/auth_utils.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:responsive_builder/responsive_builder.dart'; import 'package:responsive_builder/responsive_builder.dart';
@ -64,6 +66,14 @@ class DynamicItinerary extends StatefulWidget {
class DynamicItineraryState extends State<DynamicItinerary> { class DynamicItineraryState extends State<DynamicItinerary> {
final ApiService apiService = ApiService(); final ApiService apiService = ApiService();
late ScrollController _scrollController;
bool _canScrollLeft = false;
bool _canScrollRight = true;
Color? layoutColor;
Color? secondColor;
Color? thridColor;
String? _tripType; String? _tripType;
String selectedOption = ""; String selectedOption = "";
String selectedListOption = ""; String selectedListOption = "";
@ -98,6 +108,13 @@ class DynamicItineraryState extends State<DynamicItinerary> {
handleSelectedPlan(); handleSelectedPlan();
updateSelectedServices(); updateSelectedServices();
_tripType = widget.tripType; _tripType = widget.tripType;
loadInitialData();
_scrollController = ScrollController();
_scrollController.addListener(_updateScrollButtonState);
// Delay check after layout is built
WidgetsBinding.instance.addPostFrameCallback((_) {
_updateScrollButtonState(); // Initial scroll check
});
} }
@override @override
@ -116,6 +133,54 @@ class DynamicItineraryState extends State<DynamicItinerary> {
} }
} }
@override
void dispose() {
_scrollController.removeListener(_updateScrollButtonState);
_scrollController.dispose();
super.dispose();
}
void _updateScrollButtonState() {
if (!_scrollController.hasClients) return;
final max = _scrollController.position.maxScrollExtent;
final offset = _scrollController.offset;
setState(() {
_canScrollLeft = offset > 0;
_canScrollRight = offset < max;
});
}
void loadInitialData() async {
String? layoutString = await getLayoutColor();
String? secondString = await getSecondaryColor();
String? thridString = await getTernaryColor();
// String? bodyStringColor = await getBodyColor();
setState(() {
layoutColor =
layoutString != null
? Color(int.parse(layoutString))
: Colors.redAccent;
secondColor =
layoutString != null
? Color(int.parse(secondString!))
: Colors.orange;
thridColor =
layoutString != null
? Color(int.parse(thridString!))
: Colors.orangeAccent;
// bodyColor =
// bodyStringColor != null
// ? Color(int.parse(bodyStringColor))
// : Colors.white;
});
}
void updateTripType(String? newTripType) { void updateTripType(String? newTripType) {
if (_tripType != newTripType) { if (_tripType != newTripType) {
setState(() { setState(() {
@ -823,10 +888,11 @@ class DynamicItineraryState extends State<DynamicItinerary> {
left: MediaQuery.of(context).size.width * 0.05, left: MediaQuery.of(context).size.width * 0.05,
right: MediaQuery.of(context).size.width * 0.05, right: MediaQuery.of(context).size.width * 0.05,
child: Container( child: Container(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 12), padding: EdgeInsets.symmetric(vertical: 2, horizontal: 2),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, // Card background color: Colors.white, // Card background
borderRadius: BorderRadius.circular(8), // color: thridColor, // Card background
borderRadius: BorderRadius.circular(40),
// color: Color(0xFFE6E7F5) // color: Color(0xFFE6E7F5)
// border: Border.all(color: Colors.black12, width: 1.3), // border: Border.all(color: Colors.black12, width: 1.3),
@ -840,16 +906,54 @@ class DynamicItineraryState extends State<DynamicItinerary> {
), ),
], ],
), ),
child: child: Row(
children: [
isMobile isMobile
? SingleChildScrollView( ? IconButton(
scrollDirection: Axis.horizontal, icon: Icon(
child: Row(children: _buildOptions()), Icons.arrow_back_ios,
color: Colors.black54,
// color: _canScrollLeft ? Colors.black : Colors.grey,
),
onPressed:
_canScrollLeft
? () {
_scrollBy(-100);
}
: null,
) )
: Row( : SizedBox.shrink(),
mainAxisAlignment: MainAxisAlignment.spaceEvenly, Expanded(
children: _buildOptions(), child:
), isMobile
? SingleChildScrollView(
controller: _scrollController,
scrollDirection: Axis.horizontal,
child: Row(children: _buildOptions()),
)
: Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: _buildOptions(),
),
),
isMobile
? IconButton(
icon: Icon(
Icons.arrow_forward_ios,
color: Colors.black54,
// color: _canScrollRight ? Colors.black : Colors.grey,
),
onPressed:
_canScrollRight
? () {
_scrollBy(100);
}
: null,
)
: SizedBox.shrink(),
],
),
), ),
), ),
], ],
@ -858,6 +962,21 @@ class DynamicItineraryState extends State<DynamicItinerary> {
); );
} }
void _scrollBy(double offset) {
if (!_scrollController.hasClients) return;
final targetOffset = (_scrollController.offset + offset).clamp(
_scrollController.position.minScrollExtent,
_scrollController.position.maxScrollExtent,
);
_scrollController.animateTo(
targetOffset,
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
}
bool hasValidItineraryEntries() { bool hasValidItineraryEntries() {
if (ServicesChoosed == null || ServicesChoosed!.isEmpty) return false; if (ServicesChoosed == null || ServicesChoosed!.isEmpty) return false;
@ -986,39 +1105,66 @@ class DynamicItineraryState extends State<DynamicItinerary> {
}, },
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border( // border: Border(
bottom: BorderSide( // bottom: BorderSide(
color: isOptionSelected ? Color(0xFF114D8B) : Colors.transparent, // color: isOptionSelected ? Color(0xFF114D8B) : Colors.transparent,
width: 2, // width: 2,
), // ),
), // ),
), ),
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 10), padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 3),
child: Column( child: Column(
children: [ children: [
iconUrl.isNotEmpty DottedBorder(
? Image.network( options: RoundedRectDottedBorderOptions(
iconUrl, dashPattern: [1, 3],
width: 18, strokeWidth: 1.5,
height: 18, radius: Radius.circular(46),
errorBuilder: (context, error, stackTrace) { color: isOptionSelected ? secondColor! : Colors.transparent,
return Icon( padding: EdgeInsets.all(3.5),
fallbackIcon, ),
size: 25, child: Container(
color: decoration: BoxDecoration(
isOptionSelected color: isOptionSelected ? secondColor : Colors.white,
? Color(0xFF114D8B)
: Color(0xFF475569), borderRadius: BorderRadius.circular(20.0),
);
},
)
: Icon(
fallbackIcon,
size: 25,
color:
isOptionSelected ? Color(0xFF114D8B) : Color(0xFF475569),
), ),
SizedBox(height: 2),
padding: const EdgeInsets.all(3.0),
child:
iconUrl.isNotEmpty
? Image.network(
iconUrl,
width: 15,
height: 15,
errorBuilder: (context, error, stackTrace) {
return Icon(
fallbackIcon,
size: 20,
color:
isOptionSelected
? Colors.white
: Colors.black87,
// color:
// isOptionSelected
// ? Color(0xFF114D8B)
// : Color(0xFF475569),
);
},
)
: Icon(
fallbackIcon,
size: 20,
color:
isOptionSelected ? Colors.white : Colors.black87,
// color:
// isOptionSelected
// ? Color(0xFF114D8B)
// : Color(0xFF475569),
),
),
),
SizedBox(height: 1),
Row( Row(
children: [ children: [
Text( Text(
@ -1027,15 +1173,16 @@ class DynamicItineraryState extends State<DynamicItinerary> {
// style: GoogleFonts.poppins( fontSize: 12, // style: GoogleFonts.poppins( fontSize: 12,
// fontWeight: FontWeight.w600, // fontWeight: FontWeight.w600,
// color: Color(0xFF575A74)) // color: Color(0xFF575A74))
style: TextStyle( style: GoogleFonts.poppins(
fontSize: 14, fontSize: 12,
color: color: Colors.black,
isOptionSelected // color:
? Color(0xFF114D8B) // isOptionSelected
: Color(0xFF475569), // ? Color(0xFF114D8B)
fontFamily: "Inter", // : Color(0xFF475569),
// fontFamily: "Inter",
fontWeight: fontWeight:
isOptionSelected ? FontWeight.bold : FontWeight.w500, isOptionSelected ? FontWeight.w700 : FontWeight.w400,
), ),
), ),
SizedBox(width: 4), SizedBox(width: 4),

View File

@ -40,7 +40,7 @@ class Policy extends StatefulWidget {
class _PolicyState extends State<Policy> { class _PolicyState extends State<Policy> {
final GlobalKey<PolicyCriteriaState> policyCriteriaKey = final GlobalKey<PolicyCriteriaState> policyCriteriaKey =
GlobalKey<PolicyCriteriaState>(); GlobalKey<PolicyCriteriaState>();
final ApiService apiService = ApiService(); final ApiService apiService = ApiService();
@ -84,23 +84,22 @@ class _PolicyState extends State<Policy> {
Map<String, dynamic> get policyData { Map<String, dynamic> get policyData {
List<Map<String, dynamic>> policyDetails = List<Map<String, dynamic>> policyDetails =
policy_details!.where((service) { policy_details!.where((service) {
// Only check these specific fields for emptiness // Only check these specific fields for emptiness
final fieldsToCheck = [ final fieldsToCheck = [
'cost', 'cost',
'class', 'class',
'a1_action', 'a1_action',
'a2_action', 'a2_action',
'a3_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<String, dynamic> data = { Map<String, dynamic> data = {
"name": _policyController.text, "name": _policyController.text,
@ -153,6 +152,7 @@ class _PolicyState extends State<Policy> {
// } // }
// }); // });
} }
void _addFocusListener(FocusNode node, Function(bool) updateState) { void _addFocusListener(FocusNode node, Function(bool) updateState) {
node.addListener(() { node.addListener(() {
setState(() { setState(() {
@ -160,6 +160,7 @@ class _PolicyState extends State<Policy> {
}); });
}); });
} }
void _checkAuthAndLoadData() async { void _checkAuthAndLoadData() async {
final String? token = await getToken(); // Your async function to get token final String? token = await getToken(); // Your async function to get token
@ -198,14 +199,14 @@ class _PolicyState extends State<Policy> {
setState(() { setState(() {
layoutColor = layoutColor =
layoutString != null layoutString != null
? Color(int.parse(layoutString)) ? Color(int.parse(layoutString))
: Colors.redAccent; : Colors.redAccent;
bodyColor = bodyColor =
bodyStringColor != null bodyStringColor != null
? Color(int.parse(bodyStringColor)) ? Color(int.parse(bodyStringColor))
: Colors.white; : Colors.white;
}); });
} }
@ -237,9 +238,9 @@ class _PolicyState extends State<Policy> {
try { try {
List<dynamic> decoded = json.decode(rawServices); List<dynamic> decoded = json.decode(rawServices);
List<Map<String, String>> formatted = List<Map<String, String>> formatted =
decoded decoded
.map((e) => {"service_id": e['service_id'].toString()}) .map((e) => {"service_id": e['service_id'].toString()})
.toList(); .toList();
setState(() { setState(() {
selectedOrgServiceIds = formatted; selectedOrgServiceIds = formatted;
@ -264,7 +265,7 @@ class _PolicyState extends State<Policy> {
await loadOrgSelectedAlServices(); await loadOrgSelectedAlServices();
final selectedIds = final selectedIds =
selectedOrgServiceIds.map((e) => e['service_id']).toSet(); selectedOrgServiceIds.map((e) => e['service_id']).toSet();
if (widget.policy != null) { if (widget.policy != null) {
final details = List<Map<String, dynamic>>.from( final details = List<Map<String, dynamic>>.from(
@ -277,12 +278,12 @@ class _PolicyState extends State<Policy> {
// pr int("UUFiltered Selected Services - $details"); // pr int("UUFiltered Selected Services - $details");
final filtered = final filtered =
selectedAllServices! selectedAllServices!
.where( .where(
(service) => (service) =>
selectedIds.contains(service['service_id'].toString()), selectedIds.contains(service['service_id'].toString()),
) )
.toList(); .toList();
setState(() { setState(() {
ServicesChoosed = filtered; ServicesChoosed = filtered;
@ -307,11 +308,11 @@ class _PolicyState extends State<Policy> {
List<Map<String, dynamic>>.from(decoded) List<Map<String, dynamic>>.from(decoded)
.map( .map(
(service) => { (service) => {
'service_id': service['service_id'].toString(), 'service_id': service['service_id'].toString(),
'name': service['name'].toString(), 'name': service['name'].toString(),
'order': service['order'].toString(), 'order': service['order'].toString(),
}, },
) )
.toList(); .toList();
}); });
@ -321,12 +322,12 @@ class _PolicyState extends State<Policy> {
print("Filtered Selected Services Added to Policy: $ServicesChoosed"); print("Filtered Selected Services Added to Policy: $ServicesChoosed");
} else { } else {
final filtered = final filtered =
selectedAllServices! selectedAllServices!
.where( .where(
(service) => (service) =>
selectedIds.contains(service['service_id'].toString()), selectedIds.contains(service['service_id'].toString()),
) )
.toList(); .toList();
print("ServicesChoosedYY: $ServicesChoosed"); print("ServicesChoosedYY: $ServicesChoosed");
setState(() { setState(() {
@ -341,12 +342,12 @@ class _PolicyState extends State<Policy> {
ServicesChoosed! ServicesChoosed!
.map( .map(
(service) => { (service) => {
'service_id': service['service_id'].toString(), 'service_id': service['service_id'].toString(),
'name': 'name':
service['name'].toString(), // no space before 'name' service['name'].toString(), // no space before 'name'
'order': service['order'].toString(), 'order': service['order'].toString(),
}, },
) )
.toList(); .toList();
}); });
@ -461,7 +462,6 @@ class _PolicyState extends State<Policy> {
}); });
} }
bool isValidData(Map<String, dynamic> data) { bool isValidData(Map<String, dynamic> data) {
errorMessages.clear(); // Reset previous errors errorMessages.clear(); // Reset previous errors
@ -480,7 +480,7 @@ class _PolicyState extends State<Policy> {
if (domestic != "1" && international != "1") { if (domestic != "1" && international != "1") {
errorMessages["trip_type"] = errorMessages["trip_type"] =
"Required"; // "Please select Domestic or International."; "Required"; // "Please select Domestic or International.";
} }
// Validate at least one policy_detail with valid content // Validate at least one policy_detail with valid content
@ -502,7 +502,7 @@ class _PolicyState extends State<Policy> {
if (!hasAtLeastOneDetail) { if (!hasAtLeastOneDetail) {
errorMessages["policy_details"] = errorMessages["policy_details"] =
"Required"; // "At least one valid policy detail is required."; "Required"; // "At least one valid policy detail is required.";
} }
return errorMessages.isEmpty; return errorMessages.isEmpty;
@ -571,16 +571,16 @@ class _PolicyState extends State<Policy> {
drawer: CustomDrawer(isDesktop: false), drawer: CustomDrawer(isDesktop: false),
body: Padding( body: Padding(
padding: padding:
isDesktop isDesktop
? EdgeInsets.symmetric( ? EdgeInsets.symmetric(
horizontal: horizontal:
MediaQuery.of(context).size.width * MediaQuery.of(context).size.width *
0.1, // 30% of screen width as horizontal padding 0.1, // 30% of screen width as horizontal padding
vertical: vertical:
MediaQuery.of(context).size.height * MediaQuery.of(context).size.height *
0, // 5% of screen height as vertical padding 0, // 5% of screen height as vertical padding
) )
: EdgeInsets.all(8), : EdgeInsets.all(8),
child: Column( child: Column(
children: [ children: [
Expanded( Expanded(
@ -666,15 +666,15 @@ class _PolicyState extends State<Policy> {
color: Colors.white, color: Colors.white,
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: child:
isDesktop isDesktop
? Row( ? Row(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: _buildSubmit(isDesktop), children: _buildSubmit(isDesktop),
) )
: Row( : Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: _buildSubmit(isDesktop), children: _buildSubmit(isDesktop),
), ),
), ),
], ],
), ),
@ -687,9 +687,9 @@ class _PolicyState extends State<Policy> {
// ? EdgeInsets.all(10.0) // ? EdgeInsets.all(10.0)
// : EdgeInsets.only(left: 20.0, bottom: 20.0, top: 10.0, right: 20.0), // : EdgeInsets.only(left: 20.0, bottom: 20.0, top: 10.0, right: 20.0),
height: height:
isDesktop isDesktop
? MediaQuery.of(context).size.height * 0.98 ? MediaQuery.of(context).size.height * 0.98
: MediaQuery.of(context).size.height, : MediaQuery.of(context).size.height,
// decoration: BoxDecoration( // decoration: BoxDecoration(
// border: isDesktop // border: isDesktop
// ? Border.all( // ? Border.all(
@ -738,23 +738,23 @@ class _PolicyState extends State<Policy> {
Container( Container(
padding: isDesktop ? const EdgeInsets.only(left: 35) : null, padding: isDesktop ? const EdgeInsets.only(left: 35) : null,
child: child:
isDesktop isDesktop
? Row( ? Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Expanded(child: _buildPolicyNameField(isDesktop)), Expanded(child: _buildPolicyNameField(isDesktop)),
Spacer(), Spacer(),
Expanded(child: _buildPolicyTypeField(isDesktop)), Expanded(child: _buildPolicyTypeField(isDesktop)),
], ],
) )
: Column( : Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
_buildPolicyNameField(isDesktop), _buildPolicyNameField(isDesktop),
SizedBox(height: 20), SizedBox(height: 20),
_buildPolicyTypeField(isDesktop), _buildPolicyTypeField(isDesktop),
], ],
), ),
), ),
SizedBox(height: 10), SizedBox(height: 10),
Divider(thickness: 0.1, color: Colors.grey), Divider(thickness: 0.1, color: Colors.grey),
@ -767,66 +767,66 @@ class _PolicyState extends State<Policy> {
], ],
isDesktop isDesktop
? Padding( ? Padding(
padding: const EdgeInsets.only(left: 30.0, right: 98.0), padding: const EdgeInsets.only(left: 30.0, right: 98.0),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
"Approval Criteria", "Approval Criteria",
style: GoogleFonts.poppins( style: GoogleFonts.poppins(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Color(0xFF575A74), color: Color(0xFF575A74),
), ),
),
Text(
"Service Priority",
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(), : SizedBox.shrink(),
isDesktop isDesktop
? Container( ? Container(
// color: Colors.yellow.shade50, // color: Colors.yellow.shade50,
height: MediaQuery.of(context).size.height * 0.54, height: MediaQuery.of(context).size.height * 0.54,
child: SingleChildScrollView( child: SingleChildScrollView(
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
children: [ children: [
_buildPolicyOrdering(isDesktop), Column(
_buildPolicyCategory(isDesktop), children: [
_buildPolicyOrdering(isDesktop),
_buildPolicyCategory(isDesktop),
],
),
Column(children: [_buildPolicyCategoryList(isDesktop)]),
], ],
), ),
Column(children: [_buildPolicyCategoryList(isDesktop)]), ),
], )
),
),
)
: Expanded( : Expanded(
child: Container( child: Container(
child: SingleChildScrollView( child: SingleChildScrollView(
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
child: Column( child: Column(
children: [ children: [
_buildPolicyCategoryList(isDesktop), _buildPolicyCategoryList(isDesktop),
_buildPolicyOrdering(isDesktop), _buildPolicyOrdering(isDesktop),
_buildPolicyCategory(isDesktop), _buildPolicyCategory(isDesktop),
], ],
),
),
), ),
), ),
),
),
// isDesktop // isDesktop
// ? Expanded( // ? Expanded(
// child: Row( // child: Row(
@ -940,28 +940,28 @@ class _PolicyState extends State<Policy> {
border: Border.all(color: Colors.blueGrey.shade100, width: 0.35), border: Border.all(color: Colors.blueGrey.shade100, width: 0.35),
), ),
child: child:
isDesktop isDesktop
? Padding( ? Padding(
padding: const EdgeInsets.all(10.0), padding: const EdgeInsets.all(10.0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [_buildPolicySubCategoryList(isDesktop)], children: [_buildPolicySubCategoryList(isDesktop)],
), ),
) )
: Column( : Column(
children: [ children: [
Container( Container(
// color: Colors.amber, // color: Colors.amber,
child: _buildPolicySubCategoryList(isDesktop), child: _buildPolicySubCategoryList(isDesktop),
// child: Text("FAta"), // child: Text("FAta"),
// child: Row( // child: Row(
// mainAxisAlignment: MainAxisAlignment.start, // mainAxisAlignment: MainAxisAlignment.start,
// children: [_buildPolicySubCategoryList(isDesktop)], // children: [_buildPolicySubCategoryList(isDesktop)],
// ), // ),
), ),
], ],
), ),
); );
} }
@ -1118,21 +1118,21 @@ class _PolicyState extends State<Policy> {
width: isDesktop ? MediaQuery.of(context).size.width * 0.62 : null, width: isDesktop ? MediaQuery.of(context).size.width * 0.62 : null,
// width: isDesktop ? MediaQuery.of(context).size.width * 0.75 : null, // width: isDesktop ? MediaQuery.of(context).size.width * 0.75 : null,
child: child:
isDesktop isDesktop
? Container( ? Container(
// color: Colors.amber, // color: Colors.amber,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [_buildPolicyServiceOrdering(isDesktop)], children: [_buildPolicyServiceOrdering(isDesktop)],
), ),
) )
: Container( : Container(
// color: Colors.amber, // color: Colors.amber,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [_buildPolicyServiceOrdering(isDesktop)], children: [_buildPolicyServiceOrdering(isDesktop)],
), ),
), ),
); );
} }
@ -1143,14 +1143,16 @@ class _PolicyState extends State<Policy> {
// Sort services by 'order' // Sort services by 'order'
ServicesChoosed!.sort( ServicesChoosed!.sort(
(a, b) => (a['order'] ?? 0).compareTo(b['order'] ?? 0), (a, b) => (a['order'] ?? 0).compareTo(b['order'] ?? 0),
); );
List<String> services = List<String> services =
ServicesChoosed!.map((service) => service['name'].toString()).toList(); ServicesChoosed!.map((service) => service['name'].toString()).toList();
List<String> serviceDBvalue = List<String> serviceDBvalue =
ServicesChoosed!.map((service) => service['service_id'].toString()).toList(); ServicesChoosed!
.map((service) => service['service_id'].toString())
.toList();
print("1093"); print("1093");
print(services); print(services);
@ -1162,109 +1164,110 @@ class _PolicyState extends State<Policy> {
child: Flex( child: Flex(
direction: Axis.horizontal, direction: Axis.horizontal,
children: children:
services.asMap().entries.map((entry) { services.asMap().entries.map((entry) {
int index = entry.key + 1; int index = entry.key + 1;
String service = entry.value; String service = entry.value;
String serviceId = index.toString(); String serviceId = index.toString();
bool isSelected = bool isSelected =
selectedServiceIndex.value == index.toString(); selectedServiceIndex.value == index.toString();
return SizedBox( return SizedBox(
// width: isDesktop ? 40 : null, // width: isDesktop ? 40 : null,
height: height:
isDesktop isDesktop
? max( ? max(
(MediaQuery.of(context).size.height * 0.075), (MediaQuery.of(context).size.height * 0.075),
10, 10,
) )
: 45, : 45,
// max((MediaQuery.of(context).size.height * 0.09), 10) // max((MediaQuery.of(context).size.height * 0.09), 10)
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
print("Selected Services - $service - $index"); print("Selected Services - $service - $index");
setState(() { setState(() {
selectedServiceIndex.value = index.toString(); selectedServiceIndex.value = index.toString();
selectedServiceDBValue = serviceDBvalue[entry.key]; selectedServiceDBValue = serviceDBvalue[entry.key];
selectedService = service; selectedService = service;
print( print(
" selectedServiceIndex.value - ${selectedServiceIndex.value}", " selectedServiceIndex.value - ${selectedServiceIndex.value}",
); );
print( print(
" selectedServiceDBValue.value - ${selectedServiceDBValue}", " selectedServiceDBValue.value - ${selectedServiceDBValue}",
); );
// policyCriteriaKey.currentState?.fieldForPolicy(); // policyCriteriaKey.currentState?.fieldForPolicy();
// policyCriteriaKey.currentState // policyCriteriaKey.currentState
// ?.addOrUpdatePolicy(selectedServiceIndex.value); // ?.addOrUpdatePolicy(selectedServiceIndex.value);
print("policyselectedService - $selectedService"); print("policyselectedService - $selectedService");
if (selectedService == "Flight" || if (selectedService == "Flight" ||
selectedService == "Train" || selectedService == "Accomodation") { selectedService == "Train" ||
showClass = true; selectedService == "Accomodation") {
showCost = false; showClass = true;
int serviceCode = selectedService == "Flight" ? 1 : 2; showCost = false;
print("policyselectedService1 - $selectedService"); int serviceCode = selectedService == "Flight" ? 1 : 2;
policyCriteriaKey.currentState print("policyselectedService1 - $selectedService");
?.fetchTrainFlightClass(); policyCriteriaKey.currentState
} ?.fetchTrainFlightClass();
// else if (selectedService == "Accommodation") { }
// showClass = true; // else if (selectedService == "Accommodation") {
// showCost = false; // showClass = true;
// } // showCost = false;
else { // }
showClass = false; else {
showCost = false; showClass = false;
} showCost = false;
}); }
}, });
child: Container( },
margin: const EdgeInsets.all(5), child: Container(
padding: margin: const EdgeInsets.all(5),
isDesktop padding:
? const EdgeInsets.all(8) isDesktop
: const EdgeInsets.symmetric( ? const EdgeInsets.all(8)
horizontal: 8, : const EdgeInsets.symmetric(
vertical: 3, horizontal: 8,
), vertical: 3,
alignment: Alignment.center, ),
child: Column( alignment: Alignment.center,
mainAxisSize: MainAxisSize.min, child: Column(
children: [ mainAxisSize: MainAxisSize.min,
Text( children: [
service, Text(
style: GoogleFonts.poppins( service,
color: style: GoogleFonts.poppins(
isSelected color:
? const Color(0xFF114D8B) isSelected
: Colors.black87, ? const Color(0xFF114D8B)
fontSize: 13, : Colors.black87,
fontWeight: fontSize: 13,
isSelected fontWeight:
? FontWeight.bold isSelected
: FontWeight.w500, ? FontWeight.bold
decoration: : FontWeight.w500,
TextDecoration decoration:
.none, // remove built-in underline 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),
),
],
), ),
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(),
);
}).toList(),
), ),
), ),
); );
@ -1288,7 +1291,7 @@ class _PolicyState extends State<Policy> {
} }
List<String> services = List<String> services =
ServicesChoosed!.map((service) => service['name'].toString()).toList(); ServicesChoosed!.map((service) => service['name'].toString()).toList();
return Expanded( return Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
@ -1296,88 +1299,88 @@ class _PolicyState extends State<Policy> {
child: Flex( child: Flex(
direction: isDesktop ? Axis.vertical : Axis.horizontal, direction: isDesktop ? Axis.vertical : Axis.horizontal,
children: children:
services.asMap().entries.map((entry) { services.asMap().entries.map((entry) {
int index = entry.key + 1; int index = entry.key + 1;
String service = entry.value; String service = entry.value;
bool isSelected = bool isSelected =
selectedServiceIndex.value == index.toString(); selectedServiceIndex.value == index.toString();
return SizedBox( return SizedBox(
width: isDesktop ? 180 : null, width: isDesktop ? 180 : null,
height: height:
isDesktop isDesktop
? max( ? max(
(MediaQuery.of(context).size.height * 0.075), (MediaQuery.of(context).size.height * 0.075),
10, 10,
) )
: 45, : 45,
// max((MediaQuery.of(context).size.height * 0.09), 10) // max((MediaQuery.of(context).size.height * 0.09), 10)
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
print("Selected Services - $service - $index"); print("Selected Services - $service - $index");
setState(() { setState(() {
// selectedServiceIndex.value = index.toString(); // selectedServiceIndex.value = index.toString();
// selectedService = service; // selectedService = service;
// //
// if (selectedService == "Flight" || // if (selectedService == "Flight" ||
// selectedService == "Train") { // selectedService == "Train") {
// showClass = true; // showClass = true;
// showCost = true; // showCost = true;
// int serviceCode = selectedService == "Flight" ? 1 : 2; // int serviceCode = selectedService == "Flight" ? 1 : 2;
// policyCriteriaKey.currentState?.fetchTrainFlightClass(); // policyCriteriaKey.currentState?.fetchTrainFlightClass();
// } else if (selectedService == "Accommodation") { // } else if (selectedService == "Accommodation") {
// showClass = true; // showClass = true;
// showCost = false; // showCost = false;
// } else { // } else {
// showClass = false; // showClass = false;
// showCost = false; // showCost = false;
// } // }
}); });
}, },
child: Container( child: Container(
margin: EdgeInsets.all(5), margin: EdgeInsets.all(5),
padding: padding:
isDesktop isDesktop
? EdgeInsets.all(8) ? EdgeInsets.all(8)
: EdgeInsets.only( : EdgeInsets.only(
top: 3, top: 3,
bottom: 3, bottom: 3,
left: 8, left: 8,
right: 8, right: 8,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
// color: Colors.blue, // color: Colors.blue,
color: isSelected ? Color(0xFF114D8B) : Colors.white, color: isSelected ? Color(0xFF114D8B) : Colors.white,
// : Color(0xFFEBEBF7), // : Color(0xFFEBEBF7),
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
border: Border.all( border: Border.all(
color: Colors.white, // Light grey border color: Colors.white, // Light grey border
width: 1, width: 1,
), ),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
color: Colors.grey.withAlpha(90), // Shadow color color: Colors.grey.withAlpha(90), // Shadow color
blurRadius: 1, // Blur radius blurRadius: 1, // Blur radius
spreadRadius: 1, // Spread radius spreadRadius: 1, // Spread radius
offset: Offset(0, 1), // Shadow position 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,
),
), ),
],
),
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(),
), ),
), ),
); );
@ -1455,14 +1458,14 @@ class _PolicyState extends State<Policy> {
borderRadius: BorderRadius.circular(4), // Rounded rectangle borderRadius: BorderRadius.circular(4), // Rounded rectangle
border: Border.all( border: Border.all(
color: color:
_selectedTripType == "1" ? Colors.green : Colors.black, _selectedTripType == "1" ? Colors.green : Colors.black,
width: _selectedTripType == "1" ? 2 : 1, width: _selectedTripType == "1" ? 2 : 1,
), ),
), ),
child: child:
_selectedTripType == "1" _selectedTripType == "1"
? Icon(Icons.rectangle, size: 8, color: Colors.green) ? Icon(Icons.rectangle, size: 8, color: Colors.green)
: null, // Add checkmark if selected : null, // Add checkmark if selected
), ),
), ),
], ],
@ -1511,14 +1514,14 @@ class _PolicyState extends State<Policy> {
borderRadius: BorderRadius.circular(4), // Rounded rectangle borderRadius: BorderRadius.circular(4), // Rounded rectangle
border: Border.all( border: Border.all(
color: color:
_selectedTripType == "2" ? Colors.green : Colors.black, _selectedTripType == "2" ? Colors.green : Colors.black,
width: _selectedTripType == "2" ? 2 : 1, width: _selectedTripType == "2" ? 2 : 1,
), ),
), ),
child: child:
_selectedTripType == "2" _selectedTripType == "2"
? Icon(Icons.rectangle, size: 8, color: Colors.green) ? Icon(Icons.rectangle, size: 8, color: Colors.green)
: null, // Add checkmark if selected : null, // Add checkmark if selected
), ),
), ),
], ],
@ -1563,17 +1566,17 @@ class _PolicyState extends State<Policy> {
SizedBox(width: 20), SizedBox(width: 20),
MouseRegion( MouseRegion(
cursor: cursor:
isViewMode isViewMode
? SystemMouseCursors.forbidden ? SystemMouseCursors.forbidden
: SystemMouseCursors.click, : SystemMouseCursors.click,
child: ElevatedButton( child: ElevatedButton(
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: backgroundColor:
isViewMode ? layoutColor : layoutColor, // Keep original color isViewMode ? layoutColor : layoutColor, // Keep original color
foregroundColor: foregroundColor:
isViewMode ? Colors.white : Colors.white, // Keep original color isViewMode ? Colors.white : Colors.white, // Keep original color
disabledBackgroundColor: disabledBackgroundColor:
layoutColor, // Ensure color remains when disabled layoutColor, // Ensure color remains when disabled
disabledForegroundColor: Colors.white, disabledForegroundColor: Colors.white,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
@ -1582,8 +1585,8 @@ class _PolicyState extends State<Policy> {
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
), ),
onPressed: onPressed:
// isViewMode ? null : handleSubmit, // Disable when in view mode // isViewMode ? null : handleSubmit, // Disable when in view mode
isViewMode || isDisable ? null : handleSubmit, isViewMode || isDisable ? null : handleSubmit,
child: Text("Submit", style: GoogleFonts.poppins(fontSize: 10)), child: Text("Submit", style: GoogleFonts.poppins(fontSize: 10)),
), ),
), ),
@ -1655,4 +1658,4 @@ class _PolicyState extends State<Policy> {
), ),
]; ];
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -31,14 +31,34 @@ class _MyAppState extends State<MyApp> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
SemanticsBinding.instance.ensureSemantics(); // Safe here - for testing uncomment this SemanticsBinding.instance
.ensureSemantics(); // Safe here -only for testing uncomment, Otherwise Email Template wont allow to type
if (kIsWeb) { if (kIsWeb) {
final uri = Uri.parse(html.window.location.href); final uri = Uri.parse(html.window.location.href);
print("URI - $uri"); print("URI - $uri");
final fragment = uri.fragment; // e.g., 'authredirection?code=xyz123'
if (uri.path == '/tstat/authredirection' && print("Full URI: $uri");
uri.queryParameters['code'] != null) { print("Fragment: $fragment");
_authCode = uri.queryParameters['code'];
// Parse just the fragment safely
final fragmentParts = fragment.split('?');
print("fragmentParts: $fragmentParts");
final fragmentPath = fragmentParts.first;
print("fragmentPath: $fragmentPath");
final query = fragmentParts.length > 1 ? fragmentParts[1] : '';
print("query: $query");
final queryParams = Uri.splitQueryString(query);
print("query: $query");
final authCode = queryParams['code'];
if (fragmentPath == '/authredirection' && authCode != null) {
// _authCode = uri.queryParameters['code'];
_authCode = queryParams['code'];
// _isAuthRedirect = true; // _isAuthRedirect = true;
html.window.console.log("Auth code detected: $_authCode"); html.window.console.log("Auth code detected: $_authCode");
// print(">>> _isAuthRedirect: $_isAuthRedirect"); // print(">>> _isAuthRedirect: $_isAuthRedirect");
@ -54,9 +74,14 @@ class _MyAppState extends State<MyApp> {
} }
Future<void> handleTokenUsingMS(String? authCode) async { Future<void> handleTokenUsingMS(String? authCode) async {
print("handleTokenUsingMS- $authCode");
if (authCode == null) return; if (authCode == null) return;
// final url =
// 'http://localhost:40617/tstat/auth/verifyMSAuthUser?code=$authCode';
final url = '$apiUrl/auth/verifyMSAuthUser?code=$authCode'; final url = '$apiUrl/auth/verifyMSAuthUser?code=$authCode';
print("url- $url");
try { try {
final response = await http.get( final response = await http.get(
Uri.parse(url), Uri.parse(url),
@ -103,57 +128,6 @@ class _MyAppState extends State<MyApp> {
} }
} }
// Future<void> handleTokenUsingMS(authCode) async {
// if (authCode == null) return;
//
// final url = '$apiUrl/auth/verifyMSAuthUser?code=$authCode';
// try {
// final response = await http.get(
// Uri.parse(url),
// headers: {'Content-Type': 'application/json'},
// );
//
// if (response.statusCode == 200) {
// final MS_Token = json.decode(response.body)['token'];
// print("MS_Token - $MS_Token");
//
// if (MS_Token != '') {
// print('Microsoft - Token Available');
// await storeUserDetails(MS_Token);
//
// print("userRole - $userRole");
//
// if (userRole == "Travel Agent") {
// router.go('/listTravelAgentPlan');
// } else if (userRole == "Org Admin" || userRole == "Travel Admin") {
// router.go('/listAllPlan');
// } else {
// router.go('/listPlan');
// }
// } else {
// print('Microsoft - Token Not Available');
// throw Exception('Token not Founded');
// }
// } else {
// // final errorMessage = json.decode(response.body)['message'];
// // print(errorMessage);
// // throw Exception(errorMessage);
//
// try {
// final errorMessage = json.decode(response.body)['message'];
// print(errorMessage);
// throw Exception(errorMessage);
// } catch (_) {
// print("Non-JSON error from server: ${response.body}");
// throw Exception("Authentication failed: ${response.body}");
// }
// }
// } catch (e) {
// router.go('/');
// print("Error: $e");
// }
// }
Future<void> storeUserDetails(String token) async { Future<void> storeUserDetails(String token) async {
try { try {
final parts = token.split('.'); final parts = token.split('.');
@ -209,176 +183,3 @@ class _MyAppState extends State<MyApp> {
); );
} }
} }
//
// import 'package:flutter/foundation.dart';
// import 'package:flutter/material.dart';
// import 'package:flutter/rendering.dart';
// import 'package:flutter_quill/flutter_quill.dart';
// import 'package:flutter_localizations/flutter_localizations.dart';
//
// import 'package:frontend/routes/custom_router.dart';
// import 'dart:html' as html;
// import 'package:frontend/config/apiUrl.dart'; // 1 newly added
// import 'package:go_router/go_router.dart';
// import 'package:http/http.dart' as http; // 2 newly added
// import 'dart:convert'; // 3 newly added
//
// import 'package:shared_preferences/shared_preferences.dart';
//
// import 'Screens/myTemplates/templateTest.dart';
//
// class MyApp extends StatefulWidget {
// const MyApp({super.key});
//
// @override
// State<MyApp> createState() => _MyAppState();
// }
//
// class _MyAppState extends State<MyApp> {
// String? _authCode;
// String? userRole;
// bool _isAuthRedirect = false;
// @override
// void initState() {
// super.initState();
// SemanticsBinding.instance.ensureSemantics(); // Safe here
// if (kIsWeb) {
// final uri = Uri.parse(html.window.location.href);
// if (uri.path == '/authredirection' &&
// uri.queryParameters['code'] != null) {
// _authCode = uri.queryParameters['code'];
// // _isAuthRedirect = true;
// html.window.console.log("Auth code detected: $_authCode");
// // print(">>> _isAuthRedirect: $_isAuthRedirect");
// print(">>> Auth code found at startup: $_authCode");
//
// WidgetsBinding.instance.addPostFrameCallback((_) {
// handleTokenUsingMS(_authCode);
// });
// } else {
// html.window.console.log("No auth code found or wrong path.");
// }
// }
// }
//
// Future<void> handleTokenUsingMS(authCode) async {
// if (authCode == null) return;
//
// final url = '$apiUrl/auth/verifyMSAuthUser?code=$authCode';
// try {
// final response = await http.get(
// Uri.parse(url),
// headers: {'Content-Type': 'application/json'},
// );
//
// if (response.statusCode == 200) {
// final MS_Token = json.decode(response.body)['token'];
// print("MS_Token - $MS_Token");
//
// if (MS_Token != '') {
// print('Microsoft - Token Available');
// await storeUserDetails(MS_Token);
//
// print("userRole - $userRole");
//
// if (userRole == "Travel Agent") {
// router.go('/listTravelAgentPlan');
// } else if (userRole == "Org Admin" || userRole == "Travel Admin") {
// router.go('/listAllPlan');
// } else {
// router.go('/listPlan');
// }
// } else {
// print('Microsoft - Token Not Available');
// throw Exception('Token not Founded');
// }
// } else {
// final errorMessage = json.decode(response.body)['message'];
// print(errorMessage);
// throw Exception(errorMessage);
// }
// } catch (e) {
// print("Error: $e");
// }
// }
//
// Future<void> storeUserDetails(String token) async {
// try {
// final parts = token.split('.');
// if (parts.length != 3) throw Exception('Invalid token format');
//
// final payload = json.decode(
// utf8.decode(base64Url.decode(base64Url.normalize(parts[1]))),
// );
//
// final userData = payload['data'];
//
// final prefs = await SharedPreferences.getInstance();
// await prefs.setString('auth_token', token);
// await prefs.setString(
// 'user_data',
// jsonEncode(userData),
// ); // Store full user data
//
// if (userData != null) {
// final pref = await SharedPreferences.getInstance();
// await pref.setString('auth_token', token);
// await pref.setString('user_data', jsonEncode(userData));
//
// userRole = userData['role'];
//
// print("userData - $userData");
// print("userData11 - ${userData['role']}");
// print("userData12 - $userRole");
// }
// } catch (e) {
// print('Error decoding token: $e');
// }
// }
//
// @override
// Widget build(BuildContext context) {
// // if (_isAuthRedirect) {
// // print("Rendering MicrosoftPage with code: $_authCode");
// // return MaterialApp(
// // home: MicrosoftPage(code: _authCode),
// // debugShowCheckedModeBanner: false,
// // );
// // }
// // return MaterialApp(
// // title: 'Quill Web Test',
// // localizationsDelegates: const [
// // GlobalMaterialLocalizations.delegate,
// // GlobalCupertinoLocalizations.delegate,
// // GlobalWidgetsLocalizations.delegate,
// // FlutterQuillLocalizations.delegate,
// // ],
// // supportedLocales: const [Locale('en')],
// // home: const MyHomePage(title: 'Flutter Demo Home Page'),
// // );
// return MaterialApp.router(
// title: 'TRIP MANAGEMENT',
// routerConfig: router,
// debugShowCheckedModeBanner: false,
// localizationsDelegates: const [
// GlobalMaterialLocalizations.delegate,
// GlobalCupertinoLocalizations.delegate,
// GlobalWidgetsLocalizations.delegate,
// FlutterQuillLocalizations.delegate,
// ],
// supportedLocales: const [
// Locale('en'),
// Locale('es'), // Add more as needed
// ],
// localeResolutionCallback: (locale, supportedLocales) {
// for (var supportedLocale in supportedLocales) {
// if (supportedLocale.languageCode == locale?.languageCode) {
// return supportedLocale;
// }
// }
// return supportedLocales.first;
// },
// );
// }
// }

View File

@ -1,4 +1,5 @@
//api url //api url
// const String apiUrl = 'http://localhost/tstat_be'; // const String apiUrl = 'http://localhost/tstat_be';
// const String apiUrl = 'https://uat.tripapprovaltool.com/tstat_be'; // const String apiUrl = 'https://uat.tripapprovaltool.com/tstat_be';
const String apiUrl = 'http://apitest.tripapprovaltool.com/tstat_be'; // look at this const String apiUrl =
'http://apitest.tripapprovaltool.com/tstat_be'; // look at this

View File

@ -145,6 +145,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.4.1" version: "0.4.1"
dotted_border:
dependency: "direct main"
description:
name: dotted_border
sha256: "99b091ec6891ba0c5331fdc2b502993c7c108f898995739a73c6845d71dad70c"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
dropdown_search: dropdown_search:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@ -63,6 +63,7 @@ dependencies:
html2md: ^1.3.2 html2md: ^1.3.2
flutter_quill_delta_from_html: ^1.5.2 flutter_quill_delta_from_html: ^1.5.2
flutter_launcher_icons: ^0.14.4 flutter_launcher_icons: ^0.14.4
dotted_border: ^3.1.0

View File

@ -31,7 +31,7 @@
<!-- Favicon --> <!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/> <link rel="icon" type="image/png" href="favicon.png"/>
<title>frontend</title> <title>Trip Approval Tool</title>
<link rel="manifest" href="manifest.json"> <link rel="manifest" href="manifest.json">
</head> </head>
<body> <body>