notification and chart changes done
This commit is contained in:
parent
f4186a876b
commit
4917749f65
@ -15,12 +15,12 @@ if (localPropertiesFile.exists()) {
|
|||||||
|
|
||||||
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
|
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
|
||||||
if (flutterVersionCode == null) {
|
if (flutterVersionCode == null) {
|
||||||
flutterVersionCode = "17"
|
flutterVersionCode = "20"
|
||||||
}
|
}
|
||||||
|
|
||||||
def flutterVersionName = localProperties.getProperty("flutter.versionName")
|
def flutterVersionName = localProperties.getProperty("flutter.versionName")
|
||||||
if (flutterVersionName == null) {
|
if (flutterVersionName == null) {
|
||||||
flutterVersionName = "1.0.16"
|
flutterVersionName = "1.0.19"
|
||||||
}
|
}
|
||||||
|
|
||||||
def keystorePropertiesFile = rootProject.file("key.properties")
|
def keystorePropertiesFile = rootProject.file("key.properties")
|
||||||
|
|||||||
@ -15,6 +15,11 @@
|
|||||||
"exit": "خروج",
|
"exit": "خروج",
|
||||||
|
|
||||||
"bookmark_title": "إشارة مرجعية",
|
"bookmark_title": "إشارة مرجعية",
|
||||||
|
"failed_To_Remove": "فشلت الإزالة",
|
||||||
|
"removed_from_Bookmark": "تمت الإزالة من الإشارة المرجعية",
|
||||||
|
"added_to_Bookmark":"تمت إضافته إلى الإشارة المرجعية",
|
||||||
|
"guide_title": "نموذج الملاحظات",
|
||||||
|
"notification": "إشعار",
|
||||||
|
|
||||||
"guide_title": "نموذج الملاحظات",
|
"guide_title": "نموذج الملاحظات",
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,10 @@
|
|||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"exit": "Exit",
|
"exit": "Exit",
|
||||||
"bookmark_title": "Bookmark",
|
"bookmark_title": "Bookmark",
|
||||||
|
"failed_To_Remove": "Failed to Remove",
|
||||||
|
"removed_from_Bookmark": "Removed from Bookmark",
|
||||||
|
"added_to_Bookmark": "Added to Bookmark.",
|
||||||
|
"notification": "Notification",
|
||||||
|
|
||||||
"register_title": "Register",
|
"register_title": "Register",
|
||||||
"register_details": "Please enter your details",
|
"register_details": "Please enter your details",
|
||||||
|
|||||||
@ -148,9 +148,9 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
|
|
||||||
// ToastUtil.showSuccessToast("Added to Bookmark.");
|
// ToastUtil.showSuccessToast("Added to Bookmark.");
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(
|
SnackBar(
|
||||||
content: Text(
|
content: Text(
|
||||||
'Added to Bookmark.',
|
AppLocalizations.of(context)!.added_to_Bookmark,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Color(0xFF2F692C), fontWeight: FontWeight.w600),
|
color: Color(0xFF2F692C), fontWeight: FontWeight.w600),
|
||||||
),
|
),
|
||||||
@ -164,7 +164,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(
|
content: Text(
|
||||||
'Failed to Add',
|
AppLocalizations.of(context)!.failed_To_Remove,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Color(0xFF544C4C), fontWeight: FontWeight.w600),
|
color: Color(0xFF544C4C), fontWeight: FontWeight.w600),
|
||||||
),
|
),
|
||||||
@ -194,9 +194,9 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
});
|
});
|
||||||
// ToastUtil.showSuccessToast("Removed from Bookmark.");
|
// ToastUtil.showSuccessToast("Removed from Bookmark.");
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(
|
SnackBar(
|
||||||
content: Text(
|
content: Text(
|
||||||
'Removed from Bookmark.',
|
AppLocalizations.of(context)!.removed_from_Bookmark,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Color(0xFF2F692C), fontWeight: FontWeight.w600),
|
color: Color(0xFF2F692C), fontWeight: FontWeight.w600),
|
||||||
),
|
),
|
||||||
@ -1189,19 +1189,6 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
|
|
||||||
void processCardData(cardData){
|
|
||||||
|
|
||||||
print('PRocessCardData');
|
|
||||||
setState(() {
|
|
||||||
filteredAndSortedData = (cardData as List)
|
|
||||||
.where((card) => (card as Map<String, dynamic>)['is_chart'] == 'false')
|
|
||||||
.map((card) => card as Map<String, dynamic>)
|
|
||||||
.toList()
|
|
||||||
..sort((a, b) => (a['order_id'] as int).compareTo(b['order_id'] as int));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void processChartData(chartsData) {
|
void processChartData(chartsData) {
|
||||||
// Group data by 'kpi'
|
// Group data by 'kpi'
|
||||||
Map<String, List<Map<String, dynamic>>> groupedData = {};
|
Map<String, List<Map<String, dynamic>>> groupedData = {};
|
||||||
@ -1236,7 +1223,6 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
return {'id': kpi, 'name': tabHeading, 'order': tabOrder.toString()};
|
return {'id': kpi, 'name': tabHeading, 'order': tabOrder.toString()};
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
|
|
||||||
// Sort tabs by tab_order
|
// Sort tabs by tab_order
|
||||||
_tabs.sort((a, b) {
|
_tabs.sort((a, b) {
|
||||||
int orderA = int.tryParse(a['order'] ?? '0') ?? 0;
|
int orderA = int.tryParse(a['order'] ?? '0') ?? 0;
|
||||||
@ -1244,7 +1230,6 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
return orderA.compareTo(orderB);
|
return orderA.compareTo(orderB);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
print('Sorted Tabs: $_tabs');
|
print('Sorted Tabs: $_tabs');
|
||||||
|
|
||||||
print('Grouped Data: $groupedData');
|
print('Grouped Data: $groupedData');
|
||||||
@ -1282,10 +1267,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
cardData = nonChartData;
|
cardData = nonChartData;
|
||||||
chartScreenData = data['chartScreenData'] ?? {};
|
chartScreenData = data['chartScreenData'] ?? {};
|
||||||
|
|
||||||
processCardData(cardData);
|
|
||||||
processChartData(chartsData);
|
processChartData(chartsData);
|
||||||
|
|
||||||
|
|
||||||
print('chartsData :- $chartsData');
|
print('chartsData :- $chartsData');
|
||||||
print('cardData :- $cardData');
|
print('cardData :- $cardData');
|
||||||
print('chartScreenData :- $chartScreenData');
|
print('chartScreenData :- $chartScreenData');
|
||||||
@ -1436,16 +1419,16 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
children: [
|
children: [
|
||||||
// Header Section
|
// Header Section
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top:16.0, bottom: 0.0, left: 16.0, right: 16.0),
|
padding: const EdgeInsets.only(
|
||||||
|
top: 16.0, bottom: 0.0, left: 16.0, right: 16.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
|
|
||||||
Image.asset(
|
Image.asset(
|
||||||
UaeNumbersAssetPath.filterUae,
|
UaeNumbersAssetPath.filterUae,
|
||||||
color:Color(0xFF8E8E8E), // Outline color
|
color: Color(0xFF8E8E8E), // Outline color
|
||||||
width: 24, // Slightly larger
|
width: 24, // Slightly larger
|
||||||
height: 24,
|
height: 24,
|
||||||
),
|
),
|
||||||
@ -1460,7 +1443,6 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
fontFamily: 'Roboto',
|
fontFamily: 'Roboto',
|
||||||
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -1582,7 +1564,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
horizontal: 16.0, vertical: 12.0),
|
horizontal: 16.0, vertical: 12.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(color: Color(0xFF7296BE)),
|
border:
|
||||||
|
Border.all(color: Color(0xFF7296BE)),
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
),
|
),
|
||||||
child: Wrap(
|
child: Wrap(
|
||||||
@ -1745,8 +1728,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
fit: BoxFit
|
fit: BoxFit
|
||||||
.scaleDown, // Ensures text resizes if necessary
|
.scaleDown, // Ensures text resizes if necessary
|
||||||
child: Text(
|
child: Text(
|
||||||
context.translate(
|
context.translate('Filter', 'فلتر'),
|
||||||
'Filter', 'فلتر'),
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
@ -1826,8 +1808,14 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
return chart['kpi'] == tabId;
|
return chart['kpi'] == tabId;
|
||||||
}).toList(); // Convert to list after filtering
|
}).toList(); // Convert to list after filtering
|
||||||
|
|
||||||
print('tabFilteredCardData Data for Tab $tabId: $tabFilteredCardData');
|
print(
|
||||||
|
'tabFilteredCardData Data for Tab before $tabId: $tabFilteredCardData');
|
||||||
|
|
||||||
|
tabFilteredCardData
|
||||||
|
.sort((a, b) => (a['order_id'] as int).compareTo(b['order_id'] as int));
|
||||||
|
|
||||||
|
print(
|
||||||
|
'tabFilteredCardData Data for Tab after $tabId: $tabFilteredCardData');
|
||||||
setState(() {
|
setState(() {
|
||||||
cardData = tabFilteredCardData;
|
cardData = tabFilteredCardData;
|
||||||
originalTabCardData = List.from(tabFilteredCardData);
|
originalTabCardData = List.from(tabFilteredCardData);
|
||||||
@ -1858,14 +1846,12 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
// return crossAxisCount == 1 ? 0.2 : (crossAxisCount > 2 ? 0.9 : 0.7);
|
// return crossAxisCount == 1 ? 0.2 : (crossAxisCount > 2 ? 0.9 : 0.7);
|
||||||
return crossAxisCount == 2 ? 1.0 : 0.7; // Larger Content
|
return crossAxisCount == 2 ? 1.0 : 0.7; // Larger Content
|
||||||
// return crossAxisCount == 2 ? 1.5 : 0.9;
|
// return crossAxisCount == 2 ? 1.5 : 0.9;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return crossAxisCount == 2 ? 1.5 : 0.9;
|
return crossAxisCount == 2 ? 1.5 : 0.9;
|
||||||
// Shorter Content
|
// Shorter Content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// double calculateAspectRatio(int crossAxisCount, List<dynamic> cardData) {
|
// double calculateAspectRatio(int crossAxisCount, List<dynamic> cardData) {
|
||||||
// if (cardData.any((item) =>
|
// if (cardData.any((item) =>
|
||||||
// item['chart_type'] == 'total' || item['chart_type'] == 'average')) {
|
// item['chart_type'] == 'total' || item['chart_type'] == 'average')) {
|
||||||
@ -1888,8 +1874,6 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
// return 1.0; // Default fallback (should never be reached)
|
// return 1.0; // Default fallback (should never be reached)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final locale = ref.watch(localeProvider);
|
final locale = ref.watch(localeProvider);
|
||||||
@ -1957,17 +1941,19 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
// style: TextStyle(color: Colors.white),
|
// style: TextStyle(color: Colors.white),
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
title: Text(context.translate(
|
title: Text(
|
||||||
|
context.translate(
|
||||||
'UAE Numbers',
|
'UAE Numbers',
|
||||||
'أرقام الإمارات',
|
'أرقام الإمارات',
|
||||||
),),
|
|
||||||
// appbarColor: Color(int.parse(widget.bgColor)), // Example color
|
|
||||||
appbarColor: Color(
|
|
||||||
int.parse((chartScreenData['header_color'] ?? '#ffffff').replaceFirst('#', '0xff'))
|
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
// appbarColor: Color(int.parse(widget.bgColor)), // Example color
|
||||||
|
appbarColor: Color(int.parse(
|
||||||
|
(chartScreenData['header_color'] ?? '#ffffff')
|
||||||
|
.replaceFirst('#', '0xff'))),
|
||||||
// Example color
|
// Example color
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
colorChange:true,
|
colorChange: true,
|
||||||
navBackArrow: Text(widget.keyParam ?? 'Default Value'),
|
navBackArrow: Text(widget.keyParam ?? 'Default Value'),
|
||||||
body: isLoading
|
body: isLoading
|
||||||
? Center(child: CircularProgressIndicator())
|
? Center(child: CircularProgressIndicator())
|
||||||
@ -1979,7 +1965,9 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
// height: myheight / 5,
|
// height: myheight / 5,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
// color: color,
|
// color: color,
|
||||||
color: Color(int.parse((chartScreenData['header_color']?? '#898C81').replaceFirst('#', '0xff'))),
|
color: Color(int.parse(
|
||||||
|
(chartScreenData['header_color'] ?? '#898C81')
|
||||||
|
.replaceFirst('#', '0xff'))),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
left: 30, right: 30, top: 8, bottom: 5),
|
left: 30, right: 30, top: 8, bottom: 5),
|
||||||
@ -1993,8 +1981,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 26,
|
fontSize: 26,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
fontFamily: 'Roboto'
|
fontFamily: 'Roboto'),
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
width: mywidth / 7,
|
width: mywidth / 7,
|
||||||
@ -2006,7 +1993,9 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
Text(
|
Text(
|
||||||
// widget.title,
|
// widget.title,
|
||||||
chartScreenData['data_set_tile_heading'] ?? '',
|
chartScreenData['data_set_tile_heading'] ?? '',
|
||||||
style: TextStyle(color: Colors.white, fontSize: 20,
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
fontFamily: 'Roboto'),
|
fontFamily: 'Roboto'),
|
||||||
),
|
),
|
||||||
@ -2033,7 +2022,9 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
Container(
|
Container(
|
||||||
color: Color(int.parse((chartScreenData['header_color']?? '#898C81').replaceFirst('#', '0xff'))),
|
color: Color(int.parse(
|
||||||
|
(chartScreenData['header_color'] ?? '#898C81')
|
||||||
|
.replaceFirst('#', '0xff'))),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
@ -2042,6 +2033,16 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
key: bookMarkKey,
|
key: bookMarkKey,
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
if (isBookmarked) {
|
||||||
|
showRemoveBookmarkDialog();
|
||||||
|
} else {
|
||||||
|
showAddBookmarkDialog();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
context.translate(
|
context.translate(
|
||||||
@ -2054,17 +2055,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(width: 5),
|
SizedBox(width: 5),
|
||||||
GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
if (isBookmarked) {
|
|
||||||
showRemoveBookmarkDialog();
|
|
||||||
} else {
|
|
||||||
showAddBookmarkDialog();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
// Text(
|
// Text(
|
||||||
// "Bookmark",
|
// "Bookmark",
|
||||||
// style: const TextStyle(
|
// style: const TextStyle(
|
||||||
@ -2082,7 +2073,12 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
// width: 24,
|
// width: 24,
|
||||||
// height: 24,
|
// height: 24,
|
||||||
// ),
|
// ),
|
||||||
Icon(Icons.bookmarks_rounded, color:isBookmarked ? Colors.black:Colors.white ,),
|
Icon(
|
||||||
|
Icons.bookmarks_rounded,
|
||||||
|
color: isBookmarked
|
||||||
|
? Colors.black
|
||||||
|
: Colors.white,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -2142,7 +2138,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
),
|
),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
showRightSideModal(context, filterData, chartsData);
|
showRightSideModal(
|
||||||
|
context, filterData, chartsData);
|
||||||
},
|
},
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
UaeNumbersAssetPath.filterUae,
|
UaeNumbersAssetPath.filterUae,
|
||||||
@ -2159,11 +2156,9 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
// context, filterData, chartsData);
|
// context, filterData, chartsData);
|
||||||
// },
|
// },
|
||||||
// ),
|
// ),
|
||||||
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(width: 10),
|
||||||
width: 10),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -2171,7 +2166,9 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Color(int.parse((chartScreenData['body_color']?? '#898C81').replaceFirst('#', '0xff'))),
|
color: Color(int.parse(
|
||||||
|
(chartScreenData['body_color'] ?? '#898C81')
|
||||||
|
.replaceFirst('#', '0xff'))),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(10.0),
|
padding: const EdgeInsets.all(10.0),
|
||||||
child: ListView(
|
child: ListView(
|
||||||
@ -2182,8 +2179,9 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
// Left arrow button
|
// Left arrow button
|
||||||
if (_tabsData.length > 1)
|
if (_tabsData.length > 1)
|
||||||
_buildArrowButton(
|
_buildArrowButton(
|
||||||
onPressed:
|
onPressed: _activeTabIndex > 0
|
||||||
_activeTabIndex > 0 ? _scrollLeft : null,
|
? _scrollLeft
|
||||||
|
: null,
|
||||||
icon: Icons.arrow_back_ios_new,
|
icon: Icons.arrow_back_ios_new,
|
||||||
),
|
),
|
||||||
// Tabs with horizontal scroll
|
// Tabs with horizontal scroll
|
||||||
@ -2193,11 +2191,12 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
child: Row(
|
child: Row(
|
||||||
children:
|
children: List.generate(
|
||||||
List.generate(_tabsData.length, (index) {
|
_tabsData.length, (index) {
|
||||||
return _buildTab(
|
return _buildTab(
|
||||||
_tabsData[index],
|
_tabsData[index],
|
||||||
isActive: index == _activeTabIndex,
|
isActive:
|
||||||
|
index == _activeTabIndex,
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
@ -2206,7 +2205,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
// Right arrow button
|
// Right arrow button
|
||||||
if (_tabsData.length > 1)
|
if (_tabsData.length > 1)
|
||||||
_buildArrowButton(
|
_buildArrowButton(
|
||||||
onPressed: _activeTabIndex < _tabsData.length - 1
|
onPressed:
|
||||||
|
_activeTabIndex < _tabsData.length - 1
|
||||||
? _scrollRight
|
? _scrollRight
|
||||||
: null,
|
: null,
|
||||||
icon: Icons.arrow_forward_ios,
|
icon: Icons.arrow_forward_ios,
|
||||||
@ -2232,7 +2232,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
gridDelegate:
|
gridDelegate:
|
||||||
SliverGridDelegateWithFixedCrossAxisCount(
|
SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
// crossAxisCount:2,
|
// crossAxisCount:2,
|
||||||
crossAxisCount: cardData.length % 2 == 0 ? 2 : 3,
|
crossAxisCount:
|
||||||
|
cardData.length % 2 == 0 ? 2 : 3,
|
||||||
// crossAxisCount: cardData.length == 2
|
// crossAxisCount: cardData.length == 2
|
||||||
// ? 2
|
// ? 2
|
||||||
// : cardData.length == 3
|
// : cardData.length == 3
|
||||||
@ -2242,8 +2243,13 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
// : 3, // Default to 3 if more than 4 items // 2 cards per row
|
// : 3, // Default to 3 if more than 4 items // 2 cards per row
|
||||||
crossAxisSpacing: 2,
|
crossAxisSpacing: 2,
|
||||||
mainAxisSpacing: 5,
|
mainAxisSpacing: 5,
|
||||||
childAspectRatio: MediaQuery.of(context).size.width /
|
childAspectRatio: MediaQuery.of(context)
|
||||||
(MediaQuery.of(context).size.height / (cardData.length % 2 == 0 ? 2 : 1.3)),
|
.size
|
||||||
|
.width /
|
||||||
|
(MediaQuery.of(context).size.height /
|
||||||
|
(cardData.length % 2 == 0
|
||||||
|
? 2
|
||||||
|
: 1.3)),
|
||||||
// childAspectRatio:
|
// childAspectRatio:
|
||||||
// calculateAspectRatio(cardData.length, cardData),
|
// calculateAspectRatio(cardData.length, cardData),
|
||||||
),
|
),
|
||||||
@ -2251,19 +2257,20 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
// Sort and filter the cardData
|
// Sort and filter the cardData
|
||||||
|
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final item = filteredAndSortedData[index];
|
final item = cardData[index];
|
||||||
|
|
||||||
// print('item');
|
|
||||||
// final item = cardData[index];
|
|
||||||
print('item item item $item');
|
print('item item item $item');
|
||||||
final chart_type = item['chart_type'];
|
final chart_type = item['chart_type'];
|
||||||
final chart_heading = item['chart_heading'];
|
final chart_heading = item['chart_heading'];
|
||||||
final response = item['response'] as List<dynamic>? ?? [];
|
final response =
|
||||||
|
item['response'] as List<dynamic>? ??
|
||||||
|
[];
|
||||||
final card_logo = item['card_logo'];
|
final card_logo = item['card_logo'];
|
||||||
final data = apiService.processNonChartData(item);
|
final data =
|
||||||
|
apiService.processNonChartData(item);
|
||||||
print('processNonChartData');
|
print('processNonChartData');
|
||||||
|
|
||||||
double cardHeight = (chart_type == 'totals' ||
|
double cardHeight =
|
||||||
|
(chart_type == 'totals' ||
|
||||||
chart_type == 'averages')
|
chart_type == 'averages')
|
||||||
? 180.0
|
? 180.0
|
||||||
: 130.0;
|
: 130.0;
|
||||||
@ -2278,38 +2285,50 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
return Container(
|
return Container(
|
||||||
margin: const EdgeInsets.all(10),
|
margin: const EdgeInsets.all(10),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius:
|
||||||
|
BorderRadius.circular(12),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: Color(int.parse(
|
color: Color(int.parse(
|
||||||
(chartScreenData['border_color']?? '#898C81')
|
(chartScreenData[
|
||||||
.replaceFirst('#', '0xff'))),
|
'border_color'] ??
|
||||||
|
'#898C81')
|
||||||
|
.replaceFirst(
|
||||||
|
'#', '0xff'))),
|
||||||
// Dynamic border color
|
// Dynamic border color
|
||||||
width: 1, // Adjust border thickness
|
width:
|
||||||
|
1, // Adjust border thickness
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Card(
|
child: Card(
|
||||||
margin: const EdgeInsets.all(0),
|
margin: const EdgeInsets.all(0),
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius:
|
||||||
|
BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
elevation: 2,
|
elevation: 2,
|
||||||
child: Container(
|
child: Container(
|
||||||
height: cardHeight,
|
height: cardHeight,
|
||||||
padding: const EdgeInsets.only(left:16.0, right: 16.0, bottom: 1.0 , top: 1.0),
|
padding: const EdgeInsets.only(
|
||||||
|
left: 16.0,
|
||||||
|
right: 16.0,
|
||||||
|
bottom: 1.0,
|
||||||
|
top: 1.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisAlignment: MainAxisAlignment
|
mainAxisAlignment:
|
||||||
.center,
|
MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Image.network(
|
Image.network(
|
||||||
card_logo ?? '',
|
card_logo ?? '',
|
||||||
width: 30,
|
width: 30,
|
||||||
height: 30,
|
height: 30,
|
||||||
errorBuilder:
|
errorBuilder: (context,
|
||||||
(context, error, stackTrace) {
|
error, stackTrace) {
|
||||||
return Icon(Icons.public,
|
return Icon(Icons.public,
|
||||||
color: Color(0xFF90B0D5),
|
color:
|
||||||
size: 30); // Fallback icon
|
Color(0xFF90B0D5),
|
||||||
|
size:
|
||||||
|
30); // Fallback icon
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 1),
|
const SizedBox(height: 1),
|
||||||
@ -2317,18 +2336,18 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
fit: FlexFit.loose,
|
fit: FlexFit.loose,
|
||||||
// child: FittedBox(
|
// child: FittedBox(
|
||||||
child: Text(
|
child: Text(
|
||||||
|
|
||||||
'${chart_heading ?? 'NA'}',
|
'${chart_heading ?? 'NA'}',
|
||||||
textAlign: TextAlign.center,
|
textAlign:
|
||||||
|
TextAlign.center,
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
// Limit to 2 lines
|
// Limit to 2 lines
|
||||||
softWrap:
|
softWrap: true,
|
||||||
true,
|
|
||||||
// Enable soft wrapping
|
// Enable soft wrapping
|
||||||
// overflow: TextOverflow.ellipsis, // Handle overflow gracefully
|
// overflow: TextOverflow.ellipsis, // Handle overflow gracefully
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 9,
|
fontSize: 9,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight:
|
||||||
|
FontWeight.w400,
|
||||||
color: Colors.black87,
|
color: Colors.black87,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -2339,14 +2358,16 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
fit: FlexFit.loose,
|
fit: FlexFit.loose,
|
||||||
child: FittedBox(
|
child: FittedBox(
|
||||||
child: Text(
|
child: Text(
|
||||||
'(${ response[0]['display_value'] ?? 'NA'})',
|
'(${response[0]['display_value'] ?? 'NA'})',
|
||||||
// '(${data['firstYear'] ??
|
// '(${data['firstYear'] ??
|
||||||
// 'NA'} - ${data['lastYear'] ??
|
// 'NA'} - ${data['lastYear'] ??
|
||||||
// 'NA'})',
|
// 'NA'})',
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 10,
|
fontSize: 10,
|
||||||
color: Colors.grey),
|
color: Colors.grey),
|
||||||
),),),
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
const SizedBox(height: 1),
|
const SizedBox(height: 1),
|
||||||
Flexible(
|
Flexible(
|
||||||
fit: FlexFit.loose,
|
fit: FlexFit.loose,
|
||||||
@ -2355,14 +2376,18 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
child: FittedBox(
|
child: FittedBox(
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
child: Text(
|
child: Text(
|
||||||
response[0]['value'] ?? 'NA',
|
response[0]
|
||||||
|
['value'] ??
|
||||||
|
'NA',
|
||||||
// '${data['roundedAverage'] ??
|
// '${data['roundedAverage'] ??
|
||||||
// 'NA'}',
|
// 'NA'}',
|
||||||
style: const TextStyle(
|
style:
|
||||||
|
const TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight
|
fontWeight:
|
||||||
.w900,
|
FontWeight.w900,
|
||||||
color: Color(0xFF90B0D5),
|
color: Color(
|
||||||
|
0xFF90B0D5),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -2372,24 +2397,29 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
} else {
|
||||||
else{
|
return Container(
|
||||||
return
|
|
||||||
Container(
|
|
||||||
margin: const EdgeInsets.all(10),
|
margin: const EdgeInsets.all(10),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius:
|
||||||
|
BorderRadius.circular(12),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: Color(int.parse((chartScreenData['border_color']?? '#898C81').replaceFirst('#', '0xff'))), // Dynamic border color
|
color: Color(int.parse((chartScreenData[
|
||||||
|
'border_color'] ??
|
||||||
|
'#898C81')
|
||||||
|
.replaceFirst('#',
|
||||||
|
'0xff'))), // Dynamic border color
|
||||||
width: 1, // Adjust border thickness
|
width: 1, // Adjust border thickness
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Card(
|
child: Card(
|
||||||
margin: const EdgeInsets.all(0),
|
margin: const EdgeInsets.all(0),
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius:
|
||||||
|
BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
elevation: 0, // Remove shadow to keep only the outli
|
elevation:
|
||||||
|
0, // Remove shadow to keep only the outli
|
||||||
|
|
||||||
child: Container(
|
child: Container(
|
||||||
height: cardHeight,
|
height: cardHeight,
|
||||||
@ -2397,7 +2427,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize
|
mainAxisSize: MainAxisSize
|
||||||
.min, // Adjust card height based on content
|
.min, // Adjust card height based on content
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
// const Icon(Icons.public,
|
// const Icon(Icons.public,
|
||||||
// color: Color(0xFF90B0D5), size: 30),
|
// color: Color(0xFF90B0D5), size: 30),
|
||||||
@ -2405,11 +2436,13 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
card_logo ?? '',
|
card_logo ?? '',
|
||||||
width: 30,
|
width: 30,
|
||||||
height: 30,
|
height: 30,
|
||||||
errorBuilder:
|
errorBuilder: (context, error,
|
||||||
(context, error, stackTrace) {
|
stackTrace) {
|
||||||
return Icon(Icons.public,
|
return Icon(Icons.public,
|
||||||
color: Color(0xFF90B0D5),
|
color:
|
||||||
size: 30); // Fallback icon
|
Color(0xFF90B0D5),
|
||||||
|
size:
|
||||||
|
30); // Fallback icon
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 3),
|
const SizedBox(height: 3),
|
||||||
@ -2421,14 +2454,17 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
'${chart_heading ?? 'NA'}',
|
'${chart_heading ?? 'NA'}',
|
||||||
// "TOTAL",
|
// "TOTAL",
|
||||||
textAlign: TextAlign.center,
|
textAlign:
|
||||||
maxLines: 2, // Limit to 2 lines
|
TextAlign.center,
|
||||||
|
maxLines:
|
||||||
|
2, // Limit to 2 lines
|
||||||
softWrap:
|
softWrap:
|
||||||
true, // Enable soft wrapping
|
true, // Enable soft wrapping
|
||||||
// overflow: TextOverflow.ellipsis, // Handle overflow gracefully
|
// overflow: TextOverflow.ellipsis, // Handle overflow gracefully
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 8,
|
fontSize: 8,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight:
|
||||||
|
FontWeight.w400,
|
||||||
color: Colors.black87,
|
color: Colors.black87,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -2441,7 +2477,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
|
|
||||||
// '(${data['lastYear'] ?? 'NA'})',
|
// '(${data['lastYear'] ?? 'NA'})',
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 10, color: Colors.grey),
|
fontSize: 10,
|
||||||
|
color: Colors.grey),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 1),
|
const SizedBox(height: 1),
|
||||||
Flexible(
|
Flexible(
|
||||||
@ -2449,7 +2486,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
child: FittedBox(
|
child: FittedBox(
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
child: Text(
|
child: Text(
|
||||||
response[0]['value'] ?? 'NA',
|
response[0]['value'] ??
|
||||||
|
'NA',
|
||||||
|
|
||||||
// apiService.formatAmount(
|
// apiService.formatAmount(
|
||||||
// data['lastYearValue']),
|
// data['lastYearValue']),
|
||||||
@ -2457,14 +2495,17 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
// data['lastYearValue']),
|
// data['lastYearValue']),
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight: FontWeight.w900,
|
fontWeight:
|
||||||
color: Color(0xFF90B0D5),
|
FontWeight.w900,
|
||||||
|
color:
|
||||||
|
Color(0xFF90B0D5),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 2, // Height of the divider
|
height:
|
||||||
|
2, // Height of the divider
|
||||||
child: Divider(
|
child: Divider(
|
||||||
color: Color(0xFFBBBCBD),
|
color: Color(0xFFBBBCBD),
|
||||||
thickness:
|
thickness:
|
||||||
@ -2476,33 +2517,35 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
child: FittedBox(
|
child: FittedBox(
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
child: Text(
|
child: Text(
|
||||||
response[1]['value'] ?? 'NA',
|
response[1]['value'] ??
|
||||||
|
'NA',
|
||||||
// apiService.formatAmount(
|
// apiService.formatAmount(
|
||||||
// data['secondLastYearValue']),
|
// data['secondLastYearValue']),
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight:
|
||||||
color: Color(0xFFD83731),
|
FontWeight.w600,
|
||||||
|
color:
|
||||||
|
Color(0xFFD83731),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
|
|
||||||
'(${response[1]['display_value'] ?? 'NA'})',
|
'(${response[1]['display_value'] ?? 'NA'})',
|
||||||
// '(${data['secondLastYear'] ?? 'NA'})',
|
// '(${data['secondLastYear'] ?? 'NA'})',
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 9,
|
fontSize: 9,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight:
|
||||||
|
FontWeight.w500,
|
||||||
color: Colors.grey),
|
color: Colors.grey),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),);
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -2517,17 +2560,21 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
ConstrainedBox(
|
ConstrainedBox(
|
||||||
constraints: const BoxConstraints(
|
constraints: const BoxConstraints(
|
||||||
minHeight: 200, // Minimum height
|
minHeight:
|
||||||
maxHeight: 400, // Maximum height
|
200, // Minimum height
|
||||||
|
maxHeight:
|
||||||
|
400, // Maximum height
|
||||||
),
|
),
|
||||||
// child: buildChart(chartsData[index]),
|
// child: buildChart(chartsData[index]),
|
||||||
child: ChartWidget(
|
child: ChartWidget(
|
||||||
chartData: chartsData[index])),
|
chartData:
|
||||||
|
chartsData[index])),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -2542,7 +2589,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),);
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildArrowButton(
|
Widget _buildArrowButton(
|
||||||
|
|||||||
@ -231,6 +231,15 @@ class ChartWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
Text(
|
||||||
|
chartData['chart_sub_heading'] ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
SizedBox(height: 20),
|
SizedBox(height: 20),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ValueListenableBuilder<int?>(
|
child: ValueListenableBuilder<int?>(
|
||||||
@ -307,6 +316,15 @@ class ChartWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
Text(
|
||||||
|
chartData['chart_sub_heading'] ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
AspectRatio(
|
AspectRatio(
|
||||||
aspectRatio: 1.5,
|
aspectRatio: 1.5,
|
||||||
@ -522,6 +540,15 @@ class ChartWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
Text(
|
||||||
|
chartData['chart_sub_heading'] ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
// Chart
|
// Chart
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -624,6 +651,15 @@ class ChartWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
Text(
|
||||||
|
chartData['chart_sub_heading'] ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
|
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -631,8 +667,8 @@ class ChartWidget extends StatelessWidget {
|
|||||||
scrollDirection: Axis.horizontal, // Enable horizontal scrolling
|
scrollDirection: Axis.horizontal, // Enable horizontal scrolling
|
||||||
padding: const EdgeInsets.only(right: 40),
|
padding: const EdgeInsets.only(right: 40),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: (uniqueXValues.length * 80) +
|
width: (uniqueXValues.length * 50) +
|
||||||
80, // Adjust width dynamically
|
50, // Adjust width dynamically
|
||||||
child: LineChart(LineChartData(
|
child: LineChart(LineChartData(
|
||||||
lineTouchData: lineTouchData1(),
|
lineTouchData: lineTouchData1(),
|
||||||
gridData: gridData(),
|
gridData: gridData(),
|
||||||
@ -735,6 +771,15 @@ class ChartWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
Text(
|
||||||
|
chartData['chart_sub_heading'] ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
// Chart
|
// Chart
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -742,8 +787,8 @@ class ChartWidget extends StatelessWidget {
|
|||||||
scrollDirection: Axis.horizontal, // Enable horizontal scrolling
|
scrollDirection: Axis.horizontal, // Enable horizontal scrolling
|
||||||
padding: const EdgeInsets.only(right: 40),
|
padding: const EdgeInsets.only(right: 40),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: (uniqueXValues.length * 80) +
|
width: (uniqueXValues.length * 50) +
|
||||||
80, // Adjust width dynamically
|
50, // Adjust width dynamically
|
||||||
child: LineChart(
|
child: LineChart(
|
||||||
LineChartData(
|
LineChartData(
|
||||||
lineTouchData: lineTouchData1(),
|
lineTouchData: lineTouchData1(),
|
||||||
@ -753,6 +798,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
lineBarsData: lineBars,
|
lineBarsData: lineBars,
|
||||||
minX: uniqueXValues.reduce((a, b) => a < b ? a : b),
|
minX: uniqueXValues.reduce((a, b) => a < b ? a : b),
|
||||||
maxX: uniqueXValues.reduce((a, b) => a > b ? a : b),
|
maxX: uniqueXValues.reduce((a, b) => a > b ? a : b),
|
||||||
|
minY: 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -781,6 +827,15 @@ class ChartWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
Text(
|
||||||
|
chartData['chart_sub_heading'] ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
// Chart
|
// Chart
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -888,6 +943,15 @@ class ChartWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
Text(
|
||||||
|
chartData['chart_sub_heading'] ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
// Chart
|
// Chart
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -1019,6 +1083,15 @@ class ChartWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
Text(
|
||||||
|
chartData['chart_sub_heading'] ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
// Chart
|
// Chart
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -1224,6 +1297,15 @@ class ChartWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
Text(
|
||||||
|
chartData['chart_sub_heading'] ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
// Chart
|
// Chart
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -1790,12 +1872,15 @@ class ChartWidget extends StatelessWidget {
|
|||||||
bottomTitles: AxisTitles(
|
bottomTitles: AxisTitles(
|
||||||
sideTitles: SideTitles(
|
sideTitles: SideTitles(
|
||||||
showTitles: true,
|
showTitles: true,
|
||||||
interval: 1, // Ensure each year is shown only once
|
interval: 10, // Ensure each year is shown only once
|
||||||
getTitlesWidget: (value, meta) {
|
getTitlesWidget: (value, meta) {
|
||||||
if (xValues.contains(value)) {
|
if (xValues.contains(value)) {
|
||||||
return Text(
|
return Transform.rotate(
|
||||||
|
angle: -0.5, // Slight rotation to improve readability
|
||||||
|
child: Text(
|
||||||
value.toInt().toString(),
|
value.toInt().toString(),
|
||||||
style: TextStyle(color: Colors.black, fontSize: 12),
|
style: TextStyle(color: Colors.black, fontSize: 12),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return SizedBox.shrink(); // Hide non-relevant labels
|
return SizedBox.shrink(); // Hide non-relevant labels
|
||||||
|
|||||||
@ -21,6 +21,7 @@ class _ManageUserRouterState extends State<ManageUserRouter> {
|
|||||||
int _sortColumnIndex = 0;
|
int _sortColumnIndex = 0;
|
||||||
bool _isAscending = true;
|
bool _isAscending = true;
|
||||||
List<User> filteredUserData = [];
|
List<User> filteredUserData = [];
|
||||||
|
bool isLoading = true;
|
||||||
|
|
||||||
// final List<String> statusOptions = ['Approved', 'Denied', 'Pending'];
|
// final List<String> statusOptions = ['Approved', 'Denied', 'Pending'];
|
||||||
|
|
||||||
@ -52,9 +53,9 @@ class _ManageUserRouterState extends State<ManageUserRouter> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
|
isLoading = true;
|
||||||
userData = result.map((record) {
|
userData = result.map((record) {
|
||||||
final createdDate =
|
final createdDate = DateTime.parse(record.created).add(Duration(hours: 4));// Parse the created date
|
||||||
DateTime.parse(record.created); // Parse the created date
|
|
||||||
final formattedDate = DateFormat('dd/MM/yyyy').format(createdDate);
|
final formattedDate = DateFormat('dd/MM/yyyy').format(createdDate);
|
||||||
return User(
|
return User(
|
||||||
id: record.id, // Correctly passing the ID
|
id: record.id, // Correctly passing the ID
|
||||||
@ -64,7 +65,17 @@ class _ManageUserRouterState extends State<ManageUserRouter> {
|
|||||||
status: record.getStringValue('status'),
|
status: record.getStringValue('status'),
|
||||||
);
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
|
userData.sort((a,b){
|
||||||
|
DateTime dateA= DateFormat('dd/MM/yyyy').parse(a.registrationDate);
|
||||||
|
DateTime dateB = DateFormat('dd/MM/yyyy').parse(b.registrationDate);
|
||||||
|
return dateB.compareTo(dateA);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
filteredUserData = List.from(userData);
|
filteredUserData = List.from(userData);
|
||||||
|
|
||||||
|
isLoading = false;
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error fetching unverified users: $e');
|
print('Error fetching unverified users: $e');
|
||||||
@ -337,6 +348,7 @@ class _ManageUserRouterState extends State<ManageUserRouter> {
|
|||||||
image: ExactAssetImage(MiscIconAssetPath.search),
|
image: ExactAssetImage(MiscIconAssetPath.search),
|
||||||
width: 24,
|
width: 24,
|
||||||
height: 24,
|
height: 24,
|
||||||
|
color: Color(0xFFAA8E83)
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
||||||
@ -348,10 +360,13 @@ class _ManageUserRouterState extends State<ManageUserRouter> {
|
|||||||
contentPadding:
|
contentPadding:
|
||||||
EdgeInsets.symmetric(vertical: 8.0, horizontal: 18.0),
|
EdgeInsets.symmetric(vertical: 8.0, horizontal: 18.0),
|
||||||
),
|
),
|
||||||
|
onChanged: filterUsers,
|
||||||
),),
|
),),
|
||||||
),
|
),
|
||||||
SizedBox(height: myheight / 40),
|
SizedBox(height: myheight / 40),
|
||||||
filteredUserData.isEmpty
|
isLoading
|
||||||
|
? Center(child: CircularProgressIndicator())
|
||||||
|
:filteredUserData.isEmpty
|
||||||
? Center(
|
? Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:pocketbase/pocketbase.dart';
|
||||||
import '../../custom_drawer_routes.dart';
|
import '../../custom_drawer_routes.dart';
|
||||||
|
|
||||||
class NotificationPage extends StatefulWidget {
|
class NotificationPage extends StatefulWidget {
|
||||||
@ -9,23 +11,63 @@ class NotificationPage extends StatefulWidget {
|
|||||||
|
|
||||||
class _NotificationPageState extends State<NotificationPage> {
|
class _NotificationPageState extends State<NotificationPage> {
|
||||||
// Example notification data
|
// Example notification data
|
||||||
List<Map<String, dynamic>> notifications = [
|
final _pb = PocketBase('https://pb.venbait.in');
|
||||||
{"title": "Social datasets are updated", "date": "04 Nov 2024 08:25 PM", "category": "Social"},
|
List<Map<String, dynamic>> notifications = [];
|
||||||
{"title": "New feature updated", "date": "04 Nov 2024 08:25 PM", "category": "App updates"},
|
|
||||||
];
|
|
||||||
|
|
||||||
// Current selected tab index
|
// Current selected tab index
|
||||||
int selectedTabIndex = 0;
|
int selectedTabIndex = 0;
|
||||||
|
|
||||||
// Tab categories
|
// Tab categories
|
||||||
final List<String> tabs = ["All updates", "App updates", "Social", "Economy", "Environment", "Favourites"];
|
final List<String> tabs = [
|
||||||
|
"All updates",
|
||||||
|
"App updates",
|
||||||
|
"Social",
|
||||||
|
"Economy",
|
||||||
|
"Environment",
|
||||||
|
"Favourites"
|
||||||
|
];
|
||||||
|
|
||||||
|
String formatDate(String dateString) {
|
||||||
|
try {
|
||||||
|
DateTime dateTime =
|
||||||
|
DateTime.parse(dateString); // Convert API date to DateTime
|
||||||
|
return DateFormat('dd MMM yyyy hh:mm a')
|
||||||
|
.format(dateTime); // Format DateTime
|
||||||
|
} catch (e) {
|
||||||
|
return 'Invalid Date'; // Handle parsing errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> fetchNotifications() async {
|
||||||
|
try {
|
||||||
|
await _pb.admins
|
||||||
|
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
|
||||||
|
|
||||||
|
final result = await _pb.collection('notification').getFullList();
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
notifications = result.map((record) => record.toJson()).toList();
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
print('Error fetching notifications: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
fetchNotifications();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// Filter notifications based on the selected tab
|
// Filter notifications based on the selected tab
|
||||||
List<Map<String, dynamic>> filteredNotifications = selectedTabIndex == 0
|
List<Map<String, dynamic>> filteredNotifications = selectedTabIndex == 0
|
||||||
? notifications
|
? notifications
|
||||||
: notifications.where((notification) => notification["category"] == tabs[selectedTabIndex]).toList();
|
: notifications
|
||||||
|
.where((notification) =>
|
||||||
|
notification["category"] == tabs[selectedTabIndex])
|
||||||
|
.toList();
|
||||||
|
|
||||||
return PopScope(
|
return PopScope(
|
||||||
canPop: false,
|
canPop: false,
|
||||||
@ -72,11 +114,13 @@ class _NotificationPageState extends State<NotificationPage> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.info_outline, size: 100, color: Colors.grey[400]),
|
Icon(Icons.info_outline,
|
||||||
|
size: 100, color: Colors.grey[400]),
|
||||||
SizedBox(height: 16),
|
SizedBox(height: 16),
|
||||||
Text(
|
Text(
|
||||||
'No notifications available.',
|
'No notifications available.',
|
||||||
style: TextStyle(fontSize: 16, color: Colors.grey),
|
style:
|
||||||
|
TextStyle(fontSize: 16, color: Colors.grey),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -86,9 +130,9 @@ class _NotificationPageState extends State<NotificationPage> {
|
|||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final notification = filteredNotifications[index];
|
final notification = filteredNotifications[index];
|
||||||
return NotificationTile(
|
return NotificationTile(
|
||||||
title: notification["title"]!,
|
title: notification['title'] ?? 'No Title',
|
||||||
date: notification["date"]!,
|
date: formatDate(notification['created'] ?? ''),
|
||||||
category: notification["category"]!,
|
category: notification['category'] ?? 'Unknown',
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -128,8 +172,11 @@ class TabBarHeader extends StatelessWidget {
|
|||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => onTabSelected(index),
|
onPressed: () => onTabSelected(index),
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
foregroundColor: MaterialStateProperty.resolveWith((states) {
|
foregroundColor:
|
||||||
return selectedIndex == index ? Color(0xFF985400) : Colors.grey[700];
|
MaterialStateProperty.resolveWith((states) {
|
||||||
|
return selectedIndex == index
|
||||||
|
? Color(0xFF985400)
|
||||||
|
: Colors.grey[700];
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
child: Text(text),
|
child: Text(text),
|
||||||
@ -169,7 +216,8 @@ class NotificationTile extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: Icon(Icons.circle, size: 12, color: category == "Social" ? Colors.red : Colors.grey),
|
leading: Icon(Icons.circle,
|
||||||
|
size: 12, color: category == "Social" ? Colors.red : Colors.grey),
|
||||||
title: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)),
|
title: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||||
subtitle: Text(date),
|
subtitle: Text(date),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -698,9 +698,9 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
leading: Padding(
|
leading: Padding(
|
||||||
padding: const EdgeInsets.only(top: 7.0,left: 4),
|
padding: const EdgeInsets.only(top: 7.0, left: 4),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize:MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
if (widget.showBackButton == true)
|
if (widget.showBackButton == true)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
@ -721,7 +721,9 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(width: 7,),
|
SizedBox(
|
||||||
|
width: 7,
|
||||||
|
),
|
||||||
Builder(
|
Builder(
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
@ -743,8 +745,6 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|
||||||
),
|
),
|
||||||
drawer: Drawer(
|
drawer: Drawer(
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
@ -824,7 +824,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
|||||||
if (userId != 'guest')
|
if (userId != 'guest')
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.notifications_none),
|
leading: Icon(Icons.notifications_none),
|
||||||
title: const Text('Notification'),
|
title: Text(AppLocalizations.of(context)!.notification),
|
||||||
onTap: () => _navigateTo(context, '/notification'),
|
onTap: () => _navigateTo(context, '/notification'),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
@ -837,7 +837,8 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
|||||||
// ),
|
// ),
|
||||||
// title: const Text('Feedback'),
|
// title: const Text('Feedback'),
|
||||||
title: Text(AppLocalizations.of(context)!.feedback_title),
|
title: Text(AppLocalizations.of(context)!.feedback_title),
|
||||||
onTap: () => _navigateTo(context, '/feedback', extra: userName),
|
onTap: () =>
|
||||||
|
_navigateTo(context, '/feedback', extra: userName),
|
||||||
),
|
),
|
||||||
if (role == 'admin')
|
if (role == 'admin')
|
||||||
ListTile(
|
ListTile(
|
||||||
@ -1012,6 +1013,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
|||||||
body: widget.body,
|
body: widget.body,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//drawer close code
|
//drawer close code
|
||||||
void _navigateTo(BuildContext context, String route, {Object? extra}) {
|
void _navigateTo(BuildContext context, String route, {Object? extra}) {
|
||||||
Navigator.pop(context); // Close the drawer
|
Navigator.pop(context); // Close the drawer
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
name: uae_stat
|
name: uae_stat
|
||||||
description: "View statistics about the UAE from the Federal Center for Statistics and Competitiveness."
|
description: "View statistics about the UAE from the Federal Center for Statistics and Competitiveness."
|
||||||
publish_to: "none"
|
publish_to: "none"
|
||||||
version: 1.0.16+17
|
version: 1.0.19+20
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.2.3 <4.0.0"
|
sdk: ">=3.2.3 <4.0.0"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user