API-SECURITY AUTH_WITH_ADMIN

This commit is contained in:
venbaittech 2025-08-29 12:53:25 +05:30
parent 397e1b9f6c
commit b49beb06e8
35 changed files with 1904 additions and 1481 deletions

View File

@ -4,6 +4,8 @@ import 'package:go_router/go_router.dart';
import 'package:pocketbase/pocketbase.dart'; import 'package:pocketbase/pocketbase.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/theme/auth_provider.dart';
import 'package:uae_stat/config/theme/service.dart';
import 'package:uae_stat/infrastructure/data/p_auth_repo.dart'; import 'package:uae_stat/infrastructure/data/p_auth_repo.dart';
import 'package:uae_stat/domain/entities/session_entity.dart'; import 'package:uae_stat/domain/entities/session_entity.dart';
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart'; import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
@ -38,11 +40,25 @@ class _SessionCheckScreenState extends ConsumerState<SessionCheckScreen> {
final userId = prefs.getString('userId'); final userId = prefs.getString('userId');
// Authenticate admin d // Authenticate admin d
final adminAuth = await pb.admins.authWithPassword( // final adminAuth = await pb.admins.authWithPassword(
'pb@venbainfotech.com', // 'pb@venbainfotech.com',
'pb@venbainfotech.com', // 'pb@venbainfotech.com',
// );
final auth = ref.watch(authProvider);
// final adminAuth = await pb.admins.authWithPassword(
// auth.email,
// auth.password,
// );
// final String adminToken = adminAuth.token;
final themeService = ThemeBaseService();
final adminToken = await themeService.getAdminToken(
email: auth.email,
password: auth.password,
); );
final String adminToken = adminAuth.token;
print('adminToken: $adminToken'); print('adminToken: $adminToken');
// Fetch user details // Fetch user details
@ -147,9 +163,10 @@ class SplashScreen extends StatelessWidget {
color: isDark ? null : Colors.white, color: isDark ? null : Colors.white,
image: isDark image: isDark
? DecorationImage( ? DecorationImage(
image: AssetImage('assets/splash_screen/background_splash_dark.png'), // 🔄 Add this background for dark mode image: AssetImage(
fit: BoxFit.cover, 'assets/splash_screen/background_splash_dark.png'), // 🔄 Add this background for dark mode
) fit: BoxFit.cover,
)
: null, : null,
), ),
child: Center( child: Center(
@ -180,7 +197,7 @@ class SplashScreen extends StatelessWidget {
fontFamily: 'NotoKufi', fontFamily: 'NotoKufi',
), ),
), ),
], ],
), ),
), ),
], ],
@ -191,7 +208,6 @@ class SplashScreen extends StatelessWidget {
} }
} }
// import 'dart:math'; // import 'dart:math';
// //
// import 'package:flutter/material.dart'; // import 'package:flutter/material.dart';

View File

@ -0,0 +1,62 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
class AuthState {
final String email;
final String password;
// AuthState({
// this.email = 'kannan@sightspectrum.com', // default value
// this.password = '1DgZ_we3k5UuCZiF9wziwECQzQo1YNRQ', // default value
// });
AuthState({
this.email = "pb@venbainfotech.com", // default value
this.password = "pb@venbainfotech.com", // default value
});
// AuthState({
// this.email = 'sangeethae9919@gmail.com', // default value
// this.password = 'Sang@123', // default value
// });
}
final authProvider = StateProvider<AuthState>((ref) => AuthState());
// --------------------- Dynamic USER Email and Password
// final adminAuth = await PocketBaseService.users.authWithPassword(
// 'user1@gmail.com',
// 'tes@123',
// );
//
// /// Holds login credentials
// class AuthState {
// final String? email;
// final String? password;
//
// const AuthState({this.email, this.password});
//
// AuthState copyWith({String? email, String? password}) {
// return AuthState(
// email: email ?? this.email,
// password: password ?? this.password,
// );
// }
// }
//
// class AuthNotifier extends StateNotifier<AuthState> {
// AuthNotifier() : super(const AuthState());
//
// void setCredentials(String email, String password) {
// state = AuthState(email: email, password: password);
// }
//
// void clearCredentials() {
// state = const AuthState();
// }
// }
//
// final authProvider = StateNotifierProvider<AuthNotifier, AuthState>((ref) {
// return AuthNotifier();
// });

View File

@ -1,8 +1,11 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:pocketbase/pocketbase.dart'; import 'package:pocketbase/pocketbase.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/theme/auth_provider.dart';
import 'package:uae_stat/infrastructure/services/pocketbase_service.dart';
class ThemeBaseService { class ThemeBaseService {
final pb = PocketBase(apiUrl); final pb = PocketBase(apiUrl);
@ -38,14 +41,40 @@ class ThemeBaseService {
// // } // // }
// } // }
Future<dynamic> getUserTheme(String userId) async { Future<dynamic> getAdminToken({
required String email,
required String password,
}) async {
print("ADminTOKEN");
try {
final adminAuth = await pb.admins.authWithPassword(email, password);
return adminAuth.token; // return only the token
} catch (e) {
throw Exception("Admin auth failed: $e");
}
}
Future<dynamic> getUserTheme(String userId, WidgetRef ref) async {
print('getUserTheme'); print('getUserTheme');
final url = "${pb.baseUrl}/api/collections/users/records/$userId"; final url = "${pb.baseUrl}/api/collections/users/records/$userId";
// final adminAuth = await pb.admins.authWithPassword(
// 'pb@venbainfotech.com',
// 'pb@venbainfotech.com',
// );
final auth = ref.watch(authProvider);
final adminAuth = await pb.admins.authWithPassword( final adminAuth = await pb.admins.authWithPassword(
'pb@venbainfotech.com', auth.email,
'pb@venbainfotech.com', auth.password,
); );
// final adminAuth = await PocketBaseService.users.authWithPassword(
// 'sangeethae9919@gmail.com',
// 'Sang@123',
// );
final String adminToken = adminAuth.token; final String adminToken = adminAuth.token;
print('adminToken: $adminToken'); print('adminToken: $adminToken');
final response = await http.get( final response = await http.get(
@ -71,13 +100,21 @@ class ThemeBaseService {
} }
} }
Future<void> updateUserTheme(String userId, String theme) async { Future<void> updateUserTheme(
String userId, String theme, WidgetRef ref) async {
print('updateUserTheme'); print('updateUserTheme');
// Authenticate admin d // Authenticate admin d
final url = "${pb.baseUrl}/api/collections/users/records/$userId"; final url = "${pb.baseUrl}/api/collections/users/records/$userId";
// final adminAuth = await pb.admins.authWithPassword(
// 'pb@venbainfotech.com',
// 'pb@venbainfotech.com',
// );
final auth = ref.watch(authProvider);
final adminAuth = await pb.admins.authWithPassword( final adminAuth = await pb.admins.authWithPassword(
'pb@venbainfotech.com', auth.email,
'pb@venbainfotech.com', auth.password,
); );
final String adminToken = adminAuth.token; final String adminToken = adminAuth.token;
print('adminToken: $adminToken'); print('adminToken: $adminToken');

View File

@ -1,11 +1,15 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:pocketbase/pocketbase.dart'; import 'package:pocketbase/pocketbase.dart';
import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/theme/auth_provider.dart';
import 'package:uae_stat/config/theme/service.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/notification/notification.dart';
class UserService { class UserService {
final _pb = PocketBase(apiUrl); final _pb = PocketBase(apiUrl);
Future<void> updateLanguage(String localeCode) async { Future<void> updateLanguage(String localeCode, WidgetRef ref) async {
try { try {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
final userId = prefs.getString('userId'); final userId = prefs.getString('userId');
@ -14,9 +18,22 @@ class UserService {
throw Exception('User ID not found'); throw Exception('User ID not found');
} }
// Authenticate as admin // Authenticate as admin
final adminAuth = await _pb.admins // final adminAuth = await _pb.admins
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); // .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
final token = adminAuth.token;
final auth = ref.watch(authProvider);
// final adminAuth = await pb.admins.authWithPassword(
// auth.email,
// auth.password,
// );
// final token = adminAuth.token;
final themeService = ThemeBaseService();
final token = await themeService.getAdminToken(
email: auth.email,
password: auth.password,
);
final headers = { final headers = {
'Authorization': 'Bearer $token', 'Authorization': 'Bearer $token',

View File

@ -57,6 +57,7 @@ class AuthUseCase extends _$AuthUseCase {
} }
Future<SessionEntity> login(String email, String pw) async { Future<SessionEntity> login(String email, String pw) async {
print("Auth_use_case_1");
final session = await _repo.login(email, pw); final session = await _repo.login(email, pw);
final localPrefs = await getIt.call<TLocalPreferencesRepo>().get(); final localPrefs = await getIt.call<TLocalPreferencesRepo>().get();
if (localPrefs != null) { if (localPrefs != null) {
@ -76,9 +77,9 @@ class AuthUseCase extends _$AuthUseCase {
final localPrefs = await getIt.call<TLocalPreferencesRepo>().get(); final localPrefs = await getIt.call<TLocalPreferencesRepo>().get();
if (localPrefs != null) { if (localPrefs != null) {
await getIt.call<TUserRepo>().syncPreferences( await getIt.call<TUserRepo>().syncPreferences(
localPrefs, localPrefs,
id: session.id, id: session.id,
); );
} }
state = AsyncData(session); state = AsyncData(session);
return session; // Return the session with user details. return session; // Return the session with user details.

View File

@ -48,6 +48,8 @@ class PAuthRepo implements TAuthRepo {
@override @override
Future<SessionEntity> login(String email, String pw) async { Future<SessionEntity> login(String email, String pw) async {
late final RecordAuth user; late final RecordAuth user;
print('P_auth_repo_2');
try { try {
user = await PocketBaseService.users.authWithPassword( user = await PocketBaseService.users.authWithPassword(
email, email,
@ -90,7 +92,6 @@ class PAuthRepo implements TAuthRepo {
return se; return se;
} }
@override @override
Future<void> logout() { Future<void> logout() {
PocketBaseService.authStore.clear(); PocketBaseService.authStore.clear();

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:pocketbase/pocketbase.dart'; import 'package:pocketbase/pocketbase.dart';
import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/notification/notification.dart';
abstract class PocketBaseService { abstract class PocketBaseService {
static const _host = apiUrl; static const _host = apiUrl;

View File

@ -7,6 +7,8 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/connectivity_provider.dart'; import 'package:uae_stat/config/connectivity_provider.dart';
import 'package:uae_stat/config/my_router.dart'; import 'package:uae_stat/config/my_router.dart';
import 'package:uae_stat/config/theme/auth_provider.dart';
import 'package:uae_stat/config/theme/service.dart';
import 'package:uae_stat/config/theme/theme_provider.dart'; import 'package:uae_stat/config/theme/theme_provider.dart';
import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/data/p_auth_repo.dart'; import 'package:uae_stat/infrastructure/data/p_auth_repo.dart';
@ -18,6 +20,7 @@ import 'package:uae_stat/presentation/components/my_toggle.dart';
import 'package:uae_stat/presentation/components/space.dart'; import 'package:uae_stat/presentation/components/space.dart';
import 'package:uae_stat/l10n/app_localizations.dart'; import 'package:uae_stat/l10n/app_localizations.dart';
import 'package:uae_stat/config/my_theme.dart'; import 'package:uae_stat/config/my_theme.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/notification/notification.dart';
class CreateNewPw extends ConsumerStatefulWidget { class CreateNewPw extends ConsumerStatefulWidget {
final String userId; final String userId;
@ -146,9 +149,22 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
isLoading = true; isLoading = true;
}); });
// Authenticate as admin // Authenticate as admin
final adminAuth = await _pb.admins // final adminAuth = await _pb.admins
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); // .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
final token = adminAuth.token;
final auth = ref.watch(authProvider);
// final adminAuth = await pb.admins.authWithPassword(
// auth.email,
// auth.password,
// );
// final token = adminAuth.token;
final themeService = ThemeBaseService();
final token = await themeService.getAdminToken(
email: auth.email,
password: auth.password,
);
final headers = { final headers = {
'Authorization': 'Bearer $token', 'Authorization': 'Bearer $token',

View File

@ -7,6 +7,8 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/connectivity_provider.dart'; import 'package:uae_stat/config/connectivity_provider.dart';
import 'package:uae_stat/config/my_router.dart'; import 'package:uae_stat/config/my_router.dart';
import 'package:uae_stat/config/theme/auth_provider.dart';
import 'package:uae_stat/config/theme/service.dart';
import 'package:uae_stat/config/theme/theme_provider.dart'; import 'package:uae_stat/config/theme/theme_provider.dart';
import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/data/p_auth_repo.dart'; import 'package:uae_stat/infrastructure/data/p_auth_repo.dart';
@ -18,6 +20,7 @@ import 'package:uae_stat/presentation/components/indicators/locale_provider.dart
import 'package:uae_stat/presentation/components/my_toggle.dart'; import 'package:uae_stat/presentation/components/my_toggle.dart';
import 'package:uae_stat/presentation/components/space.dart'; import 'package:uae_stat/presentation/components/space.dart';
import 'package:uae_stat/config/my_theme.dart'; import 'package:uae_stat/config/my_theme.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/notification/notification.dart';
class ForgotPassword extends ConsumerStatefulWidget { class ForgotPassword extends ConsumerStatefulWidget {
final String email; final String email;
@ -174,9 +177,23 @@ class _ForgotPasswordState extends ConsumerState<ForgotPassword> {
isLoading = true; isLoading = true;
}); });
// Authenticate as admin // Authenticate as admin
final adminAuth = await _pb.admins // final adminAuth = await _pb.admins
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); // .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
final token = adminAuth.token;
final auth = ref.watch(authProvider);
// final adminAuth = await pb.admins.authWithPassword(
// auth.email,
// auth.password,
// );
//
// final token = adminAuth.token;
final themeService = ThemeBaseService();
final token = await themeService.getAdminToken(
email: auth.email,
password: auth.password,
);
final headers = { final headers = {
'Authorization': 'Bearer $token', 'Authorization': 'Bearer $token',

View File

@ -13,6 +13,8 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; import 'package:tutorial_coach_mark/tutorial_coach_mark.dart';
import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/connectivity_provider.dart'; import 'package:uae_stat/config/connectivity_provider.dart';
import 'package:uae_stat/config/theme/auth_provider.dart';
import 'package:uae_stat/config/theme/service.dart';
import 'package:uae_stat/config/theme/theme_provider.dart'; import 'package:uae_stat/config/theme/theme_provider.dart';
import 'package:uae_stat/config/toast_util.dart'; import 'package:uae_stat/config/toast_util.dart';
import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/config/toggle_lang_service.dart';
@ -23,6 +25,7 @@ import 'package:uae_stat/presentation/Screens/charts/widgets/chart_widget.dart';
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart'; import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
import 'package:uae_stat/presentation/components/my_toggle.dart'; import 'package:uae_stat/presentation/components/my_toggle.dart';
import 'package:uae_stat/l10n/app_localizations.dart'; import 'package:uae_stat/l10n/app_localizations.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/notification/notification.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
import 'package:uae_stat/presentation/Screens/app_tour/Target_content.dart'; import 'package:uae_stat/presentation/Screens/app_tour/Target_content.dart';
import '../filters/search_filter_helper.dart'; import '../filters/search_filter_helper.dart';
@ -140,12 +143,24 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
final userID = prefs.getString('userId'); final userID = prefs.getString('userId');
try { try {
final adminAuth = await _pb.admins.authWithPassword( // final adminAuth = await _pb.admins.authWithPassword(
'pb@venbainfotech.com', // 'pb@venbainfotech.com',
'pb@venbainfotech.com', // 'pb@venbainfotech.com',
); // );
final adminToken = adminAuth.token; final auth = ref.watch(authProvider);
// final adminAuth = await pb.admins.authWithPassword(
// auth.email,
// auth.password,
// );
// final adminToken = adminAuth.token;
final themeService = ThemeBaseService();
final adminToken = await themeService.getAdminToken(
email: auth.email,
password: auth.password,
);
final result = await _pb.collection('bookmark').getList( final result = await _pb.collection('bookmark').getList(
filter: "user_id = '${userID}' && dataset = '${widget.dataSets}'", filter: "user_id = '${userID}' && dataset = '${widget.dataSets}'",
@ -170,8 +185,15 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
final userID = prefs.getString('userId'); final userID = prefs.getString('userId');
try { try {
final adminAuth = await _pb.admins // final adminAuth = await _pb.admins
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); // .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
final auth = ref.watch(authProvider);
final adminAuth = await pb.admins.authWithPassword(
auth.email,
auth.password,
);
final adminToken = adminAuth.token; final adminToken = adminAuth.token;
final response = await _pb.collection('bookmark').create(body: { final response = await _pb.collection('bookmark').create(body: {
'user_id': userID, 'user_id': userID,
@ -2398,7 +2420,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
isLoading = true; isLoading = true;
print('isLoadingref $isLoading'); print('isLoadingref $isLoading');
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
// fetchChartData(widget.dataSets, localeCode); // fetchChartData(widget.dataSets, localeCode);
print('Saving currentTab: $tabWiseKpi before locale change'); print('Saving currentTab: $tabWiseKpi before locale change');

View File

@ -16,7 +16,7 @@ class ApiService {
static const String baseUrl = '$apiUrl/api/getDataSet'; static const String baseUrl = '$apiUrl/api/getDataSet';
Future<Map<String, dynamic>> fetchChartData(String dataSets, locale, kpi, Future<Map<String, dynamic>> fetchChartData(String dataSets, locale, kpi,
List<Map<String, dynamic>> filterData,themeMode) async { List<Map<String, dynamic>> filterData, themeMode) async {
List<dynamic> isChartData = []; List<dynamic> isChartData = [];
List<dynamic> nonChartData = []; List<dynamic> nonChartData = [];
List<dynamic> originalChartsData = []; List<dynamic> originalChartsData = [];
@ -35,7 +35,7 @@ class ApiService {
'kpi': kpi.isNotEmpty ? kpi : null, // Avoid sending empty kpi 'kpi': kpi.isNotEmpty ? kpi : null, // Avoid sending empty kpi
'filter_data': 'filter_data':
filterData.isNotEmpty ? filterData : [], // Avoid empty list filterData.isNotEmpty ? filterData : [], // Avoid empty list
'color_mode' : themeMode, 'color_mode': themeMode,
}; };
// final url = Uri.https('$baseUrl?dataset=$dataSets&language=$locale'); // final url = Uri.https('$baseUrl?dataset=$dataSets&language=$locale');
@ -46,7 +46,10 @@ class ApiService {
try { try {
final response = await http.post( final response = await http.post(
url, url,
headers: {'Content-Type': 'application/json'}, headers: {
'Content-Type': 'application/json',
'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'
},
body: jsonEncode(requestBody), body: jsonEncode(requestBody),
); );

View File

@ -16,13 +16,16 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/connectivity_provider.dart'; import 'package:uae_stat/config/connectivity_provider.dart';
import 'package:uae_stat/config/my_theme.dart'; import 'package:uae_stat/config/my_theme.dart';
import 'package:uae_stat/config/theme/auth_provider.dart';
import 'package:uae_stat/config/theme/service.dart';
import 'package:uae_stat/config/theme/theme_provider.dart'; import 'package:uae_stat/config/theme/theme_provider.dart';
import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/data/p_auth_repo.dart'; import 'package:uae_stat/infrastructure/data/p_auth_repo.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart';
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart'; import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
import 'package:uae_stat/presentation/components/my_toggle.dart'; import 'package:uae_stat/presentation/components/my_toggle.dart';
import 'package:uae_stat/l10n/app_localizations.dart'; import 'package:uae_stat/l10n/app_localizations.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/notification/notification.dart';
class ProfileScreen extends ConsumerStatefulWidget { class ProfileScreen extends ConsumerStatefulWidget {
final String userId; // Add this field to hold the user ID final String userId; // Add this field to hold the user ID
@ -162,9 +165,23 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
Future<void> _fetchUserData() async { Future<void> _fetchUserData() async {
try { try {
final adminAuth = await _pb.admins // final adminAuth = await _pb.admins
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); // .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
final adminToken = adminAuth.token;
final auth = ref.watch(authProvider);
// final adminAuth = await pb.admins.authWithPassword(
// auth.email,
// auth.password,
// );
//
// final adminToken = adminAuth.token;
final themeService = ThemeBaseService();
final adminToken = await themeService.getAdminToken(
email: auth.email,
password: auth.password,
);
print('adminToken- ${adminToken}'); print('adminToken- ${adminToken}');
final userDetailsResponse = await _pb.collection('users').getOne( final userDetailsResponse = await _pb.collection('users').getOne(
widget.userId, widget.userId,
@ -201,10 +218,10 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
_isLoading = true; // Start loading _isLoading = true; // Start loading
}); });
final XFile? pickedFile = final XFile? pickedFile =
await _picker.pickImage(source: ImageSource.gallery); await _picker.pickImage(source: ImageSource.gallery);
if (pickedFile != null) { if (pickedFile != null) {
final String fileExtension = final String fileExtension =
pickedFile.path.split('.').last.toLowerCase(); pickedFile.path.split('.').last.toLowerCase();
if (fileExtension == 'jpg' || if (fileExtension == 'jpg' ||
fileExtension == 'jpeg' || fileExtension == 'jpeg' ||
fileExtension == 'png' || fileExtension == 'png' ||
@ -217,13 +234,13 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text( content: Text(
'Please select a JPG, JPEG, or PNG file.', 'Please select a JPG, JPEG, or PNG file.',
style: TextStyle( style: TextStyle(
fontFamily: context.translate( fontFamily: context.translate(
'Roboto', 'Roboto',
'NotoKufi', 'NotoKufi',
)), )),
)), )),
); );
} }
} }
@ -358,7 +375,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
// Create a multipart request // Create a multipart request
final uri = final uri =
Uri.parse('${_pb.baseUrl}/api/collections/users/records/$userID'); Uri.parse('${_pb.baseUrl}/api/collections/users/records/$userID');
final request = http.MultipartRequest('PATCH', uri); final request = http.MultipartRequest('PATCH', uri);
// Add other fields // Add other fields
@ -384,13 +401,13 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
print(response); print(response);
ScaffoldMessenger.of(context).showSnackBar(SnackBar( ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text( content: Text(
AppLocalizations.of(context)!.profile_updated_successfully, AppLocalizations.of(context)!.profile_updated_successfully,
style: TextStyle( style: TextStyle(
fontFamily: context.translate( fontFamily: context.translate(
'Roboto', 'Roboto',
'NotoKufi', 'NotoKufi',
)), )),
))); )));
// **Set Default Locale in Provider** // **Set Default Locale in Provider**
print('_selectedLanguage $_selectedLanguage'); print('_selectedLanguage $_selectedLanguage');
preferredLang = _selectedLanguage == 'English' ? 'en' : 'ar'; preferredLang = _selectedLanguage == 'English' ? 'en' : 'ar';
@ -411,14 +428,14 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text( content: Text(
context.translate("Failed to update profile: $error", context.translate("Failed to update profile: $error",
'$error فشل في تحديث الملف الشخصي: '), '$error فشل في تحديث الملف الشخصي: '),
style: TextStyle( style: TextStyle(
fontFamily: context.translate( fontFamily: context.translate(
'Roboto', 'Roboto',
'NotoKufi', 'NotoKufi',
)), )),
)), )),
); );
} }
} }
@ -685,7 +702,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
backgroundImage: _profileImage != null backgroundImage: _profileImage != null
? FileImage(_profileImage!) ? FileImage(_profileImage!)
: AssetImage("assets/edit_profile/profile.png") : AssetImage("assets/edit_profile/profile.png")
as ImageProvider, as ImageProvider,
child: Align( child: Align(
alignment: Alignment.bottomRight, alignment: Alignment.bottomRight,
child: GestureDetector( child: GestureDetector(
@ -709,7 +726,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
child: CircularProgressIndicator( child: CircularProgressIndicator(
strokeWidth: 2, strokeWidth: 2,
valueColor: valueColor:
AlwaysStoppedAnimation<Color>(Colors.grey), AlwaysStoppedAnimation<Color>(Colors.grey),
), ),
), ),
], ],
@ -983,7 +1000,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
'NotoKufi', 'NotoKufi',
), ),
color: color:
isDarkTheme ? Colors.white : Color(0xFFC3C6CB), isDarkTheme ? Colors.white : Color(0xFFC3C6CB),
// color: Color(0xFFB68A34), // color: Color(0xFFB68A34),
fontSize: 14, fontSize: 14,
), ),
@ -992,11 +1009,11 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
width: 45, width: 45,
padding: EdgeInsets.only(right: 1), padding: EdgeInsets.only(right: 1),
alignment: alignment:
Alignment.center, // Center the icon vertically Alignment.center, // Center the icon vertically
child: Icon( child: Icon(
Icons.keyboard_arrow_down_sharp, Icons.keyboard_arrow_down_sharp,
color: color:
_isHoveringDate ? Colors.black : Colors.grey, _isHoveringDate ? Colors.black : Colors.grey,
), ),
), ),
), ),
@ -1086,27 +1103,27 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
: Colors.grey), : Colors.grey),
items: _countries items: _countries
.map((item) => DropdownMenuItem<ISOCountry>( .map((item) => DropdownMenuItem<ISOCountry>(
value: item, value: item,
child: SizedBox( child: SizedBox(
width: double.infinity, width: double.infinity,
child: Text( child: Text(
// item.nameEN, // item.nameEN,
context.translate( context.translate(
item.nameEN, item.nameAR), item.nameEN, item.nameAR),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
maxLines: 1, maxLines: 1,
style: TextStyle( style: TextStyle(
fontFamily: context.translate( fontFamily: context.translate(
'Roboto', 'Roboto',
'NotoKufi', 'NotoKufi',
), ),
// color: Colors.red // color: Colors.red
color: color:
isDarkTheme ? Colors.white : null, isDarkTheme ? Colors.white : null,
), ),
), ),
), ),
)) ))
.toList(), .toList(),
onChanged: (ISOCountry? newValue) { onChanged: (ISOCountry? newValue) {
setState(() { setState(() {
@ -1250,18 +1267,18 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
: Colors.grey), : Colors.grey),
items: preferred_language items: preferred_language
.map((item) => DropdownMenuItem<String>( .map((item) => DropdownMenuItem<String>(
value: item, value: item,
child: Text( child: Text(
item, item,
style: TextStyle( style: TextStyle(
fontFamily: context.translate( fontFamily: context.translate(
'Roboto', 'Roboto',
'NotoKufi', 'NotoKufi',
), ),
color: isDarkTheme ? Colors.white : null, color: isDarkTheme ? Colors.white : null,
), ),
), ),
)) ))
.toList(), .toList(),
onChanged: (String? newValue) { onChanged: (String? newValue) {
setState(() { setState(() {
@ -1312,7 +1329,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
color: isDarkTheme color: isDarkTheme
? Colors.white ? Colors.white
: Color( : Color(
0xFF898C81), // Change to your desired color 0xFF898C81), // Change to your desired color
), ),
children: [ children: [
TextSpan( TextSpan(
@ -1351,7 +1368,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
color: isDarkTheme color: isDarkTheme
? Colors.white ? Colors.white
: Color( : Color(
0xFF898C81), // Change to your desired color 0xFF898C81), // Change to your desired color
), ),
), ),
TextSpan( TextSpan(
@ -1390,7 +1407,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
color: isDarkTheme color: isDarkTheme
? Colors.white ? Colors.white
: Color( : Color(
0xFF898C81), // Change to your desired color 0xFF898C81), // Change to your desired color
), ),
), ),
], ],
@ -1426,34 +1443,34 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
], ],
), ),
SizedBox(height: 20), SizedBox(height: 20),
if(isOAuthLogin != 1) if (isOAuthLogin != 1)
Center( Center(
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
final userId = widget.userId; final userId = widget.userId;
final email = _emailController.text; final email = _emailController.text;
context.push('/createNewPw/$userId/$email'); context.push('/createNewPw/$userId/$email');
}, },
child: Text( child: Text(
AppLocalizations.of(context)!.change_password, AppLocalizations.of(context)!.change_password,
style: TextStyle( style: TextStyle(
// color: Color(0xFF648CBA), // color: Color(0xFF648CBA),
color: Color(0xFFB68A34), color: Color(0xFFB68A34),
// color: isDarkTheme // color: isDarkTheme
// ? Color(0xFF9EB3E4) // ? Color(0xFF9EB3E4)
// : Color(0xFF985400), // : Color(0xFF985400),
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
fontFamily: context.translate( fontFamily: context.translate(
'Roboto', 'Roboto',
'NotoKufi', 'NotoKufi',
),
// decoration: TextDecoration.underline),
), ),
// decoration: TextDecoration.underline),
), ),
), ),
), ),
),
SizedBox(height: 20), SizedBox(height: 20),
// ElevatedButton.icon( // ElevatedButton.icon(
ElevatedButton( ElevatedButton(
@ -1468,7 +1485,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
} else { } else {
setState(() { setState(() {
showError = showError =
!isChecked; // Show error if the checkbox is not checked !isChecked; // Show error if the checkbox is not checked
}); });
} }
}, },
@ -1484,7 +1501,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
), ),
child: Row( child: Row(
mainAxisAlignment: mainAxisAlignment:
MainAxisAlignment.center, // Center the content MainAxisAlignment.center, // Center the content
children: [ children: [
Text( Text(
AppLocalizations.of(context)!.save, AppLocalizations.of(context)!.save,
@ -1566,7 +1583,7 @@ class ConfirmationDialog extends ConsumerWidget {
'NotoKufi', 'NotoKufi',
), ),
color: color:
isDarkTheme ? Colors.white : null), // Bold for "name" isDarkTheme ? Colors.white : null), // Bold for "name"
), ),
TextSpan( TextSpan(
text: context.translate(' or ', 'أو'), text: context.translate(' or ', 'أو'),
@ -1612,11 +1629,11 @@ class ConfirmationDialog extends ConsumerWidget {
}, },
style: OutlinedButton.styleFrom( style: OutlinedButton.styleFrom(
side: BorderSide(color: Color(0xFFB68A34) side: BorderSide(color: Color(0xFFB68A34)
// color: // color:
// isDarkTheme ? Color(0xFF7296BE) : Color(0xFF92722A) // isDarkTheme ? Color(0xFF7296BE) : Color(0xFF92722A)
// //
), ),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(7)), borderRadius: BorderRadius.all(Radius.circular(7)),
), // Set the border color here ), // Set the border color here

View File

@ -17,6 +17,7 @@ import 'package:uae_stat/config/app_links_helper.dart';
import 'package:uae_stat/config/connectivity_provider.dart'; import 'package:uae_stat/config/connectivity_provider.dart';
import 'package:uae_stat/config/my_theme.dart'; import 'package:uae_stat/config/my_theme.dart';
import 'package:uae_stat/config/theme/app_theme.dart'; import 'package:uae_stat/config/theme/app_theme.dart';
import 'package:uae_stat/config/theme/auth_provider.dart';
import 'package:uae_stat/config/theme/service.dart'; import 'package:uae_stat/config/theme/service.dart';
import 'package:uae_stat/config/theme/theme_provider.dart'; import 'package:uae_stat/config/theme/theme_provider.dart';
import 'package:uae_stat/domain/entities/session_entity.dart'; import 'package:uae_stat/domain/entities/session_entity.dart';
@ -25,6 +26,7 @@ import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/data/p_auth_repo.dart'; import 'package:uae_stat/infrastructure/data/p_auth_repo.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart';
import 'package:uae_stat/infrastructure/services/pocketbase_service.dart';
import 'package:uae_stat/l10n/app_localizations.dart'; import 'package:uae_stat/l10n/app_localizations.dart';
import 'package:uae_stat/presentation/components/dialogs.dart'; import 'package:uae_stat/presentation/components/dialogs.dart';
import 'package:uae_stat/presentation/components/lang_toggle.dart'; import 'package:uae_stat/presentation/components/lang_toggle.dart';
@ -60,13 +62,22 @@ class LoginRoute extends HookConsumerWidget {
Future<bool> profileStatus(String userId, WidgetRef ref) async { Future<bool> profileStatus(String userId, WidgetRef ref) async {
try { try {
// Authenticate admin // Authenticate admin
final adminAuth = await pb.admins.authWithPassword( // final adminAuth = await pb.admins.authWithPassword(
'pb@venbainfotech.com', // 'pb@venbainfotech.com',
'pb@venbainfotech.com', // 'pb@venbainfotech.com',
); // );
final String adminToken = adminAuth.token; final auth = ref.watch(authProvider);
print('adminToken: $adminToken');
// final adminToken = await pb.admins.authWithPassword(
// auth.email,
// auth.password,
// );
final themeService = ThemeBaseService();
final adminToken = await themeService.getAdminToken(
email: auth.email,
password: auth.password,
);
// Fetch user details // Fetch user details
final userDetailsResponse = await pb.collection('users').getOne( final userDetailsResponse = await pb.collection('users').getOne(
userId, userId,
@ -125,7 +136,8 @@ class LoginRoute extends HookConsumerWidget {
// print("FCM Token: $token"); // print("FCM Token: $token");
// } // }
Future<void> getDeviceToken(BuildContext context, String userId) async { Future<void> getDeviceToken(
BuildContext context, String userId, WidgetRef ref) async {
try { try {
// await _firebaseMessaging.requestPermission(); // await _firebaseMessaging.requestPermission();
print("FCM Token Entry"); print("FCM Token Entry");
@ -133,7 +145,7 @@ class LoginRoute extends HookConsumerWidget {
print("FCM Token: $token"); print("FCM Token: $token");
if (token != null) { if (token != null) {
await updateDeviceToken(userId, token); await updateDeviceToken(userId, token, ref);
// Automatically copy to clipboard // Automatically copy to clipboard
// Clipboard.setData(ClipboardData(text: token)); // Clipboard.setData(ClipboardData(text: token));
@ -172,14 +184,28 @@ class LoginRoute extends HookConsumerWidget {
} }
} }
Future<void> updateDeviceToken(String userId, String token) async { Future<void> updateDeviceToken(
String userId, String token, WidgetRef ref) async {
final url = "${pb.baseUrl}/api/collections/users/records/$userId"; final url = "${pb.baseUrl}/api/collections/users/records/$userId";
try { try {
// Authenticate admin (Persist session globally instead) // Authenticate admin (Persist session globally instead)
await pb.admins.authWithPassword( // await pb.admins.authWithPassword(
'pb@venbainfotech.com', // 'pb@venbainfotech.com',
'pb@venbainfotech.com', // 'pb@venbainfotech.com',
// );
final auth = ref.watch(authProvider);
//
// await pb.admins.authWithPassword(
// auth.email,
// auth.password,
// );
final themeService = ThemeBaseService();
final adminToken = await themeService.getAdminToken(
email: auth.email,
password: auth.password,
); );
final response = await http.patch( final response = await http.patch(
@ -209,7 +235,8 @@ class LoginRoute extends HookConsumerWidget {
Uri.parse("${pb.baseUrl}api/auth/request-password-reset?email=$email"); Uri.parse("${pb.baseUrl}api/auth/request-password-reset?email=$email");
try { try {
final response = await http.get(url); final response = await http
.get(url, headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
final body = json.decode(response.body); final body = json.decode(response.body);
if (response.statusCode == 200) { if (response.statusCode == 200) {
return body['status'] ?? 'Reset link sent successfully.'; return body['status'] ?? 'Reset link sent successfully.';
@ -322,7 +349,7 @@ class LoginRoute extends HookConsumerWidget {
Future<void> initializeTheme( Future<void> initializeTheme(
BuildContext context, WidgetRef ref, String userId) async { BuildContext context, WidgetRef ref, String userId) async {
final themeService = ThemeBaseService(); final themeService = ThemeBaseService();
final theme = await themeService.getUserTheme(userId); // e.g., "dark" final theme = await themeService.getUserTheme(userId, ref); // e.g., "dark"
final platformBrightness = MediaQuery.of(context).platformBrightness; final platformBrightness = MediaQuery.of(context).platformBrightness;
ref ref
.read(themeProvider.notifier) .read(themeProvider.notifier)
@ -360,7 +387,7 @@ class LoginRoute extends HookConsumerWidget {
print("Email: ${loginCount}"); print("Email: ${loginCount}");
await loginCountApi(userId!); await loginCountApi(userId!);
await updateOAuthUserDetails(userId!, metaDetails); await updateOAuthUserDetails(userId!, metaDetails, ref);
// await saveUserId(userId!, loginCount); // await saveUserId(userId!, loginCount);
// await getDeviceToken(context, userId); // await getDeviceToken(context, userId);
await initializeTheme(context, ref, userId); await initializeTheme(context, ref, userId);
@ -429,11 +456,11 @@ class LoginRoute extends HookConsumerWidget {
Future<void> loginCountApi(String userId) async { Future<void> loginCountApi(String userId) async {
if (userId.isNotEmpty) { if (userId.isNotEmpty) {
final url = final url = Uri.parse('$apiUrl/api/login_success?id=$userId');
Uri.parse('$apiUrl/api/login_success?id=$userId');
try { try {
final response = await http.get(url); final response = await http
.get(url, headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
print("Login success API call successful: ${response.body}"); print("Login success API call successful: ${response.body}");
@ -452,7 +479,8 @@ class LoginRoute extends HookConsumerWidget {
} }
} }
Future<void> updateOAuthUserDetails(String userId, metaDetails) async { Future<void> updateOAuthUserDetails(
String userId, metaDetails, WidgetRef ref) async {
final url = "${pb.baseUrl}/api/collections/users/records/$userId"; final url = "${pb.baseUrl}/api/collections/users/records/$userId";
try { try {
@ -461,7 +489,18 @@ class LoginRoute extends HookConsumerWidget {
// 'pb@venbainfotech.com', // 'pb@venbainfotech.com',
// 'pb@venbainfotech.com', // 'pb@venbainfotech.com',
// ); // );
final auth = ref.watch(authProvider);
// await pb.admins.authWithPassword(
// auth.email,
// auth.password,
// );
final themeService = ThemeBaseService();
final adminToken = await themeService.getAdminToken(
email: auth.email,
password: auth.password,
);
final userDetails = metaDetails['rawUser']; final userDetails = metaDetails['rawUser'];
print('oauthDetails $userDetails'); print('oauthDetails $userDetails');
@ -894,14 +933,35 @@ class LoginRoute extends HookConsumerWidget {
if (!context.mounted || session == null) return; if (!context.mounted || session == null) return;
final userId = session.id; final userId = session.id;
if (userId.isNotEmpty) { if (userId.isNotEmpty) {
final url = print('EMAIL - $email ');
Uri.parse('$apiUrl/api/login_success?id=$userId'); print('PASSWORD - ${pwCtl.text}');
// USE Dynamic USER EMail and Password
// var password = pwCtl.text;
// Save to AuthProvider
// ref.read(authProvider.notifier).setCredentials(email, password);
// final session = await context.loaderWithErrorDialog(
// () =>
// ref.read(authUseCaseProvider.notifier).login(email, password),
// );
//
// final auth = ref.watch(authProvider);
//
// print("EMAIL - ${auth.email}");
// print("PASSWORD - ${auth.password}");
final url = Uri.parse('${apiUrl}api/login_success?id=$userId');
try { try {
final response = await http.get(url); final response = await http.get(url,
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
print("Login success API call successful: ${response.body}"); print("Login success API call successful: ${response.body}");
print("LOginBtn");
final count = jsonDecode(response.body); final count = jsonDecode(response.body);
loginCount = loginCount =
count["login_count"]; // Directly assign it as an int count["login_count"]; // Directly assign it as an int
@ -915,7 +975,7 @@ class LoginRoute extends HookConsumerWidget {
} }
await saveUserId(userId, loginCount); await saveUserId(userId, loginCount);
await getDeviceToken(context, userId); await getDeviceToken(context, userId, ref);
await initializeTheme(context, ref, userId); await initializeTheme(context, ref, userId);
} }
try { try {

View File

@ -116,8 +116,9 @@ class _UaenumberWidgetState extends ConsumerState<uaenumberWidget> {
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -208,7 +209,7 @@ class _UaenumberWidgetState extends ConsumerState<uaenumberWidget> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&

View File

@ -1016,11 +1016,12 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
// } // }
// } // }
Future<void> fetchData(locale,themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getHomePageData'; const baseUrl = '$apiUrl/api/getHomePageData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
data = json.decode(response.body); data = json.decode(response.body);
@ -1072,7 +1073,7 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&

View File

@ -6,6 +6,9 @@ import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:uae_stat/config/theme/auth_provider.dart';
import 'package:uae_stat/config/theme/service.dart';
import 'package:uae_stat/infrastructure/services/pocketbase_service.dart';
import 'package:uae_stat/l10n/app_localizations.dart'; import 'package:uae_stat/l10n/app_localizations.dart';
import 'package:pocketbase/pocketbase.dart'; import 'package:pocketbase/pocketbase.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -18,6 +21,7 @@ import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/bookmark_
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/uae_numbers_asset_path.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/uae_numbers_asset_path.dart';
// import 'package:uae_stat/l10n/app_localizations.dart'; // import 'package:uae_stat/l10n/app_localizations.dart';
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart'; import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/notification/notification.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
class BookMark extends ConsumerStatefulWidget { class BookMark extends ConsumerStatefulWidget {
@ -69,8 +73,9 @@ class _BookMarkState extends ConsumerState<BookMark> {
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -129,6 +134,9 @@ class _BookMarkState extends ConsumerState<BookMark> {
'language': locale, 'language': locale,
'color_mode': themeMode 'color_mode': themeMode
}, },
options: Options(
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'},
),
); );
if (response.statusCode == 200 && response.data != null) { if (response.statusCode == 200 && response.data != null) {
@ -243,9 +251,28 @@ class _BookMarkState extends ConsumerState<BookMark> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
final adminAuth = await _pb.admins // final adminAuth = await _pb.admins
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); // .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
final adminToken = adminAuth.token;
final auth = ref.watch(authProvider);
// final adminAuth = await pb.admins.authWithPassword(
// auth.email,
// auth.password,
// );
//
//
final themeService = ThemeBaseService();
final adminToken = await themeService.getAdminToken(
email: auth.email,
password: auth.password,
);
print('adminTokenETRE1- ');
// final adminToken = adminAuth.token;
print('adminTokenETRE- $adminToken');
await _pb.collection('bookmark').delete(bookmarkId!, headers: { await _pb.collection('bookmark').delete(bookmarkId!, headers: {
'Authorization': adminToken, 'Authorization': adminToken,
@ -271,9 +298,9 @@ class _BookMarkState extends ConsumerState<BookMark> {
AppLocalizations.of(context)!.removed_from_Bookmark, AppLocalizations.of(context)!.removed_from_Bookmark,
style: TextStyle( style: TextStyle(
fontFamily: context.translate( fontFamily: context.translate(
'Roboto', 'Roboto',
'NotoKufi', 'NotoKufi',
)), )),
), ),
duration: Duration(seconds: 2), duration: Duration(seconds: 2),
), ),
@ -390,7 +417,7 @@ class _BookMarkState extends ConsumerState<BookMark> {
foregroundColor: Colors.white, foregroundColor: Colors.white,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: borderRadius:
BorderRadius.circular(10.0), // Set text color BorderRadius.circular(10.0), // Set text color
), ),
), ),
child: Text( child: Text(
@ -426,7 +453,7 @@ class _BookMarkState extends ConsumerState<BookMark> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
@ -486,11 +513,11 @@ class _BookMarkState extends ConsumerState<BookMark> {
]; ];
List<Map<String, dynamic>> bookmarks = List<Map<String, dynamic>> bookmarks =
dataList.where((item) => item['isBookmark'] == true).toList(); dataList.where((item) => item['isBookmark'] == true).toList();
List<Map<String, dynamic>> filteredBookmarks = dataList.where((bookmark) { List<Map<String, dynamic>> filteredBookmarks = dataList.where((bookmark) {
String mainTopic = bookmark['main_topic'].toString().trim().toLowerCase(); String mainTopic = bookmark['main_topic'].toString().trim().toLowerCase();
String selectedTabTitle = String selectedTabTitle =
tabs[selectedTabIndex]['title'].toString().trim().toLowerCase(); tabs[selectedTabIndex]['title'].toString().trim().toLowerCase();
// Debugging prints // Debugging prints
print( print(
@ -521,220 +548,220 @@ class _BookMarkState extends ConsumerState<BookMark> {
), ),
body: isLoading body: isLoading
? Container( ? Container(
color: isDarkTheme ? Color(0xFF111111) : Colors.white, color: isDarkTheme ? Color(0xFF111111) : Colors.white,
// color: Color(0x98FFFCE5), // Semi-transparent background // color: Color(0x98FFFCE5), // Semi-transparent background
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Container( Container(
margin: EdgeInsets.symmetric( margin: EdgeInsets.symmetric(
horizontal: 40), // Left & Right space horizontal: 40), // Left & Right space
child: LinearProgressIndicator( child: LinearProgressIndicator(
minHeight: 5, // Adjust thickness minHeight: 5, // Adjust thickness
backgroundColor: backgroundColor:
Colors.grey[100], // Optional: Background color Colors.grey[100], // Optional: Background color
valueColor: AlwaysStoppedAnimation<Color>( valueColor: AlwaysStoppedAnimation<Color>(
Color(0xFFAA8E83)), // Loader color Color(0xFFAA8E83)), // Loader color
),
),
],
), ),
), )
],
),
)
: Column( : Column(
children: [ children: [
TabBarHeader( TabBarHeader(
tabs: tabs, tabs: tabs,
selectedIndex: selectedTabIndex, selectedIndex: selectedTabIndex,
onTabSelected: (index) { onTabSelected: (index) {
setState(() { setState(() {
selectedTabIndex = index; selectedTabIndex = index;
}); });
}, },
isDarkTheme: isDarkTheme), isDarkTheme: isDarkTheme),
Expanded( Expanded(
child: selectedTabIndex == 0 child: selectedTabIndex == 0
? (bookmarks.isNotEmpty ? (bookmarks.isNotEmpty
? SingleChildScrollView( ? SingleChildScrollView(
child: Container( child: Container(
padding: const EdgeInsets.all(13.0), padding: const EdgeInsets.all(13.0),
child: Column( child: Column(
children: List.generate( children: List.generate(
transformedList.length, (i) { transformedList.length, (i) {
final mainTopic = transformedList[i]; final mainTopic = transformedList[i];
print('oustside1 $mainTopic'); print('oustside1 $mainTopic');
final list = List.from( final list = List.from(
mainTopic['SubTopic'] ?? []); mainTopic['SubTopic'] ?? []);
print('oustside2 $list'); print('oustside2 $list');
return CustomExpandableTile( return CustomExpandableTile(
index: i, index: i,
isExpanded: expandedIndex == i, isExpanded: expandedIndex == i,
onTap: (int index) { onTap: (int index) {
// 🔹 Expecting an index // 🔹 Expecting an index
setState(() { setState(() {
expandedIndex = expandedIndex =
(expandedIndex == index) (expandedIndex == index)
? null ? null
: index; : index;
}); });
}, },
title: mainTopic['main_topic'] ?? title: mainTopic['main_topic'] ??
'No Topic', 'No Topic',
childWidget: Container( childWidget: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: isDarkTheme color: isDarkTheme
? Color(0xFF111111) ? Color(0xFF111111)
: Colors.white, : Colors.white,
// borderRadius: BorderRadius.all(Radius.circular(20)) // borderRadius: BorderRadius.all(Radius.circular(20))
), ),
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
vertical: 16), vertical: 16),
child: GridView.builder( child: GridView.builder(
shrinkWrap: true, shrinkWrap: true,
physics: physics:
NeverScrollableScrollPhysics(), NeverScrollableScrollPhysics(),
gridDelegate: gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount( const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, crossAxisCount: 2,
crossAxisSpacing: 10.0, crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0, mainAxisSpacing: 10.0,
mainAxisExtent: 100, mainAxisExtent: 100,
), ),
itemCount: list.length, itemCount: list.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return _buildBoxes( return _buildBoxes(
mainTopic['SubTopic'][index], mainTopic['SubTopic'][index],
context, context,
mainTopic['valueColor'], mainTopic['valueColor'],
isDarkTheme); isDarkTheme);
}, },
), ),
), ),
filteredBookmarks: List.from( filteredBookmarks: List.from(
mainTopic['SubTopic'] ?? []), mainTopic['SubTopic'] ?? []),
titleBackgroundColor: titleBackgroundColor:
mainTopic['valueColor'], mainTopic['valueColor'],
// Ensure it's a new list // Ensure it's a new list
isDarkTheme: isDarkTheme, isDarkTheme: isDarkTheme,
); );
}), }),
), ),
), ),
) )
: Center( : Center(
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Icon(Icons.info_outline, Icon(Icons.info_outline,
size: 100, color: Colors.grey[400]), size: 100, color: Colors.grey[400]),
SizedBox(height: 16), SizedBox(height: 16),
Text( Text(
context.translate('No BookMark Added', context.translate('No BookMark Added',
'لم يتم إضافة أي علامة مرجعية'), 'لم يتم إضافة أي علامة مرجعية'),
style: TextStyle( style: TextStyle(
fontFamily: context.translate( fontFamily: context.translate(
'Roboto', 'Roboto',
'NotoKufi', 'NotoKufi',
), ),
fontSize: 16, fontSize: 16,
color: Colors.grey), color: Colors.grey),
), ),
], ],
), ),
)) ))
: filteredBookmarks.isEmpty : filteredBookmarks.isEmpty
? Center( ? Center(
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Icon(Icons.info_outline, Icon(Icons.info_outline,
size: 100, color: Colors.grey[400]), size: 100, color: Colors.grey[400]),
SizedBox(height: 16), SizedBox(height: 16),
Text( Text(
context.translate('No BookMark Added', context.translate('No BookMark Added',
'لم يتم إضافة أي علامة مرجعية'), 'لم يتم إضافة أي علامة مرجعية'),
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
color: Colors.grey, color: Colors.grey,
fontFamily: context.translate( fontFamily: context.translate(
'Roboto', 'Roboto',
'NotoKufi', 'NotoKufi',
), ),
), ),
), ),
], ],
), ),
) )
: Padding( : Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Container( child: Container(
margin: const EdgeInsets.all(8.0), margin: const EdgeInsets.all(8.0),
child: Column( child: Column(
children: [ children: [
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: tabs[selectedTabIndex] color: tabs[selectedTabIndex]
['color'], ['color'],
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
topLeft: Radius.circular(20), topLeft: Radius.circular(20),
topRight: Radius.circular(20)) topRight: Radius.circular(20))
// borderRadius: BorderRadius.all( // borderRadius: BorderRadius.all(
// Radius.circular(35)) // Radius.circular(35))
), ),
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 16, left: 16,
bottom: 5, bottom: 5,
top: 5, top: 5,
right: 10), right: 10),
child: Row( child: Row(
mainAxisAlignment: mainAxisAlignment:
MainAxisAlignment.center, MainAxisAlignment.center,
children: [ children: [
Text( Text(
tabs[selectedTabIndex] tabs[selectedTabIndex]
['titleUpper'], ['titleUpper'],
style: TextStyle( style: TextStyle(
fontFamily: context.translate( fontFamily: context.translate(
'Roboto', 'Roboto',
'NotoKufi', 'NotoKufi',
),
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 20,
),
),
],
),
),
SizedBox(
height: 20,
),
Expanded(
child: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
mainAxisExtent: 100,
),
itemCount: filteredBookmarks.length,
itemBuilder: (context, index) {
return _buildBox(
filteredBookmarks[index],
context,
isDarkTheme);
},
),
),
],
),
), ),
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 20,
), ),
),
],
),
),
SizedBox(
height: 20,
),
Expanded(
child: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
mainAxisExtent: 100,
),
itemCount: filteredBookmarks.length,
itemBuilder: (context, index) {
return _buildBox(
filteredBookmarks[index],
context,
isDarkTheme);
},
),
),
],
), ),
), ],
), ),
),
],
),
), ),
); );
} }
@ -856,11 +883,11 @@ class _BookMarkState extends ConsumerState<BookMark> {
} }
Widget _buildBoxes( Widget _buildBoxes(
Map<String, dynamic> data, Map<String, dynamic> data,
BuildContext context, BuildContext context,
Color styleColor, Color styleColor,
bool isDarkTheme, bool isDarkTheme,
) { ) {
// Color borderColor = data['valueColor']; // Color borderColor = data['valueColor'];
print('inside function $data'); print('inside function $data');
return GestureDetector( return GestureDetector(
@ -973,9 +1000,9 @@ class TabBarHeader extends StatelessWidget {
TabBarHeader( TabBarHeader(
{required this.tabs, {required this.tabs,
required this.selectedIndex, required this.selectedIndex,
required this.onTabSelected, required this.onTabSelected,
required this.isDarkTheme}); required this.isDarkTheme});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -995,7 +1022,7 @@ class TabBarHeader extends StatelessWidget {
onPressed: () => onTabSelected(index), onPressed: () => onTabSelected(index),
style: ButtonStyle( style: ButtonStyle(
foregroundColor: foregroundColor:
MaterialStateProperty.resolveWith((states) { MaterialStateProperty.resolveWith((states) {
return selectedIndex == index return selectedIndex == index
? entry.value['color'] ? entry.value['color']
: Color(0xFF898C81); : Color(0xFF898C81);
@ -1078,7 +1105,7 @@ class _CustomExpandableTileState extends State<CustomExpandableTile> {
color: widget.isDarkTheme color: widget.isDarkTheme
? Color(0xFF111111) ? Color(0xFF111111)
: Colors : Colors
.white, // Ensuring the background outside the rounded container is white .white, // Ensuring the background outside the rounded container is white
), ),
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
@ -1086,8 +1113,8 @@ class _CustomExpandableTileState extends State<CustomExpandableTile> {
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
topLeft: Radius.circular(20), topLeft: Radius.circular(20),
topRight: Radius.circular(20)) topRight: Radius.circular(20))
// borderRadius: BorderRadius.all(Radius.circular(35)) // borderRadius: BorderRadius.all(Radius.circular(35))
), ),
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 16, bottom: 5, top: 5, right: 10), left: 16, bottom: 5, top: 5, right: 10),
child: Row( child: Row(
@ -1128,9 +1155,9 @@ class _CustomExpandableTileState extends State<CustomExpandableTile> {
// height: widget.isExpanded ? myheight * 0.4 : 0, // height: widget.isExpanded ? myheight * 0.4 : 0,
child: widget.isExpanded child: widget.isExpanded
? SingleChildScrollView( ? SingleChildScrollView(
child: Column( child: Column(
children: [ children: [
widget.childWidget, widget.childWidget,
// Container( // Container(
// decoration: BoxDecoration( // decoration: BoxDecoration(
// color: Colors.white, // color: Colors.white,
@ -1153,9 +1180,9 @@ class _CustomExpandableTileState extends State<CustomExpandableTile> {
// }, // },
// ), // ),
// ), // ),
], ],
), ),
) )
: null, : null,
), ),
), ),

View File

@ -53,8 +53,11 @@ class _ContactState extends ConsumerState<Contact> {
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(
baseUrl + '?language=$locale&color_mode=$themeMode',
),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -87,7 +90,7 @@ class _ContactState extends ConsumerState<Contact> {
ref.listen<Locale?>(localeProvider, (previous, next) async { ref.listen<Locale?>(localeProvider, (previous, next) async {
final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
}); });
ref.listen<Locale?>(localeProvider, (previous, next) async { ref.listen<Locale?>(localeProvider, (previous, next) async {
@ -95,7 +98,7 @@ class _ContactState extends ConsumerState<Contact> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&

View File

@ -7,6 +7,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:uae_stat/config/theme/auth_provider.dart';
import 'package:uae_stat/config/theme/service.dart';
import 'package:uae_stat/config/theme/theme_provider.dart'; import 'package:uae_stat/config/theme/theme_provider.dart';
import 'package:pocketbase/pocketbase.dart'; import 'package:pocketbase/pocketbase.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -17,12 +19,14 @@ import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/feedback_asset_path.dart'; import 'package:uae_stat/infrastructure/services/img_asset_paths/feedback_asset_path.dart';
import 'package:uae_stat/infrastructure/services/packages/go_router.dart'; import 'package:uae_stat/infrastructure/services/packages/go_router.dart';
import 'package:uae_stat/infrastructure/services/pocketbase_service.dart';
import 'package:uae_stat/l10n/app_localizations.dart'; import 'package:uae_stat/l10n/app_localizations.dart';
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart'; import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
import 'package:uae_stat/presentation/components/my_drawer.dart'; import 'package:uae_stat/presentation/components/my_drawer.dart';
import 'package:mailer/mailer.dart'; import 'package:mailer/mailer.dart';
import 'package:mailer/smtp_server.dart'; import 'package:mailer/smtp_server.dart';
import 'package:uae_stat/presentation/components/space.dart'; import 'package:uae_stat/presentation/components/space.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/notification/notification.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
import '../../../../config/my_theme.dart'; import '../../../../config/my_theme.dart';
import '../../../../domain/use_cases/preferences_use_case.dart'; import '../../../../domain/use_cases/preferences_use_case.dart';
@ -145,8 +149,9 @@ class _FeedbackFormState extends ConsumerState<FeedbackForm>
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -305,7 +310,7 @@ class _FeedbackFormState extends ConsumerState<FeedbackForm>
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&
@ -1001,9 +1006,22 @@ class _FeedbackFormState extends ConsumerState<FeedbackForm>
}; };
try { try {
final adminAuth = await _pb.admins // final adminAuth = await _pb.admins
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); // .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
final adminToken = adminAuth.token; final auth = ref.watch(authProvider);
// final adminAuth = await pb.admins.authWithPassword(
// auth.email,
// auth.password,
// );
//
// final adminToken = adminAuth.token;
final themeService = ThemeBaseService();
final adminToken = await themeService.getAdminToken(
email: auth.email,
password: auth.password,
);
final response = await _pb final response = await _pb
.collection('feedback') .collection('feedback')
.create(body: feedbackData, headers: {'Authorization': adminToken}); .create(body: feedbackData, headers: {'Authorization': adminToken});

View File

@ -7,6 +7,7 @@ import 'package:pocketbase/pocketbase.dart';
import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/connectivity_provider.dart'; import 'package:uae_stat/config/connectivity_provider.dart';
import 'package:uae_stat/config/theme/app_theme.dart'; import 'package:uae_stat/config/theme/app_theme.dart';
import 'package:uae_stat/config/theme/auth_provider.dart';
import 'package:uae_stat/config/theme/service.dart'; import 'package:uae_stat/config/theme/service.dart';
import 'package:uae_stat/config/theme/theme_provider.dart'; import 'package:uae_stat/config/theme/theme_provider.dart';
import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/config/toggle_lang_service.dart';
@ -16,6 +17,7 @@ import 'package:uae_stat/presentation/components/indicators/locale_provider.dart
import 'package:uae_stat/presentation/components/my_bottom_nav_bar.dart'; import 'package:uae_stat/presentation/components/my_bottom_nav_bar.dart';
import 'package:uae_stat/presentation/components/my_drawer.dart'; import 'package:uae_stat/presentation/components/my_drawer.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/notification/notification.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart'; import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
import 'package:uae_stat/l10n/app_localizations.dart'; import 'package:uae_stat/l10n/app_localizations.dart';
@ -58,8 +60,21 @@ class _ManageUserRouterState extends ConsumerState<ManageUserRouter> {
Future<void> fetchUnverifiedUsers() async { Future<void> fetchUnverifiedUsers() async {
try { try {
await _pb.admins // await _pb.admins
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); // .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
final auth = ref.watch(authProvider);
// await pb.admins.authWithPassword(
// auth.email,
// auth.password,
// );
final themeService = ThemeBaseService();
final adminToken = await themeService.getAdminToken(
email: auth.email,
password: auth.password,
);
final result = await _pb.collection('users').getFullList( final result = await _pb.collection('users').getFullList(
filter: 'role="user"', filter: 'role="user"',
); );
@ -348,7 +363,7 @@ class _ManageUserRouterState extends ConsumerState<ManageUserRouter> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||

View File

@ -8,6 +8,8 @@ import 'package:pocketbase/pocketbase.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/connectivity_provider.dart'; import 'package:uae_stat/config/connectivity_provider.dart';
import 'package:uae_stat/config/theme/auth_provider.dart';
import 'package:uae_stat/config/theme/service.dart';
import 'package:uae_stat/config/theme/theme_provider.dart'; import 'package:uae_stat/config/theme/theme_provider.dart';
import 'package:uae_stat/config/toggle_lang_service.dart'; import 'package:uae_stat/config/toggle_lang_service.dart';
import 'package:uae_stat/domain/use_cases/language.dart'; import 'package:uae_stat/domain/use_cases/language.dart';
@ -73,8 +75,9 @@ class _NotificationPageState extends ConsumerState<NotificationPage> {
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -130,9 +133,22 @@ class _NotificationPageState extends ConsumerState<NotificationPage> {
try { try {
String? fetchedUserId = await getUserId(); String? fetchedUserId = await getUserId();
userID = fetchedUserId; userID = fetchedUserId;
final adminAuth = await _pb.admins // final adminAuth = await _pb.admins
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); // .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
final adminToken = adminAuth.token;
final auth = ref.watch(authProvider);
//
// final adminAuth = await pb.admins.authWithPassword(
// auth.email,
// auth.password,
// );
// final adminToken = adminAuth.token;
final themeService = ThemeBaseService();
final adminToken = await themeService.getAdminToken(
email: auth.email,
password: auth.password,
);
print('adminToken- ${adminToken}'); print('adminToken- ${adminToken}');
final userDetailsResponse = await _pb.collection('users').getOne( final userDetailsResponse = await _pb.collection('users').getOne(
fetchedUserId!, fetchedUserId!,
@ -181,7 +197,8 @@ class _NotificationPageState extends ConsumerState<NotificationPage> {
Future<void> fetchNotifications(locale) async { Future<void> fetchNotifications(locale) async {
final baseUrl = apiUrl + '/api/getNotification'; final baseUrl = apiUrl + '/api/getNotification';
try { try {
final response = await http.get(Uri.parse('$baseUrl?language=$locale')); final response = await http.get(Uri.parse('$baseUrl?language=$locale'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
final Map<String, dynamic> jsonResponse = final Map<String, dynamic> jsonResponse =
@ -238,7 +255,7 @@ class _NotificationPageState extends ConsumerState<NotificationPage> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&
@ -312,7 +329,6 @@ class _NotificationPageState extends ConsumerState<NotificationPage> {
// }, // },
// ]; // ];
// 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
@ -467,8 +483,12 @@ class TabBarHeader extends StatelessWidget {
foregroundColor: foregroundColor:
MaterialStateProperty.resolveWith((states) { MaterialStateProperty.resolveWith((states) {
return selectedIndex == index return selectedIndex == index
? isDarkTheme ? Color(0xFFFFFFFF) : Color(0xFFB68A34) ? isDarkTheme
: isDarkTheme ? Color(0xFFBBBBBB) : Color(0xFF898C81); ? Color(0xFFFFFFFF)
: Color(0xFFB68A34)
: isDarkTheme
? Color(0xFFBBBBBB)
: Color(0xFF898C81);
}), }),
), ),
child: Text( child: Text(
@ -502,7 +522,7 @@ class TabBarHeader extends StatelessWidget {
} }
} }
class NotificationTile extends StatelessWidget { class NotificationTile extends ConsumerWidget {
final String title; final String title;
final String message; final String message;
final String date; final String date;
@ -524,13 +544,13 @@ class NotificationTile extends StatelessWidget {
}); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context, WidgetRef ref) {
bool isPushed = userReadedNotiOrNot.contains(id); bool isPushed = userReadedNotiOrNot.contains(id);
print('isPushed $isPushed , $id'); print('isPushed $isPushed , $id');
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
readedNotification(userID, id); readedNotification(userID, id, ref);
final encodedKey = Uri.encodeQueryComponent('notification'); final encodedKey = Uri.encodeQueryComponent('notification');
context.go('/notification_details', extra: { context.go('/notification_details', extra: {
'title': title, 'title': title,
@ -553,12 +573,13 @@ class NotificationTile extends StatelessWidget {
title: Row( title: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Padding( Padding(
padding: EdgeInsets.only(top: 4.0, right: 6), padding: EdgeInsets.only(top: 4.0, right: 6),
child: isPushed child: isPushed
? const Icon(Icons.circle, size: 8, color: Color(0xFFFF274E)) ? const Icon(Icons.circle, size: 8, color: Color(0xFFFF274E))
: const Icon(Icons.circle, size: 8, color: Colors.transparent), : const Icon(Icons.circle,
), size: 8, color: Colors.transparent),
),
Expanded( Expanded(
child: Text( child: Text(
title, title,
@ -567,8 +588,12 @@ class NotificationTile extends StatelessWidget {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontFamily: context.translate('Roboto', 'NotoKufi'), fontFamily: context.translate('Roboto', 'NotoKufi'),
color: isPushed color: isPushed
? (isDarkTheme ? Colors.white : Color(0xFF414042)) // dark title ? (isDarkTheme
: (isDarkTheme ? Color(0xFF999999) : Color(0x99414042)), // light grey title ? Colors.white
: Color(0xFF414042)) // dark title
: (isDarkTheme
? Color(0xFF999999)
: Color(0x99414042)), // light grey title
), ),
), ),
), ),
@ -590,7 +615,8 @@ class NotificationTile extends StatelessWidget {
// ), // ),
// ), // ),
subtitle: Padding( subtitle: Padding(
padding: const EdgeInsets.only(left: 15), // 👈 set your desired left padding here padding: const EdgeInsets.only(
left: 15), // 👈 set your desired left padding here
child: Text( child: Text(
date, date,
style: TextStyle( style: TextStyle(
@ -612,10 +638,24 @@ class NotificationTile extends StatelessWidget {
} }
final pb = PocketBase(apiUrl); final pb = PocketBase(apiUrl);
Future<void> readedNotification(String userId, String notificationId) async { Future<void> readedNotification(
await pb.admins.authWithPassword( String userId, String notificationId, WidgetRef ref) async {
'pb@venbainfotech.com', // await pb.admins.authWithPassword(
'pb@venbainfotech.com', // 'pb@venbainfotech.com',
// 'pb@venbainfotech.com',
// );
final auth = ref.watch(authProvider);
// await pb.admins.authWithPassword(
// auth.email,
// auth.password,
// );
final themeService = ThemeBaseService();
final adminToken = await themeService.getAdminToken(
email: auth.email,
password: auth.password,
); );
final url = final url =
@ -627,6 +667,7 @@ Future<void> readedNotification(String userId, String notificationId) async {
headers: { headers: {
'Content-Type': 'application/json', // Add this 'Content-Type': 'application/json', // Add this
'Authorization': pb.authStore.token, // Correct way to send auth token 'Authorization': pb.authStore.token, // Correct way to send auth token
'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'
}, },
); );

View File

@ -88,8 +88,9 @@ class _NotificationDetailsState extends ConsumerState<NotificationDetails> {
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -113,8 +114,9 @@ class _NotificationDetailsState extends ConsumerState<NotificationDetails> {
notificationID = widget.id; notificationID = widget.id;
final baseUrl = apiUrl + '/api/getNotification'; final baseUrl = apiUrl + '/api/getNotification';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse('$baseUrl?language=$locale&id=$notificationID')); Uri.parse('$baseUrl?language=$locale&id=$notificationID'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
final Map<String, dynamic> jsonResponse = final Map<String, dynamic> jsonResponse =
@ -167,7 +169,7 @@ class _NotificationDetailsState extends ConsumerState<NotificationDetails> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
fetchNotifications(localeCode); fetchNotifications(localeCode);
}); });
@ -176,7 +178,7 @@ class _NotificationDetailsState extends ConsumerState<NotificationDetails> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&

View File

@ -49,8 +49,9 @@ class _aboutFCSCState extends ConsumerState<aboutFCSC> {
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -77,7 +78,7 @@ class _aboutFCSCState extends ConsumerState<aboutFCSC> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&
@ -163,20 +164,19 @@ class _aboutFCSCState extends ConsumerState<aboutFCSC> {
), ),
), ),
SizedBox( SizedBox(
width: MediaQuery.of(context).size.width, width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.36, height: MediaQuery.of(context).size.height * 0.36,
child: child: Image.asset(
Image.asset( isDarkTheme
isDarkTheme ? 'assets/user_guide/aboutfcscdark.png'
? 'assets/user_guide/aboutfcscdark.png' : 'assets/user_guide/aboutfcsclight.png',
: 'assets/user_guide/aboutfcsclight.png', )
) // Image.asset(
// Image.asset( // 'assets/user_guide/about fcsc dark.png',
// 'assets/user_guide/about fcsc dark.png', // fit: BoxFit.contain,
// fit: BoxFit.contain, // ),
// ),
), ),
SizedBox( SizedBox(
height: 5, height: 5,
), ),

View File

@ -49,8 +49,9 @@ class _GetStartedState extends ConsumerState<GetStarted> {
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -77,7 +78,7 @@ class _GetStartedState extends ConsumerState<GetStarted> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&

View File

@ -52,8 +52,9 @@ class _AppFeaturesState extends ConsumerState<AppFeatures> {
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -80,7 +81,7 @@ class _AppFeaturesState extends ConsumerState<AppFeatures> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&

View File

@ -50,8 +50,9 @@ class _ChangeMyPasswordState extends ConsumerState<ChangeMyPassword> {
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -78,7 +79,7 @@ class _ChangeMyPasswordState extends ConsumerState<ChangeMyPassword> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&

View File

@ -50,8 +50,9 @@ class _EditMyProfileState extends ConsumerState<EditMyProfile> {
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -78,7 +79,7 @@ class _EditMyProfileState extends ConsumerState<EditMyProfile> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&

View File

@ -51,8 +51,9 @@ class _HowUseTheAppState extends ConsumerState<HowUseTheApp> {
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -79,7 +80,7 @@ class _HowUseTheAppState extends ConsumerState<HowUseTheApp> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&

View File

@ -53,8 +53,9 @@ class _PurposeState extends ConsumerState<Purpose> {
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -81,7 +82,7 @@ class _PurposeState extends ConsumerState<Purpose> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&

View File

@ -53,8 +53,9 @@ class _StayUpdateState extends ConsumerState<StayUpdate> {
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -81,7 +82,7 @@ class _StayUpdateState extends ConsumerState<StayUpdate> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&

View File

@ -52,8 +52,9 @@ class _WhoUseTheAppState extends ConsumerState<WhoUseTheApp> {
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -80,7 +81,7 @@ class _WhoUseTheAppState extends ConsumerState<WhoUseTheApp> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&

View File

@ -52,8 +52,9 @@ class _aboutTheAppState extends ConsumerState<aboutTheApp> {
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -80,7 +81,7 @@ class _aboutTheAppState extends ConsumerState<aboutTheApp> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&

View File

@ -50,8 +50,9 @@ class _FAQPageState extends ConsumerState<FAQPage> {
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -78,7 +79,7 @@ class _FAQPageState extends ConsumerState<FAQPage> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&

View File

@ -53,8 +53,9 @@ class _UsingFeaturesState extends ConsumerState<UsingFeatures> {
Future<void> fetchData(locale, themeMode) async { Future<void> fetchData(locale, themeMode) async {
const baseUrl = '$apiUrl/api/getUAENumbersData'; const baseUrl = '$apiUrl/api/getUAENumbersData';
try { try {
final response = await http final response = await http.get(
.get(Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode')); Uri.parse(baseUrl + '?language=$locale&color_mode=$themeMode'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
homePageData = (json.decode(response.body) as List) homePageData = (json.decode(response.body) as List)
@ -81,7 +82,7 @@ class _UsingFeaturesState extends ConsumerState<UsingFeatures> {
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
await _userService.updateLanguage(localeCode); await _userService.updateLanguage(localeCode, ref);
final currentTheme = ref.read(themeProvider); final currentTheme = ref.read(themeProvider);
final isDark = currentTheme == ThemeMode.dark || final isDark = currentTheme == ThemeMode.dark ||
(currentTheme == ThemeMode.system && (currentTheme == ThemeMode.system &&

View File

@ -15,6 +15,7 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; import 'package:tutorial_coach_mark/tutorial_coach_mark.dart';
import 'package:uae_stat/config/injector.dart'; import 'package:uae_stat/config/injector.dart';
import 'package:uae_stat/config/theme/app_theme.dart'; import 'package:uae_stat/config/theme/app_theme.dart';
import 'package:uae_stat/config/theme/auth_provider.dart';
import 'package:uae_stat/config/theme/service.dart'; import 'package:uae_stat/config/theme/service.dart';
import 'package:uae_stat/config/theme/themeDialog.dart'; import 'package:uae_stat/config/theme/themeDialog.dart';
import 'package:uae_stat/config/theme/theme_provider.dart'; import 'package:uae_stat/config/theme/theme_provider.dart';
@ -31,6 +32,7 @@ import 'package:uae_stat/presentation/Screens/app_tour/Target_content.dart';
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart'; import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
import 'package:uae_stat/presentation/components/my_toggle.dart'; import 'package:uae_stat/presentation/components/my_toggle.dart';
import 'package:uae_stat/config/api_config.dart'; import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/notification/notification.dart';
final selectedIndexProvider = StateProvider<int>((ref) => 0); final selectedIndexProvider = StateProvider<int>((ref) => 0);
@ -134,7 +136,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
void _calculatetooglePosition() { void _calculatetooglePosition() {
final RenderBox cardRenderBox = final RenderBox cardRenderBox =
toggleKey.currentContext!.findRenderObject() as RenderBox; toggleKey.currentContext!.findRenderObject() as RenderBox;
final Offset cardPosition = cardRenderBox.localToGlobal(Offset.zero); final Offset cardPosition = cardRenderBox.localToGlobal(Offset.zero);
final Size cardSize = cardRenderBox.size; final Size cardSize = cardRenderBox.size;
toggleHeight = cardSize.height; toggleHeight = cardSize.height;
@ -259,7 +261,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
.state = true; .state = true;
ref ref
.read(previousChartsTourProvider .read(previousChartsTourProvider
.notifier) .notifier)
.state = false; .state = false;
context.go( context.go(
'/chartScreen/marriages?bgColor=0xFFAA8E83&mainTopic=null&title=Marriages', '/chartScreen/marriages?bgColor=0xFFAA8E83&mainTopic=null&title=Marriages',
@ -292,7 +294,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
.state = true; .state = true;
ref ref
.read(previousChartsTourProvider .read(previousChartsTourProvider
.notifier) .notifier)
.state = false; .state = false;
context.go( context.go(
'/chartScreen/marriages?bgColor=0xFFAA8E83&mainTopic=اجتماعي&title=الزواج&key=home', '/chartScreen/marriages?bgColor=0xFFAA8E83&mainTopic=اجتماعي&title=الزواج&key=home',
@ -584,9 +586,9 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
ElevatedButton( ElevatedButton(
onPressed: () async { onPressed: () async {
final prefs = final prefs =
await SharedPreferences.getInstance(); await SharedPreferences.getInstance();
String? loginCount = String? loginCount =
prefs.getString('login_count'); prefs.getString('login_count');
if (loginCount == '1') { if (loginCount == '1') {
await prefs.setString('login_count', '2'); await prefs.setString('login_count', '2');
} }
@ -596,10 +598,10 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
.state = true; .state = true;
ref ref
.read( .read(
previousChartsTourProvider.notifier) previousChartsTourProvider.notifier)
.state = true; .state = true;
ref.read(homeTourProvider.notifier).state = ref.read(homeTourProvider.notifier).state =
true; true;
ref ref
.read(previousHomeTourProvider.notifier) .read(previousHomeTourProvider.notifier)
.state = true; .state = true;
@ -608,7 +610,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
.state = true; .state = true;
ref ref
.read(previousScaffoldTourProvider .read(previousScaffoldTourProvider
.notifier) .notifier)
.state = true; .state = true;
tutorialCoachMark.finish(); tutorialCoachMark.finish();
}, },
@ -699,10 +701,23 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
Future<void> _fetchUserData() async { Future<void> _fetchUserData() async {
try { try {
final adminAuth = await _pb.admins // final adminAuth = await _pb.admins
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); // .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
final adminToken = adminAuth.token;
final auth = ref.watch(authProvider);
// final adminAuth = await pb.admins.authWithPassword(
// auth.email,
// auth.password,
// );
// final adminToken = adminAuth.token;
//print('adminToken- ${adminToken}'); //print('adminToken- ${adminToken}');
final themeService = ThemeBaseService();
final adminToken = await themeService.getAdminToken(
email: auth.email,
password: auth.password,
);
final userDetailsResponse = await _pb.collection('users').getOne( final userDetailsResponse = await _pb.collection('users').getOne(
userId!, userId!,
headers: { headers: {
@ -721,7 +736,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
String collectionId = String collectionId =
userDetailsResponse.data['collectionId'] ?? '_pb_users_auth_'; userDetailsResponse.data['collectionId'] ?? '_pb_users_auth_';
List<dynamic> userReadedNotification = List<dynamic> userReadedNotification =
userDetailsResponse.data['pushed_notification']; userDetailsResponse.data['pushed_notification'];
// Convert to List<String> // Convert to List<String>
userReadedNotiOrNot = List<String>.from(userReadedNotification); userReadedNotiOrNot = List<String>.from(userReadedNotification);
@ -749,11 +764,12 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
Future<void> fetchNotifications(locale) async { Future<void> fetchNotifications(locale) async {
final baseUrl = apiUrl + '/api/getNotification'; final baseUrl = apiUrl + '/api/getNotification';
try { try {
final response = await http.get(Uri.parse('$baseUrl?language=$locale')); final response = await http.get(Uri.parse('$baseUrl?language=$locale'),
headers: {'APP_SIGNATURE': 'fcsc.gov.ae.X7pL9qZm2A'});
if (response.statusCode == 200) { if (response.statusCode == 200) {
final Map<String, dynamic> jsonResponse = final Map<String, dynamic> jsonResponse =
jsonDecode(response.body); // Decode JSON jsonDecode(response.body); // Decode JSON
if (jsonResponse['message'] == 'Success') { if (jsonResponse['message'] == 'Success') {
setState(() { setState(() {
@ -942,7 +958,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
? (platformBrightness == Brightness.dark ? 'dark' : 'light') ? (platformBrightness == Brightness.dark ? 'dark' : 'light')
: selectedTheme.name; : selectedTheme.name;
await ThemeBaseService().updateUserTheme(userId, themeToSend); await ThemeBaseService().updateUserTheme(userId, themeToSend, ref);
} }
} }
@ -1012,12 +1028,12 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
leadingWidth: widget.showBackButton ? mywidth * 0.18 : null, leadingWidth: widget.showBackButton ? mywidth * 0.18 : null,
bottom: widget.showDivider bottom: widget.showDivider
? PreferredSize( ? PreferredSize(
preferredSize: Size.fromHeight(1), // Height of the line preferredSize: Size.fromHeight(1), // Height of the line
child: Container( child: Container(
color: widget.dividerColor, // Line color color: widget.dividerColor, // Line color
height: 1, // Line thickness height: 1, // Line thickness
), ),
) )
: null, : null,
// bottom: widget.showDivider // bottom: widget.showDivider
@ -1148,19 +1164,19 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
child: ClipOval( child: ClipOval(
child: _avatarUrl.isNotEmpty child: _avatarUrl.isNotEmpty
? Image( ? Image(
image: NetworkImage(_avatarUrl), image: NetworkImage(_avatarUrl),
fit: BoxFit.cover, fit: BoxFit.cover,
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
) )
: Image( : Image(
image: AssetImage( image: AssetImage(
'assets/edit_profile/profile.jpg', 'assets/edit_profile/profile.jpg',
), ),
fit: BoxFit.cover, fit: BoxFit.cover,
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
), ),
), ),
//child: Image(image: AssetImage('assets/edit_profile/profile.png')) //child: Image(image: AssetImage('assets/edit_profile/profile.png'))
), ),
@ -1217,8 +1233,8 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
'Loading...', // Shows full email on hover 'Loading...', // Shows full email on hover
child: SizedBox( child: SizedBox(
width: MediaQuery.of(context) width: MediaQuery.of(context)
.size .size
.width * .width *
0.6, // Adjust width as needed 0.6, // Adjust width as needed
child: Text( child: Text(
userEmail ?? 'Loading...', userEmail ?? 'Loading...',
@ -1263,7 +1279,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
), ),
), ),
trailing: trailing:
_buildNotificationBadge(count: notificationCount), _buildNotificationBadge(count: notificationCount),
onTap: () => _navigateTo(context, '/notification'), onTap: () => _navigateTo(context, '/notification'),
), ),
ListTile( ListTile(
@ -1395,7 +1411,8 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
), ),
), ),
), ),
onTap: () => _showLogoutConfirmationDialog(context,isDarkTheme), onTap: () =>
_showLogoutConfirmationDialog(context, isDarkTheme),
), ),
if (userId == 'guest') if (userId == 'guest')
ListTile( ListTile(
@ -1740,7 +1757,7 @@ Future<void> logout(BuildContext context) async {
context.go('/login'); // Redirect to login after logout context.go('/login'); // Redirect to login after logout
} }
void _showLogoutConfirmationDialog(BuildContext context,isDarkTheme) { void _showLogoutConfirmationDialog(BuildContext context, isDarkTheme) {
double myheight = MediaQuery.of(context).size.height; double myheight = MediaQuery.of(context).size.height;
showDialog( showDialog(
context: context, context: context,
@ -1787,7 +1804,7 @@ void _showLogoutConfirmationDialog(BuildContext context,isDarkTheme) {
children: [ children: [
SizedBox( SizedBox(
width: width:
MediaQuery.of(context).size.width * 0.3, // Set button width MediaQuery.of(context).size.width * 0.3, // Set button width
child: TextButton( child: TextButton(
onPressed: () => Navigator.pop(dialogContext), onPressed: () => Navigator.pop(dialogContext),
style: TextButton.styleFrom( style: TextButton.styleFrom(
@ -1815,7 +1832,7 @@ void _showLogoutConfirmationDialog(BuildContext context,isDarkTheme) {
SizedBox(width: 16), SizedBox(width: 16),
SizedBox( SizedBox(
width: width:
MediaQuery.of(context).size.width * 0.3, // Set button width MediaQuery.of(context).size.width * 0.3, // Set button width
child: TextButton( child: TextButton(
onPressed: () => logout(context), onPressed: () => logout(context),
style: TextButton.styleFrom( style: TextButton.styleFrom(