chart changes

This commit is contained in:
venbaittech 2025-12-08 12:58:01 +05:30
parent 0b0a30f9d6
commit 2488d0f72c
23 changed files with 2541 additions and 272 deletions

File diff suppressed because one or more lines are too long

View File

@ -156,6 +156,55 @@ class ApiService {
}
}
Future<Map<String, dynamic>> CheckDuplicate(
BuildContext context,
String value,
) async {
if (_token == null) {
await _initializeToken();
}
String apiUrldata;
final response = await http.get(
Uri.parse('${Env.apiUrl}enquiry/checkVehicleDuplicate?reg_no=$value'),
headers: {
'Authorization': 'Bearer $_token' ?? '',
'app-signature': Env.App_Signature,
},
);
if (response.statusCode == 200) {
try {
final data = json.decode(response.body);
// Updated to match actual response structure
if (data['status'] == "exists") {
final msg = data['message'] ?? "Already exists";
final field = data['field'] ?? "";
print("$field - $value : $msg");
print("EXIST REG");
return {"message": msg, "field": field};
} else {
print("NOT EXIST REG");
// print("$value : ${data['message'] ?? "is a new value"}");
return {};
}
} catch (e) {
throw Exception('Error parsing response: $e');
}
} else if (response.statusCode == 403) {
await clearLocalStorageAndRedirect();
return {};
} else {
throw Exception(
'Failed to load checkDuplicate data. Status code: ${response.statusCode}',
);
}
}
Future<void> getPdfDownload1(path, id) async {
// final url = Uri.parse(
// 'https://venbait.in/nhance/partner/dev/api/agent/downloadAgentCertificateFile?agent_id=1',
@ -474,6 +523,40 @@ class ApiService {
return response;
}
Future<Map<String, dynamic>> findBusinessDashboardData(id, broker) async {
// print(_token);
if (_token == null) {
await _initializeToken();
}
final url = Uri.parse(
'${Env.apiUrl}dashboard/businessDashboard?manager_id=$id',
);
final headers = {
'Authorization': 'Bearer $_token' ?? '',
'app-signature': Env.App_Signature,
};
final response = await _makeGetRequest(url, headers);
return response;
}
Future<Map<String, dynamic>> findPartnerDashboardData(id, broker) async {
// print(_token);
if (_token == null) {
await _initializeToken();
}
final url = Uri.parse(
'${Env.apiUrl}dashboard/partnerDashboard?manager_id=$id',
);
final headers = {
'Authorization': 'Bearer $_token' ?? '',
'app-signature': Env.App_Signature,
};
final response = await _makeGetRequest(url, headers);
return response;
}
// -------------------------------- AGENT ----------------------------------------------
Future<Map<String, dynamic>> fetchAgentIncentiveList(agentId) async {

View File

@ -0,0 +1,10 @@
import 'package:flutter/material.dart';
class BarData {
final Color color;
final double value1;
final double value2;
final double shadowValue;
const BarData(this.color, this.value1, this.value2, this.shadowValue);
}

View File

@ -0,0 +1,12 @@
// TODO Implement this library.
// Widget data structure
import '../data/models/bar_data.dart';
class ChartItem {
final String id;
final String title;
final List<BarData> dataList;
final List<String> labels;
ChartItem(this.id, this.title, this.dataList, this.labels);
}

View File

@ -0,0 +1,38 @@
// State Notifier
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../data/models/bar_data.dart';
import '../../models/chart_item.dart';
class ChartLayoutNotifier extends StateNotifier<List<ChartItem>> {
ChartLayoutNotifier() : super(_initialCharts);
static final List<BarData> _defaultData = [
BarData(Colors.blue, 10, 5, 8),
BarData(Colors.orange, 12, 6, 10),
BarData(Colors.green, 8, 5, 5),
];
static final List<ChartItem> _initialCharts = [
ChartItem('1', 'Chart A', _defaultData, ['A', 'B', 'C']),
ChartItem('2', 'Chart B', _defaultData, ['A', 'B', 'C']),
ChartItem('3', 'Chart C', _defaultData, ['A', 'B', 'C']),
];
void reorder(int oldIndex, int newIndex) {
final List<ChartItem> newList = List.from(state);
final item = newList.removeAt(oldIndex);
newList.insert(newIndex, item);
state = newList;
}
// void reorder(List<String> newItems) {
// state = newItems; // or whatever logic you use
// }
}
final chartLayoutProvider =
StateNotifierProvider<ChartLayoutNotifier, List<ChartItem>>((ref) {
return ChartLayoutNotifier();
});

View File

@ -721,6 +721,7 @@ class PolicyTabState extends ConsumerState<PolicyTab> {
field: ThemedFormField(
controller: controllers['regNum']!,
readOnly: true,
// validator: (value) => Validators.requiredField(value, "name"),
txtwidth: ResponsiveLayout.isMobile(context)
? null

View File

@ -86,28 +86,6 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
void filterDateRange() {
print('SelectedStatus - $SelectedStatus');
// // Validate the form first
// if (!_formKey.currentState!.validate()) {
// // stop execution if validation fails
// return;
// }
//
// final fromDateText = controllers['startDate']?.text ?? '';
// final toDateText = controllers['endDate']?.text ?? '';
// // Optional: double-check End >= Start
// final fromDate = DateFormat('dd-MM-yyyy').parse(fromDateText);
// final toDate = DateFormat('dd-MM-yyyy').parse(toDateText);
//
// if (toDate.isBefore(fromDate)) {
// // This is already caught by the validator, but extra safety
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(content: Text("End Date cannot be earlier than Start Date")),
// );
// return;
// }
// Call your API
getStaffList(userId, roleId);
}
@ -500,6 +478,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
endController: controllers['endDate']!,
onStatusChanged: (val) {
SelectedStatus = val; // update parent
filterDateRange();
},
formKey: _formKey,
isMobile: ResponsiveLayout.isMobile(context),

View File

@ -6,6 +6,8 @@ import 'package:intl/intl.dart';
import 'package:nhance_partner/presentation/screens/dashboard/tabs/bussiness.dart';
import 'package:nhance_partner/presentation/screens/dashboard/tabs/chart.dart';
import 'package:nhance_partner/presentation/screens/dashboard/tabs/live.dart';
import 'package:nhance_partner/presentation/screens/dashboard/tabs/partner.dart';
import 'package:nhance_partner/presentation/screens/dashboard/tabs/productivity.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../core/responsive/responsive_builder.dart';
import '../../../core/routing/routes.dart';
@ -111,11 +113,13 @@ class _DashboardState extends ConsumerState<Dashboard>
),
child: Text(
tabs[index],
style: TextStyle(
style: GoogleFonts.poppins(
// color: isSelected ? Colors.white : Colors.black87,
color: Colors.black87,
fontSize: 11,
fontWeight: FontWeight.w500,
fontWeight: isSelected
? FontWeight.w500
: FontWeight.w400,
),
),
),
@ -130,10 +134,8 @@ class _DashboardState extends ConsumerState<Dashboard>
// Text('A'),
LiveDashboard(),
BussinessDashboard(),
// BarChartSample7(),
// ReportsPage(),
// UsersPage(),
// SettingsPage(),
PartnerDashboard(),
ProductiviyDashboard(),
],
),
),

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,239 @@
// import 'package:flutter/cupertino.dart';
// import 'package:flutter/material.dart';
// import 'package:flutter/src/widgets/framework.dart';
// import 'package:flutter_riverpod/flutter_riverpod.dart';
// import 'package:google_fonts/google_fonts.dart';
//
// import '../../../../data/models/bar_data.dart';
// import '../../../themes/charts/barChart.dart';
//
// class BussinessDashboard extends ConsumerStatefulWidget {
// const BussinessDashboard({super.key});
//
// @override
// ConsumerState<BussinessDashboard> createState() => _BussinessDashboardState();
// }
//
// class _BussinessDashboardState extends ConsumerState<BussinessDashboard> {
// @override
// Widget build(BuildContext context) {
// final data = [
// BarData(Colors.blue, 10, 8),
// BarData(Colors.orange, 12, 10),
// BarData(Colors.green, 8, 5),
// ];
//
// return Container(
// margin: EdgeInsets.all(10),
// // color: Colors.white,
// // color: Colors.amber.shade100,
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// // Text('PRODUCT WISE', style: _headerStyle2),
// Row(
// children: [
// Expanded(
// child: Container(
// padding: EdgeInsets.all(20.0),
// margin: EdgeInsets.only(right: 20),
// decoration: BoxDecoration(
// color: Color(0XFFFFFFFF),
// borderRadius: BorderRadius.circular(10),
// ),
//
// // width: MediaQuery.of(context).size.width * 0.2,
// height: 200,
// child: CustomBarChart(
// dataList: data,
// labels: ['A', 'B', 'C'],
// ),
// ),
// ),
//
// Expanded(
// child: Container(
// padding: EdgeInsets.all(20.0),
// margin: EdgeInsets.only(right: 10),
// decoration: BoxDecoration(
// color: Color(0XFFFFFFFF),
// borderRadius: BorderRadius.circular(10),
// ),
// // width: MediaQuery.of(context).size.width * 0.02,
// height: 200,
// child: CustomBarChart(
// dataList: data,
// labels: ['A', 'B', 'C'],
// ),
// ),
// ),
//
// Expanded(
// child: Container(
// padding: EdgeInsets.all(20.0),
// margin: EdgeInsets.only(right: 10),
// decoration: BoxDecoration(
// color: Color(0XFFFFFFFF),
// borderRadius: BorderRadius.circular(10),
// ),
// // width: MediaQuery.of(context).size.width * 0.2,
// height: 200,
// child: CustomBarChart(
// dataList: data,
// labels: ['A', 'B', 'C'],
// ),
// ),
// ),
// ],
// ),
// ],
// ),
//
// // Column(children: [Text('Insurer WISE', style: _headerStyle2)]),
// ],
// ),
// );
// }
// }
//
// // class _BussinessDashboardState extends ConsumerState<BussinessDashboard> {
// // int? expandedIndex; // tracks which container is expanded
// //
// // @override
// // Widget build(BuildContext context) {
// // final data = [
// // BarData(Colors.blue, 10, 8),
// // BarData(Colors.orange, 12, 10),
// // BarData(Colors.green, 8, 5),
// // ];
// //
// // return Container(
// // margin: EdgeInsets.all(10),
// // child: Column(
// // crossAxisAlignment: CrossAxisAlignment.start,
// // children: [
// // Text('PRODUCT WISE', style: _headerStyle2),
// //
// // SizedBox(height: 10),
// //
// // // If a container is expanded show only that container
// // if (expandedIndex != null)
// // _buildExpandedItem(context, expandedIndex!, data)
// // else
// // Row(
// // children: [
// // _buildChartItem(
// // context,
// // 0,
// // data,
// // margin: EdgeInsets.only(right: 20),
// // ),
// // _buildChartItem(
// // context,
// // 1,
// // data,
// // margin: EdgeInsets.only(right: 20),
// // ),
// // _buildChartItem(
// // context,
// // 2,
// // data,
// // margin: EdgeInsets.only(right: 10),
// // ),
// // ],
// // ),
// //
// // SizedBox(height: 20),
// // Text('INSURER WISE', style: _headerStyle2),
// // if (expandedIndex != null)
// // _buildExpandedItem(context, expandedIndex!, data)
// // else
// // Row(
// // children: [
// // _buildChartItem(
// // context,
// // 3,
// // data,
// // margin: EdgeInsets.only(right: 20),
// // ),
// // _buildChartItem(
// // context,
// // 4,
// // data,
// // margin: EdgeInsets.only(right: 20),
// // ),
// // _buildChartItem(
// // context,
// // 5,
// // data,
// // margin: EdgeInsets.only(right: 10),
// // ),
// // ],
// // ),
// // ],
// // ),
// // );
// // }
// //
// // // 🔵 Regular item in row
// // Widget _buildChartItem(
// // BuildContext context,
// // int index,
// // List<BarData> data, {
// // EdgeInsets margin = EdgeInsets.zero,
// // }) {
// // return Expanded(
// // child: GestureDetector(
// // onTap: () {
// // setState(() {
// // expandedIndex = index; // expand clicked chart
// // });
// // },
// // child: Container(
// // padding: EdgeInsets.all(20),
// // margin: margin,
// // decoration: BoxDecoration(
// // color: Colors.white,
// // borderRadius: BorderRadius.circular(10),
// // ),
// // height: 200,
// // child: CustomBarChart(dataList: data, labels: ['A', 'B', 'C']),
// // ),
// // ),
// // );
// // }
// //
// // // 🔵 Expanded full screen widget
// // Widget _buildExpandedItem(
// // BuildContext context,
// // int index,
// // List<BarData> data,
// // ) {
// // return GestureDetector(
// // onTap: () {
// // setState(() {
// // expandedIndex = null; // collapse back to row
// // });
// // },
// // child: Container(
// // width: double.infinity,
// // height: MediaQuery.of(context).size.height * 0.6,
// // padding: EdgeInsets.all(20),
// // decoration: BoxDecoration(
// // color: Colors.white,
// // borderRadius: BorderRadius.circular(10),
// // ),
// // child: CustomBarChart(dataList: data, labels: ['A', 'B', 'C']),
// // ),
// // );
// // }
// // }
//
// final _headerStyle2 = GoogleFonts.poppins(
// fontSize: 12,
// color: Colors.black,
// fontWeight: FontWeight.w500,
// );

View File

@ -0,0 +1,178 @@
// import 'package:flutter/cupertino.dart';
// import 'package:flutter/material.dart';
// import 'package:flutter/src/widgets/framework.dart';
// import 'package:flutter_riverpod/flutter_riverpod.dart';
// import 'package:google_fonts/google_fonts.dart';
//
// import 'package:flutter_reorderable_grid_view/widgets/reorderable_builder.dart';
//
// import '../../../../data/models/bar_data.dart';
// import '../../../../models/chart_item.dart';
// import '../../../providers/chart_provider.dart';
// import '../../../themes/charts/barChart.dart';
//
// enum ReorderableType {
// gridView,
// gridViewCount,
// gridViewExtent,
// gridViewBuilder,
// }
//
// class BussinessDashboard extends ConsumerStatefulWidget {
// const BussinessDashboard({super.key});
//
// @override
// ConsumerState<BussinessDashboard> createState() => _BussinessDashboardState();
// }
//
// class _BussinessDashboardState extends ConsumerState<BussinessDashboard> {
// // final GlobalKey<SliverReorderableGridState> _gridKey = GlobalKey();
// final GlobalKey _gridKey = GlobalKey();
// ReorderableType reorderableType = ReorderableType.gridViewBuilder;
//
// final ScrollController _scrollController = ScrollController();
//
// List<String> items = ['A', 'B', 'C', 'D', 'E'];
//
// @override
// Widget build(BuildContext context) {
// List<ChartItem> chartItems = ref.watch(chartLayoutProvider);
//
// final charts = ref.watch(chartLayoutProvider);
// final notifier = ref.read(chartLayoutProvider.notifier);
// // void reorder(List<String> newItems) {
// // setState(() {
// // // final removed = items.removeAt(oldIndex);
// // items.insert(newItems);
// // });
// // }
//
// // void reorder(List<String> newItems) {
// // state = newItems; // or whatever logic you use
// // }
//
// final children = items
// .map(
// (e) => Container(
// key: ValueKey(e),
// color: Colors.blueAccent,
// child: Center(
// child: Text(
// e,
// style: TextStyle(color: Colors.white, fontSize: 24),
// ),
// ),
// ),
// )
// .toList();
//
// // Determine the current layout based on the number of items
// // Since you only have 3 items, you will have to create a separate state
// // to track the 1x3 (default) vs the custom 2-stacked + 1 layout
// // after the drag action.
//
// // For this example, we will stick to a reorderable grid/row layout.
//
// return Container(
// margin: EdgeInsets.all(10),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Container(
// height: 400, // fixed height to allow drag detection
// padding: EdgeInsets.all(12),
// child: ReorderableBuilder<ChartItem>(
// enableLongPress: true,
// enableDraggable: true,
// children: chartItems
// .map(
// (item) => Container(
// key: ValueKey(item.id),
// margin: EdgeInsets.all(4),
// color: Colors.blueAccent,
// alignment: Alignment.center,
// child: Text(
// item.title,
// style: TextStyle(color: Colors.white, fontSize: 24),
// ),
// ),
// )
// .toList(),
// onReorder: (reorderCallback) {
// final newList = reorderCallback(chartItems).cast<ChartItem>();
// ref.read(chartLayoutProvider.notifier).state = newList;
// },
// builder: (children) {
// return GridView.count(
// crossAxisCount: 2,
// mainAxisSpacing: 8,
// crossAxisSpacing: 8,
// children: children,
// shrinkWrap: true,
// physics: NeverScrollableScrollPhysics(),
// );
// },
// ),
// ),
//
// // Container(
// // height: 400,
// // child: ReorderableBuilder<ChartItem>(
// // scrollController: _scrollController,
// // enableLongPress: true, // enable drag on long press
// // enableDraggable: true,
// // children: chartItems
// // .map(
// // (item) => Container(
// // key: ValueKey(item.id),
// // color: Colors.blueAccent,
// // child: Center(
// // child: Text(
// // item.title, // show chart name
// // style: TextStyle(color: Colors.white, fontSize: 24),
// // ),
// // ),
// // ),
// // )
// // .toList(),
// // onReorder: (reorderCallback) {
// // final newList = reorderCallback(chartItems).cast<ChartItem>();
// // ref.read(chartLayoutProvider.notifier).state = newList;
// // },
// // builder: (children) {
// // return GridView.count(
// // crossAxisCount: 2,
// // mainAxisSpacing: 8,
// // crossAxisSpacing: 8,
// // padding: const EdgeInsets.all(12),
// // children: children,
// // );
// // },
// // ),
// // ),
// ],
// ),
// );
// }
// }
//
// // Placeholder for your chart widget
// class CustomBarChart extends StatelessWidget {
// final List<BarData> dataList;
// final List<String> labels;
//
// const CustomBarChart({required this.dataList, required this.labels, Key? key})
// : super(key: key);
//
// @override
// Widget build(BuildContext context) {
// // Implement your chart rendering here
// return Center(child: Text("Chart: ${dataList[0].value}"));
// }
// }
//
// final _headerStyle2 = GoogleFonts.poppins(
// fontSize: 12,
// color: Colors.black,
// fontWeight: FontWeight.w500,
// );

View File

@ -3,7 +3,11 @@ import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:nhance_partner/presentation/providers/manager_provider.dart';
import '../../../../core/services/api_service.dart';
import '../../../../data/models/bar_data.dart';
import '../../../providers/userRoleProvider.dart';
import '../../../themes/charts/barChart.dart';
class BussinessDashboard extends ConsumerStatefulWidget {
@ -14,31 +18,475 @@ class BussinessDashboard extends ConsumerStatefulWidget {
}
class _BussinessDashboardState extends ConsumerState<BussinessDashboard> {
dynamic managerId;
late ApiService apiService;
// List<Map<String, dynamic>> dataVal = [];
List<Map<String, dynamic>> getBusinessDshBdData = [];
List<Map<String, dynamic>> originalData = [];
List<Map<String, dynamic>> filteredData = [];
List<Map<String, dynamic>> brokerWise = [];
List<Map<String, dynamic>> productWise = [];
List<Map<String, dynamic>> insurerWise = [];
List<Map<String, dynamic>> originalBrokerWise = [];
List<Map<String, dynamic>> filteredBrokerWise = [];
List<Map<String, dynamic>> originalProductWise = [];
List<Map<String, dynamic>> filteredProductWise = [];
List<Map<String, dynamic>> originalInsurerWise = [];
List<Map<String, dynamic>> filteredInsurerWise = [];
bool isLoading = false;
bool isInsureWisePolicy = true;
bool isBrokerWisePolicy = true;
bool isProductWisePolicy = true;
bool showInsurer = true;
bool showBroker = true;
bool showProduct = true;
int selectedView = 0;
// 0 = Insurer
// 1 = Broker
// 2 = Product
String? SelctdBusinessbroker;
@override
void initState() {
super.initState();
apiService = ApiService();
Future.microtask(() {
// final id = ref.read(managerIdProvider);
final roleId = ref.read(userRoleProvider);
managerId = ref.read(managerIdProvider);
// print("ENQroleId - $roleId");
if (managerId != null) {
getBusinessDashBrdList(managerId);
}
});
}
Future<void> getBusinessDashBrdList(id) async {
// print('getClaimList called MagId - $managerId - $role');
setState(() {
isLoading = true;
});
// dynamic id = widget.policyNumber;
print('getBusinessDshID - $id');
try {
final response = await apiService.findBusinessDashboardData(
id,
SelctdBusinessbroker,
);
if (response['status'] == 'success') {
final data = response['data'];
print('getBusinessDshBdData - ${response['data']}');
setState(() {
if (data is List) {
// Already a list of maps
getBusinessDshBdData = List<Map<String, dynamic>>.from(data);
} else if (data is Map) {
// Single object, wrap in a list
getBusinessDshBdData = [Map<String, dynamic>.from(data)];
} else {
getBusinessDshBdData = [];
}
// getBusinessDshBdData = List<Map<String, dynamic>>.from(response['data']);
originalData = getBusinessDshBdData;
filteredData = List.from(originalData);
// print('originalData - $getClaimPolicies');
});
if (data is Map<String, dynamic>) {
setState(() {
// Store BrokerWise
brokerWise = List<Map<String, dynamic>>.from(
data['brokerWise'] ?? [],
);
print('brokerWise - ${brokerWise}');
originalBrokerWise = List.from(brokerWise);
filteredBrokerWise = List.from(brokerWise);
// Store ProductWise
productWise = List<Map<String, dynamic>>.from(
data['productWise'] ?? [],
);
print('productWise - ${productWise}');
originalProductWise = List.from(productWise);
filteredProductWise = List.from(productWise);
// Store InsurerWise
insurerWise = List<Map<String, dynamic>>.from(
data['insurerWise'] ?? [],
);
print('insurerWise - ${insurerWise}');
originalInsurerWise = List.from(insurerWise);
filteredInsurerWise = List.from(insurerWise);
});
} else {
// fallback
brokerWise = [];
productWise = [];
insurerWise = [];
}
} else {
getBusinessDshBdData = [];
originalData = [];
}
} catch (e) {
print('Exception occurred: $e');
} finally {
setState(() {
isLoading = false;
});
}
}
List<BarData> buildInsurerBarData() {
double parseDouble(dynamic value) {
if (value == null) return 0.0;
if (value is num) return value.toDouble();
if (value is String) return double.tryParse(value) ?? 0.0;
return 0.0;
}
return filteredInsurerWise.map((item) {
print('policies_current - ${item['total_policies_current_month']}');
print('policies_PREV - ${item['total_policies_pre_month']}');
print('premium_current - ${item['total_premium_current_month']}');
print('premium_PREV - ${item['total_premium_pre_month']}');
return BarData(
Colors.blue,
isInsureWisePolicy
? parseDouble(item['total_policies_current_month'])
: parseDouble(item['total_premium_current_month']),
isInsureWisePolicy
? parseDouble(item['total_policies_pre_month'])
: parseDouble(item['total_premium_pre_month']),
5,
);
}).toList();
}
List<String> buildInsurerLabels() {
return filteredInsurerWise.map<String>((item) {
final name = item['short_name'];
if (name != null && name.toString().trim().isNotEmpty) {
return name.toString();
} else {
return item['short_name']?.toString() ?? '';
}
}).toList();
}
List<BarData> buildBrokerBarData() {
double parseDouble(dynamic value) {
if (value == null) return 0.0;
if (value is num) return value.toDouble();
if (value is String) return double.tryParse(value) ?? 0.0;
return 0.0;
}
return filteredBrokerWise.map((item) {
print('policies_current - ${item['total_policies_current_month']}');
print('policies_PREV - ${item['total_policies_pre_month']}');
print('premium_current - ${item['total_premium_current_month']}');
print('premium_PREV - ${item['total_premium_pre_month']}');
return BarData(
Colors.blue,
isBrokerWisePolicy
? parseDouble(item['total_policies_current_month'])
: parseDouble(item['total_premium_current_month']),
isBrokerWisePolicy
? parseDouble(item['total_policies_pre_month'])
: parseDouble(item['total_premium_pre_month']),
5,
);
}).toList();
}
List<String> buildBrokerLabels() {
return filteredBrokerWise.map<String>((item) {
final name = item['broker_name'];
if (name != null && name.toString().trim().isNotEmpty) {
return name.toString();
} else {
return item['broker_name']?.toString() ?? '';
}
}).toList();
}
List<BarData> buildProductBarData() {
double parseDouble(dynamic value) {
if (value == null) return 0.0;
if (value is num) return value.toDouble();
if (value is String) return double.tryParse(value) ?? 0.0;
return 0.0;
}
return filteredProductWise.map((item) {
print('policies_current - ${item['total_policies_current_month']}');
print('policies_PREV - ${item['total_policies_pre_month']}');
print('premium_current - ${item['total_premium_current_month']}');
print('premium_PREV - ${item['total_premium_pre_month']}');
return BarData(
Colors.blue,
isProductWisePolicy
? parseDouble(item['total_policies_current_month'])
: parseDouble(item['total_premium_current_month']),
isProductWisePolicy
? parseDouble(item['total_policies_pre_month'])
: parseDouble(item['total_premium_pre_month']),
10,
);
}).toList();
}
List<String> buildProductLabels() {
return filteredProductWise.map<String>((item) {
final name = item['vehicle_type'];
if (name != null && name.toString().trim().isNotEmpty) {
return name.toString();
} else {
return item['vehicle_type']?.toString() ?? '';
}
}).toList();
}
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(10),
// color: Colors.white,
margin: EdgeInsets.only(left: 10, right: 10, bottom: 10),
// color: Colors.amber.shade100,
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,
// mainAxisSize: MainAxisSize.min,
children: [
Text('Product Wise', style: _headerStyle2),
// BarChart(
// dataList: [
// _BarData(Colors.blue, 10, 8),
// _BarData(Colors.orange, 12, 10),
// _BarData(Colors.green, 8, 5),
// ],
// labels: ["A", "B", "C"],
// ),
Text('Hide and Show Charts : ', style: _styleSmall1),
TextButton(
onPressed: () {
setState(() => showInsurer = !showInsurer);
},
child: Text(
showInsurer ? "Insurer" : "Insurer Hidden",
style: _styleSmall2,
),
),
TextButton(
onPressed: () {
setState(() => showBroker = !showBroker);
},
child: Text(
showBroker ? "Broker" : "Broker Hidden",
style: _styleSmall2,
),
),
TextButton(
onPressed: () {
setState(() => showProduct = !showProduct);
},
child: Text(
showProduct ? "Product " : "Product Hidden",
style: _styleSmall2,
),
),
],
),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
showInsurer ? Expanded(child: insurerContainer()) : SizedBox(),
showBroker ? Expanded(child: brokerContainer()) : SizedBox(),
showProduct ? Expanded(child: productContainer()) : SizedBox(),
],
),
),
],
),
);
}
Widget insurerContainer() {
final chartInsurerData = buildInsurerBarData();
final chartInsurerLabels = buildInsurerLabels();
print('chartInsurerData - $chartInsurerData');
print('chartInsurerLabels - $chartInsurerLabels');
return Container(
padding: EdgeInsets.all(10),
margin: EdgeInsets.only(right: 20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(
'Insurer Wise (Previous / Current Month)',
style: _chartHeader,
),
),
Text(
isInsureWisePolicy ? "Policies" : "Premium",
style: _styleSmall1,
),
Transform.scale(
scale: 0.5,
child: Switch(
value: isInsureWisePolicy,
onChanged: (val) => setState(() => isInsureWisePolicy = val),
),
),
],
),
SizedBox(height: 10),
Expanded(
child: CustomBarChart(
dataList: chartInsurerData,
labels: chartInsurerLabels,
),
),
legendWidget(),
],
),
);
}
Widget brokerContainer() {
final chartBrokerData = buildBrokerBarData();
final chartBrokerLabels = buildBrokerLabels();
print('chartBrokerData - $chartBrokerData');
print('chartBrokerLabels - $chartBrokerLabels');
return Container(
padding: EdgeInsets.all(10),
margin: EdgeInsets.only(right: 20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(
'Broker Wise (Previous / Current Month)',
style: _chartHeader,
),
),
Text(
isBrokerWisePolicy ? "Policies" : "Premium",
style: _styleSmall1,
),
Transform.scale(
scale: 0.5,
child: Switch(
value: isBrokerWisePolicy,
onChanged: (val) => setState(() => isBrokerWisePolicy = val),
),
),
],
),
SizedBox(height: 10),
Expanded(
child: CustomBarChart(
dataList: chartBrokerData,
labels: chartBrokerLabels,
),
),
legendWidget(),
],
),
);
}
Widget productContainer() {
final chartProductData = buildProductBarData();
final chartProductLabels = buildProductLabels();
print('chartProductData - $chartProductData');
print('chartProductLabels - $chartProductLabels');
return Container(
padding: EdgeInsets.all(10),
margin: EdgeInsets.only(right: 20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(
'Product Wise (Previous / Current Month)',
style: _chartHeader,
),
),
Text(
isProductWisePolicy ? "Policies" : "Premium",
style: _styleSmall1,
),
Transform.scale(
scale: 0.5,
child: Switch(
value: isProductWisePolicy,
onChanged: (val) => setState(() => isProductWisePolicy = val),
),
),
],
),
SizedBox(height: 10),
Expanded(
child: CustomBarChart(
dataList: chartProductData,
labels: chartProductLabels,
),
),
legendWidget(),
],
),
);
}
Widget legendWidget() {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.circle, size: 10, color: Colors.cyan.shade300),
SizedBox(width: 2),
Text('Current Month', style: _styleSmall1),
SizedBox(width: 5),
Icon(Icons.circle, size: 10, color: Colors.orange.shade300),
SizedBox(width: 2),
Text('Previous Month', style: _styleSmall1),
],
);
}
}
final _headerStyle2 = GoogleFonts.poppins(
@ -46,3 +494,18 @@ final _headerStyle2 = GoogleFonts.poppins(
color: Colors.black,
fontWeight: FontWeight.w500,
);
final _chartHeader = GoogleFonts.poppins(
fontSize: 11.5,
color: Colors.black,
fontWeight: FontWeight.w500,
);
final _styleSmall1 = GoogleFonts.poppins(
fontSize: 10,
fontWeight: FontWeight.w400,
);
final _styleSmall2 = GoogleFonts.poppins(
fontSize: 10,
fontWeight: FontWeight.w400,
color: Colors.blueGrey,
);

View File

@ -186,16 +186,6 @@ class _DashboardState extends ConsumerState<LiveDashboard> {
final data = response['data'];
print('B99 => getStaffListData => ${response['data']}');
setState(() {
// policiesIssuedToday = data['policies_issued']['today'].toString();
// policiesIssuedYear = data['policies_issued']['year'].toString();
// policiesIssuedMonth = data['policies_issued']['month'].toString();
// premiumValueToday = data['premium_value']['today'].toString();
// premiumValueYear = data['premium_value']['year'].toString();
// premiumValueMonth = data['premium_value']['month'].toString();
// earningsToday = data['earnings']['today'].toString();
// earningsYear = data['earnings']['year'].toString();
// earningsMonth = data['earnings']['month'].toString();
// Policies Issued
if (data['policies_issued'] != null) {
policiesIssuedToday =
@ -364,41 +354,6 @@ class _DashboardState extends ConsumerState<LiveDashboard> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 🔹 Stats cards stacked
// Padding(
// padding: const EdgeInsets.all(8.0),
// child: StatCard(
// title: "Policies Issued",
// today: policiesIssuedToday ?? '',
// month: policiesIssuedMonth ?? '',
// year: policiesIssuedYear ?? '',
// imagePath: "assets/dashboard/Policy issue icon.png",
// ),
// ),
// // const SizedBox(height: 12),
// Padding(
// padding: const EdgeInsets.all(8.0),
// child: StatCard(
// title: "Premium Value",
// today: premiumValueToday ?? '',
// month: premiumValueMonth ?? '',
// year: premiumValueYear ?? '',
// imagePath: "assets/dashboard/Policy issue icon.png",
// ),
// ),
// // const SizedBox(height: 12),
// Padding(
// padding: const EdgeInsets.all(8.0),
// child: StatCard(
// title: "Earnings",
// today: earningsToday ?? '',
// month: earningsMonth ?? '',
// year: earningsYear ?? '',
// imagePath: "assets/dashboard/Policy issue icon.png",
// ),
// ),
//
// const SizedBox(height: 20),
Container(
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
@ -1270,7 +1225,7 @@ class othersPendings extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(title, style: _title),
Text(title, style: _chartHeader),
InkWell(
onTap: () {
@ -1870,7 +1825,7 @@ class Performance extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Title
Text(title, style: _title),
Text(title, style: _chartHeader),
const SizedBox(height: 10),
// Header row
@ -2027,7 +1982,7 @@ class UnassignedEnq extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Title
Text(title, style: _title),
Text(title, style: _chartHeader),
const SizedBox(height: 10),
// Header row
@ -2259,3 +2214,8 @@ final topHeaderStyle = GoogleFonts.inter(
color: Colors.black,
fontWeight: FontWeight.w500,
);
final _chartHeader = GoogleFonts.poppins(
fontSize: 11.5,
color: Colors.black,
fontWeight: FontWeight.w500,
);

View File

@ -0,0 +1,871 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../../core/responsive/responsive_builder.dart';
import '../../../../core/routing/routes.dart';
import '../../../../core/services/api_service.dart';
import '../../../providers/manager_provider.dart';
import '../../../providers/quotation_staff_proivder.dart';
import '../../../providers/userRoleProvider.dart';
import '../../staff/Enquiry/tabs/tab.dart';
import '../../staff/assignStaff.dart';
class PartnerDashboard extends ConsumerStatefulWidget {
const PartnerDashboard({super.key});
@override
ConsumerState<PartnerDashboard> createState() => _DashboardState();
}
class _DashboardState extends ConsumerState<PartnerDashboard> {
int selectedIndex = 1;
int switcherStatus = 1;
late ApiService apiService;
String? policiesIssuedToday;
String? policiesIssuedYear;
String? policiesIssuedMonth;
String? premiumValueToday;
String? premiumValueYear;
String? premiumValueMonth;
String? earningsToday;
String? earningsMonth;
String? earningsYear;
String? quotationsPendingCounts; // cross verify
String? currentKey; // cross verify
String? SelctdPartnerbroker; // cross verify
// List<Map<String, dynamic>> dataVal = [];
List<Map<String, dynamic>> getStaffData = [];
// List<Map<String, dynamic>> originalData = [];
// List<Map<String, dynamic>> filteredData = [];
int selectedTabIndex = 0;
List<Map<String, dynamic>> currentList = [];
List<Map<String, dynamic>> staffQuotationsPendingList = []; // cross verify
List<Map<String, dynamic>> quotationsPendingList = []; // cross verify
List<Map<String, dynamic>> policiesPendingList = []; // cross verify
List<Map<String, dynamic>> awaitingApprovalList = []; // cross verify
List<Map<String, dynamic>> unAssignedEnqList = []; // cross verify
List<Map<String, dynamic>> agentsPerformanceList = []; // cross verify
List<Map<String, dynamic>> nonAgentsPerformanceList = [];
List<Map<String, dynamic>> agentsPerformanceListPremium = []; // cross verify
List<Map<String, dynamic>> nonAgentsPerformanceListPremium =
[]; // cross verify
dynamic prefid;
dynamic prefroleId;
bool isLoading = false;
List<Map<String, dynamic>> getBusinessDshBdData = [];
List<Map<String, dynamic>> originalData = [];
List<Map<String, dynamic>> filteredData = [];
List<Map<String, dynamic>> brokerWise = [];
List<Map<String, dynamic>> productWise = [];
List<Map<String, dynamic>> insurerWise = [];
List<Map<String, dynamic>> originalBrokerWise = [];
List<Map<String, dynamic>> filteredBrokerWise = [];
List<Map<String, dynamic>> originalProductWise = [];
List<Map<String, dynamic>> filteredProductWise = [];
List<Map<String, dynamic>> originalInsurerWise = [];
List<Map<String, dynamic>> filteredInsurerWise = [];
bool isPerfomingAgntPolicy = true;
bool isNonPerfomingAgntPolicy = true;
bool isBrokerWisePolicy = true;
bool isProductWisePolicy = true;
@override
void initState() {
super.initState();
apiService = ApiService();
Future.microtask(() {
final prefmanagerid = ref.read(managerIdProvider);
final prefuserid = ref.read(userIdProvider);
final prefroleId = ref.read(userRoleProvider);
print("B81 => roleId: $prefroleId | userId: $prefuserid ");
if (prefuserid != null) {
getParnterDashBrdList(prefuserid);
// getStaffList(prefmanagerid!, prefroleId, prefuserid);
}
});
}
void refresh() {
print('___DASHBOARD___');
final prefmanagerid = ref.read(managerIdProvider);
final prefuserid = ref.read(userIdProvider);
final prefroleId = ref.read(userRoleProvider);
// if (prefuserid != null) {
// print("REFRESH- calling getStaffList with $prefmanagerid, $prefuserid");
// getStaffList(prefmanagerid!, prefroleId, prefuserid);
// }
}
Future<void> getParnterDashBrdList(id) async {
// print('getClaimList called MagId - $managerId - $role');
setState(() {
isLoading = true;
});
// dynamic id = widget.policyNumber;
print('getBusinessDshID - $id');
try {
final response = await apiService.findPartnerDashboardData(
id,
SelctdPartnerbroker,
);
if (response['status'] == 'success') {
final data = response['data'];
print('getBusinessDshBdData - ${response['data']}');
setState(() {
if (data is List) {
// Already a list of maps
getBusinessDshBdData = List<Map<String, dynamic>>.from(data);
} else if (data is Map) {
// Single object, wrap in a list
getBusinessDshBdData = [Map<String, dynamic>.from(data)];
} else {
getBusinessDshBdData = [];
}
// getBusinessDshBdData = List<Map<String, dynamic>>.from(response['data']);
originalData = getBusinessDshBdData;
filteredData = List.from(originalData);
// print('originalData - $getClaimPolicies');
});
if (data is Map<String, dynamic>) {
setState(() {
// agents_performance Policy
if (data['monthlyPolicyCount'] != null) {
agentsPerformanceList = List<Map<String, dynamic>>.from(
(data['monthlyPolicyCount'] as List).map(
(item) => Map<String, dynamic>.from(item),
),
);
} // agents_performance Premium
if (data['monthlyPremiumAmount'] != null) {
agentsPerformanceListPremium = List<Map<String, dynamic>>.from(
(data['monthlyPremiumAmount'] as List).map(
(item) => Map<String, dynamic>.from(item),
),
);
}
if (data['noPolicyTimeRange'] != null) {
nonAgentsPerformanceList = List<Map<String, dynamic>>.from(
(data['noPolicyTimeRange'] as List).map(
(item) => Map<String, dynamic>.from(item),
),
);
} // agents_performance Premium
if (data['below50tPremiumTimeRange'] != null) {
nonAgentsPerformanceListPremium = List<Map<String, dynamic>>.from(
(data['below50tPremiumTimeRange'] as List).map(
(item) => Map<String, dynamic>.from(item),
),
);
}
print(
'agentsPerformanceListPremium - ${agentsPerformanceListPremium}',
);
originalBrokerWise = List.from(brokerWise);
filteredBrokerWise = List.from(brokerWise);
// Store ProductWise
productWise = List<Map<String, dynamic>>.from(
data['productWise'] ?? [],
);
print('productWise - ${productWise}');
originalProductWise = List.from(productWise);
filteredProductWise = List.from(productWise);
// Store InsurerWise
insurerWise = List<Map<String, dynamic>>.from(
data['insurerWise'] ?? [],
);
print('insurerWise - ${insurerWise}');
originalInsurerWise = List.from(insurerWise);
filteredInsurerWise = List.from(insurerWise);
});
} else {
// fallback
brokerWise = [];
productWise = [];
insurerWise = [];
}
} else {
getBusinessDshBdData = [];
originalData = [];
}
} catch (e) {
print('Exception occurred: $e');
} finally {
setState(() {
isLoading = false;
});
}
}
Future<void> handleEdit(String id) async {
// Navigator.pop(context);
print('EDITStaff');
print('EDITStaff - $id');
// dynamic id = data['id'];
// context.go('/tabEnquiry/$id');
final prefs = await SharedPreferences.getInstance();
// Remove old value (if any)
await prefs.remove('enqAgentDataId');
// setState(() {
// final id = item['id'].toString();
// Save the new id
// await prefs.setString('enqAgentDataId', id.toString());
await prefs.setString('enqAgentDataId', id);
ref.read(enquiryIdProvider.notifier).state = id;
context.go(AppRoutes.tabEnquiry);
}
Future<void> handleStaffEdit(String id, String? flag) async {
// Navigator.pop(context); ddd
dynamic val;
print('EDITStaff - $id');
if (flag == "Policies") {
val = 'Policy';
} else {
val = '';
}
var enqId = id;
final prefs = await SharedPreferences.getInstance();
// Remove old value (if any)
await prefs.remove('enqStaffDataId');
// Save the new id
await prefs.setString('enqStaffDataId', enqId.toString());
await prefs.setString('navFromDashboard', 'Dashboard');
ref.read(quotationStaffIdProvider.notifier).state = enqId;
ref.read(navFromEnqStaffProvider.notifier).state = 'Dashboard';
// showDialog(
// context: context,
// builder: (context) => TabEnquiryStaffList(showKey: val),
// );
final result = await showDialog(
context: context,
barrierDismissible:
false, // optional - prevents closing by tapping outside
builder: (context) => TabEnquiryStaffList(showKey: val),
);
// Code here runs *after* the dialog is closed
print("Dialog closed");
print("Dialog result: $result");
refresh();
}
@override
Widget build(BuildContext context) {
// final enquiries = ref.watch(enquiriesProvider);
final managerId = ref.watch(managerIdProvider);
final userId = ref.watch(userIdProvider);
final role = ref.watch(userRoleProvider);
return Column(
children: [
Container(
margin: EdgeInsets.all(10),
// color: Colors.red.shade100,
// height: MediaQuery.of(context).size.height * 0.75,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: [
if (role == 'manager' || role == 'hanlder')
SizedBox(
height: MediaQuery.of(context).size.height * 0.78,
// replace Expanded
// height: 350, // adjust height as needed
child: Row(
children: [
Expanded(
child: Container(
padding: const EdgeInsets.all(12.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black12,
blurRadius: 4,
offset: Offset(0, 2),
),
],
),
child: Column(
children: [
Row(
children: [
Expanded(
child: Text(
'Performing Partner ( Top 50 )',
style: _chartHeader,
),
),
Text(
isPerfomingAgntPolicy
? "Policies"
: "Premium",
style: _styleSmall1,
),
Transform.scale(
scale: 0.5,
child: Switch(
value: isPerfomingAgntPolicy,
activeColor: Colors.teal,
activeTrackColor: Colors.grey.shade200,
inactiveThumbColor: Colors.orange,
inactiveTrackColor: Colors.white,
onChanged: (val) {
setState(
() => isPerfomingAgntPolicy = val,
);
},
),
),
],
),
Expanded(
child: Performance(
title: "Performing Partner",
data: isPerfomingAgntPolicy
? agentsPerformanceList
: agentsPerformanceListPremium,
isPerfomingAgntPolicy:
isPerfomingAgntPolicy,
),
),
],
),
),
),
SizedBox(width: 16),
Expanded(
child: Container(
padding: const EdgeInsets.all(12.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black12,
blurRadius: 4,
offset: Offset(0, 2),
),
],
),
child: Column(
children: [
Row(
children: [
Expanded(
child: Text(
'Non Performing Partner',
style: _chartHeader,
),
),
Text(
isNonPerfomingAgntPolicy
? "No Business"
: "Business Less than 50,000",
style: _styleSmall1,
),
Transform.scale(
scale: 0.5,
child: Switch(
value: isNonPerfomingAgntPolicy,
activeColor: Colors.teal,
activeTrackColor: Colors.grey.shade200,
inactiveThumbColor: Colors.orange,
inactiveTrackColor: Colors.white,
onChanged: (val) {
setState(
() =>
isNonPerfomingAgntPolicy = val,
);
},
),
),
],
),
Expanded(
child: Performance(
title: "Non-Performing Partner",
data: isNonPerfomingAgntPolicy
? nonAgentsPerformanceList
: nonAgentsPerformanceListPremium,
isPerfomingAgntPolicy:
isNonPerfomingAgntPolicy,
),
),
],
),
),
),
],
),
),
],
),
),
),
],
);
}
}
class Performance extends StatefulWidget {
final String title;
final List<Map<String, dynamic>> data;
final bool isPerfomingAgntPolicy;
Performance({
Key? key,
required this.title,
required this.data,
required this.isPerfomingAgntPolicy,
}) : super(key: key);
@override
State<Performance> createState() => _PerformanceState();
}
class _PerformanceState extends State<Performance> {
late bool isPerfomingAgntPolicy;
@override
void initState() {
super.initState();
isPerfomingAgntPolicy = widget.isPerfomingAgntPolicy;
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
// elevation: 1,
// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: Padding(
padding: const EdgeInsets.all(0.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// HEADER
Container(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
decoration: BoxDecoration(
color: Color(0xFFE3F9F8),
borderRadius: BorderRadius.circular(10),
),
child: Row(
children: [
Expanded(
child: Text(
"Partner Name",
textAlign: TextAlign.center,
style: _headerStyle,
),
),
Expanded(
child: Text(
"Partner Code",
textAlign: TextAlign.center,
style: _headerStyle,
),
),
(widget.title == 'Performing Partner')
? Expanded(
child: Text(
widget.isPerfomingAgntPolicy
? "Policy count"
: "Premium count",
textAlign: TextAlign.center,
style: _headerStyle,
),
)
: SizedBox(),
],
),
),
const SizedBox(height: 8),
// LIST
Flexible(
child: ListView.builder(
itemCount: widget.data.length,
itemBuilder: (context, index) {
final row = widget.data[index];
return Container(
margin: const EdgeInsets.symmetric(vertical: 5),
padding: const EdgeInsets.symmetric(
vertical: 5,
horizontal: 12,
),
decoration: BoxDecoration(
color: Colors.white,
border: Border(
bottom: BorderSide(
color: Colors.blueGrey.shade100,
width: 0.3,
),
),
),
child: Row(
children: [
Expanded(
child: Text(
row['agent_name'] ?? "",
textAlign: TextAlign.center,
style: _tableDataStyle,
),
),
Expanded(
child: Text(
row['agent_code'] ?? "",
textAlign: TextAlign.center,
style: _tableDataStyle,
),
),
(widget.title == 'Performing Partner')
? Expanded(
child: Text(
isPerfomingAgntPolicy
? (row['policy_count']?.toString() ?? "0")
: (row['total_premium_amount']
?.toString() ??
"0"),
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontSize: 11,
fontWeight: FontWeight.w500,
// color: isPerfomingAgntPolicy
// ? Colors.black
// : (row['status']?.toString().toLowerCase() ==
// "active"
// ? Colors.green
// : Colors.red),
),
),
)
: SizedBox(),
],
),
);
},
),
),
],
),
),
);
}
}
class UnassignedEnq extends StatelessWidget {
final String title;
final List<Map<String, dynamic>> data;
final VoidCallback? onRefresh;
String role;
UnassignedEnq({
Key? key,
required this.title,
required this.data,
this.onRefresh,
required this.role,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Card(
color: Colors.white,
// color: const Color(0xFFEAF6F4),
elevation: 1,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Title
Text(title, style: _title),
const SizedBox(height: 10),
// Header row
Container(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
decoration: BoxDecoration(
// color: const Color(0xFF3E5B56),
color: Color(0xFFE3F9F8),
borderRadius: BorderRadius.circular(10),
),
child: Row(
children: [
// Expanded(
// child: Text(
// "S.No",
// textAlign: TextAlign.center,
// style: _headerStyle,
// ),
// ),
Expanded(
child: Text(
"Date",
// textAlign: TextAlign.center,
style: _headerStyle,
),
),
Expanded(
child: Text(
"Partner",
// textAlign: TextAlign.center,
style: _headerStyle,
),
),
Expanded(
child: Text(
"Reg.No.",
// textAlign: TextAlign.center,
style: _headerStyle,
),
),
Expanded(
child: Text(
"Insured Name",
// textAlign: TextAlign.center,
style: _headerStyle,
),
),
],
),
),
const SizedBox(height: 8),
// List of rows
Flexible(
child: ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
final row = data[index];
String date = "";
String time = "";
if ((row['created_on'] ?? "").isNotEmpty) {
final parts = row['created_on'].split(' ');
date = parts[0];
if (parts.isNotEmpty) {
DateTime parsedDate = DateTime.parse(parts[0]);
date = DateFormat(
'dd-MM-yyyy',
).format(parsedDate); // 19/09/2025
}
// time = parts.length > 1 ? parts[1] : "";
// Format the time part (HH:mm)
if (parts.length >= 2) {
final timeParts = parts[1].split(":");
time = "${timeParts[0]}:${timeParts[1]}"; // 05:45
} else {
time = "";
}
}
return InkWell(
focusColor: Color(0xFF3E5B56),
highlightColor: Color(0xFF3E5B56),
borderRadius: BorderRadius.circular(2), // for ripple effect
// onTap: () {
// handleDashboardNavigation(
// context,
// status: "To be assigned",
// staffId: row['staff_id'] ?? '',
// role: role,
// );
// },
onTap: () {
// Print the id when row is clicked
print("Clicked ID fd: ${row['id']}");
// You can also navigate or perform any action here
showDialog(
context: context,
builder: (ctx) => AssignStaffDialog(
enquiryPrimaryId: row['id'],
regNum: row['reg_no'],
userId: 1,
onSubmit: (value) {
debugPrint("New assignY: $value");
if (onRefresh != null) {
onRefresh!(); // call the parent's refresh
}
},
),
);
},
child: Container(
// height: 5200,
margin: const EdgeInsets.symmetric(vertical: 5),
padding: const EdgeInsets.symmetric(
vertical: 5,
horizontal: 12,
),
decoration: BoxDecoration(
color: Colors.white,
border: Border(
bottom: BorderSide(
color: Colors.blueGrey.shade100,
width: 0.3,
),
),
// borderRadius: BorderRadius.circular(10),
),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(date, style: _tableDataStyle),
Text(time, style: _tableDataTimeStyle),
],
),
),
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,
),
),
],
),
),
);
},
),
),
],
),
),
);
}
}
Future<void> handleDashboardNavigation(
BuildContext context, {
required String status,
String? staffId,
required String role,
}) async {
print('Dashboard Tap => Status: $status | Staff: $staffId');
final prefs = await SharedPreferences.getInstance();
// Clear any old data
await prefs.remove('dashboardKeyProvider');
await prefs.remove('dashboardStatusProvider');
await prefs.remove('dashboardStaffIdProvider');
// Save new values
await prefs.setString('dashboardKeyProvider', 'fromDashboard');
await prefs.setString('dashboardStatusProvider', status);
await prefs.setString('dashboardStaffIdProvider', staffId!);
context.go(AppRoutes.enquiryForStaff);
// // Navigate
// if (role == 'manager') {
// context.go(AppRoutes.enquiryForStaff);
// } else {
// context.go(AppRoutes.enquiryHandlerLst);
// }
}
final _headerStyle = GoogleFonts.inter(
fontWeight: FontWeight.w600,
fontSize: 11.5,
color: Colors.black,
);
final _title = GoogleFonts.inter(
fontWeight: FontWeight.bold,
fontSize: 11.5,
// color: Colors.red,
color: const Color(0xff425B5B),
);
final _tableDataStyle = GoogleFonts.inter(
fontSize: 11,
fontWeight: FontWeight.w500,
);
final _tableDataTimeStyle = GoogleFonts.inter(
fontSize: 10,
fontWeight: FontWeight.w400,
);
final topHeaderStyle = GoogleFonts.inter(
fontSize: 11,
color: Colors.black,
fontWeight: FontWeight.w500,
);
final _styleSmall1 = GoogleFonts.poppins(
fontSize: 10,
fontWeight: FontWeight.w400,
);
final _chartHeader = GoogleFonts.poppins(
fontSize: 11.5,
color: Colors.black,
fontWeight: FontWeight.w500,
);

View File

@ -0,0 +1,304 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:nhance_partner/presentation/providers/manager_provider.dart';
import '../../../../core/services/api_service.dart';
import '../../../../data/models/bar_data.dart';
import '../../../providers/userRoleProvider.dart';
import '../../../themes/charts/barChart.dart';
class ProductiviyDashboard extends ConsumerStatefulWidget {
const ProductiviyDashboard({super.key});
@override
ConsumerState<ProductiviyDashboard> createState() =>
_ProductiviyDashboardState();
}
class _ProductiviyDashboardState extends ConsumerState<ProductiviyDashboard> {
dynamic managerId;
late ApiService apiService;
// List<Map<String, dynamic>> dataVal = [];
List<Map<String, dynamic>> getBusinessDshBdData = [];
List<Map<String, dynamic>> originalData = [];
List<Map<String, dynamic>> filteredData = [];
List<Map<String, dynamic>> brokerWise = [];
List<Map<String, dynamic>> productWise = [];
List<Map<String, dynamic>> insurerWise = [];
List<Map<String, dynamic>> originalBrokerWise = [];
List<Map<String, dynamic>> filteredBrokerWise = [];
List<Map<String, dynamic>> originalProductWise = [];
List<Map<String, dynamic>> filteredProductWise = [];
List<Map<String, dynamic>> originalInsurerWise = [];
List<Map<String, dynamic>> filteredInsurerWise = [];
bool isLoading = false;
bool isInsureWisePolicy = true;
bool isBrokerWisePolicy = true;
bool isProductWisePolicy = true;
bool showInsurer = true;
bool showBroker = true;
bool showProduct = true;
int selectedView = 0;
// 0 = Insurer
// 1 = Broker
// 2 = Product
String? SelctdBusinessbroker;
@override
void initState() {
super.initState();
apiService = ApiService();
Future.microtask(() {
// final id = ref.read(managerIdProvider);
final roleId = ref.read(userRoleProvider);
managerId = ref.read(managerIdProvider);
// print("ENQroleId - $roleId");
if (managerId != null) {
getBusinessDashBrdList(managerId);
}
});
}
Future<void> getBusinessDashBrdList(id) async {
// print('getClaimList called MagId - $managerId - $role');
setState(() {
isLoading = true;
});
// dynamic id = widget.policyNumber;
print('getBusinessDshID - $id');
try {
final response = await apiService.findBusinessDashboardData(
id,
SelctdBusinessbroker,
);
if (response['status'] == 'success') {
final data = response['data'];
print('getBusinessDshBdData - ${response['data']}');
setState(() {
if (data is List) {
// Already a list of maps
getBusinessDshBdData = List<Map<String, dynamic>>.from(data);
} else if (data is Map) {
// Single object, wrap in a list
getBusinessDshBdData = [Map<String, dynamic>.from(data)];
} else {
getBusinessDshBdData = [];
}
// getBusinessDshBdData = List<Map<String, dynamic>>.from(response['data']);
originalData = getBusinessDshBdData;
filteredData = List.from(originalData);
// print('originalData - $getClaimPolicies');
});
if (data is Map<String, dynamic>) {
setState(() {
// Store BrokerWise
brokerWise = List<Map<String, dynamic>>.from(
data['brokerWise'] ?? [],
);
print('brokerWise - ${brokerWise}');
originalBrokerWise = List.from(brokerWise);
filteredBrokerWise = List.from(brokerWise);
// Store ProductWise
productWise = List<Map<String, dynamic>>.from(
data['productWise'] ?? [],
);
print('productWise - ${productWise}');
originalProductWise = List.from(productWise);
filteredProductWise = List.from(productWise);
// Store InsurerWise
insurerWise = List<Map<String, dynamic>>.from(
data['insurerWise'] ?? [],
);
print('insurerWise - ${insurerWise}');
originalInsurerWise = List.from(insurerWise);
filteredInsurerWise = List.from(insurerWise);
});
} else {
// fallback
brokerWise = [];
productWise = [];
insurerWise = [];
}
} else {
getBusinessDshBdData = [];
originalData = [];
}
} catch (e) {
print('Exception occurred: $e');
} finally {
setState(() {
isLoading = false;
});
}
}
List<BarData> buildInsurerBarData() {
double parseDouble(dynamic value) {
if (value == null) return 0.0;
if (value is num) return value.toDouble();
if (value is String) return double.tryParse(value) ?? 0.0;
return 0.0;
}
return filteredInsurerWise.map((item) {
print('policies_current - ${item['total_policies_current_month']}');
print('policies_PREV - ${item['total_policies_pre_month']}');
print('premium_current - ${item['total_premium_current_month']}');
print('premium_PREV - ${item['total_premium_pre_month']}');
return BarData(
Colors.blue,
isInsureWisePolicy
? parseDouble(item['total_policies_current_month'])
: parseDouble(item['total_premium_current_month']),
isInsureWisePolicy
? parseDouble(item['total_policies_pre_month'])
: parseDouble(item['total_premium_pre_month']),
5,
);
}).toList();
}
List<String> buildInsurerLabels() {
return filteredInsurerWise.map<String>((item) {
final name = item['short_name'];
if (name != null && name.toString().trim().isNotEmpty) {
return name.toString();
} else {
return item['short_name']?.toString() ?? '';
}
}).toList();
}
List<BarData> buildBrokerBarData() {
double parseDouble(dynamic value) {
if (value == null) return 0.0;
if (value is num) return value.toDouble();
if (value is String) return double.tryParse(value) ?? 0.0;
return 0.0;
}
return filteredBrokerWise.map((item) {
print('policies_current - ${item['total_policies_current_month']}');
print('policies_PREV - ${item['total_policies_pre_month']}');
print('premium_current - ${item['total_premium_current_month']}');
print('premium_PREV - ${item['total_premium_pre_month']}');
return BarData(
Colors.blue,
isBrokerWisePolicy
? parseDouble(item['total_policies_current_month'])
: parseDouble(item['total_premium_current_month']),
isBrokerWisePolicy
? parseDouble(item['total_policies_pre_month'])
: parseDouble(item['total_premium_pre_month']),
5,
);
}).toList();
}
List<String> buildBrokerLabels() {
return filteredBrokerWise.map<String>((item) {
final name = item['broker_name'];
if (name != null && name.toString().trim().isNotEmpty) {
return name.toString();
} else {
return item['broker_name']?.toString() ?? '';
}
}).toList();
}
List<BarData> buildProductBarData() {
double parseDouble(dynamic value) {
if (value == null) return 0.0;
if (value is num) return value.toDouble();
if (value is String) return double.tryParse(value) ?? 0.0;
return 0.0;
}
return filteredProductWise.map((item) {
print('policies_current - ${item['total_policies_current_month']}');
print('policies_PREV - ${item['total_policies_pre_month']}');
print('premium_current - ${item['total_premium_current_month']}');
print('premium_PREV - ${item['total_premium_pre_month']}');
return BarData(
Colors.blue,
isProductWisePolicy
? parseDouble(item['total_policies_current_month'])
: parseDouble(item['total_premium_current_month']),
isProductWisePolicy
? parseDouble(item['total_policies_pre_month'])
: parseDouble(item['total_premium_pre_month']),
10,
);
}).toList();
}
List<String> buildProductLabels() {
return filteredProductWise.map<String>((item) {
final name = item['vehicle_type'];
if (name != null && name.toString().trim().isNotEmpty) {
return name.toString();
} else {
return item['vehicle_type']?.toString() ?? '';
}
}).toList();
}
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(left: 10, right: 10, bottom: 10),
// color: Colors.amber.shade100,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [Text('No Data Found ', style: _styleSmall1)],
),
);
}
}
final _headerStyle2 = GoogleFonts.poppins(
fontSize: 12,
color: Colors.black,
fontWeight: FontWeight.w500,
);
final _chartHeader = GoogleFonts.poppins(
fontSize: 11.5,
color: Colors.black,
fontWeight: FontWeight.w500,
);
final _styleSmall1 = GoogleFonts.poppins(
fontSize: 10,
fontWeight: FontWeight.w400,
);
final _styleSmall2 = GoogleFonts.poppins(
fontSize: 10,
fontWeight: FontWeight.w400,
color: Colors.blueGrey,
);

View File

@ -71,7 +71,7 @@ class CreateProposal_QuickFormState
Map<String, TextEditingController> controllers = {};
final _formKey = GlobalKey<FormState>();
Map<String, String?> fieldErrors = {};
String? docUploadedFileUrlFromApi;
String? selectedId;
PlatformFile? docUploadedFile;
@ -1349,7 +1349,31 @@ class CreateProposal_QuickFormState
UpperCaseTextFormatter(), // 👈 custom formatter for uppercase
FilteringTextInputFormatter.allow(RegExp(r'[A-Za-z0-9- ]')),
],
validator: (value) => Validators.requiredField(value, "regNo"),
onChanged: (val) async {
print('Vehicle - $val');
final res = await apiService.CheckDuplicate(context, val);
print('Vehicle res- $res');
if (res["message"] != null && res["message"] != "") {
ToastHelper.showErrorToast(context, res['message']);
setState(() {
fieldErrors['regNo'] = res['message']; // store API message
}); // 🔥 store backend message
} else {
setState(() {
fieldErrors['regNo'] = res['message']; // store API message
});
}
},
validator: (value) {
// Show backend validation message
if (fieldErrors['regNo'] != null &&
fieldErrors['regNo']!.isNotEmpty) {
return fieldErrors['regNo']; // show API message
}
return Validators.requiredField(value, "regNo");
},
// validator: (value) => Validators.requiredVechileNum(value, "regNo"),
widthNone: true,
),

View File

@ -667,6 +667,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
setState(() {
if (SelectedStatus == 'Completed') {
selectedIndex = 1;
} else {
selectedIndex = 0;
}
controllers['startDate']?.text = fromDate;
controllers['endDate']?.text = toDate;
@ -1747,7 +1749,31 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
UpperCaseTextFormatter(), // 👈 custom formatter for uppercase
FilteringTextInputFormatter.allow(RegExp(r'[A-Za-z0-9- ]')),
],
validator: (value) => Validators.requiredVechileNum(value, "regNo"),
onChanged: (val) async {
print('Vehicle - $val');
final res = await apiService.CheckDuplicate(context, val);
print('Vehicle res- $res');
if (res["message"] != null && res["message"] != "") {
ToastHelper.showErrorToast(context, res['message']);
setState(() {
fieldErrors['regNo'] = res['message']; // store API message
}); // 🔥 store backend message
} else {
setState(() {
fieldErrors['regNo'] = res['message']; // store API message
});
}
},
validator: (value) {
// Show backend validation message
if (fieldErrors['regNo'] != null &&
fieldErrors['regNo']!.isNotEmpty) {
return fieldErrors['regNo']; // show API message
}
return Validators.requiredField(value, "regNo");
},
// widthNone: true,
),
),
@ -3222,21 +3248,23 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
children: [
if (_showFilterRow) ...[
DateFilterRow(
key: ValueKey(SelectedStatus ?? ''),
formKey: _formKey,
// key: ValueKey(SelectedStatus ?? ''),
role: roleId,
id: userId,
selectedStatusVal: SelectedStatus,
selectedStaffId: SelectedStaffId,
onFilterStaff: (val) {
print('Selected Filterd STAFF Id - $val');
SelectedStaffId = val;
},
selectedStaffId: SelectedStaffId,
// selectedStaffId: SelectedStaffId,
startController: controllers['startDate']!,
endController: controllers['endDate']!,
onStatusChanged: (val) {
SelectedStatus = val; // update parent
},
formKey: _formKey,
isMobile: ResponsiveLayout.isMobile(context),
onFilter: () {
// call your filter logic

View File

@ -3,8 +3,10 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:nhance_partner/data/utils/toastNotification.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../../core/services/api_service.dart';
@ -798,6 +800,7 @@ class RaiseEnqFormState extends ConsumerState<RaiseEnqForm> {
width: MediaQuery.of(context).size.width * 0.15,
child: ThemedFormInlineField(
controller: controllers['regNo']!,
hintText: 'Vehicle Number',
borderColor: Color(0xFFE2E8F0),
highlightColor: Color(0xFF50A398),
@ -807,8 +810,33 @@ class RaiseEnqFormState extends ConsumerState<RaiseEnqForm> {
UpperCaseTextFormatter(), // 👈 custom formatter for uppercase
FilteringTextInputFormatter.allow(RegExp(r'[A-Za-z0-9- ]')),
],
validator: (value) => Validators.requiredField(value, "regNo"),
// validator: (value) => Validators.requiredVechileNum(value, "regNo"),
// validator: (value) => Validators.requiredField(value, "regNo"),
onChanged: (val) async {
print('Vehicle - $val');
final res = await apiService.CheckDuplicate(context, val);
print('Vehicle res- $res');
if (res["message"] != null && res["message"] != "") {
ToastHelper.showErrorToast(context, res['message']);
setState(() {
fieldErrors['regNo'] = res['message']; // store API message
}); // 🔥 store backend message
} else {
setState(() {
fieldErrors['regNo'] = res['message']; // store API message
});
}
},
validator: (value) {
// Show backend validation message
if (fieldErrors['regNo'] != null &&
fieldErrors['regNo']!.isNotEmpty) {
return fieldErrors['regNo']; // show API message
}
return Validators.requiredField(value, "regNo");
},
widthNone: true,
),
),

View File

@ -1,21 +1,23 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../../../data/models/bar_data.dart';
import 'appChartColors.dart';
class BarChart extends StatefulWidget {
final List<_BarData>? dataList;
final List<String>? labels;
class CustomBarChart extends StatefulWidget {
final List<BarData> dataList;
final List<String> labels;
final String title;
final String? btnName;
final double maxY;
final int initialRotation;
const BarChart(
BarChartData barChartData, {
const CustomBarChart({
super.key,
this.dataList,
this.labels,
required this.dataList,
required this.labels,
this.btnName,
this.title = "Horizontal Bar Chart",
this.maxY = 20,
this.initialRotation = 1,
@ -24,10 +26,10 @@ class BarChart extends StatefulWidget {
final shadowColor = const Color(0xFFCCCCCC);
@override
State<BarChart> createState() => _BarChartState();
State<CustomBarChart> createState() => _CustomBarChartState();
}
class _BarChartState extends State<BarChart> {
class _CustomBarChartState extends State<CustomBarChart> {
int touchedGroupIndex = -1;
late int rotationTurns;
@ -40,14 +42,19 @@ class _BarChartState extends State<BarChart> {
BarChartGroupData generateBarGroup(
int x,
Color color,
double value,
double value1,
double value2,
double shadowValue,
) {
return BarChartGroupData(
x: x,
groupVertically: false,
// barsSpace: 20,
barRods: [
BarChartRodData(toY: value, color: color, width: 6),
BarChartRodData(toY: shadowValue, color: widget.shadowColor, width: 6),
BarChartRodData(toY: value1, color: Colors.cyan.shade300, width: 6),
// BarChartRodData(toY: 2, color: Colors.orange.shade300, width: 6),
BarChartRodData(toY: value2, color: widget.shadowColor, width: 6),
],
showingTooltipIndicators: touchedGroupIndex == x ? [0] : [],
);
@ -55,82 +62,123 @@ class _BarChartState extends State<BarChart> {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(24),
child: Column(
children: [
Row(
children: [
const Spacer(),
Text(
widget.title,
style: const TextStyle(
color: AppColors.mainTextColor1,
fontSize: 20,
),
return AspectRatio(
aspectRatio: 1.4,
child: BarChart(
BarChartData(
alignment: BarChartAlignment.spaceBetween,
rotationQuarterTurns: rotationTurns,
borderData: FlBorderData(
show: true,
border: Border(
bottom: BorderSide(
color: AppColors.contentColorBlack,
width: 0.1,
),
Spacer(),
IconButton(
onPressed: () {
setState(() => rotationTurns += 1);
},
icon: RotatedBox(
quarterTurns: rotationTurns - 1,
child: const Icon(Icons.rotate_90_degrees_cw),
),
),
],
),
const SizedBox(height: 18),
AspectRatio(
aspectRatio: 1.4,
child: BarChart(
BarChartData(
alignment: BarChartAlignment.spaceBetween,
rotationQuarterTurns: rotationTurns,
borderData: FlBorderData(show: false),
titlesData: FlTitlesData(
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
getTitlesWidget: (value, meta) {
final i = value.toInt();
if (i >= widget.labels!.length) return const SizedBox();
return SideTitleWidget(
meta: meta,
child: Text(widget.labels![i]),
);
},
),
),
leftTitles: const AxisTitles(),
),
gridData: const FlGridData(show: false),
barGroups: widget.dataList?.asMap().entries.map((e) {
final index = e.key;
final data = e.value;
return generateBarGroup(
index,
data.color,
data.value,
data.shadowValue,
);
}).toList(),
maxY: widget.maxY,
),
// dataList: [],
// labels: [],
right: BorderSide(color: AppColors.contentColorBlack, width: 0.1),
),
),
],
gridData: FlGridData(
show: true,
drawVerticalLine: false,
getDrawingHorizontalLine: (value) => FlLine(
color: AppColors.borderColor.withValues(alpha: 0.2),
strokeWidth: 1,
),
),
titlesData: FlTitlesData(
bottomTitles: AxisTitles(
axisNameWidget: widget.btnName != null
? Text(widget.btnName!)
: Text(''),
axisNameSize: 10,
sideTitles: SideTitles(
reservedSize: 60,
showTitles: true,
getTitlesWidget: (value, meta) {
final i = value.toInt();
if (i >= widget.labels.length) return const SizedBox();
return SideTitleWidget(
meta: meta,
child: Text(
widget.labels[i],
style: GoogleFonts.poppins(
fontSize: 9.5,
fontWeight: FontWeight.w500,
),
textAlign: TextAlign.end,
),
);
},
),
),
leftTitles: const AxisTitles(),
// rightTitles: const AxisTitles(),
topTitles: const AxisTitles(),
),
barGroups: widget.dataList.asMap().entries.map((e) {
final index = e.key;
final data = e.value;
print('generateBarGroupBAR - $data');
return generateBarGroup(
index,
data.color,
data.value1,
data.value2,
data.shadowValue,
);
}).toList(),
// maxY: widget.maxY,
maxY: (widget.dataList != null && widget.dataList!.isNotEmpty)
? widget.dataList!
.map((e) => e.value1 > e.value2 ? e.value1 : e.value2)
.reduce((a, b) => a > b ? a : b) +
5
: 20,
// barTouchData: BarTouchData(
// enabled: true,
// handleBuiltInTouches: false,
// touchTooltipData: BarTouchTooltipData(
// getTooltipColor: (group) => Colors.transparent,
// tooltipMargin: 0,
// getTooltipItem:
// (
// BarChartGroupData group,
// int groupIndex,
// BarChartRodData rod,
// int rodIndex,
// ) {
// return BarTooltipItem(
// rod.toY.toString(),
// TextStyle(
// fontWeight: FontWeight.bold,
// color: rod.color,
// fontSize: 18,
// shadows: const [
// Shadow(color: Colors.black26, blurRadius: 12),
// ],
// ),
// );
// },
// ),
// touchCallback: (event, response) {
// if (event.isInterestedForInteractions &&
// response != null &&
// response.spot != null) {
// setState(() {
// touchedGroupIndex = response.spot!.touchedBarGroupIndex;
// });
// } else {
// setState(() {
// touchedGroupIndex = -1;
// });
// }
// },
// ),
),
),
);
}
}
class _BarData {
final Color color;
final double value;
final double shadowValue;
const _BarData(this.color, this.value, this.shadowValue);
}

View File

@ -206,6 +206,7 @@ class ThemedFormInlineField extends HookWidget {
fontWeight: FontWeight.w400, // optional
color: textColr ?? Colors.black, // optional
),
onChanged: onChanged,
),
),
);

View File

@ -56,7 +56,7 @@ class DateFilterRow extends ConsumerStatefulWidget {
required this.onFilter,
required this.onRefresh,
required this.onStatusChanged,
required this.onFilterStaff,
this.onFilterStaff,
required this.selectedStaffId,
this.selectedStatusVal,
required this.formKey,
@ -280,6 +280,7 @@ class _DateFilterRowState extends ConsumerState<DateFilterRow> {
'dd-MM-yyyy',
).format(date);
// controllers['date']?.text = date as String;
Future.microtask(() => widget.onFilter());
},
),
),
@ -322,6 +323,7 @@ class _DateFilterRowState extends ConsumerState<DateFilterRow> {
onDateSelected: (date) {
print("Picked Date: $date");
widget.endController.text = DateFormat('dd-MM-yyyy').format(date);
Future.microtask(() => widget.onFilter());
// controllers['date']?.text = date as String;
},
),
@ -456,6 +458,8 @@ class _DateFilterRowState extends ConsumerState<DateFilterRow> {
print("Selected Status: ${val['status']}");
if (widget.onStatusChanged != null)
widget.onStatusChanged!(val['status']);
Future.microtask(() => widget.onFilter());
}
},
),
@ -609,11 +613,13 @@ class _DateFilterRowState extends ConsumerState<DateFilterRow> {
if (val != null) {
print("Selected Staff : ${val['name']}");
print("Id: ${val['id']}");
selectedStaffName = val['name'];
selectedStaff = val['id'];
// selectedStaffName = val['name'];
// selectedStaff = val['id'];
if (widget.onFilterStaff != null)
widget.onFilterStaff!(val['id']);
Future.microtask(() => widget.onFilter());
// controllers['agentId']?.text = val['agent_code'];
// agentId = agent['id'];
}

View File

@ -69,10 +69,10 @@ packages:
dependency: transitive
description:
name: build
sha256: "5b887c55a0f734b433b3b2d89f9cd1f99eb636b17e268a5b4259258bc916504b"
sha256: c1668065e9ba04752570ad7e038288559d1e2ca5c6d0131c0f5f55e39e777413
url: "https://pub.dev"
source: hosted
version: "4.0.0"
version: "4.0.3"
build_config:
dependency: transitive
description:
@ -85,18 +85,18 @@ packages:
dependency: transitive
description:
name: build_daemon
sha256: "8e928697a82be082206edb0b9c99c5a4ad6bc31c9e9b8b2f291ae65cd4a25daa"
sha256: bf05f6e12cfea92d3c09308d7bcdab1906cd8a179b023269eed00c071004b957
url: "https://pub.dev"
source: hosted
version: "4.0.4"
version: "4.1.1"
build_runner:
dependency: "direct dev"
description:
name: build_runner
sha256: "804c47c936df75e1911c19a4fb8c46fa8ff2b3099b9f2b2aa4726af3774f734b"
sha256: "110c56ef29b5eb367b4d17fc79375fa8c18a6cd7acd92c05bb3986c17a079057"
url: "https://pub.dev"
source: hosted
version: "2.8.0"
version: "2.10.4"
built_collection:
dependency: transitive
description:
@ -109,10 +109,10 @@ packages:
dependency: transitive
description:
name: built_value
sha256: a30f0a0e38671e89a492c44d005b5545b830a961575bbd8336d42869ff71066d
sha256: "426cf75afdb23aa74bd4e471704de3f9393f3c7b04c1e2d9c6f1073ae0b8b139"
url: "https://pub.dev"
source: hosted
version: "8.12.0"
version: "8.12.1"
characters:
dependency: transitive
description:
@ -189,18 +189,18 @@ packages:
dependency: transitive
description:
name: cross_file
sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
sha256: "701dcfc06da0882883a2657c445103380e53e647060ad8d9dfb710c100996608"
url: "https://pub.dev"
source: hosted
version: "0.3.4+2"
version: "0.3.5+1"
crypto:
dependency: transitive
description:
name: crypto
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
url: "https://pub.dev"
source: hosted
version: "3.0.6"
version: "3.0.7"
csslib:
dependency: transitive
description:
@ -293,34 +293,34 @@ packages:
dependency: "direct main"
description:
name: file_picker
sha256: f2d9f173c2c14635cc0e9b14c143c49ef30b4934e8d1d274d6206fcb0086a06f
sha256: "7872545770c277236fd32b022767576c562ba28366204ff1a5628853cf8f2200"
url: "https://pub.dev"
source: hosted
version: "10.3.3"
version: "10.3.7"
firebase_auth:
dependency: "direct main"
description:
name: firebase_auth
sha256: b843f8b6897654899bfc437e385f710f79fdf1fe872ce629cbdf6017772d5803
sha256: e54fb3ba57de041d832574126a37726eedf0f57400869f1942b0ca8ce4a6e209
url: "https://pub.dev"
source: hosted
version: "6.0.2"
version: "6.1.2"
firebase_auth_platform_interface:
dependency: transitive
description:
name: firebase_auth_platform_interface
sha256: c7acba5e95dc8095149c4534e968d61099896f1a09421d46d7c3fc3069082a37
sha256: "421f95dc553cb283ed9d4d140e719800c0331d49ed37b962e513c9d1d61b090b"
url: "https://pub.dev"
source: hosted
version: "8.1.1"
version: "8.1.4"
firebase_auth_web:
dependency: transitive
description:
name: firebase_auth_web
sha256: "083c57b761b33f766824d7835c2b47abacbc4d82c7193e91442d77b983675b28"
sha256: a064ffee202f7d42d62e2c01775899d4ffcb83c602af07632f206acd46a0964e
url: "https://pub.dev"
source: hosted
version: "6.0.2"
version: "6.1.0"
firebase_core:
dependency: "direct main"
description:
@ -349,26 +349,26 @@ packages:
dependency: "direct main"
description:
name: firebase_messaging
sha256: aad5dcdea5698499b70d74d5a53b1f6a9972f85f97225e4b7ac006dd8d4f9bac
sha256: "22086f857d2340f5d973776cfd542d3fb30cf98e1c643c3aa4a7520bb12745bb"
url: "https://pub.dev"
source: hosted
version: "16.0.1"
version: "16.0.4"
firebase_messaging_platform_interface:
dependency: transitive
description:
name: firebase_messaging_platform_interface
sha256: "825bc11767bf50a43dccf49b3026f847ec31d0f176139bfc48d662cc128b5014"
sha256: a59920cbf2eb7c83d34a5f354331210ffec116b216dc72d864d8b8eb983ca398
url: "https://pub.dev"
source: hosted
version: "4.7.1"
version: "4.7.4"
firebase_messaging_web:
dependency: transitive
description:
name: firebase_messaging_web
sha256: db8dbdd79921245c4de02407e33cae2d1868683be18a5ba948d2af5311e3ef5d
sha256: "1183e40e6fd2a279a628951cc3b639fcf5ffe7589902632db645011eb70ebefb"
url: "https://pub.dev"
source: hosted
version: "4.0.1"
version: "4.1.0"
fixnum:
dependency: transitive
description:
@ -418,10 +418,18 @@ packages:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: b0694b7fb1689b0e6cc193b3f1fcac6423c4f93c74fb20b806c6b6f196db0c31
sha256: c2fe1001710127dfa7da89977a08d591398370d099aacdaa6d44da7eb14b8476
url: "https://pub.dev"
source: hosted
version: "2.0.30"
version: "2.0.31"
flutter_reorderable_grid_view:
dependency: "direct main"
description:
name: flutter_reorderable_grid_view
sha256: beb85f95325c83515d8953e8612dc70d287a69d1437c14262b7d738070133a87
url: "https://pub.dev"
source: hosted
version: "5.5.2"
flutter_riverpod:
dependency: "direct main"
description:
@ -496,22 +504,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "9.0.0"
frontend_server_client:
dependency: transitive
description:
name: frontend_server_client
sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
url: "https://pub.dev"
source: hosted
version: "4.0.0"
get_it:
dependency: "direct main"
description:
name: get_it
sha256: a4292e7cf67193f8e7c1258203104eb2a51ec8b3a04baa14695f4064c144297b
sha256: ae78de7c3f2304b8d81f2bb6e320833e5e81de942188542328f074978cc0efa9
url: "https://pub.dev"
source: hosted
version: "8.2.0"
version: "8.3.0"
glob:
dependency: transitive
description:
@ -524,18 +524,18 @@ packages:
dependency: "direct main"
description:
name: go_router
sha256: eb059dfe59f08546e9787f895bd01652076f996bcbf485a8609ef990419ad227
sha256: d8f590a69729f719177ea68eb1e598295e8dbc41bbc247fed78b2c8a25660d7c
url: "https://pub.dev"
source: hosted
version: "16.2.1"
version: "16.3.0"
google_fonts:
dependency: "direct main"
description:
name: google_fonts
sha256: ebc94ed30fd13cefd397cb1658b593f21571f014b7d1197eeb41fb95f05d899a
sha256: "517b20870220c48752eafa0ba1a797a092fb22df0d89535fd9991e86ee2cdd9c"
url: "https://pub.dev"
source: hosted
version: "6.3.1"
version: "6.3.2"
google_identity_services_web:
dependency: transitive
description:
@ -548,26 +548,26 @@ packages:
dependency: "direct main"
description:
name: google_sign_in
sha256: "939a8b58f84c4053811b8c1bc9adbcb59449a15b37958264bbf60020698cca0e"
sha256: "521031b65853b4409b8213c0387d57edaad7e2a949ce6dea0d8b2afc9cb29763"
url: "https://pub.dev"
source: hosted
version: "7.1.1"
version: "7.2.0"
google_sign_in_android:
dependency: transitive
description:
name: google_sign_in_android
sha256: "666c3a133f5ec4256f08884359dc34788778d96a378d804203bc57a73ffbd9c0"
sha256: "799165f4c0621ed233bccdded4c2e92739bc1fe73e970163b2f7493b301adad3"
url: "https://pub.dev"
source: hosted
version: "7.0.5"
version: "7.2.1"
google_sign_in_ios:
dependency: transitive
description:
name: google_sign_in_ios
sha256: c7ee744ebbcd98353966dbdee735d4fca085226f6bf725c6bea8a5c8fe0055bc
sha256: d9d80f953a244a099a40df1ff6aadc10ee375e6a098bbd5d55be332ce26db18c
url: "https://pub.dev"
source: hosted
version: "6.1.0"
version: "6.2.1"
google_sign_in_platform_interface:
dependency: transitive
description:
@ -580,10 +580,10 @@ packages:
dependency: transitive
description:
name: google_sign_in_web
sha256: "09ac306b2787b48f19c857b9f93375b654f774643c75bd6a1a078c85f4f7b468"
sha256: "2fc1f941e6443b2d6984f4056a727a3eaeab15d8ee99ba7125d79029be75a1da"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
version: "1.1.0"
graphs:
dependency: transitive
description:
@ -604,10 +604,10 @@ packages:
dependency: "direct main"
description:
name: http
sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007
sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412"
url: "https://pub.dev"
source: hosted
version: "1.5.0"
version: "1.6.0"
http_multi_server:
dependency: transitive
description:
@ -668,10 +668,10 @@ packages:
dependency: "direct dev"
description:
name: json_serializable
sha256: "33a040668b31b320aafa4822b7b1e177e163fc3c1e835c6750319d4ab23aa6fe"
sha256: c5b2ee75210a0f263c6c7b9eeea80553dbae96ea1bf57f02484e806a3ffdffa3
url: "https://pub.dev"
source: hosted
version: "6.11.1"
version: "6.11.2"
jwt_decode:
dependency: "direct main"
description:
@ -740,10 +740,10 @@ packages:
dependency: transitive
description:
name: local_auth_platform_interface
sha256: "1b842ff177a7068442eae093b64abe3592f816afd2a533c0ebcdbe40f9d2075a"
sha256: f98b8e388588583d3f781f6806e4f4c9f9e189d898d27f0c249b93a1973dd122
url: "https://pub.dev"
source: hosted
version: "1.0.10"
version: "1.1.0"
local_auth_windows:
dependency: transitive
description:
@ -796,10 +796,10 @@ packages:
dependency: "direct main"
description:
name: month_picker_dialog
sha256: "8196c59bbd3339ea57de2c372ca51a8cfdbb242d6e45100925b9e1982ba4617d"
sha256: "4b5cf251f17d679f213db4749a269fb995943cb62fd8335e772d2347f1350c26"
url: "https://pub.dev"
source: hosted
version: "6.5.0"
version: "6.7.0"
nested:
dependency: transitive
description:
@ -924,10 +924,10 @@ packages:
dependency: transitive
description:
name: path_provider_android
sha256: "993381400e94d18469750e5b9dcb8206f15bc09f9da86b9e44a9b0092a0066db"
sha256: "3b4c1fc3aa55ddc9cd4aa6759984330d5c8e66aa7702a6223c61540dc6380c37"
url: "https://pub.dev"
source: hosted
version: "2.2.18"
version: "2.2.19"
path_provider_foundation:
dependency: transitive
description:
@ -1004,10 +1004,10 @@ packages:
dependency: transitive
description:
name: pool
sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d"
url: "https://pub.dev"
source: hosted
version: "1.5.1"
version: "1.5.2"
provider:
dependency: transitive
description:
@ -1060,10 +1060,10 @@ packages:
dependency: transitive
description:
name: shared_preferences_android
sha256: a2608114b1ffdcbc9c120eb71a0e207c71da56202852d4aab8a5e30a82269e74
sha256: bd14436108211b0d4ee5038689a56d4ae3620fd72fd6036e113bf1345bc74d9e
url: "https://pub.dev"
source: hosted
version: "2.4.12"
version: "2.4.13"
shared_preferences_foundation:
dependency: transitive
description:
@ -1129,10 +1129,10 @@ packages:
dependency: transitive
description:
name: source_gen
sha256: ccf30b0c9fbcd79d8b6f5bfac23199fb354938436f62475e14aea0f29ee0f800
sha256: "07b277b67e0096c45196cbddddf2d8c6ffc49342e88bf31d460ce04605ddac75"
url: "https://pub.dev"
source: hosted
version: "4.0.1"
version: "4.1.1"
source_helper:
dependency: transitive
description:
@ -1149,14 +1149,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.10.1"
sprintf:
dependency: transitive
description:
name: sprintf
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
stack_trace:
dependency: transitive
description:
@ -1233,18 +1225,18 @@ packages:
dependency: "direct main"
description:
name: universal_html
sha256: "56536254004e24d9d8cfdb7dbbf09b74cf8df96729f38a2f5c238163e3d58971"
sha256: c0bcae5c733c60f26c7dfc88b10b0fd27cbcc45cb7492311cdaa6067e21c9cd4
url: "https://pub.dev"
source: hosted
version: "2.2.4"
version: "2.3.0"
universal_io:
dependency: transitive
description:
name: universal_io
sha256: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad"
sha256: f63cbc48103236abf48e345e07a03ce5757ea86285ed313a6a032596ed9301e2
url: "https://pub.dev"
source: hosted
version: "2.2.2"
version: "2.3.1"
universal_platform:
dependency: transitive
description:
@ -1281,10 +1273,10 @@ packages:
dependency: transitive
description:
name: url_launcher_linux
sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a
url: "https://pub.dev"
source: hosted
version: "3.2.1"
version: "3.2.2"
url_launcher_macos:
dependency: transitive
description:
@ -1313,18 +1305,18 @@ packages:
dependency: transitive
description:
name: url_launcher_windows
sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f"
url: "https://pub.dev"
source: hosted
version: "3.1.4"
version: "3.1.5"
uuid:
dependency: transitive
description:
name: uuid
sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
sha256: a11b666489b1954e01d992f3d601b1804a33937b5a8fe677bd26b8a9f96f96e8
url: "https://pub.dev"
source: hosted
version: "4.5.1"
version: "4.5.2"
vector_math:
dependency: transitive
description:
@ -1345,10 +1337,10 @@ packages:
dependency: transitive
description:
name: watcher
sha256: "5bf046f41320ac97a469d506261797f35254fa61c641741ef32dacda98b7d39c"
sha256: "592ab6e2892f67760543fb712ff0177f4ec76c031f02f5b4ff8d3fc5eb9fb61a"
url: "https://pub.dev"
source: hosted
version: "1.1.3"
version: "1.1.4"
web:
dependency: transitive
description:
@ -1377,10 +1369,10 @@ packages:
dependency: transitive
description:
name: win32
sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03"
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
url: "https://pub.dev"
source: hosted
version: "5.14.0"
version: "5.15.0"
xdg_directories:
dependency: transitive
description:

View File

@ -69,6 +69,7 @@ dependencies:
file_picker: ^10.3.3
fluttertoast: ^9.0.0
fl_chart: ^0.70.0
flutter_reorderable_grid_view: ^5.5.2
# fl_chart: ^1.1.0