notification bug fix
This commit is contained in:
parent
b5d0b38ac7
commit
44c21defa7
@ -22,7 +22,7 @@ class LoadingOverlay {
|
||||
color: Colors.black.withOpacity(0.5), dismissible: false),
|
||||
Center(
|
||||
child: Image.asset(
|
||||
"assets/images/loading.gif", // Make sure to add the GIF in assets
|
||||
"assets/FCSC-GIF.gif", // Make sure to add the GIF in assets
|
||||
width: 100,
|
||||
height: 100,
|
||||
),
|
||||
|
||||
@ -364,302 +364,305 @@ final FlutterSecureStorage _secureStorage = const FlutterSecureStorage();
|
||||
// }
|
||||
|
||||
final GoRouter router = GoRouter(
|
||||
initialLocation: '/',
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/',
|
||||
//builder: (context, state) => MyHomePage(),
|
||||
builder: (context, state) => SessionCheckScreen(),
|
||||
),
|
||||
// GoRoute(
|
||||
// path: '/',
|
||||
// redirect: (context, state) async => await _checkSession(),
|
||||
// ),
|
||||
GoRoute(
|
||||
path: '/internetcheck',
|
||||
builder: (context, state) => InternetCheck(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/login',
|
||||
builder: (context, state) => LoginRoute(),
|
||||
//builder: (context, state) => LoginRoute(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/myhomepage',
|
||||
builder: (context, state) => MyHomePage(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/register',
|
||||
builder: (context, state) => RegisterScreen(),
|
||||
),
|
||||
// GoRoute(
|
||||
// path: '/DemoHome/:dataSets',
|
||||
// builder: (context, state) {
|
||||
// final dataSets = state.pathParameters['dataSets']!;
|
||||
// print('Router $dataSets');
|
||||
// return ChartPage(dataSets: dataSets);
|
||||
// },
|
||||
// ),
|
||||
// GoRoute(
|
||||
// path: '/Chart/:dataSets',
|
||||
// builder: (context, state) {
|
||||
// final dataSets = state.pathParameters['dataSets']!;
|
||||
// print('Router $dataSets');
|
||||
// return ChartScreen(dataSets: dataSets);
|
||||
// },
|
||||
// ),
|
||||
GoRoute(
|
||||
path: '/chartScreen/:dataSets',
|
||||
builder: (context, state) {
|
||||
// Retrieve path parameter
|
||||
final dataSets = state.pathParameters['dataSets']!;
|
||||
// Retrieve query parameter
|
||||
final bgColor = state.uri.queryParameters['bgColor'] ??
|
||||
'0xFFFFFFFF'; // Default white
|
||||
final mainTopic = state.uri.queryParameters['mainTopic'] ?? '';
|
||||
final title = state.uri.queryParameters['title'] ?? '';
|
||||
final key = state.uri.queryParameters['key'] ?? '';
|
||||
final kpi = state.uri.queryParameters['kpi'] ?? ''; // Get kpi
|
||||
initialLocation: '/',
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/',
|
||||
//builder: (context, state) => MyHomePage(),
|
||||
builder: (context, state) => SessionCheckScreen(),
|
||||
),
|
||||
// GoRoute(
|
||||
// path: '/',
|
||||
// redirect: (context, state) async => await _checkSession(),
|
||||
// ),
|
||||
GoRoute(
|
||||
path: '/internetcheck',
|
||||
builder: (context, state) => InternetCheck(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/login',
|
||||
builder: (context, state) => LoginRoute(),
|
||||
//builder: (context, state) => LoginRoute(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/myhomepage',
|
||||
builder: (context, state) => MyHomePage(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/register',
|
||||
builder: (context, state) => RegisterScreen(),
|
||||
),
|
||||
// GoRoute(
|
||||
// path: '/DemoHome/:dataSets',
|
||||
// builder: (context, state) {
|
||||
// final dataSets = state.pathParameters['dataSets']!;
|
||||
// print('Router $dataSets');
|
||||
// return ChartPage(dataSets: dataSets);
|
||||
// },
|
||||
// ),
|
||||
// GoRoute(
|
||||
// path: '/Chart/:dataSets',
|
||||
// builder: (context, state) {
|
||||
// final dataSets = state.pathParameters['dataSets']!;
|
||||
// print('Router $dataSets');
|
||||
// return ChartScreen(dataSets: dataSets);
|
||||
// },
|
||||
// ),
|
||||
GoRoute(
|
||||
path: '/chartScreen/:dataSets',
|
||||
builder: (context, state) {
|
||||
// Retrieve path parameter
|
||||
final dataSets = state.pathParameters['dataSets']!;
|
||||
// Retrieve query parameter
|
||||
final bgColor = state.uri.queryParameters['bgColor'] ??
|
||||
'0xFFFFFFFF'; // Default white
|
||||
final mainTopic = state.uri.queryParameters['mainTopic'] ?? '';
|
||||
final title = state.uri.queryParameters['title'] ?? '';
|
||||
final key = state.uri.queryParameters['key'] ?? '';
|
||||
final kpi = state.uri.queryParameters['kpi'] ?? ''; // Get kpi
|
||||
|
||||
// Parse filter_data as a JSON list
|
||||
// Parse filter_data as a JSON list
|
||||
List<Map<String, dynamic>> filterData = [];
|
||||
// Parse filter_data as a JSON list
|
||||
// Parse filter_data as a JSON list
|
||||
List<Map<String, dynamic>> filterData = [];
|
||||
|
||||
if (state.uri.queryParameters.containsKey('filter_data') &&
|
||||
state.uri.queryParameters['filter_data']!.isNotEmpty) {
|
||||
try {
|
||||
filterData = List<Map<String, dynamic>>.from(
|
||||
jsonDecode(state.uri.queryParameters['filter_data']!));
|
||||
} catch (e) {
|
||||
print('Error parsing filter_data: $e');
|
||||
filterData = []; // Assign an empty list to prevent null issues
|
||||
if (state.uri.queryParameters.containsKey('filter_data') &&
|
||||
state.uri.queryParameters['filter_data']!.isNotEmpty) {
|
||||
try {
|
||||
filterData = List<Map<String, dynamic>>.from(
|
||||
jsonDecode(state.uri.queryParameters['filter_data']!));
|
||||
} catch (e) {
|
||||
print('Error parsing filter_data: $e');
|
||||
filterData = []; // Assign an empty list to prevent null issues
|
||||
}
|
||||
} else {
|
||||
filterData = []; // Ensure it's a valid list
|
||||
}
|
||||
} else {
|
||||
filterData = []; // Ensure it's a valid list
|
||||
}
|
||||
|
||||
print('Router dataSets: $dataSets');
|
||||
print('Router bgColor: $bgColor');
|
||||
print('Router mainTopic: $mainTopic');
|
||||
print('Router title: $title');
|
||||
print('Router filter: $filterData');
|
||||
print('Router dataSets: $dataSets');
|
||||
print('Router bgColor: $bgColor');
|
||||
print('Router mainTopic: $mainTopic');
|
||||
print('Router title: $title');
|
||||
print('Router filter: $filterData');
|
||||
|
||||
// Pass both values to the screen
|
||||
return ChartScreen1(
|
||||
dataSets: dataSets,
|
||||
bgColor: bgColor,
|
||||
mainTopic: mainTopic,
|
||||
title: title,
|
||||
keyParam: key,
|
||||
kpi: kpi,
|
||||
filter_data: filterData,
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/mailverification',
|
||||
builder: (context, state) => EmailVerificationScreen(
|
||||
email: '',
|
||||
userId: '',
|
||||
otp: '',
|
||||
otpId: '',
|
||||
sendVerificationCode: (String) {},
|
||||
// Pass both values to the screen
|
||||
return ChartScreen1(
|
||||
dataSets: dataSets,
|
||||
bgColor: bgColor,
|
||||
mainTopic: mainTopic,
|
||||
title: title,
|
||||
keyParam: key,
|
||||
kpi: kpi,
|
||||
filter_data: filterData,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/changepassword/:userId',
|
||||
builder: (context, state) {
|
||||
final userId = state.pathParameters['userId']!;
|
||||
return Changepassword(userId: userId);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/createNewPw/:userId/:email',
|
||||
builder: (context, state) {
|
||||
final userId = state.pathParameters['userId']!;
|
||||
final email = state.pathParameters['email']!;
|
||||
final key = state.uri.queryParameters['key'] ?? '';
|
||||
|
||||
return CreateNewPw(userId: userId, email: email, keyParam: key);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/confirmpasswd',
|
||||
builder: (context, state) => ConfirmPassword(
|
||||
email: '',
|
||||
userId: '',
|
||||
GoRoute(
|
||||
path: '/mailverification',
|
||||
builder: (context, state) => EmailVerificationScreen(
|
||||
email: '',
|
||||
userId: '',
|
||||
otp: '',
|
||||
otpId: '',
|
||||
sendVerificationCode: (String) {},
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/changepassword/:userId',
|
||||
builder: (context, state) {
|
||||
final userId = state.pathParameters['userId']!;
|
||||
return Changepassword(userId: userId);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/createNewPw/:userId/:email',
|
||||
builder: (context, state) {
|
||||
final userId = state.pathParameters['userId']!;
|
||||
final email = state.pathParameters['email']!;
|
||||
final key = state.uri.queryParameters['key'] ?? '';
|
||||
|
||||
return CreateNewPw(userId: userId, email: email, keyParam: key);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/confirmpasswd',
|
||||
builder: (context, state) => ConfirmPassword(
|
||||
email: '',
|
||||
userId: '',
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/terms&conditions',
|
||||
builder: (context, state) => TermsOfUse(),
|
||||
//builder: (context, state) => LoginRoute(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/privacy_policy',
|
||||
builder: (context, state) => PrivacyPolicy(),
|
||||
//builder: (context, state) => LoginRoute(),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/terms&conditions',
|
||||
builder: (context, state) => TermsOfUse(),
|
||||
//builder: (context, state) => LoginRoute(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/privacy_policy',
|
||||
builder: (context, state) => PrivacyPolicy(),
|
||||
//builder: (context, state) => LoginRoute(),
|
||||
),
|
||||
|
||||
// Drawer Routers
|
||||
GoRoute(
|
||||
path: '/feedback',
|
||||
builder: (context, state) => FeedbackForm(),
|
||||
),
|
||||
//Sub route
|
||||
GoRoute(
|
||||
path: '/profile/:userId',
|
||||
builder: (context, state) {
|
||||
final userId = state.pathParameters['userId']!;
|
||||
return ProfileScreen(userId: userId);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/notification',
|
||||
builder: (context, state) {
|
||||
// final userId = state.pathParameters['userId']!;
|
||||
return NotificationPage();
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/notification_details',
|
||||
builder: (context, state) {
|
||||
final Map<String, dynamic> data = state.extra as Map<String, dynamic>;
|
||||
return NotificationDetails(
|
||||
title: data['title'] ?? '',
|
||||
message: data['message'] ?? '',
|
||||
date: data['date'] ?? '',
|
||||
category: data['category'] ?? '',
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/user-guide',
|
||||
builder: (context, state) => Userguide(),
|
||||
routes: <RouteBase>[
|
||||
GoRoute(
|
||||
path: '/features',
|
||||
name: 'features',
|
||||
builder: (context, state) => UsingFeatures(),
|
||||
routes: <RouteBase>[
|
||||
GoRoute(
|
||||
path: 'whoUseApp',
|
||||
name: 'whoUseApp',
|
||||
builder: (context, state) => WhoUseTheApp(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'howUseApp',
|
||||
name: 'howUseApp',
|
||||
builder: (context, state) => HowUseTheApp(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'purpose',
|
||||
name: 'purpose',
|
||||
builder: (context, state) => Purpose(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'stayUpdated',
|
||||
name: 'stayUpdated',
|
||||
builder: (context, state) => StayUpdate(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'changeMyPassword',
|
||||
name: 'changeMyPassword',
|
||||
builder: (context, state) => ChangeMyPassword(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'appFeatures',
|
||||
name: 'appFeatures',
|
||||
builder: (context, state) => AppFeatures(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'editMyProfile',
|
||||
name: 'editMyProfile',
|
||||
builder: (context, state) => EditMyProfile(),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: 'aboutApp',
|
||||
builder: (context, state) => aboutTheApp(),
|
||||
GoRoute(
|
||||
path: '/feedback',
|
||||
builder: (context, state) => FeedbackForm(),
|
||||
),
|
||||
//Sub route
|
||||
GoRoute(
|
||||
path: '/profile/:userId',
|
||||
builder: (context, state) {
|
||||
final userId = state.pathParameters['userId']!;
|
||||
return ProfileScreen(userId: userId);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/notification',
|
||||
builder: (context, state) {
|
||||
// final userId = state.pathParameters['userId']!;
|
||||
return NotificationPage();
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/notification_details',
|
||||
builder: (context, state) {
|
||||
final Map<String, dynamic> data = state.extra as Map<String, dynamic>;
|
||||
return NotificationDetails(
|
||||
title: data['title'] ?? '',
|
||||
message: data['message'] ?? '',
|
||||
date: data['date'] ?? '',
|
||||
category: data['category'] ?? '',
|
||||
id: data['id'] ?? '',
|
||||
backNavigation: data['backNavigation'] ?? '',
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/user-guide',
|
||||
builder: (context, state) => Userguide(),
|
||||
routes: <RouteBase>[
|
||||
GoRoute(
|
||||
path: '/features',
|
||||
name: 'features',
|
||||
builder: (context, state) => UsingFeatures(),
|
||||
routes: <RouteBase>[
|
||||
GoRoute(
|
||||
path: 'aboutFCSC',
|
||||
name: 'aboutFCSC',
|
||||
builder: (context, state) => aboutFCSC(),
|
||||
path: 'whoUseApp',
|
||||
name: 'whoUseApp',
|
||||
builder: (context, state) => WhoUseTheApp(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'getStarted',
|
||||
name: 'getStarted',
|
||||
builder: (context, state) => GetStarted(),
|
||||
path: 'howUseApp',
|
||||
name: 'howUseApp',
|
||||
builder: (context, state) => HowUseTheApp(),
|
||||
),
|
||||
]),
|
||||
GoRoute(
|
||||
path: '/faq',
|
||||
name: 'faq',
|
||||
builder: (context, state) => FAQPage(),
|
||||
),
|
||||
],
|
||||
),
|
||||
// GoRoute(
|
||||
// path: '/manageuser',
|
||||
// builder: (context, state) {
|
||||
// // Retrieve the title from extra or query params
|
||||
// final title = state.extra as String? ?? 'Manage users';
|
||||
// return ManageUserRouter(title: title);
|
||||
// },
|
||||
// ),
|
||||
GoRoute(
|
||||
path: '/editProfile',
|
||||
builder: (context, state) => EditProfile(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/bookmark',
|
||||
builder: (context, state) => BookMark(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/manageuser',
|
||||
builder: (context, state) => ManageUserRouter(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'purpose',
|
||||
name: 'purpose',
|
||||
builder: (context, state) => Purpose(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'stayUpdated',
|
||||
name: 'stayUpdated',
|
||||
builder: (context, state) => StayUpdate(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'changeMyPassword',
|
||||
name: 'changeMyPassword',
|
||||
builder: (context, state) => ChangeMyPassword(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'appFeatures',
|
||||
name: 'appFeatures',
|
||||
builder: (context, state) => AppFeatures(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'editMyProfile',
|
||||
name: 'editMyProfile',
|
||||
builder: (context, state) => EditMyProfile(),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: 'aboutApp',
|
||||
builder: (context, state) => aboutTheApp(),
|
||||
routes: <RouteBase>[
|
||||
GoRoute(
|
||||
path: 'aboutFCSC',
|
||||
name: 'aboutFCSC',
|
||||
builder: (context, state) => aboutFCSC(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'getStarted',
|
||||
name: 'getStarted',
|
||||
builder: (context, state) => GetStarted(),
|
||||
),
|
||||
]),
|
||||
GoRoute(
|
||||
path: '/faq',
|
||||
name: 'faq',
|
||||
builder: (context, state) => FAQPage(),
|
||||
),
|
||||
],
|
||||
),
|
||||
// GoRoute(
|
||||
// path: '/manageuser',
|
||||
// builder: (context, state) {
|
||||
// // Retrieve the title from extra or query params
|
||||
// final title = state.extra as String? ?? 'Manage users';
|
||||
// return ManageUserRouter(title: title);
|
||||
// },
|
||||
// ),
|
||||
GoRoute(
|
||||
path: '/editProfile',
|
||||
builder: (context, state) => EditProfile(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/bookmark',
|
||||
builder: (context, state) => BookMark(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/manageuser',
|
||||
builder: (context, state) => ManageUserRouter(),
|
||||
),
|
||||
|
||||
// Bottom Navigation Routes
|
||||
// GoRoute(
|
||||
// path: '/uaenumbers',
|
||||
// builder: (context, state) => UaeNumbers(),
|
||||
// ),
|
||||
GoRoute(path: '/uaenumbers', builder: (context, state) => UaeNumbers()),
|
||||
// Bottom Navigation Routes
|
||||
// GoRoute(
|
||||
// path: '/uaenumbers',
|
||||
// builder: (context, state) => UaeNumbers(),
|
||||
// ),
|
||||
GoRoute(path: '/uaenumbers', builder: (context, state) => UaeNumbers()),
|
||||
|
||||
GoRoute(
|
||||
path: '/competitiveness',
|
||||
builder: (context, state) => Competitiveness(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/competitiveness',
|
||||
builder: (context, state) => Competitiveness(),
|
||||
),
|
||||
|
||||
GoRoute(
|
||||
path: '/countryprofile',
|
||||
builder: (context, state) => CountryProfile(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/countryprofile',
|
||||
builder: (context, state) => CountryProfile(),
|
||||
),
|
||||
|
||||
GoRoute(
|
||||
path: '/marriages',
|
||||
builder: (context, state) => Marriages(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/marriages',
|
||||
builder: (context, state) => Marriages(),
|
||||
),
|
||||
|
||||
GoRoute(
|
||||
path: '/contact',
|
||||
builder: (context, state) => Contact(),
|
||||
),
|
||||
],
|
||||
GoRoute(
|
||||
path: '/contact',
|
||||
builder: (context, state) => Contact(),
|
||||
),
|
||||
],
|
||||
redirect: (context, state) async {
|
||||
if (state.uri.path == '/SessionCheckScreen' || state.uri.path == '/login') {
|
||||
if (state.uri.path == '/SessionCheckScreen' ||
|
||||
state.uri.path == '/login') {
|
||||
return null;
|
||||
}
|
||||
|
||||
final session = await PAuthRepo().fetchLocallyStored();
|
||||
|
||||
if (session == null || session.freshness == SessionFreshness.expired) {
|
||||
print('Session expired, redirecting to login with intendedPath: ${state.uri.path}');
|
||||
print(
|
||||
'Session expired, redirecting to login with intendedPath: ${state.uri.path}');
|
||||
return '/login${state.uri.path != '/' ? '?intendedPath=${state.uri.path}' : ''}';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
@ -45,6 +45,13 @@
|
||||
"account_confirmation": "هل لديك حساب؟ سجل الدخول",
|
||||
"login_title": "تسجيل الدخول",
|
||||
|
||||
"all_updates": "جميع التحديثات",
|
||||
"app_updates": "تحديثات التطبيق",
|
||||
"notificationSocial": "اجتماعي",
|
||||
"notificationEconomy": "اقتصاد",
|
||||
"notificationEnvironment": "بيئة",
|
||||
"notificationFavourites": "المفضلة",
|
||||
|
||||
"profile_title": "نموذج الملاحظات",
|
||||
"my_profile": "ملفي الشخصي",
|
||||
"logout": "تسجيل الخروج",
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
{
|
||||
"all_bookmarks":"All Bookmarks",
|
||||
"economy_title":"Economy",
|
||||
"social_title":"Social",
|
||||
"environment_title":"Environment",
|
||||
"all_bookmarks": "All Bookmarks",
|
||||
"economy_title": "Economy",
|
||||
"social_title": "Social",
|
||||
"environment_title": "Environment",
|
||||
"bookmarks": "Bookmarks",
|
||||
|
||||
"feedback_title": "Feedback",
|
||||
@ -41,7 +41,12 @@
|
||||
"account_confirmation": "Already have an account?",
|
||||
"login_title": "Login",
|
||||
|
||||
|
||||
"all_updates": "All updates",
|
||||
"app_updates": "App updates",
|
||||
"notificationSocial": "Social",
|
||||
"notificationEconomy": "Economy",
|
||||
"notificationEnvironment": "Environment",
|
||||
"notificationFavourites": "Favourites",
|
||||
|
||||
"profile_title": "Edit Profile",
|
||||
"my_profile": "My Profile",
|
||||
|
||||
@ -65,7 +65,19 @@ class _EditProfileState extends State<EditProfile> {
|
||||
'India',
|
||||
'Canada',
|
||||
];
|
||||
final List<String> preferred_language = ['English', 'Arabic'];
|
||||
final Map<String, String> languageMap = {
|
||||
"en": "English",
|
||||
"ar": "Arabic",
|
||||
};
|
||||
|
||||
// Reverse mapping for saving back to API
|
||||
final Map<String, String> reverseLanguageMap = {
|
||||
"English": "en",
|
||||
"Arabic": "ar",
|
||||
};
|
||||
String? _selectedCountry;
|
||||
String? _selectedLanguage;
|
||||
bool isChecked = false;
|
||||
bool showError = false;
|
||||
final _picker = ImagePicker();
|
||||
@ -82,6 +94,7 @@ class _EditProfileState extends State<EditProfile> {
|
||||
dynamic role;
|
||||
|
||||
bool _isHoveringDropdown = false;
|
||||
bool _isHoveringPreferredLang = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -177,10 +190,16 @@ class _EditProfileState extends State<EditProfile> {
|
||||
|
||||
print('userDetails: $userDetailsResponse');
|
||||
setState(() {
|
||||
setState(() {
|
||||
_selectedLanguage =
|
||||
languageMap[userDetailsResponse.data['language']] ??
|
||||
'English'; // Default to English if not found
|
||||
});
|
||||
_usernameController.text = userDetailsResponse.data['uname'] ?? '';
|
||||
_emailController.text = userDetailsResponse.data['email'] ?? '';
|
||||
_fullNameController.text = userDetailsResponse.data['full_name'] ?? '';
|
||||
_selectedCountry = userDetailsResponse.data['country_region'] ?? '';
|
||||
// _selectedLanguage = userDetailsResponse.data['language'] ?? '';
|
||||
_isProfileCompleted =
|
||||
userDetailsResponse.data['is_profile_completed'] ?? false;
|
||||
//_isProfileCompleted = true ;
|
||||
@ -321,6 +340,13 @@ class _EditProfileState extends State<EditProfile> {
|
||||
return null;
|
||||
}
|
||||
|
||||
String? _validatePreferredLang(String? value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return context.translate('Required', 'مطلوب');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void _toggleCheckbox(bool? value) {
|
||||
setState(() {
|
||||
isChecked = value ?? false;
|
||||
@ -335,7 +361,8 @@ class _EditProfileState extends State<EditProfile> {
|
||||
|
||||
// if (result == true) {
|
||||
// Validate only the country field
|
||||
if (_validateDropdown(_selectedCountry) == null) {
|
||||
if (_validateDropdown(_selectedCountry) == null &&
|
||||
_validatePreferredLang(_selectedLanguage) == null) {
|
||||
try {
|
||||
String userID = userId;
|
||||
|
||||
@ -343,6 +370,7 @@ class _EditProfileState extends State<EditProfile> {
|
||||
// Retrieve data from the country/region field
|
||||
String countryRegion =
|
||||
_selectedCountry ?? ''; // Ensure the country is selected
|
||||
String preferredLang = _selectedLanguage ?? '';
|
||||
|
||||
// Create a multipart request
|
||||
final uri =
|
||||
@ -352,6 +380,7 @@ class _EditProfileState extends State<EditProfile> {
|
||||
// Add fields to the request
|
||||
request.fields['country_region'] =
|
||||
countryRegion; // Only update country here
|
||||
request.fields['language'] = preferredLang == 'English' ? 'en' : 'ar';
|
||||
|
||||
// If profile image exists, add it
|
||||
if (_profileImage != null) {
|
||||
@ -406,6 +435,7 @@ class _EditProfileState extends State<EditProfile> {
|
||||
_fullNameController.clear();
|
||||
_dateController.clear();
|
||||
_selectedCountry = null;
|
||||
_selectedLanguage = null;
|
||||
isChecked = false;
|
||||
|
||||
// Reset profile image
|
||||
@ -829,6 +859,73 @@ class _EditProfileState extends State<EditProfile> {
|
||||
validator: _validateDropdown,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
AppLocalizations.of(context)!
|
||||
.preferredLang,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
MouseRegion(
|
||||
onEnter: (_) => setState(
|
||||
() => _isHoveringPreferredLang = true),
|
||||
onExit: (_) => setState(
|
||||
() => _isHoveringPreferredLang = false),
|
||||
child: DropdownButtonFormField<String>(
|
||||
style: TextStyle(
|
||||
fontFamily: 'Roboto',
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Color(0xFF544C4C),
|
||||
),
|
||||
value: _selectedLanguage,
|
||||
decoration: InputDecoration(
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(10),
|
||||
borderSide: BorderSide(
|
||||
color: MyTheme.topicColor(
|
||||
IndicatorTopic.economy)
|
||||
.shade400,
|
||||
width: 1), // Enabled border
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFF7296BE),
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius.circular(8),
|
||||
),
|
||||
labelText: 'Select',
|
||||
),
|
||||
icon: Icon(
|
||||
Icons.keyboard_arrow_down_sharp,
|
||||
color: _isHoveringPreferredLang
|
||||
? Colors.black
|
||||
: Colors.grey),
|
||||
items: preferred_language
|
||||
.map(
|
||||
(item) => DropdownMenuItem<String>(
|
||||
value: item,
|
||||
child: Text(item),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
_selectedLanguage = newValue;
|
||||
});
|
||||
},
|
||||
validator: _validatePreferredLang,
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 20),
|
||||
if (!_isProfileCompleted) // Conditional rendering
|
||||
Column(
|
||||
|
||||
@ -10,6 +10,7 @@ import 'package:uae_stat/domain/use_cases/language.dart';
|
||||
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
|
||||
import '../../custom_drawer_routes.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
class NotificationPage extends ConsumerStatefulWidget {
|
||||
@override
|
||||
@ -66,6 +67,7 @@ class _NotificationPageState extends ConsumerState<NotificationPage> {
|
||||
setState(() {
|
||||
notifications = List<Map<String, dynamic>>.from(
|
||||
jsonResponse['data']); // Assign decoded data
|
||||
print('notifications $notifications');
|
||||
});
|
||||
} else {
|
||||
throw Exception('Failed to load data');
|
||||
@ -100,13 +102,21 @@ class _NotificationPageState extends ConsumerState<NotificationPage> {
|
||||
final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null
|
||||
fetchNotifications(localeCode);
|
||||
});
|
||||
final List<Map<String, dynamic>> tabs = [
|
||||
{'title': AppLocalizations.of(context)!.all_updates},
|
||||
{'title': AppLocalizations.of(context)!.app_updates},
|
||||
{'title': AppLocalizations.of(context)!.notificationSocial},
|
||||
{'title': AppLocalizations.of(context)!.notificationEconomy},
|
||||
{'title': AppLocalizations.of(context)!.notificationEnvironment},
|
||||
{'title': AppLocalizations.of(context)!.notificationFavourites},
|
||||
];
|
||||
|
||||
// Filter notifications based on the selected tab
|
||||
List<Map<String, dynamic>> filteredNotifications = selectedTabIndex == 0
|
||||
? notifications
|
||||
: notifications.where((notification) {
|
||||
print(
|
||||
"Comparing: '${notification["category"]}' with '${tabs[selectedTabIndex]}'");
|
||||
return notification["category"] == tabs[selectedTabIndex];
|
||||
// print("Comparing: '${notification["category"]}' with '${tabs[selectedTabIndex]}'");
|
||||
return notification["category"] == tabs[selectedTabIndex]['title'];
|
||||
}).toList();
|
||||
|
||||
return PopScope(
|
||||
@ -125,7 +135,7 @@ class _NotificationPageState extends ConsumerState<NotificationPage> {
|
||||
body: Column(
|
||||
children: [
|
||||
TabBarHeader(
|
||||
tabs: tabs,
|
||||
tabs: tabs.map((tab) => tab['title'] as String).toList(),
|
||||
selectedIndex: selectedTabIndex,
|
||||
onTabSelected: (index) {
|
||||
setState(() {
|
||||
@ -162,10 +172,12 @@ class _NotificationPageState extends ConsumerState<NotificationPage> {
|
||||
),
|
||||
),
|
||||
child: NotificationTile(
|
||||
title: notification['title'] ?? 'No Title',
|
||||
date: formatDate(notification['created'] ?? ''),
|
||||
category: notification['category'] ?? 'Unknown',
|
||||
message: notification['message'] ?? ''),
|
||||
title: notification['title'] ?? 'No Title',
|
||||
date: formatDate(notification['created'] ?? ''),
|
||||
category: notification['category'] ?? 'Unknown',
|
||||
message: notification['message'] ?? '',
|
||||
id: notification['id'],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
@ -240,23 +252,28 @@ class NotificationTile extends StatelessWidget {
|
||||
final String message;
|
||||
final String date;
|
||||
final String category;
|
||||
final String id;
|
||||
|
||||
const NotificationTile({
|
||||
required this.title,
|
||||
required this.message,
|
||||
required this.date,
|
||||
required this.category,
|
||||
required this.id,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
final encodedKey = Uri.encodeQueryComponent('notification');
|
||||
context.go('/notification_details', extra: {
|
||||
'title': title,
|
||||
'message': message,
|
||||
'date': date,
|
||||
'category': category,
|
||||
'id': id,
|
||||
'backNavigation': encodedKey
|
||||
});
|
||||
},
|
||||
child: ListTile(
|
||||
|
||||
@ -1,14 +1,22 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:pocketbase/pocketbase.dart';
|
||||
import 'package:uae_stat/config/api_config.dart';
|
||||
import 'package:uae_stat/domain/use_cases/language.dart';
|
||||
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
|
||||
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
|
||||
import '../../custom_drawer_routes.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class NotificationDetails extends ConsumerWidget {
|
||||
class NotificationDetails extends ConsumerStatefulWidget {
|
||||
final String title;
|
||||
final String message;
|
||||
final String date;
|
||||
final String category;
|
||||
final String id;
|
||||
final String backNavigation;
|
||||
|
||||
const NotificationDetails({
|
||||
super.key,
|
||||
@ -16,10 +24,85 @@ class NotificationDetails extends ConsumerWidget {
|
||||
required this.message,
|
||||
required this.date,
|
||||
required this.category,
|
||||
required this.id,
|
||||
required this.backNavigation,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
_NotificationDetailsState createState() => _NotificationDetailsState();
|
||||
}
|
||||
|
||||
class _NotificationDetailsState extends ConsumerState<NotificationDetails> {
|
||||
// Example notification data
|
||||
final _pb = PocketBase(apiUrl);
|
||||
Map<String, dynamic>? notification;
|
||||
|
||||
// Current selected tab index
|
||||
int selectedTabIndex = 0;
|
||||
late final Locale locale;
|
||||
dynamic notificationID;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
print(widget.id);
|
||||
locale = ref.read(localeProvider) ?? const Locale('en');
|
||||
fetchNotifications(locale?.languageCode ?? 'en');
|
||||
}
|
||||
|
||||
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(locale) async {
|
||||
notificationID = widget.id;
|
||||
final baseUrl = apiUrl + '/api/getNotification';
|
||||
try {
|
||||
final response = await http
|
||||
.get(Uri.parse('$baseUrl?language=$locale&id=$notificationID'));
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final Map<String, dynamic> jsonResponse =
|
||||
jsonDecode(response.body); // Decode JSON
|
||||
|
||||
if (jsonResponse['message'] == 'Success') {
|
||||
setState(() {
|
||||
final data = jsonResponse['data'];
|
||||
notification = data;
|
||||
// if (data is Map<String, dynamic>) {
|
||||
// notification = data;
|
||||
// } else {
|
||||
// notification = null; // Default to null if data is not valid
|
||||
// }
|
||||
|
||||
print('notification $notification');
|
||||
});
|
||||
} else {
|
||||
throw Exception('Failed to load data');
|
||||
}
|
||||
} else {
|
||||
throw Exception(
|
||||
'Failed to load data with status code ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error fetching data: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
ref.listen<Locale?>(localeProvider, (previous, next) {
|
||||
final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null
|
||||
fetchNotifications(localeCode);
|
||||
});
|
||||
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, result) {
|
||||
@ -34,13 +117,14 @@ class NotificationDetails extends ConsumerWidget {
|
||||
),
|
||||
),
|
||||
showBackButton: true,
|
||||
navBackArrow: Text(widget.backNavigation ?? 'Default Value'),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
notification?['title'] ?? '',
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
@ -52,7 +136,7 @@ class NotificationDetails extends ConsumerWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset(
|
||||
category == 'App updates'
|
||||
notification?['category'] == 'App updates'
|
||||
? 'assets/backgrounds/Notification/App-Update.png'
|
||||
: 'assets/backgrounds/Notification/Update_notific.png',
|
||||
height: 200,
|
||||
@ -62,9 +146,8 @@ class NotificationDetails extends ConsumerWidget {
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
message.isNotEmpty
|
||||
? message
|
||||
: "No additional details available.",
|
||||
notification?['message'] ??
|
||||
"No additional details available.",
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
@ -72,11 +155,12 @@ class NotificationDetails extends ConsumerWidget {
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
"Date: $date",
|
||||
"Date: ${notification != null ? formatDate(notification!['created'] ?? '') : 'N/A'}",
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF8E8E8E)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF8E8E8E),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -67,6 +67,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
String? userEmail;
|
||||
String? userAvatar;
|
||||
String? role;
|
||||
String? preferredLanguage;
|
||||
String? userNames;
|
||||
String? userEmails;
|
||||
String? userAvatars;
|
||||
@ -654,17 +655,23 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
userEmail = userDetailsResponse.data['email'] ?? '';
|
||||
userAvatar = userDetailsResponse.data['avatar'] ?? '';
|
||||
role = userDetailsResponse.data['role'] ?? '';
|
||||
preferredLanguage = userDetailsResponse.data['language'] ?? '';
|
||||
String recordId = userId;
|
||||
String collectionId =
|
||||
userDetailsResponse.data['collectionId'] ?? '_pb_users_auth_';
|
||||
|
||||
if (userAvatar!.isNotEmpty && recordId.isNotEmpty) {
|
||||
_avatarUrl =
|
||||
'$apiUrl/api/files/$collectionId/$recordId/$userAvatar';
|
||||
_avatarUrl = '$apiUrl/api/files/$collectionId/$recordId/$userAvatar';
|
||||
} else {
|
||||
_avatarUrl = ''; // Reset to default or empty
|
||||
}
|
||||
});
|
||||
// **Set Default Locale in Provider**
|
||||
if (preferredLanguage == 'ar') {
|
||||
ref.read(localeProvider.notifier).setLocale(const Locale('ar'));
|
||||
} else {
|
||||
ref.read(localeProvider.notifier).setLocale(const Locale('en'));
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error fetching user details: $e');
|
||||
}
|
||||
@ -706,7 +713,9 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
title: Padding(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: Align(
|
||||
alignment: (locale?.languageCode == 'ar') ? Alignment.centerRight : Alignment.centerLeft,
|
||||
alignment: (locale?.languageCode == 'ar')
|
||||
? Alignment.centerRight
|
||||
: Alignment.centerLeft,
|
||||
child: DefaultTextStyle(
|
||||
style: TextStyle(
|
||||
color: widget.colorChange ? Colors.white : Color(0xFF414042),
|
||||
@ -775,12 +784,12 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
color: widget.colorChange ? Colors.white : Colors.black,
|
||||
icon: const Icon(Icons.arrow_back_ios_new, size: 24),
|
||||
onPressed: () {
|
||||
// if ((widget.navBackArrow as Text).data == 'home') {
|
||||
// context.go('/myhomepage');
|
||||
// } else {
|
||||
// context.go('/uaenumbers');
|
||||
// }
|
||||
context.pop();
|
||||
if ((widget.navBackArrow as Text).data ==
|
||||
'notification') {
|
||||
context.go('/notification');
|
||||
} else {
|
||||
context.pop();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -1195,7 +1204,7 @@ void _showLogoutConfirmationDialog(BuildContext context) {
|
||||
),
|
||||
actions: [
|
||||
Row(
|
||||
mainAxisAlignment:MainAxisAlignment.spaceEvenly,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user