chart changes
This commit is contained in:
parent
0b0a30f9d6
commit
2488d0f72c
File diff suppressed because one or more lines are too long
@ -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 {
|
||||
|
||||
10
lib/data/models/bar_data.dart
Normal file
10
lib/data/models/bar_data.dart
Normal 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);
|
||||
}
|
||||
12
lib/models/chart_item.dart
Normal file
12
lib/models/chart_item.dart
Normal 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);
|
||||
}
|
||||
38
lib/presentation/providers/chart_provider.dart
Normal file
38
lib/presentation/providers/chart_provider.dart
Normal 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();
|
||||
});
|
||||
@ -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
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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(),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -0,0 +1 @@
|
||||
|
||||
239
lib/presentation/screens/dashboard/tabs/buine.dart
Normal file
239
lib/presentation/screens/dashboard/tabs/buine.dart
Normal 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,
|
||||
// );
|
||||
178
lib/presentation/screens/dashboard/tabs/busindReorder.dart
Normal file
178
lib/presentation/screens/dashboard/tabs/busindReorder.dart
Normal 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,
|
||||
// );
|
||||
@ -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,
|
||||
);
|
||||
|
||||
@ -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,
|
||||
);
|
||||
|
||||
871
lib/presentation/screens/dashboard/tabs/partner.dart
Normal file
871
lib/presentation/screens/dashboard/tabs/partner.dart
Normal 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,
|
||||
);
|
||||
304
lib/presentation/screens/dashboard/tabs/productivity.dart
Normal file
304
lib/presentation/screens/dashboard/tabs/productivity.dart
Normal 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,
|
||||
);
|
||||
@ -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,
|
||||
),
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
),
|
||||
),
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -206,6 +206,7 @@ class ThemedFormInlineField extends HookWidget {
|
||||
fontWeight: FontWeight.w400, // optional
|
||||
color: textColr ?? Colors.black, // optional
|
||||
),
|
||||
onChanged: onChanged,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@ -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'];
|
||||
}
|
||||
|
||||
168
pubspec.lock
168
pubspec.lock
@ -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:
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user