staff-enq-redesign

This commit is contained in:
venbaittech 2025-10-22 12:06:00 +05:30
parent 659dba0f14
commit 3a0c29265b
15 changed files with 411 additions and 234 deletions

File diff suppressed because one or more lines are too long

View File

@ -9,6 +9,26 @@ class Validators {
return null; return null;
} }
static String? requiredVechileNum(String? value, String label) {
if (value == null || value.trim().isEmpty) {
return "Required";
}
// Convert to uppercase and remove extra spaces
value = value.trim().toUpperCase();
// Allow pattern like: TN 01 AB 1234 or TN01AB1234
final RegExp vehiclePattern = RegExp(
r'^[A-Z]{2}\s?\d{1,2}\s?[A-Z]{1,2}\s?\d{1,4}$',
);
if (!vehiclePattern.hasMatch(value)) {
return "Enter valid.no.(e.g.TN01AB1234 or TN 01 AB 1234)";
}
return null; // valid
}
static String? email(String? value, String label) { static String? email(String? value, String label) {
if (value == null || value.trim().isEmpty) { if (value == null || value.trim().isEmpty) {
return "Required"; return "Required";

View File

@ -2,6 +2,7 @@ import 'package:dropdown_search/dropdown_search.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
@ -797,7 +798,11 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
label: "Registration Number *", label: "Registration Number *",
field: ThemedFormField( field: ThemedFormField(
controller: controllers['regNo']!, controller: controllers['regNo']!,
validator: (value) => Validators.requiredField(value, "regNo"), inputFormatters: [
UpperCaseTextFormatter(), // 👈 custom formatter for uppercase
FilteringTextInputFormatter.allow(RegExp(r'[A-Za-z0-9- ]')),
],
validator: (value) => Validators.requiredVechileNum(value, "regNo"),
txtwidth: ResponsiveLayout.isMobile(context) txtwidth: ResponsiveLayout.isMobile(context)
? null ? null
: MediaQuery.of(context).size.width * 0.26, : MediaQuery.of(context).size.width * 0.26,

View File

@ -104,7 +104,11 @@ class AttendanceAllDetailsState extends ConsumerState<AttendanceAllDetails> {
try { try {
// Convert "10-2025" "2025-10" // Convert "10-2025" "2025-10"
final parsedDate = DateFormat('MM-yyyy').parse(fromDateText); // final parsedDate = DateFormat('MM-yyyy').parse(fromDateText);
// final apiMonth = DateFormat('yyyy-MM').format(parsedDate);
// Parse "Nov 2025" DateTime
final parsedDate = DateFormat('MMM yyyy').parse(fromDateText);
final apiMonth = DateFormat('yyyy-MM').format(parsedDate); final apiMonth = DateFormat('yyyy-MM').format(parsedDate);
print('Converted month for API: $apiMonth'); print('Converted month for API: $apiMonth');
@ -155,32 +159,16 @@ class AttendanceAllDetailsState extends ConsumerState<AttendanceAllDetails> {
if (fromDate != null && fromDate.isNotEmpty) { if (fromDate != null && fromDate.isNotEmpty) {
// Parse the string to DateTime first // Parse the string to DateTime first
// final parsedDate = DateFormat('yyyy-MM').parse(fromDate);
// final monthText = DateFormat('MM-yyyy').format(parsedDate);
// Parse the string "2025-10" to a DateTime
final parsedDate = DateFormat('yyyy-MM').parse(fromDate); final parsedDate = DateFormat('yyyy-MM').parse(fromDate);
final monthText = DateFormat('MM-yyyy').format(parsedDate); // Convert it to "Oct 2025"
final monthText = DateFormat('MMM yyyy').format(parsedDate);
controllers['month']?.text = monthText; controllers['month']?.text = monthText;
} }
// controllers['endDate']?.text = toDate;
// if (data is List) {
// getStaffData = List<Map<String, dynamic>>.from(data);
// } else if (data is Map) {
// getStaffData = [Map<String, dynamic>.from(data)];
// } else {
// getStaffData = [];
// }
// if (data is List) {
// // Safely map each item to Map<String, dynamic>
// // getStaffData = data.map<Map<String, dynamic>>((item) {
// // if (item is Map<String, dynamic>) return item;
// // if (item is Map) return Map<String, dynamic>.from(item);
// // return <String, dynamic>{}; // fallback empty map
// // }).toList();
// // Convert JSArray<dynamic> safely to List<Map<String, dynamic>>
//
// } else if (data is Map) {
// getStaffData = [Map<String, dynamic>.from(data)];
// } else {
// getStaffData = [];
// }
print('test 2'); print('test 2');
getStaffData = (data as List) getStaffData = (data as List)
.map<Map<String, dynamic>>( .map<Map<String, dynamic>>(
@ -439,10 +427,7 @@ class AttendanceAllDetailsState extends ConsumerState<AttendanceAllDetails> {
Expanded(flex: 2, child: Text('Staff Name', style: _headerStyle)), Expanded(flex: 2, child: Text('Staff Name', style: _headerStyle)),
Expanded(flex: 2, child: Text('Month', style: _headerStyle)), Expanded(flex: 2, child: Text('Month', style: _headerStyle)),
Expanded( Expanded(flex: 2, child: Text('Days', style: _headerStyle)),
flex: 2,
child: Text('Login Count', style: _headerStyle),
),
Expanded(flex: 2, child: Text('Action', style: _headerStyle)), Expanded(flex: 2, child: Text('Action', style: _headerStyle)),
], ],
), ),
@ -568,12 +553,12 @@ class AttendanceAllDetailsState extends ConsumerState<AttendanceAllDetails> {
validator: (value) => Validators.requiredField(value, "date"), validator: (value) => Validators.requiredField(value, "date"),
borderColor: Colors.grey.shade300, borderColor: Colors.grey.shade300,
controller: controllers['startDate']!, controller: controllers['startDate']!,
onDateSelected: (date) { // onDateSelected: (date) {
print("Picked Date: $date"); // print("Picked Date: $date");
// // final month = DateFormat('MM-yyyy').format(date);
controllers['startDate']?.text = DateFormat('MM-yyyy').format(date); // controllers['startDate']?.text = DateFormat('MM-yyyy').format(date);
// controllers['date']?.text = date as String; // // controllers['date']?.text = date as String;
}, // },
), ),
], ],
); );

View File

@ -109,7 +109,11 @@ class IndividualAttendanceDetailsState
try { try {
// Convert "10-2025" "2025-10" // Convert "10-2025" "2025-10"
final parsedDate = DateFormat('MM-yyyy').parse(fromDateText); // final parsedDate = DateFormat('MM-yyyy').parse(fromDateText);
// final apiMonth = DateFormat('yyyy-MM').format(parsedDate);
// Parse "Nov 2025" DateTime
final parsedDate = DateFormat('MMM yyyy').parse(fromDateText);
final apiMonth = DateFormat('yyyy-MM').format(parsedDate); final apiMonth = DateFormat('yyyy-MM').format(parsedDate);
print('Converted month for API: $apiMonth'); print('Converted month for API: $apiMonth');
@ -162,8 +166,13 @@ class IndividualAttendanceDetailsState
if (fromDate != null && fromDate.isNotEmpty) { if (fromDate != null && fromDate.isNotEmpty) {
// Parse the string to DateTime first // Parse the string to DateTime first
// final parsedDate = DateFormat('yyyy-MM').parse(fromDate);
// final monthText = DateFormat('MM-yyyy').format(parsedDate);
// Parse the string "2025-10" to a DateTime
final parsedDate = DateFormat('yyyy-MM').parse(fromDate); final parsedDate = DateFormat('yyyy-MM').parse(fromDate);
final monthText = DateFormat('MM-yyyy').format(parsedDate); // Convert it to "Oct 2025"
final monthText = DateFormat('MMM yyyy').format(parsedDate);
controllers['month']?.text = monthText; controllers['month']?.text = monthText;
} }
@ -241,10 +250,16 @@ class IndividualAttendanceDetailsState
filteredData = getStaffData.where((item) { filteredData = getStaffData.where((item) {
// final isActiveStatus = item['is_active'] == "1" ? "active" : "inactive"; // final isActiveStatus = item['is_active'] == "1" ? "active" : "inactive";
return (item['login_date'] ?? '-').toLowerCase().contains( return (item['date'] ?? '-').toLowerCase().contains(
query.toLowerCase(), query.toLowerCase(),
) || ) ||
(item['logout_date'] ?? '-').toLowerCase().contains( (item['login_time'] ?? '-').toLowerCase().contains(
query.toLowerCase(),
) ||
(item['logout_time'] ?? '-').toLowerCase().contains(
query.toLowerCase(),
) ||
(item['no_of_logged_in_time'] ?? '-').toLowerCase().contains(
query.toLowerCase(), query.toLowerCase(),
); );
}).toList(); }).toList();
@ -401,7 +416,13 @@ class IndividualAttendanceDetailsState
fileName: "staff_individual_attendance_list", fileName: "staff_individual_attendance_list",
data: filteredData, data: filteredData,
txt: !ResponsiveLayout.isMobile(context) ? true : false, txt: !ResponsiveLayout.isMobile(context) ? true : false,
headers: ["id", "login_date", "logout_date"], headers: [
"id",
"date",
"login_time",
"logout_time",
'no_of_logged_in_time',
],
), ),
], ],
), ),
@ -417,11 +438,13 @@ class IndividualAttendanceDetailsState
child: Row( child: Row(
children: [ children: [
Expanded(flex: 1, child: Text('S.No.', style: _headerStyle)), Expanded(flex: 1, child: Text('S.No.', style: _headerStyle)),
Expanded(flex: 2, child: Text('Login Date', style: _headerStyle)), Expanded(flex: 2, child: Text('Date', style: _headerStyle)),
Expanded(flex: 2, child: Text('Login', style: _headerStyle)),
Expanded(flex: 2, child: Text('Login Time', style: _headerStyle)),
Expanded( Expanded(
flex: 2, flex: 2,
child: Text('Logout Date', style: _headerStyle), child: Text('Number Of Hours', style: _headerStyle),
), ),
], ],
), ),
@ -479,14 +502,19 @@ class IndividualAttendanceDetailsState
child: Row( child: Row(
children: [ children: [
Expanded(flex: 1, child: Text('$sno' ?? '-', style: _dataBold)), Expanded(flex: 1, child: Text('$sno' ?? '-', style: _dataBold)),
Expanded( Expanded(flex: 2, child: Text(item['date'] ?? '-', style: _dataBold)),
flex: 2,
child: Text(item['login_date'] ?? '-', style: _dataBold),
),
Expanded( Expanded(
flex: 2, flex: 2,
child: Text(item['logout_date'] ?? '-', style: _dataBold), child: Text(item['login_time'] ?? '-', style: _dataBold),
),
Expanded(
flex: 2,
child: Text(item['logout_time'] ?? '-', style: _dataBold),
),
Expanded(
flex: 2,
child: Text(item['no_of_logged_in_time'] ?? '-', style: _dataBold),
), ),
], ],
), ),

View File

@ -99,6 +99,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
} }
void refresh() { void refresh() {
print('___DASHBOARD___');
final prefmanagerid = ref.read(managerIdProvider); final prefmanagerid = ref.read(managerIdProvider);
final prefuserid = ref.read(userIdProvider); final prefuserid = ref.read(userIdProvider);
final prefroleId = ref.read(userRoleProvider); final prefroleId = ref.read(userRoleProvider);
@ -579,7 +580,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
0.69 //400 0.69 //400
: (role == 'manager') : (role == 'manager')
? MediaQuery.of(context).size.height * 0.5 ? MediaQuery.of(context).size.height * 0.5
: (role == 'staff') : (role == 'staff' || role == 'handler')
? MediaQuery.of(context).size.height * 0.85 ? MediaQuery.of(context).size.height * 0.85
: MediaQuery.of(context).size.height * : MediaQuery.of(context).size.height *
0.5, // 350 adjust height as needed 0.5, // 350 adjust height as needed
@ -595,6 +596,17 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
role: role!, role: role!,
), ),
), ),
if (role == 'handler') ...[
Expanded(
child: UnassignedEnq(
key: UniqueKey(),
title: "Unassigned Enquiries",
role: role,
data: unAssignedEnqList,
onRefresh: refresh,
),
),
],
], ],
) )
: Row( : Row(
@ -720,7 +732,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
), ),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
if (role == 'manager' || role == 'handler') if (role == 'manager')
SizedBox( SizedBox(
// replace Expanded // replace Expanded
height: 350, // adjust height as needed height: 350, // adjust height as needed
@ -1222,7 +1234,7 @@ class othersPendings extends StatelessWidget {
flex: 2, flex: 2,
child: Text( child: Text(
// stringFlag + " Issued", // stringFlag + " Issued",
'Num Of Enquiry Assigned', 'Pending Enquiries',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: _headerStyle, style: _headerStyle,
), ),
@ -1251,15 +1263,15 @@ class othersPendings extends StatelessWidget {
style: _headerStyle, style: _headerStyle,
), ),
), ),
Expanded( // Expanded(
flex: 2, // flex: 2,
child: Text( // child: Text(
// stringFlag + " Issued", // // stringFlag + " Issued",
'Policy Created', // 'Policy Created',
textAlign: TextAlign.center, // textAlign: TextAlign.center,
style: _headerStyle, // style: _headerStyle,
), // ),
), // ),
], ],
), ),
), ),
@ -1357,15 +1369,15 @@ class othersPendings extends StatelessWidget {
style: _tableDataStyle, style: _tableDataStyle,
), ),
), ),
Expanded( // Expanded(
flex: 2, // flex: 2,
child: Text( // child: Text(
row['policy_created'] ?? "", // row['policy_created'] ?? "",
// row['total_approval_pending'] ?? "", // // row['total_approval_pending'] ?? "",
textAlign: TextAlign.center, // textAlign: TextAlign.center,
style: _tableDataStyle, // style: _tableDataStyle,
), // ),
), // ),
], ],
), ),
); );
@ -1726,15 +1738,29 @@ class UnassignedEnq extends StatelessWidget {
// ), // ),
Expanded( Expanded(
child: Text( child: Text(
"Vehicle Number", "Date",
textAlign: TextAlign.center, // textAlign: TextAlign.center,
style: _headerStyle, style: _headerStyle,
), ),
), ),
Expanded( Expanded(
child: Text( child: Text(
"Date", "Partner Name",
textAlign: TextAlign.center, // textAlign: TextAlign.center,
style: _headerStyle,
),
),
Expanded(
child: Text(
"Vehicle Number",
// textAlign: TextAlign.center,
style: _headerStyle,
),
),
Expanded(
child: Text(
"Insured Name",
// textAlign: TextAlign.center,
style: _headerStyle, style: _headerStyle,
), ),
), ),
@ -1782,7 +1808,7 @@ class UnassignedEnq extends StatelessWidget {
onTap: (role == 'handler') onTap: (role == 'handler')
? () { ? () {
// Print the id when row is clicked // Print the id when row is clicked
print("Clicked ID: ${row['id']}"); print("Clicked ID fd: ${row['id']}");
// You can also navigate or perform any action here // You can also navigate or perform any action here
showDialog( showDialog(
@ -1814,20 +1840,6 @@ class UnassignedEnq extends StatelessWidget {
), ),
child: Row( child: Row(
children: [ children: [
Expanded(
child: Text(
row['reg_no'] ?? "",
textAlign: TextAlign.center,
style: _tableDataStyle,
),
),
Expanded(
child: Text(
'', // convert int to string
textAlign: TextAlign.center,
style: _tableDataStyle,
),
),
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -1837,6 +1849,27 @@ class UnassignedEnq extends StatelessWidget {
], ],
), ),
), ),
Expanded(
child: Text(
row['agent_name'] ?? '', // convert int to string
// textAlign: TextAlign.center,
style: _tableDataStyle,
),
),
Expanded(
child: Text(
row['reg_no'] ?? "",
style: _tableDataStyle,
),
),
Expanded(
child: Text(
row['insured_name'] ?? "",
style: _tableDataStyle,
),
),
], ],
), ),
), ),

View File

@ -111,7 +111,7 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
} }
// Call your API // Call your API
getStaffList(userId, roleId); getStaffList(managerId, roleId);
} }
void refrshfilterDateRange() { void refrshfilterDateRange() {
@ -124,7 +124,7 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
// Reset the FormField validation // Reset the FormField validation
_formKey.currentState?.reset(); _formKey.currentState?.reset();
}); });
getStaffList(userId, roleId); getStaffList(managerId, roleId);
} }
Future<void> getStaffList( Future<void> getStaffList(
@ -643,42 +643,6 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
}, },
), ),
// Form(
// key: _formKey,
// child: Row(
// mainAxisAlignment: MainAxisAlignment.start,
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// buildStartDate(context),
// SizedBox(width: 10),
// buildEndDate(context),
// SizedBox(width: 10),
//
// Padding(
// padding: const EdgeInsets.symmetric(
// vertical: 8.0,
// ),
// child: GestureDetector(
// // onTap: filterDateRange,
// onTap: () {
// if (_formKey.currentState!.validate()) {
// filterDateRange(); // only runs if valid
// }
// },
// child: Icon(Icons.filter_alt_outlined),
// ),
// ),
//
// Padding(
// padding: const EdgeInsets.all(8.0),
// child: GestureDetector(
// onTap: refrshfilterDateRange,
// child: Icon(Icons.refresh),
// ),
// ),
// ],
// ),
// ),
Spacer(), Spacer(),
], ],
@ -822,11 +786,11 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
children: [ children: [
Expanded( Expanded(
flex: 2, flex: 2,
child: Text('Created Date', style: _headerStyle), child: Text('Received Date', style: _headerStyle),
), ),
Expanded( Expanded(
flex: 2, flex: 2,
child: Text('Updated Date', style: _headerStyle), child: Text('Assigned Date', style: _headerStyle),
), ),
Expanded( Expanded(
flex: 2, flex: 2,

View File

@ -207,10 +207,17 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
val = 'Policy'; val = 'Policy';
} }
showDialog( final result = await showDialog(
context: context, context: context,
barrierDismissible:
false, // optional - prevents closing by tapping outside
builder: (context) => TabEnquiryStaffList(showKey: val), builder: (context) => TabEnquiryStaffList(showKey: val),
); );
// Code here runs *after* the dialog is closed
print("Dialog closed");
print("Dialog result: $result");
refresh();
} }
List<dynamic> get _paginatedData2 { List<dynamic> get _paginatedData2 {

View File

@ -389,23 +389,23 @@ class CreateQuotationFormState extends ConsumerState<CreateQuotationForm> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
// Header row // Header row
Row( // Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, // mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ // children: [
Text( // Text(
widget.selectedQuotationFrmListId != null // widget.selectedQuotationFrmListId != null
? 'Update Proposal' // ? 'Update Proposal'
: 'Create Proposal', // : 'Create Proposal',
style: GoogleFonts.inter( // style: GoogleFonts.inter(
color: const Color(0xFF374141), // color: const Color(0xFF374141),
fontSize: 14, // fontSize: 14,
fontWeight: FontWeight.w600, // fontWeight: FontWeight.w600,
), // ),
), // ),
], // ],
), // ),
//
const SizedBox(height: 8), // const SizedBox(height: 8),
// 🔹 Switch content dynamically // 🔹 Switch content dynamically
buildFormFields(context), buildFormFields(context),

View File

@ -477,10 +477,10 @@ class PolicyStaffTabState extends ConsumerState<PolicyStaffTab> {
print("Response: ${response.body}"); print("Response: ${response.body}");
if (isUpdating) { if (isUpdating) {
context.go(AppRoutes.policylist); context.go(AppRoutes.enquiryForStaff);
} else { } else {
ref.read(enquiryIdProvider.notifier).state = null; ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.policylist); context.go(AppRoutes.enquiryForStaff);
} }
} else { } else {
print("❌ Submission failed. Status: ${response.statusCode}"); print("❌ Submission failed. Status: ${response.statusCode}");
@ -540,7 +540,7 @@ class PolicyStaffTabState extends ConsumerState<PolicyStaffTab> {
// const SizedBox(height: 20), // const SizedBox(height: 20),
//confirm button //confirm button
// if (!hasPolicyData) if (!hasPolicyData) ...[
Row( Row(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
@ -571,6 +571,7 @@ class PolicyStaffTabState extends ConsumerState<PolicyStaffTab> {
], ],
), ),
], ],
],
), ),
), ),
), ),
@ -1207,7 +1208,9 @@ class PolicyStaffTabState extends ConsumerState<PolicyStaffTab> {
hintText: selectedPDFFileNames ?? "Upload Document", hintText: selectedPDFFileNames ?? "Upload Document",
txtwidth: ResponsiveLayout.isMobile(context) txtwidth: ResponsiveLayout.isMobile(context)
? null ? null
: MediaQuery.of(context).size.width * 0.13, : (docUploadedPDFFileUrlFromApi != null)
? MediaQuery.of(context).size.width * 0.15
: MediaQuery.of(context).size.width * 0.175,
// backgroundColor: Color(0xFFEDF6F5), // backgroundColor: Color(0xFFEDF6F5),
onFileSelected: (fileName, file) { onFileSelected: (fileName, file) {
print("Picked file: $fileName (${file.size} bytes)"); print("Picked file: $fileName (${file.size} bytes)");
@ -1216,9 +1219,9 @@ class PolicyStaffTabState extends ConsumerState<PolicyStaffTab> {
}); });
}, },
), ),
const SizedBox(width: 10),
if (docUploadedPDFFileUrlFromApi != null) if (docUploadedPDFFileUrlFromApi != null) ...[
const SizedBox(width: 10),
Tooltip( Tooltip(
message: 'Download', message: 'Download',
// color: Colors.white, // color: Colors.white,
@ -1266,6 +1269,7 @@ class PolicyStaffTabState extends ConsumerState<PolicyStaffTab> {
// ), // ),
), ),
], ],
],
), ),
], ],
); );

View File

@ -276,7 +276,6 @@ class QuotationStaffTabState extends ConsumerState<QuotationStaffTab> {
SizedBox(height: 20), SizedBox(height: 20),
], ],
//(TABLE)
Container( Container(
// color: Colors.green, // color: Colors.green,
decoration: BoxDecoration( decoration: BoxDecoration(
@ -285,8 +284,8 @@ class QuotationStaffTabState extends ConsumerState<QuotationStaffTab> {
), ),
width: MediaQuery.of(context).size.width, width: MediaQuery.of(context).size.width,
height: !blockKey height: !blockKey
? MediaQuery.of(context).size.height * 0.44 ? MediaQuery.of(context).size.height * 0.4
: MediaQuery.of(context).size.height * 0.6, : MediaQuery.of(context).size.height * 0.55,
padding: EdgeInsets.all(12.0), padding: EdgeInsets.all(12.0),
child: SingleChildScrollView( child: SingleChildScrollView(
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,

View File

@ -11,8 +11,10 @@ import 'package:shared_preferences/shared_preferences.dart';
import '../../../../../core/routing/routes.dart'; import '../../../../../core/routing/routes.dart';
import '../../../../../core/services/api_service.dart'; import '../../../../../core/services/api_service.dart';
import '../../../../layouts/main_layout.dart'; import '../../../../layouts/main_layout.dart';
import '../../../../layouts/responsive_layout.dart';
import '../../../../providers/manager_provider.dart'; import '../../../../providers/manager_provider.dart';
import '../../../../providers/quotation_staff_proivder.dart'; import '../../../../providers/quotation_staff_proivder.dart';
import '../../../../themes/indicators/text_field_theme.dart';
class TabEnquiryStaffList extends ConsumerStatefulWidget { class TabEnquiryStaffList extends ConsumerStatefulWidget {
String? id; String? id;
@ -34,6 +36,10 @@ class TabEnquiryStaffListState extends ConsumerState<TabEnquiryStaffList> {
ScrollController _scrollController = ScrollController(); ScrollController _scrollController = ScrollController();
dynamic role; dynamic role;
dynamic selectedInsuredName;
dynamic selectedVehicleNum;
dynamic selectedVehicleType;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -77,13 +83,24 @@ class TabEnquiryStaffListState extends ConsumerState<TabEnquiryStaffList> {
Future<void> _loadData(id, {int? tabIndex}) async { Future<void> _loadData(id, {int? tabIndex}) async {
print('loadQuotationTab 2'); print('loadQuotationTab 2');
setState(() => isLoading = true); setState(() => isLoading = true);
// final response = await apiService.findEnqQuotePolicyView(id); final response = await apiService.findEnqQuotePolicyView(id);
// print('loadQuotationTab 3 '); print('loadQuotationTab 3 ');
final data = response["data"];
setState(() { setState(() {
print('loadQuotationTab 4'); print('loadQuotationTab 4');
// enquiryData = response["data"]; print('loadQuotationTab enquiryData4 - $data');
isLoading = false; isLoading = false;
enquiryData = data;
// Move these lines inside setState
selectedInsuredName = data['enquiry']?['name'];
selectedVehicleNum = data['enquiry']?['reg_no'];
selectedVehicleType = data['enquiry']?['vehicle_type'];
print(
'loadQuotationTab 4s - $selectedInsuredName - $selectedVehicleNum - $selectedVehicleType',
);
tabs = [ tabs = [
TabItem("Proposal", QuotationStaffTab()), TabItem("Proposal", QuotationStaffTab()),
// TabItem("Policy", PolicyStaffTab()), // TabItem("Policy", PolicyStaffTab()),
@ -129,8 +146,8 @@ class TabEnquiryStaffListState extends ConsumerState<TabEnquiryStaffList> {
return AlertDialog( return AlertDialog(
backgroundColor: Colors.white, backgroundColor: Colors.white,
content: Container( content: Container(
width: MediaQuery.of(context).size.width * 0.55, width: MediaQuery.of(context).size.width * 0.6,
height: MediaQuery.of(context).size.height * 0.7, height: MediaQuery.of(context).size.height * 0.8,
child: isLoading child: isLoading
? const Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
@ -148,41 +165,16 @@ class TabEnquiryStaffListState extends ConsumerState<TabEnquiryStaffList> {
Widget _buildDesktopTabs() { Widget _buildDesktopTabs() {
return Column( return Column(
children: [
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Row( Text('Enquiry Details', style: _headertextStyle),
children: List.generate(tabs.length, (index) {
final isSelected = selectedIndex == index;
return Padding(
padding: const EdgeInsets.only(left: 10.0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 2,
backgroundColor: isSelected
? const Color(0xFF425B5B)
: const Color(0xFFEDFFFC),
foregroundColor: isSelected
? Colors.white
: Colors.black87,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
padding: const EdgeInsets.symmetric(
horizontal: 24,
vertical: 12,
),
),
onPressed: () {
setState(() => selectedIndex = index);
},
child: Text(tabs[index].title),
),
);
}),
),
GestureDetector( GestureDetector(
onTap: () => Navigator.pop(context), onTap: () => Navigator.pop(context),
child: Container( child: Container(
@ -199,12 +191,139 @@ class TabEnquiryStaffListState extends ConsumerState<TabEnquiryStaffList> {
), ),
], ],
), ),
SizedBox(height: 10),
Container(
padding: const EdgeInsets.symmetric(
vertical: 6,
horizontal: 16,
),
decoration: BoxDecoration(
color: Color(0xffEDF6F5),
// color: Color(0xFFE0F7F9),
border: const Border(
bottom: BorderSide(color: Color(0xFFEAEAEA), width: 1),
),
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
insured_name(context),
vehcile_num(context),
vehcile_Type(context),
SizedBox.shrink(),
],
),
),
],
),
),
SizedBox(height: 10),
Row(
children: List.generate(tabs.length, (index) {
final isSelected = selectedIndex == index;
return Padding(
padding: const EdgeInsets.only(left: 10.0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 2,
backgroundColor: isSelected
? const Color(0xFF425B5B)
: const Color(0xFFEDFFFC),
foregroundColor: isSelected ? Colors.white : Colors.black87,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
padding: const EdgeInsets.symmetric(
horizontal: 24,
vertical: 12,
),
),
onPressed: () {
setState(() => selectedIndex = index);
},
child: Text(tabs[index].title),
),
);
}),
),
SizedBox(height: 10), SizedBox(height: 10),
Expanded(child: tabs[selectedIndex].widget), Expanded(child: tabs[selectedIndex].widget),
], ],
); );
} }
Widget insured_name(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Insured', style: _textStyle),
SizedBox(height: 10),
Text(selectedInsuredName ?? '', style: _textDataStyle),
// ThemedFormField(
// controller: controllers['insurer']!,
// readOnly: true,
// txtwidth: ResponsiveLayout.isMobile(context)
// ? null
// : MediaQuery.of(context).size.width * 0.2,
// ),
],
);
}
Widget vehcile_num(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Vehicle.No.', style: _textStyle),
SizedBox(height: 10),
Text(selectedVehicleNum ?? '', style: _textDataStyle),
// ThemedFormField(
// controller: controllers['insurer']!,
// readOnly: true,
// txtwidth: ResponsiveLayout.isMobile(context)
// ? null
// : MediaQuery.of(context).size.width * 0.2,
// ),
],
);
}
Widget vehcile_Type(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Vehicle Type', style: _textStyle),
SizedBox(height: 10),
Text(selectedVehicleType ?? '', style: _textDataStyle),
// ThemedFormField(
// controller: controllers['insurer']!,
// readOnly: true,
// txtwidth: ResponsiveLayout.isMobile(context)
// ? null
// : MediaQuery.of(context).size.width * 0.2,
// ),
],
);
}
static final _textStyle = GoogleFonts.inter(
fontSize: 12,
fontWeight: FontWeight.w500,
);
static final _textDataStyle = GoogleFonts.inter(
fontSize: 12,
fontWeight: FontWeight.w600,
);
static final _headertextStyle = GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w700,
color: const Color(0xFF425B5B),
);
} }
class TabItem { class TabItem {

View File

@ -289,7 +289,7 @@ class _AddDialogState extends ConsumerState<AssignStaffDialog> {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
'Assign Vehicle Policy', 'Assign Enquiry To Staff',
style: GoogleFonts.inter( style: GoogleFonts.inter(
color: const Color(0xFF374141), color: const Color(0xFF374141),
fontSize: 18, fontSize: 18,
@ -338,7 +338,7 @@ class _AddDialogState extends ConsumerState<AssignStaffDialog> {
color: const Color(0xFF425B5B), color: const Color(0xFF425B5B),
), ),
child: const Text( child: const Text(
'Assign Policy', 'Assign',
style: TextStyle(color: Colors.white), style: TextStyle(color: Colors.white),
), ),
), ),

View File

@ -157,3 +157,16 @@ class ThemedFormField extends HookWidget {
); );
} }
} }
class UpperCaseTextFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue,
) {
return TextEditingValue(
text: newValue.text.toUpperCase(),
selection: newValue.selection,
);
}
}

View File

@ -98,9 +98,9 @@ class MonthFilterRow extends StatelessWidget {
value == null || value.isEmpty ? "Month is required" : null, value == null || value.isEmpty ? "Month is required" : null,
borderColor: Colors.grey.shade100, borderColor: Colors.grey.shade100,
controller: monthController, controller: monthController,
onDateSelected: (date) { // onDateSelected: (date) {
monthController.text = DateFormat('MM-yyyy').format(date); // monthController.text = DateFormat('MM-yyyy').format(date);
}, // },
), ),
], ],
); );