Bug Fix - Manage User

This commit is contained in:
Juki-shiba 2025-02-17 18:32:56 +05:30
commit e25ddaafd1
10 changed files with 1188 additions and 1088 deletions

View File

@ -15,12 +15,12 @@ if (localPropertiesFile.exists()) {
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
if (flutterVersionCode == null) {
flutterVersionCode = "16"
flutterVersionCode = "20"
}
def flutterVersionName = localProperties.getProperty("flutter.versionName")
if (flutterVersionName == null) {
flutterVersionName = "1.0.15"
flutterVersionName = "1.0.19"
}
//def keystorePropertiesFile = rootProject.file("key.properties")

View File

@ -15,6 +15,11 @@
"exit": "خروج",
"bookmark_title": "إشارة مرجعية",
"failed_To_Remove": "فشلت الإزالة",
"removed_from_Bookmark": "تمت الإزالة من الإشارة المرجعية",
"added_to_Bookmark":"تمت إضافته إلى الإشارة المرجعية",
"guide_title": "نموذج الملاحظات",
"notification": "إشعار",
"guide_title": "نموذج الملاحظات",

View File

@ -16,6 +16,10 @@
"cancel": "Cancel",
"exit": "Exit",
"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_details": "Please enter your details",

View File

@ -188,7 +188,7 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
}
@override
Widget build(BuildContext contextx) {
Widget build(BuildContext context) {
double screenHeight = MediaQuery.of(context).size.height;
double screenWidth = MediaQuery.of(context).size.width;
final passwordLocale = ref.watch(localeProvider);

File diff suppressed because it is too large Load Diff

View File

@ -231,6 +231,15 @@ class ChartWidget extends StatelessWidget {
),
textAlign: TextAlign.center,
),
SizedBox(height: 5),
Text(
chartData['chart_sub_heading'] ?? '',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w300,
),
textAlign: TextAlign.center,
),
SizedBox(height: 20),
Expanded(
child: ValueListenableBuilder<int?>(
@ -261,21 +270,23 @@ class ChartWidget extends StatelessWidget {
),
),
SizedBox(height: 25),
Flexible(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
constraints: BoxConstraints(minHeight: 5), // Allow dynamic height
constraints:
BoxConstraints(minHeight: 5), // Allow dynamic height
child: Padding(
padding: const EdgeInsets.only(left: 8.0 ,right: 8.0,bottom: 8.0,top:20.0),
child: Wrap(
spacing: 12,
runSpacing: 8,
children: generateIndicators(chartData, chartData['group_by']),
),
),
),
padding: const EdgeInsets.only(
left: 8.0, right: 8.0, bottom: 8.0, top: 20.0),
child: Wrap(
spacing: 12,
runSpacing: 8,
children:
generateIndicators(chartData, chartData['group_by']),
),
),
),
),
),
],
@ -305,6 +316,15 @@ class ChartWidget extends StatelessWidget {
),
textAlign: TextAlign.center,
),
SizedBox(height: 5),
Text(
chartData['chart_sub_heading'] ?? '',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w300,
),
textAlign: TextAlign.center,
),
SizedBox(height: 10),
AspectRatio(
aspectRatio: 1.5,
@ -520,6 +540,15 @@ class ChartWidget extends StatelessWidget {
),
textAlign: TextAlign.center,
),
SizedBox(height: 5),
Text(
chartData['chart_sub_heading'] ?? '',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w300,
),
textAlign: TextAlign.center,
),
SizedBox(height: 10),
// Chart
Expanded(
@ -622,6 +651,15 @@ class ChartWidget extends StatelessWidget {
),
textAlign: TextAlign.center,
),
SizedBox(height: 5),
Text(
chartData['chart_sub_heading'] ?? '',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w300,
),
textAlign: TextAlign.center,
),
SizedBox(height: 10),
Expanded(
@ -629,8 +667,8 @@ class ChartWidget extends StatelessWidget {
scrollDirection: Axis.horizontal, // Enable horizontal scrolling
padding: const EdgeInsets.only(right: 40),
child: SizedBox(
width: (uniqueXValues.length * 80) +
80, // Adjust width dynamically
width: (uniqueXValues.length * 50) +
50, // Adjust width dynamically
child: LineChart(LineChartData(
lineTouchData: lineTouchData1(),
gridData: gridData(),
@ -733,6 +771,15 @@ class ChartWidget extends StatelessWidget {
),
textAlign: TextAlign.center,
),
SizedBox(height: 5),
Text(
chartData['chart_sub_heading'] ?? '',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w300,
),
textAlign: TextAlign.center,
),
SizedBox(height: 10),
// Chart
Expanded(
@ -740,8 +787,8 @@ class ChartWidget extends StatelessWidget {
scrollDirection: Axis.horizontal, // Enable horizontal scrolling
padding: const EdgeInsets.only(right: 40),
child: SizedBox(
width: (uniqueXValues.length * 80) +
80, // Adjust width dynamically
width: (uniqueXValues.length * 50) +
50, // Adjust width dynamically
child: LineChart(
LineChartData(
lineTouchData: lineTouchData1(),
@ -751,6 +798,7 @@ class ChartWidget extends StatelessWidget {
lineBarsData: lineBars,
minX: uniqueXValues.reduce((a, b) => a < b ? a : b),
maxX: uniqueXValues.reduce((a, b) => a > b ? a : b),
minY: 0,
),
),
),
@ -779,6 +827,15 @@ class ChartWidget extends StatelessWidget {
),
textAlign: TextAlign.center,
),
SizedBox(height: 5),
Text(
chartData['chart_sub_heading'] ?? '',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w300,
),
textAlign: TextAlign.center,
),
SizedBox(height: 10),
// Chart
Expanded(
@ -886,6 +943,15 @@ class ChartWidget extends StatelessWidget {
),
textAlign: TextAlign.center,
),
SizedBox(height: 5),
Text(
chartData['chart_sub_heading'] ?? '',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w300,
),
textAlign: TextAlign.center,
),
SizedBox(height: 10),
// Chart
Expanded(
@ -896,7 +962,22 @@ class ChartWidget extends StatelessWidget {
? yAxisData.reduce((a, b) => a > b ? a : b) * 1.2
: 10,
rotationQuarterTurns: rotationTurns,
barTouchData: BarTouchData(enabled: true),
barTouchData: BarTouchData(
enabled: true,
handleBuiltInTouches: true,
touchTooltipData: BarTouchTooltipData(
fitInsideHorizontally: true,
fitInsideVertically: true,
tooltipPadding: const EdgeInsets.all(8),
tooltipMargin: 16,
getTooltipItem: (group, groupIndex, rod, rodIndex) {
return BarTooltipItem(
'${rod.toY.toStringAsFixed(1)}',
const TextStyle(color: Colors.white),
);
},
),
),
titlesData: FlTitlesData(
leftTitles: AxisTitles(
sideTitles: SideTitles(
@ -925,11 +1006,11 @@ class ChartWidget extends StatelessWidget {
// angle: -45 *
// (3.1415927 / 180), // Rotating by -45 degrees
alignment: Alignment.center,
child: Center(
child: Center(
child: SizedBox(
width: 100,
child: Text(
xAxisData[value.toInt()],
xAxisData[value.toInt()],
style: const TextStyle(fontSize: 12),
softWrap: true,
maxLines: 2,
@ -977,39 +1058,15 @@ class ChartWidget extends StatelessWidget {
const double barWidth = 30; // Width for each bar, including spacing
return totalBars * barWidth; // Calculate total chart width
}
String cropKey = chartData['chart_type_json']['x_sub_group'];
// Group crops by CROP_TYPE
Map<String, List<String>> groupedCrops = {};
int touchedGroupIndex = -1;
// Iterate over the chartData to group crops by CROP_TYPE
for (var item in chartData['response']) {
String crop, cropType;
if (chartData['dataset'] == 'health_services') {
crop = item['ObsKey']['SECTOR'];
cropType = item['ObsKey'][groupByKey];
} else if (chartData['dataset'] == 'general_education') {
print(chartData['dataset'] == 'general_education');
crop = item['ObsKey']['GENDER'];
cropType = item['ObsKey'][groupByKey];
} else if (chartData['dataset'] == 'higher_education') {
crop = item['ObsKey']['GENDER'];
cropType = item['ObsKey'][groupByKey];
} else if (chartData['dataset'] == 'labour_force') {
crop = item['ObsKey']['GENDER'];
cropType = item['ObsKey'][groupByKey];
} else if (chartData['dataset'] == 'clinics') {
if (kDebugMode) {
print('forclinics');
print('ObsKey: ${item['ObsKey']}');
// print('NR_TYPE: ${item['ObsKey']?['NR_TYPE']}');
}
crop = item['ObsKey']['MEASURE'];
cropType = item['ObsKey'][groupByKey];
} else {
crop = item['ObsKey']['CROP'];
cropType = item['ObsKey'][groupByKey];
}
crop = item['ObsKey'][cropKey];
cropType = item['ObsKey'][groupByKey];
if (groupedCrops.containsKey(cropType)) {
groupedCrops[cropType]!.add(crop);
@ -1026,6 +1083,15 @@ class ChartWidget extends StatelessWidget {
),
textAlign: TextAlign.center,
),
SizedBox(height: 5),
Text(
chartData['chart_sub_heading'] ?? '',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w300,
),
textAlign: TextAlign.center,
),
SizedBox(height: 10),
// Chart
Expanded(
@ -1187,64 +1253,17 @@ class ChartWidget extends StatelessWidget {
]);
case 'horizontal_rotate':
String cropKey = chartData['chart_type_json']
['y_sub_group']; // Dynamically get crop key
// Group crops by CROP_TYPE
Map<String, List<String>> groupedCrops = {};
// Iterate over the chartData to group crops by CROP_TYPE
for (var item in chartData['response']) {
String crop, cropType;
if (chartData['dataset'] == 'natural_reserves') {
crop = item['ObsKey']['NR_TYPE'];
cropType = item['ObsKey'][groupByKey];
}
else if(chartData['dataset'] == 'gdp')
{
print("ForGDP");
if (kDebugMode) {
print('ObsKey: ${item['ObsKey']}');
// print('NR_TYPE: ${item['ObsKey']?['NR_TYPE']}');
}
crop = item['ObsKey']['BOP_ITEM'];
cropType = item['ObsKey'][groupByKey];
} else if(chartData['dataset'] == 'air_transport')
{
print("Forair_transport");
if (kDebugMode) {
print('ObsKey: ${item['ObsKey']}');
// print('NR_TYPE: ${item['ObsKey']?['NR_TYPE']}');
}
crop = item['ObsKey']['MEASURE'];
cropType = item['ObsKey'][groupByKey];
} else if(chartData['dataset'] == 'import')
{
print("Forimport");
if (kDebugMode) {
print('ObsKey: ${item['ObsKey']}');
// print('NR_TYPE: ${item['ObsKey']?['NR_TYPE']}');
}
crop = item['ObsKey']['COUNTRY'];
cropType = item['ObsKey'][groupByKey];
}
else if(chartData['dataset'] == 'gdpq')
{
print("ForGDPq");
if (kDebugMode) {
print('ObsKey: ${item['ObsKey']}');
}
crop = item['ObsKey']['MEASURE'];
// crop = item['ObsKey']['TIME_PERIOD'];
cropType = item['ObsKey'][groupByKey];
}
else {
crop = item['ObsKey']['CROP'];
cropType = item['ObsKey'][groupByKey];
}
// crop = item['ObsKey']['CROP'];
crop = item['ObsKey'][cropKey];
cropType = item['ObsKey'][groupByKey];
if (groupedCrops.containsKey(cropType)) {
groupedCrops[cropType]!.add(crop);
@ -1257,16 +1276,17 @@ class ChartWidget extends StatelessWidget {
int rotationTurns = 1;
print('Grouped Crops: $groupedCrops');
int numberOfBars = groupedCrops.length; // Number of grouped sets (bar groups)
int numberOfBars =
groupedCrops.length; // Number of grouped sets (bar groups)
double barHeight = 40.0; // Height per individual bar
double barSpacing = 30.0; // Space between bar sets
double minHeight = 300.0; // Minimum chart height
double maxHeight = 1000.0; // Maximum chart height
// Calculate total height dynamically
double chartHeight = ((numberOfBars * barHeight) + ((numberOfBars - 1) * barSpacing))
.clamp(minHeight, maxHeight);
double chartHeight =
((numberOfBars * barHeight) + ((numberOfBars - 1) * barSpacing))
.clamp(minHeight, maxHeight);
return Column(children: [
Text(
@ -1277,169 +1297,184 @@ class ChartWidget extends StatelessWidget {
),
textAlign: TextAlign.center,
),
SizedBox(height: 5),
Text(
chartData['chart_sub_heading'] ?? '',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w300,
),
textAlign: TextAlign.center,
),
SizedBox(height: 10),
// Chart
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child:SizedBox(
width: 1000,
height: chartHeight,
child: BarChart(
BarChartData(
maxY: 400000,
rotationQuarterTurns: rotationTurns,
barTouchData: BarTouchData(
touchTooltipData: BarTouchTooltipData(
tooltipHorizontalAlignment: FLHorizontalAlignment.center,
tooltipRoundedRadius: 8,
fitInsideHorizontally:
true, // Ensure it fits within the screen
fitInsideVertically: true,
tooltipPadding: EdgeInsets.all(8),
tooltipMargin: 16,
// Only show tooltip when touched
getTooltipItem: (group, groupIndex, rod, rodIndex) {
if (rod.toY == 0 || touchedGroupIndex == -1) {
return null; // Don't show the tooltip if the value is 0 or there's no touch
}
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SizedBox(
width: 1000,
height: chartHeight,
child: BarChart(
BarChartData(
maxY: 400000,
rotationQuarterTurns: rotationTurns,
barTouchData: BarTouchData(
touchTooltipData: BarTouchTooltipData(
tooltipHorizontalAlignment:
FLHorizontalAlignment.center,
tooltipRoundedRadius: 8,
fitInsideHorizontally:
true, // Ensure it fits within the screen
fitInsideVertically: true,
tooltipPadding: EdgeInsets.all(8),
tooltipMargin: 16,
// Only show tooltip when touched
getTooltipItem: (group, groupIndex, rod, rodIndex) {
if (rod.toY == 0 || touchedGroupIndex == -1) {
return null; // Don't show the tooltip if the value is 0 or there's no touch
}
if (groupIndex == touchedGroupIndex) {
// print('Group Index: $groupIndex, Group : $group');
if (groupIndex == touchedGroupIndex) {
// print('Group Index: $groupIndex, Group : $group');
// Get the group label dynamically
String groupLabel = groupByValues.elementAt(groupIndex);
// Get the group label dynamically
String groupLabel =
groupByValues.elementAt(groupIndex);
// Fetch the crop for the current group from groupedCrops
String cropType = groupByValues.elementAt(groupIndex);
String crop = groupedCrops[cropType]![rodIndex];
double value = rod.toY;
// Fetch the crop for the current group from groupedCrops
String cropType =
groupByValues.elementAt(groupIndex);
String crop = groupedCrops[cropType]![rodIndex];
double value = rod.toY;
String formattedValue;
if (value >= 1000000) {
formattedValue =
(value / 1000000).toStringAsFixed(1) + 'M';
} else if (value >= 1000) {
formattedValue =
(value / 1000).toStringAsFixed(1) + 'K';
} else {
formattedValue = value.toStringAsFixed(
0); // for values smaller than 1000
}
String formattedValue;
if (value >= 1000000) {
formattedValue =
(value / 1000000).toStringAsFixed(1) + 'M';
} else if (value >= 1000) {
formattedValue =
(value / 1000).toStringAsFixed(1) + 'K';
} else {
formattedValue = value.toStringAsFixed(
0); // for values smaller than 1000
}
return BarTooltipItem(
'$groupLabel\n$crop',
const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
children: [
TextSpan(
text: ' Value: $formattedValue',
style: const TextStyle(
color: Colors.yellow,
fontWeight: FontWeight.w500,
return BarTooltipItem(
'$groupLabel\n$crop',
const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
],
);
}
return null;
},
),
touchCallback: (event, response) {
if (event.isInterestedForInteractions &&
response != null &&
response.spot != null) {
// setState(() {
touchedGroupIndex = response.spot!.touchedBarGroupIndex;
// });
} else {
// setState(() {
touchedGroupIndex = -1; // Reset if no interaction
// });
}
},
),
titlesData: FlTitlesData(
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: false,
reservedSize: 20,
interval: 100000,
getTitlesWidget: (value, meta) {
return Text(
value.toInt().toString(),
style: const TextStyle(fontSize: 12),
);
},
),
),
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 80, // Added space for rotated titles
getTitlesWidget: (value, meta) {
if (value < groupByValues.length) {
String title = groupByValues.elementAt(value.toInt());
return Transform.rotate(
angle: -1.58, // Rotation in radians (~ -30 degrees)
child: Center(
child: SizedBox(
width: 80,
child: Text(
title,
style: const TextStyle(fontSize: 12),
softWrap: true,
maxLines: 2,
children: [
TextSpan(
text: ' Value: $formattedValue',
style: const TextStyle(
color: Colors.yellow,
fontWeight: FontWeight.w500,
),
),
),
),
);
],
);
}
return null;
},
),
touchCallback: (event, response) {
if (event.isInterestedForInteractions &&
response != null &&
response.spot != null) {
// setState(() {
touchedGroupIndex =
response.spot!.touchedBarGroupIndex;
// });
} else {
// setState(() {
touchedGroupIndex = -1; // Reset if no interaction
// });
}
return const SizedBox.shrink();
},
),
),
rightTitles:
AxisTitles(sideTitles: SideTitles(showTitles: false)),
topTitles:
AxisTitles(sideTitles: SideTitles(showTitles: false)),
),
borderData: FlBorderData(
show: true,
border: const Border(
// left: BorderSide(color: Colors.grey),
bottom: BorderSide(color: Colors.white),
titlesData: FlTitlesData(
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: false,
reservedSize: 20,
interval: 100000,
getTitlesWidget: (value, meta) {
return Text(
value.toInt().toString(),
style: const TextStyle(fontSize: 12),
);
},
),
),
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 80, // Added space for rotated titles
getTitlesWidget: (value, meta) {
if (value < groupByValues.length) {
String title =
groupByValues.elementAt(value.toInt());
return Transform.rotate(
angle:
-1.58, // Rotation in radians (~ -30 degrees)
child: Center(
child: SizedBox(
width: 80,
child: Text(
title,
style: const TextStyle(fontSize: 12),
softWrap: true,
maxLines: 2,
),
),
),
);
}
return const SizedBox.shrink();
},
),
),
rightTitles:
AxisTitles(sideTitles: SideTitles(showTitles: false)),
topTitles:
AxisTitles(sideTitles: SideTitles(showTitles: false)),
),
borderData: FlBorderData(
show: true,
border: const Border(
// left: BorderSide(color: Colors.grey),
bottom: BorderSide(color: Colors.white),
),
),
gridData: FlGridData(
show: false,
drawVerticalLine: true,
verticalInterval: 1,
horizontalInterval: 100000,
getDrawingHorizontalLine: (value) {
return FlLine(
color: Colors.grey.withOpacity(0.5),
strokeWidth: 1,
);
},
getDrawingVerticalLine: (value) {
return FlLine(
color: Colors.grey.withOpacity(0.5),
strokeWidth: 1,
);
},
),
barGroups: _buildHorizontalRotateBarGroups(
chartData, groupByValues),
alignment: BarChartAlignment.spaceAround,
),
),
gridData: FlGridData(
show: false,
drawVerticalLine: true,
verticalInterval: 1,
horizontalInterval: 100000,
getDrawingHorizontalLine: (value) {
return FlLine(
color: Colors.grey.withOpacity(0.5),
strokeWidth: 1,
);
},
getDrawingVerticalLine: (value) {
return FlLine(
color: Colors.grey.withOpacity(0.5),
strokeWidth: 1,
);
},
),
barGroups:
_buildHorizontalRotateBarGroups(chartData, groupByValues),
alignment: BarChartAlignment.spaceAround,
),
),
),
),
)),
// Expanded(
// child: Stack(
@ -1837,12 +1872,15 @@ class ChartWidget extends StatelessWidget {
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
interval: 1, // Ensure each year is shown only once
interval: 10, // Ensure each year is shown only once
getTitlesWidget: (value, meta) {
if (xValues.contains(value)) {
return Text(
value.toInt().toString(),
style: TextStyle(color: Colors.black, fontSize: 12),
return Transform.rotate(
angle: -0.5, // Slight rotation to improve readability
child: Text(
value.toInt().toString(),
style: TextStyle(color: Colors.black, fontSize: 12),
),
);
} else {
return SizedBox.shrink(); // Hide non-relevant labels
@ -2109,9 +2147,8 @@ class ChartWidget extends StatelessWidget {
chartData['dataset'] == 'higher_education' ||
chartData['dataset'] == 'air_transport' ||
chartData['dataset'] == 'labour_force' ||
chartData['dataset'] == 'gdp'
) {
chartData['dataset'] == 'gdp' ||
chartData['dataset'] == 'clinics') {
barColor = uniqueColorsForTwo[colorIndex % uniqueColorsForTwo.length];
colorIndex++;
} else {

View File

@ -21,6 +21,7 @@ class _ManageUserRouterState extends State<ManageUserRouter> {
int _sortColumnIndex = 0;
bool _isAscending = true;
List<User> filteredUserData = [];
bool isLoading = true;
// final List<String> statusOptions = ['Approved', 'Denied', 'Pending'];
@ -52,9 +53,9 @@ class _ManageUserRouterState extends State<ManageUserRouter> {
);
setState(() {
isLoading = true;
userData = result.map((record) {
final createdDate =
DateTime.parse(record.created); // Parse the created date
final createdDate = DateTime.parse(record.created).add(Duration(hours: 4));// Parse the created date
final formattedDate = DateFormat('dd/MM/yyyy').format(createdDate);
return User(
id: record.id, // Correctly passing the ID
@ -64,7 +65,17 @@ class _ManageUserRouterState extends State<ManageUserRouter> {
status: record.getStringValue('status'),
);
}).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);
isLoading = false;
});
} catch (e) {
print('Error fetching unverified users: $e');
@ -338,6 +349,7 @@ class _ManageUserRouterState extends State<ManageUserRouter> {
image: ExactAssetImage(MiscIconAssetPath.search),
width: 24,
height: 24,
color: Color(0xFFAA8E83)
),
@ -349,10 +361,13 @@ class _ManageUserRouterState extends State<ManageUserRouter> {
contentPadding:
EdgeInsets.symmetric(vertical: 8.0, horizontal: 18.0),
),
onChanged: filterUsers,
),),
),
SizedBox(height: myheight / 40),
filteredUserData.isEmpty
isLoading
? Center(child: CircularProgressIndicator())
:filteredUserData.isEmpty
? Center(
child: Padding(
padding: const EdgeInsets.all(16.0),

View File

@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:intl/intl.dart';
import 'package:pocketbase/pocketbase.dart';
import '../../custom_drawer_routes.dart';
class NotificationPage extends StatefulWidget {
@ -9,23 +11,63 @@ class NotificationPage extends StatefulWidget {
class _NotificationPageState extends State<NotificationPage> {
// Example notification data
List<Map<String, dynamic>> notifications = [
{"title": "Social datasets are updated", "date": "04 Nov 2024 08:25 PM", "category": "Social"},
{"title": "New feature updated", "date": "04 Nov 2024 08:25 PM", "category": "App updates"},
];
final _pb = PocketBase('https://pb.venbait.in');
List<Map<String, dynamic>> notifications = [];
// Current selected tab index
int selectedTabIndex = 0;
// 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
Widget build(BuildContext context) {
// Filter notifications based on the selected tab
List<Map<String, dynamic>> filteredNotifications = selectedTabIndex == 0
? notifications
: notifications.where((notification) => notification["category"] == tabs[selectedTabIndex]).toList();
: notifications
.where((notification) =>
notification["category"] == tabs[selectedTabIndex])
.toList();
return PopScope(
canPop: false,
@ -49,49 +91,51 @@ class _NotificationPageState extends State<NotificationPage> {
Expanded(
child: selectedTabIndex == 1
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/backgrounds/Notification/Update_notific.png',
height: 200,
),
SizedBox(height: 16),
Text(
filteredNotifications.isNotEmpty
? filteredNotifications[0]['title']
: 'No updates available.',
style: TextStyle(fontSize: 16, color: Colors.grey),
textAlign: TextAlign.center,
),
],
),
)
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/backgrounds/Notification/Update_notific.png',
height: 200,
),
SizedBox(height: 16),
Text(
filteredNotifications.isNotEmpty
? filteredNotifications[0]['title']
: 'No updates available.',
style: TextStyle(fontSize: 16, color: Colors.grey),
textAlign: TextAlign.center,
),
],
),
)
: filteredNotifications.isEmpty
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.info_outline, size: 100, color: Colors.grey[400]),
SizedBox(height: 16),
Text(
'No notifications available.',
style: TextStyle(fontSize: 16, color: Colors.grey),
),
],
),
)
: ListView.builder(
itemCount: filteredNotifications.length,
itemBuilder: (context, index) {
final notification = filteredNotifications[index];
return NotificationTile(
title: notification["title"]!,
date: notification["date"]!,
category: notification["category"]!,
);
},
),
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.info_outline,
size: 100, color: Colors.grey[400]),
SizedBox(height: 16),
Text(
'No notifications available.',
style:
TextStyle(fontSize: 16, color: Colors.grey),
),
],
),
)
: ListView.builder(
itemCount: filteredNotifications.length,
itemBuilder: (context, index) {
final notification = filteredNotifications[index];
return NotificationTile(
title: notification['title'] ?? 'No Title',
date: formatDate(notification['created'] ?? ''),
category: notification['category'] ?? 'Unknown',
);
},
),
),
],
),
@ -128,8 +172,11 @@ class TabBarHeader extends StatelessWidget {
TextButton(
onPressed: () => onTabSelected(index),
style: ButtonStyle(
foregroundColor: MaterialStateProperty.resolveWith((states) {
return selectedIndex == index ? Color(0xFF985400) : Colors.grey[700];
foregroundColor:
MaterialStateProperty.resolveWith((states) {
return selectedIndex == index
? Color(0xFF985400)
: Colors.grey[700];
}),
),
child: Text(text),
@ -169,7 +216,8 @@ class NotificationTile extends StatelessWidget {
@override
Widget build(BuildContext context) {
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)),
subtitle: Text(date),
);

View File

@ -42,11 +42,11 @@ class BaseScaffold extends ConsumerStatefulWidget {
});
final Widget body;
final Widget title;
final Widget? navBackArrow;
final Widget? navBackArrow;
final Color? dividerColor;
final bool showDivider;
final bool showBackButton;
final bool colorChange;
final bool colorChange;
final bool? mycenterTitle;
final List<Widget>? actions;
final Color? bottomColor;
@ -640,7 +640,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Padding(
title: Padding(
padding: EdgeInsets.only(top: 10),
child: Align(
alignment: Alignment.centerLeft,
@ -698,9 +698,9 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
),
],
leading: Padding(
padding: const EdgeInsets.only(top: 7.0,left: 4),
padding: const EdgeInsets.only(top: 7.0, left: 4),
child: Row(
mainAxisSize:MainAxisSize.min,
mainAxisSize: MainAxisSize.min,
children: [
if (widget.showBackButton == true)
SizedBox(
@ -721,7 +721,9 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
},
),
),
SizedBox(width: 7,),
SizedBox(
width: 7,
),
Builder(
builder: (BuildContext context) {
return SizedBox(
@ -743,8 +745,6 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
],
),
),
),
drawer: Drawer(
backgroundColor: Colors.white,
@ -826,21 +826,22 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
if (userId != 'guest')
ListTile(
leading: Icon(Icons.notifications_none),
title: const Text('Notification'),
title: Text(AppLocalizations.of(context)!.notification),
onTap: () => _navigateTo(context, '/notification'),
),
ListTile(
leading: Icon(Icons.message_outlined),
// leading: Image.asset(
// DrawerAssetIconPath.feedback,
// color: Colors.black,
// width: 20,
// height: 20,
// ),
// title: const Text('Feedback'),
title: Text(AppLocalizations.of(context)!.feedback_title),
onTap: () => _navigateTo(context, '/feedback', extra: userName),
),
ListTile(
leading: Icon(Icons.message_outlined),
// leading: Image.asset(
// DrawerAssetIconPath.feedback,
// color: Colors.black,
// width: 20,
// height: 20,
// ),
// title: const Text('Feedback'),
title: Text(AppLocalizations.of(context)!.feedback_title),
onTap: () =>
_navigateTo(context, '/feedback', extra: userName),
),
if (role == 'admin')
ListTile(
leading: Icon(Icons.manage_accounts_outlined),
@ -1014,6 +1015,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
body: widget.body,
);
}
//drawer close code
void _navigateTo(BuildContext context, String route, {Object? extra}) {
Navigator.pop(context); // Close the drawer
@ -1051,4 +1053,4 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
break;
}
}
}
}

View File

@ -1,7 +1,7 @@
name: uae_stat
description: "View statistics about the UAE from the Federal Center for Statistics and Competitiveness."
publish_to: "none"
version: 1.0.15+16
version: 1.0.19+20
environment:
sdk: ">=3.2.3 <4.0.0"