Nottification and charts changes added
This commit is contained in:
parent
de820662f7
commit
802a80a549
@ -3,6 +3,7 @@ plugins {
|
||||
id "kotlin-android"
|
||||
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
|
||||
id "dev.flutter.flutter-gradle-plugin"
|
||||
id "com.google.gms.google-services"
|
||||
}
|
||||
|
||||
def localProperties = new Properties()
|
||||
@ -13,14 +14,18 @@ if (localPropertiesFile.exists()) {
|
||||
}
|
||||
}
|
||||
|
||||
if (project.hasProperty('google-services.json')) {
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
}
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = "28"
|
||||
flutterVersionCode = "31"
|
||||
}
|
||||
|
||||
def flutterVersionName = localProperties.getProperty("flutter.versionName")
|
||||
if (flutterVersionName == null) {
|
||||
flutterVersionName = "1.0.27"
|
||||
flutterVersionName = "1.0.30"
|
||||
}
|
||||
|
||||
def keystorePropertiesFile = rootProject.file("key.properties")
|
||||
@ -46,7 +51,7 @@ android {
|
||||
applicationId = "ae.gov.fcsc.frontend"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
||||
minSdk = flutter.minSdkVersion
|
||||
minSdk = 23
|
||||
targetSdk = flutter.targetSdkVersion
|
||||
versionCode = flutterVersionCode.toInteger()
|
||||
versionName = flutterVersionName
|
||||
@ -75,3 +80,9 @@ android {
|
||||
flutter {
|
||||
source = "../.."
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(platform("com.google.firebase:firebase-bom:33.1.2"))
|
||||
implementation 'com.google.firebase:firebase-messaging:22.0.0'
|
||||
implementation("com.google.firebase:firebase-auth:23.0.0")
|
||||
}
|
||||
|
||||
29
android/app/google-services.json
Normal file
29
android/app/google-services.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "62132243005",
|
||||
"project_id": "fcsc-a161c",
|
||||
"storage_bucket": "fcsc-a161c.firebasestorage.app"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:62132243005:android:18b7ca94608afaeb7c7854",
|
||||
"android_client_info": {
|
||||
"package_name": "ae.gov.fcsc.frontend"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyB-QQbnq366f7rrKLVVFJKnSZgR9LcDWFI"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": []
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
@ -63,4 +63,4 @@
|
||||
<data android:mimeType="text/plain" />
|
||||
</intent>
|
||||
</queries>
|
||||
</manifest>
|
||||
</manifest>
|
||||
|
||||
@ -1,3 +1,14 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.1.0' // Update this if needed
|
||||
classpath 'com.google.gms:google-services:4.3.10' // ✅ Required for Firebase
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
|
||||
@ -20,7 +20,7 @@ plugins {
|
||||
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||
id "com.android.application" version "8.2.1" apply false
|
||||
id "org.jetbrains.kotlin.android" version "2.1.0" apply false
|
||||
|
||||
id("com.google.gms.google-services") version "4.4.2" apply false
|
||||
}
|
||||
|
||||
include ":app"
|
||||
|
||||
BIN
assets/FCSC-GIF.gif
Normal file
BIN
assets/FCSC-GIF.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 20 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 14 KiB |
@ -1,3 +1,4 @@
|
||||
// api_config.dart
|
||||
// const String apiUrl = 'http://192.168.1.26:8090';
|
||||
const String apiUrl = 'https://pbdev.venbait.in/';
|
||||
// const String apiUrl = 'https://pbdev.venbait.in/';
|
||||
const String apiUrl = 'https://pb.venbait.in/';
|
||||
|
||||
36
lib/config/loading_overlay.dart
Normal file
36
lib/config/loading_overlay.dart
Normal file
@ -0,0 +1,36 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class LoadingOverlay {
|
||||
static final ValueNotifier<bool> _isLoading = ValueNotifier<bool>(false);
|
||||
|
||||
static void show() {
|
||||
_isLoading.value = true;
|
||||
}
|
||||
|
||||
static void hide() {
|
||||
_isLoading.value = false;
|
||||
}
|
||||
|
||||
static Widget buildLoader() {
|
||||
return ValueListenableBuilder<bool>(
|
||||
valueListenable: _isLoading,
|
||||
builder: (context, isLoading, child) {
|
||||
return isLoading
|
||||
? Stack(
|
||||
children: [
|
||||
ModalBarrier(
|
||||
color: Colors.black.withOpacity(0.5), dismissible: false),
|
||||
Center(
|
||||
child: Image.asset(
|
||||
"assets/images/loading.gif", // Make sure to add the GIF in assets
|
||||
width: 100,
|
||||
height: 100,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: const SizedBox.shrink();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -307,6 +307,7 @@ import 'package:uae_stat/presentation/Screens/charts/screens/chart_screen.dart';
|
||||
import 'package:uae_stat/presentation/Screens/demo_home2.dart';
|
||||
import 'package:uae_stat/presentation/Screens/online_offline_verification/internet_check.dart';
|
||||
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/notification/notification.dart';
|
||||
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/notification/notification_details.dart';
|
||||
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/user_guide/AboutTheApp/AboutFCSC.dart';
|
||||
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/user_guide/AboutTheApp/getStarted.dart';
|
||||
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/user_guide/KeyFeatures/AppFeatures.dart';
|
||||
@ -366,7 +367,6 @@ final GoRouter router = GoRouter(
|
||||
path: '/',
|
||||
//builder: (context, state) => LoginRoute(),
|
||||
builder: (context, state) => SessionCheckScreen(),
|
||||
|
||||
),
|
||||
// GoRoute(
|
||||
// path: '/',
|
||||
@ -426,8 +426,7 @@ final GoRouter router = GoRouter(
|
||||
state.uri.queryParameters['filter_data']!.isNotEmpty) {
|
||||
try {
|
||||
filterData = List<Map<String, dynamic>>.from(
|
||||
jsonDecode(state.uri.queryParameters['filter_data']!)
|
||||
);
|
||||
jsonDecode(state.uri.queryParameters['filter_data']!));
|
||||
} catch (e) {
|
||||
print('Error parsing filter_data: $e');
|
||||
filterData = []; // Assign an empty list to prevent null issues
|
||||
@ -436,8 +435,6 @@ final GoRouter router = GoRouter(
|
||||
filterData = []; // Ensure it's a valid list
|
||||
}
|
||||
|
||||
|
||||
|
||||
print('Router dataSets: $dataSets');
|
||||
print('Router bgColor: $bgColor');
|
||||
print('Router mainTopic: $mainTopic');
|
||||
@ -521,6 +518,18 @@ final GoRouter router = GoRouter(
|
||||
return NotificationPage();
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/notification_details',
|
||||
builder: (context, state) {
|
||||
final Map<String, dynamic> data = state.extra as Map<String, dynamic>;
|
||||
return NotificationDetails(
|
||||
title: data['title'] ?? '',
|
||||
message: data['message'] ?? '',
|
||||
date: data['date'] ?? '',
|
||||
category: data['category'] ?? '',
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/user-guide',
|
||||
builder: (context, state) => Userguide(),
|
||||
|
||||
@ -51,6 +51,7 @@
|
||||
"full_name": "الاسم الكامل",
|
||||
"dob": "تاريخ الميلاد",
|
||||
"region": "الدولة/المنطقة",
|
||||
"preferredLang": "اللغة المفضلة",
|
||||
"cancel": "إلغاء",
|
||||
"confirm": "تأكيد",
|
||||
"change_password": "تغيير كلمة المرور",
|
||||
|
||||
@ -49,6 +49,7 @@
|
||||
"full_name": "Full Name*",
|
||||
"dob": "Date of Birth*",
|
||||
"region": "Country/Region",
|
||||
"preferredLang": "Preferred Language",
|
||||
"cancel": "Cancel",
|
||||
"confirm": "Confirm",
|
||||
"change_password": "Change Password",
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
import 'package:external_repos/external_repos.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
@ -16,8 +18,6 @@ import 'package:uae_stat/presentation/Screens/auth_verification/registration.dar
|
||||
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
|
||||
|
||||
// void main() async {
|
||||
// WidgetsFlutterBinding.ensureInitialized();
|
||||
// // await (await SharedPreferences.getInstance()).clear();
|
||||
@ -46,8 +46,6 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// void main() async {
|
||||
// WidgetsFlutterBinding.ensureInitialized();
|
||||
// // await (await SharedPreferences.getInstance()).clear();
|
||||
@ -91,10 +89,31 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
||||
// Handle background messages
|
||||
print("Handling background message: ${message.messageId}");
|
||||
}
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await Firebase.initializeApp(
|
||||
options: const FirebaseOptions(
|
||||
apiKey: 'AIzaSyB-QQbnq366f7rrKLVVFJKnSZgR9LcDWFI',
|
||||
appId: '1:62132243005:android:18b7ca94608afaeb7c7854',
|
||||
messagingSenderId: '62132243005',
|
||||
projectId: 'fcsc-a161c'));
|
||||
|
||||
FirebaseMessaging messaging = FirebaseMessaging.instance;
|
||||
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
|
||||
|
||||
// Request permission for notifications
|
||||
NotificationSettings settings = await messaging.requestPermission(
|
||||
alert: true,
|
||||
badge: true,
|
||||
sound: true,
|
||||
);
|
||||
|
||||
print('User granted permission: ${settings.authorizationStatus}');
|
||||
configureDependencies();
|
||||
runApp(
|
||||
const ProviderScope(
|
||||
@ -106,9 +125,6 @@ void main() async {
|
||||
class MainApp extends ConsumerWidget {
|
||||
const MainApp({super.key});
|
||||
|
||||
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final locale = ref.watch(localeProvider);
|
||||
@ -117,14 +133,13 @@ class MainApp extends ConsumerWidget {
|
||||
return true; // Replace with actual logic
|
||||
});
|
||||
|
||||
|
||||
// ref.listen<bool>(connectivityProvider, (previous, hasInternet) {
|
||||
// print('Previous Internet Status: $previous');
|
||||
// print('Current Internet Status: $hasInternet');
|
||||
// if (previous != null && hasInternet != previous) {
|
||||
// handleConnectivityChange(context, hasInternet);
|
||||
// }
|
||||
// });
|
||||
ref.listen<bool>(connectivityProvider, (previous, hasInternet) {
|
||||
print('Previous Internet Status: $previous');
|
||||
print('Current Internet Status: $hasInternet');
|
||||
if (previous != null && hasInternet != previous) {
|
||||
handleConnectivityChange(context, hasInternet);
|
||||
}
|
||||
});
|
||||
|
||||
return MaterialApp.router(
|
||||
debugShowCheckedModeBanner: false,
|
||||
@ -137,7 +152,8 @@ class MainApp extends ConsumerWidget {
|
||||
|
||||
void handleConnectivityChange(BuildContext context, bool hasInternet) {
|
||||
//final currentPath = GoRouter.of(context).location;
|
||||
final currentPath = GoRouter.of(context).routerDelegate.currentConfiguration.fullPath;
|
||||
final currentPath =
|
||||
GoRouter.of(context).routerDelegate.currentConfiguration.fullPath;
|
||||
if (!hasInternet && currentPath != '/internetcheck') {
|
||||
print("Status : Not connected");
|
||||
context.go('/internetcheck');
|
||||
@ -147,6 +163,3 @@ class MainApp extends ConsumerWidget {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.
|
||||
import 'package:uae_stat/presentation/components/constant/constant.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:uae_stat/config/api_config.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
class UaeNumbers extends StatelessWidget {
|
||||
const UaeNumbers({super.key});
|
||||
@ -198,14 +198,17 @@ class _UaenumberWidgetState extends ConsumerState<uaenumberWidget> {
|
||||
value); // Call filter function directly on input change
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search",
|
||||
hintStyle: TextStyle(color: Color(0xFF898C81)),
|
||||
prefixIconConstraints: BoxConstraints(maxWidth: 42, maxHeight: 42),
|
||||
hintText: AppLocalizations.of(context)!.search,
|
||||
hintStyle: TextStyle(color: Color(0xFFAA8E83)),
|
||||
prefixIconConstraints:
|
||||
BoxConstraints(maxWidth: 42, maxHeight: 42),
|
||||
prefixIcon: Container(
|
||||
padding: EdgeInsets.only(right: 5),
|
||||
padding: EdgeInsets.only(right: 5, left: 5),
|
||||
child: SvgPicture.asset(
|
||||
MiscIconAssetPath.Search,
|
||||
semanticsLabel: 'Search',
|
||||
colorFilter:
|
||||
ColorFilter.mode(Color(0xFFAA8E83), BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
|
||||
@ -215,7 +218,7 @@ class _UaenumberWidgetState extends ConsumerState<uaenumberWidget> {
|
||||
// ),
|
||||
border: InputBorder.none,
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(vertical: 8.0, horizontal: 18.0),
|
||||
EdgeInsets.symmetric(vertical: 0.5, horizontal: 18.0),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -54,7 +54,7 @@ class ChartScreen1 extends ConsumerStatefulWidget {
|
||||
class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
// final _pb = PocketBase('https://pb.venbait.in');
|
||||
final _pb = PocketBase(apiUrl);
|
||||
List<Map<String, dynamic>> selectedFiltersStorage = [];
|
||||
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
final ApiService apiService = ApiService();
|
||||
bool isLoading = true;
|
||||
@ -68,6 +68,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
List<dynamic> tabFilteredCardData = [];
|
||||
List<dynamic> cardData = [];
|
||||
List<Map<String, dynamic>> filteredAndSortedData = [];
|
||||
List<Map<String, dynamic>> selectedFiltersStorage = [];
|
||||
List<Map<String, dynamic>> selectedFiltersApi = [];
|
||||
List<dynamic> originalChartsData = [];
|
||||
List<dynamic> originalCardData = [];
|
||||
List<dynamic> originalTabCardData = [];
|
||||
@ -75,11 +77,12 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
late Color backgroundColor;
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
int _activeTabIndex = 0;
|
||||
dynamic tabWiseKpi=[];
|
||||
dynamic tabFilteredKpi=[];
|
||||
List<Map<String, dynamic>> formattedFilters=[];
|
||||
dynamic tabWiseKpi = [];
|
||||
dynamic tabFilteredKpi = [];
|
||||
List<Map<String, dynamic>> formattedFilters = [];
|
||||
|
||||
dynamic _tabsData = [];
|
||||
dynamic currentTab = [];
|
||||
// List<Map<String, dynamic>> _tabsData = [];
|
||||
late List<TargetFocus> marriageTargets;
|
||||
late List<TargetFocus> previousMarriageTargets;
|
||||
@ -90,6 +93,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
bool isBookmarked = false; // Track bookmark state
|
||||
String? bookmarkId; // Stores the ID of the bookmark record in PocketBase
|
||||
late final Locale locale;
|
||||
late String mainTopic;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -98,10 +102,12 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
print(' bgColor $bgColor');
|
||||
checkIfBookmarked();
|
||||
locale = ref.read(localeProvider) ?? const Locale('en');
|
||||
print('locale-$locale');
|
||||
|
||||
fetchChartData(widget.dataSets, locale?.languageCode ?? 'en', widget.kpi, widget.filter_data)
|
||||
.then((_) {
|
||||
if(_tabsData.isNotEmpty) {
|
||||
fetchChartData(widget.dataSets, locale?.languageCode ?? 'en', widget.kpi,
|
||||
widget.filter_data)
|
||||
.then((_) {
|
||||
if (_tabsData.isNotEmpty) {
|
||||
// Call onTabSelected for the first tab
|
||||
onTabSelected(_tabsData[0]['id']);
|
||||
}
|
||||
@ -313,7 +319,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
backgroundColor: Color(0xFFAA8E83), // Set background color
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10.0), // Set text color
|
||||
borderRadius:
|
||||
BorderRadius.circular(10.0), // Set text color
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
@ -324,7 +331,6 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
],
|
||||
),
|
||||
);
|
||||
@ -371,29 +377,30 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
SizedBox(height: 20),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [ SizedBox(
|
||||
width: 100, // Set the desired width
|
||||
child: TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
style: TextButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
10.0), // Adjust the radius as needed
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 100, // Set the desired width
|
||||
child: TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
style: TextButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
10.0), // Adjust the radius as needed
|
||||
),
|
||||
side: BorderSide(
|
||||
color: Color(0xFFAA8E83), // Set the outline color
|
||||
width: 1, // Set the border width
|
||||
),
|
||||
),
|
||||
side: BorderSide(
|
||||
color: Color(0xFFAA8E83), // Set the outline color
|
||||
width: 1, // Set the border width
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
context.translate('No', 'لا'),
|
||||
style: TextStyle(
|
||||
color: Color(0xFFAA8E83),
|
||||
fontSize: 16,
|
||||
child: Text(
|
||||
context.translate('No', 'لا'),
|
||||
style: TextStyle(
|
||||
color: Color(0xFFAA8E83),
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 100, // Set the desired width
|
||||
child: TextButton(
|
||||
@ -405,7 +412,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
backgroundColor: Color(0xFFAA8E83), // Set background color
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10.0), // Set text color
|
||||
borderRadius:
|
||||
BorderRadius.circular(10.0), // Set text color
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
@ -413,7 +421,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
style: TextStyle(color: Colors.white, fontSize: 16),
|
||||
),
|
||||
),
|
||||
),],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -1268,13 +1277,28 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> fetchChartData(String dataSets, locale, kpi, filter_data ) async {
|
||||
var data = await apiService.fetchChartData(dataSets, locale,kpi,filter_data);
|
||||
Future<void> fetchChartData(String dataSets, locale, kpi, filter_data) async {
|
||||
var data =
|
||||
await apiService.fetchChartData(dataSets, locale, kpi, filter_data);
|
||||
|
||||
tabFilteredKpi = kpi;
|
||||
print('FETCH KPI- $kpi');
|
||||
print('FETCH KFilter- $filter_data');
|
||||
print('locale1 - $locale');
|
||||
// print('locale11 - $loacleData');
|
||||
|
||||
// Store filter_data if it has a value
|
||||
if (filter_data != null && filter_data is List && filter_data.isNotEmpty) {
|
||||
selectedFiltersApi = filter_data.map<Map<String, dynamic>>((entry) {
|
||||
if (entry is Map<dynamic, dynamic>) {
|
||||
return entry.map<String, dynamic>(
|
||||
(key, value) => MapEntry(key.toString(), value));
|
||||
}
|
||||
return {};
|
||||
}).toList();
|
||||
|
||||
print('FETVCFILTEr: $selectedFiltersApi');
|
||||
}
|
||||
|
||||
if (data.containsKey('filterData')) {
|
||||
var filterData = data['filterData'];
|
||||
@ -1316,7 +1340,6 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
|
||||
void applyFilters(BuildContext context, List filters, List data,
|
||||
List dataCard, List selectedFilters) {
|
||||
|
||||
print('applyFilters called');
|
||||
print('Selected ApplyFilters: $selectedFilters');
|
||||
|
||||
@ -1332,37 +1355,38 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
}
|
||||
|
||||
// Transform the selectedFilters list into the required format
|
||||
formattedFilters = selectedFilters
|
||||
.where((filter) => filter['filter_data'] != null && filter['filter_data'].isNotEmpty)
|
||||
.map((filter){
|
||||
return{
|
||||
formattedFilters = selectedFilters
|
||||
// .where((filter) => filter['filter_data'] != null && filter['filter_data'].isNotEmpty)
|
||||
.map((filter) {
|
||||
return {
|
||||
'filter_key': filter['filter_key'],
|
||||
'filter_data':filter['filter_data'].map((item)=> item.toString()).toList()
|
||||
'filter_data':
|
||||
filter['filter_data'].map((item) => item.toString()).toList()
|
||||
};
|
||||
}).toList();
|
||||
|
||||
print('Formatted Filters1: $formattedFilters');
|
||||
|
||||
// Convert to JSON format
|
||||
String selectedFormatFilters = jsonEncode({
|
||||
'kpi': tabWiseKpi,
|
||||
'filter_data': formattedFilters
|
||||
});
|
||||
String selectedFormatFilters =
|
||||
jsonEncode({'kpi': tabWiseKpi, 'filter_data': formattedFilters});
|
||||
|
||||
print('Formatted Filters2: $selectedFormatFilters');
|
||||
final locale = ref.watch(localeProvider)?.languageCode ?? 'en';
|
||||
|
||||
// Call fetchChartData with correct parameters
|
||||
print('locale2- $locale');
|
||||
|
||||
// Call fetchChartData with correct parameters
|
||||
fetchChartData(
|
||||
widget.dataSets,
|
||||
locale.languageCode ?? 'en',
|
||||
locale,
|
||||
tabWiseKpi, // Ensure you are passing the correct KPI here
|
||||
formattedFilters // Pass the formatted filter data here
|
||||
);
|
||||
);
|
||||
Navigator.pop(context);
|
||||
|
||||
selectedFiltersStorage = List.from(selectedFilters);
|
||||
print('selectedFiltersStoraged- $selectedFiltersStorage');
|
||||
|
||||
}
|
||||
|
||||
void applyFilters1(BuildContext context, List filters, List data,
|
||||
@ -1503,7 +1527,6 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
}
|
||||
|
||||
void showRightSideModal(BuildContext context, List filters, List data) {
|
||||
|
||||
print('selectedFiltersStoraged1- $selectedFiltersStorage');
|
||||
|
||||
// Initialize selected filters structure from the stored value, if exists
|
||||
@ -1532,7 +1555,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
// Header Section
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 16.0, bottom: 0.0, left: 16.0, right: 16.0),
|
||||
top: 26.0, bottom: 0.0, left: 16.0, right: 16.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
@ -1541,7 +1564,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
SvgPicture.asset(
|
||||
UaeNumbersAssetPath.filterCharts,
|
||||
semanticsLabel: 'Filter',
|
||||
colorFilter:ColorFilter.mode(Color(0xFF8E8E8E),BlendMode.srcIn),
|
||||
colorFilter: ColorFilter.mode(
|
||||
Color(0xFF8E8E8E), BlendMode.srcIn),
|
||||
width: 25,
|
||||
height: 25,
|
||||
),
|
||||
@ -1617,6 +1641,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
builder: (context, dialogSetState) {
|
||||
final locale =
|
||||
ref.watch(localeProvider);
|
||||
|
||||
print('localelocale $locale');
|
||||
return AlertDialog(
|
||||
title: Text(
|
||||
@ -1786,13 +1811,13 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
cardData = List.from(originalTabCardData);
|
||||
});
|
||||
selectedFiltersStorage.clear();
|
||||
formattedFilters = [];
|
||||
formattedFilters = [];
|
||||
fetchChartData(
|
||||
widget.dataSets,
|
||||
locale.languageCode ?? 'en',
|
||||
tabWiseKpi, // Ensure you are passing the correct KPI here
|
||||
formattedFilters // Pass the formatted filter data here
|
||||
);
|
||||
);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
@ -1877,9 +1902,14 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
void onTabSelected(String tabId) {
|
||||
print('Selected Tab on: $tabId');
|
||||
tabWiseKpi = tabId;
|
||||
print('Selected Tab tabWiseKpi: $tabWiseKpi');
|
||||
|
||||
selectedFiltersStorage.clear();
|
||||
|
||||
if (selectedFiltersApi.isNotEmpty && tabWiseKpi == tabFilteredKpi) {
|
||||
selectedFiltersStorage = List.from(selectedFiltersApi);
|
||||
}
|
||||
|
||||
// selectedFiltersStorage.clear();
|
||||
// Filter the filterDataSet
|
||||
filterData = filterDataSet
|
||||
.where((item) => item['key'] == tabId)
|
||||
.map((item) => item['value'])
|
||||
@ -1887,9 +1917,63 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
.expand((item) => item)
|
||||
.toList();
|
||||
|
||||
print("FilteringDAtss START1 - $filterData");
|
||||
print("FilteringDAtss START1d - $filterData");
|
||||
print('TABId1 - $tabId');
|
||||
|
||||
Map<String, int> monthMap = {
|
||||
'jan': 1,
|
||||
'feb': 2,
|
||||
'mar': 3,
|
||||
'apr': 4,
|
||||
'may': 5,
|
||||
'jun': 6,
|
||||
'jul': 7,
|
||||
'aug': 8,
|
||||
'sep': 9,
|
||||
'oct': 10,
|
||||
'nov': 11,
|
||||
'dec': 12
|
||||
};
|
||||
|
||||
for (var item in filterData) {
|
||||
if (item['filter_key'] == 'TIME_PERIOD') {
|
||||
List<String> timePeriods = List<String>.from(item['filter_data']);
|
||||
|
||||
timePeriods.sort((a, b) {
|
||||
List<String> aParts = a.split(RegExp(r'[-_]'));
|
||||
List<String> bParts = b.split(RegExp(r'[-_]'));
|
||||
|
||||
int yearA = int.parse(aParts[0]);
|
||||
int yearB = int.parse(bParts[0]);
|
||||
|
||||
// if (yearA != yearB) return yearA.compareTo(yearB);
|
||||
if (yearA != yearB)
|
||||
return yearB.compareTo(yearA); // Sort years in descending order
|
||||
|
||||
if (aParts.length == 1) return -1; // Year-only comes first
|
||||
if (bParts.length == 1) return 1; // Year-only comes first
|
||||
|
||||
int monthA =
|
||||
int.tryParse(aParts[1]) ?? monthMap[aParts[1].toLowerCase()] ?? 0;
|
||||
int monthB =
|
||||
int.tryParse(bParts[1]) ?? monthMap[bParts[1].toLowerCase()] ?? 0;
|
||||
|
||||
return monthB.compareTo(
|
||||
monthA); // Sort months in descending order within the same year
|
||||
// return monthA.compareTo(monthB);
|
||||
});
|
||||
|
||||
item['filter_data'] = timePeriods;
|
||||
} else if (item['filter_key'] == 'REF_AREA') {
|
||||
continue;
|
||||
} else {
|
||||
// Sort alphabetically for all other cases
|
||||
List<String> otherFilters = List<String>.from(item['filter_data']);
|
||||
otherFilters.sort((a, b) => a.toLowerCase().compareTo(b.toLowerCase()));
|
||||
item['filter_data'] = otherFilters;
|
||||
}
|
||||
}
|
||||
|
||||
// for (var item in filterData) {
|
||||
// if (item['filter_key'] == 'TIME_PERIOD') {
|
||||
// // Convert the values to integers, sort them, and convert back to strings
|
||||
@ -1914,7 +1998,6 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
}
|
||||
|
||||
void performActionForTab(String tabId) {
|
||||
|
||||
print('Selected Tab perform: $tabId');
|
||||
|
||||
// Filter the chartsData array based on the tabId
|
||||
@ -2007,25 +2090,39 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
Widget build(BuildContext context) {
|
||||
final locale = ref.watch(localeProvider);
|
||||
final localeNotifier = ref.read(localeProvider.notifier);
|
||||
|
||||
ref.listen<Locale?>(localeProvider, (previous, next) {
|
||||
final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null
|
||||
|
||||
// fetchChartData(widget.dataSets, localeCode);
|
||||
print('Saving currentTab: $tabWiseKpi before locale change');
|
||||
print('localeCodeWgt- $localeCode');
|
||||
currentTab = tabWiseKpi;
|
||||
print('Saving currentTab: $currentTab After locale change');
|
||||
|
||||
|
||||
final List<Map<String, dynamic>> safeFilterData = widget.filter_data ?? [];
|
||||
final List<Map<String, dynamic>> safeFilterData =
|
||||
widget.filter_data ?? [];
|
||||
final String safeKpi = widget.kpi ?? '';
|
||||
fetchChartData(widget.dataSets,localeCode, safeKpi, safeFilterData).then((_) {
|
||||
fetchChartData(widget.dataSets, localeCode, safeKpi, safeFilterData)
|
||||
.then((_) {
|
||||
print('DEBUG KPI: $safeKpi');
|
||||
if (_tabsData.isNotEmpty) {
|
||||
|
||||
print('TAB11: $currentTab');
|
||||
|
||||
if (currentTab.isNotEmpty) {
|
||||
// Call onTabSelected for the first tab
|
||||
onTabSelected(currentTab);
|
||||
print('TAB1: $currentTab');
|
||||
} else if (_tabsData.isNotEmpty) {
|
||||
// Call onTabSelected for the first tab
|
||||
print('TAB2: $_tabsData');
|
||||
onTabSelected(_tabsData[0]['id']);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
double myheight = MediaQuery.of(context).size.height;
|
||||
double mywidth = MediaQuery.of(context).size.width;
|
||||
mainTopic = chartScreenData['main_topic'] ?? '';
|
||||
|
||||
int crossAxisCount =
|
||||
cardData.isNotEmpty ? (cardData.length / 2).ceil().clamp(1, 2) : 1;
|
||||
@ -2046,8 +2143,10 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
(chartScreenData['body_color'] ?? '#898C81').replaceFirst('#', '0xff'),
|
||||
),
|
||||
);
|
||||
final chartHeader = chartScreenData['main_topic'] ?? '';
|
||||
|
||||
print('ChartScrnBodyColor');
|
||||
print('chartHeader - $chartHeader');
|
||||
print(chartScreenData['body_color']);
|
||||
print(
|
||||
Color(int.parse((chartScreenData['body_color'] ?? '#898C81')
|
||||
@ -2098,7 +2197,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
children: [
|
||||
Text(
|
||||
// widget.mainTopic ?? '',
|
||||
chartScreenData['main_topic'] ?? '',
|
||||
// chartScreenData['main_topic'] ?? '',
|
||||
mainTopic,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 26,
|
||||
@ -2223,28 +2323,29 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () => shareCurrentPage(context),
|
||||
|
||||
child: Row(
|
||||
onTap: () => shareCurrentPage(context),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
context.translate(
|
||||
'Share',
|
||||
'يشارك',
|
||||
Text(
|
||||
context.translate(
|
||||
'Share',
|
||||
'يشارك',
|
||||
),
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
SvgPicture.asset(
|
||||
UaeNumbersAssetPath.share,
|
||||
semanticsLabel: 'share',
|
||||
width: 24,
|
||||
height: 24,
|
||||
)
|
||||
],),),
|
||||
SizedBox(width: 5),
|
||||
SvgPicture.asset(
|
||||
UaeNumbersAssetPath.share,
|
||||
semanticsLabel: 'share',
|
||||
width: 24,
|
||||
height: 24,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
@ -2353,7 +2454,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
// ),
|
||||
// nonChartData Cards
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
padding: const EdgeInsets.only(
|
||||
top: 8.0, left: 1.0, right: 1.0),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
List<Widget> rows = [];
|
||||
@ -2431,23 +2533,32 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
children: [
|
||||
// ConstrainedBox
|
||||
Container(
|
||||
height: (chartsData[index]
|
||||
['chart_type'] ==
|
||||
'pie_chart')
|
||||
? 500
|
||||
: (chartsData[index][
|
||||
'chart_type'] ==
|
||||
'bar_chart_horizontal')
|
||||
? 370
|
||||
: (chartsData[index]['chart_type'] == 'fl_stacked_bar')
|
||||
? 390
|
||||
: 350,
|
||||
height: (chartsData[index]
|
||||
['chart_type'] ==
|
||||
'pie_chart')
|
||||
? 500
|
||||
: (chartsData[index][
|
||||
'chart_type'] ==
|
||||
'bar_chart_horizontal')
|
||||
? 370
|
||||
: (chartsData[index][
|
||||
'chart_type'] ==
|
||||
'horizontal_rotate')
|
||||
? 385
|
||||
: (chartsData[index]
|
||||
[
|
||||
'chart_type'] ==
|
||||
'fl_stacked_bar')
|
||||
? 390
|
||||
: 350,
|
||||
|
||||
// child: buildChart(chartsData[index]),
|
||||
child: ChartWidget(
|
||||
chartData:
|
||||
chartsData[index],
|
||||
bodyColor: bodyColor))
|
||||
// child: buildChart(chartsData[index]),
|
||||
child: ChartWidget(
|
||||
chartData:
|
||||
chartsData[index],
|
||||
bodyColor: bodyColor,
|
||||
chartHeader: chartHeader),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -2595,16 +2706,14 @@ class CardWidget extends StatelessWidget {
|
||||
|
||||
final bodyColor = Color(
|
||||
int.parse(
|
||||
(chartScreenData['body_color'] ?? '#898C81').replaceFirst('#', '0xff'),
|
||||
(chartScreenData['border_color'] ?? '#898C81')
|
||||
.replaceFirst('#', '0xff'),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
if(response.isEmpty)
|
||||
{
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
else if (response.length == 1) {
|
||||
if (response.isEmpty) {
|
||||
return SizedBox.shrink();
|
||||
} else if (response.length == 1) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.all(10),
|
||||
// width: card_full_length ? double.infinity : null,
|
||||
@ -2626,7 +2735,7 @@ class CardWidget extends StatelessWidget {
|
||||
elevation: 2,
|
||||
child: Container(
|
||||
// height: cardHeight,
|
||||
height: 160,
|
||||
height: 175,
|
||||
padding: const EdgeInsets.only(
|
||||
left: 16.0, right: 16.0, bottom: 2.0, top: 1.0),
|
||||
decoration: BoxDecoration(
|
||||
@ -2757,7 +2866,7 @@ class CardWidget extends StatelessWidget {
|
||||
elevation: 0, // Remove shadow to keep only the outli
|
||||
|
||||
child: Container(
|
||||
height: 160,
|
||||
height: 175,
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
// padding: const EdgeInsets.only(
|
||||
// left: 10.0, right: 10.0, bottom: 5.0, top: 1.0),
|
||||
@ -2767,7 +2876,8 @@ class CardWidget extends StatelessWidget {
|
||||
BorderRadius.circular(12), // Ensure border radius is applied
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min, // Adjust card height based on content
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Adjust card height based on content
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// const Icon(Icons.public,
|
||||
@ -2840,8 +2950,6 @@ class CardWidget extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 1),
|
||||
|
||||
|
||||
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment
|
||||
.center, // Center-aligns the row contents
|
||||
@ -2870,19 +2978,15 @@ class CardWidget extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
|
||||
|
||||
SizedBox(
|
||||
height: 2, // Height of the divider
|
||||
width: 100,
|
||||
width: 100,
|
||||
child: Divider(
|
||||
color: Color(0xFFBBBCBD),
|
||||
thickness: 1, // Divider line thickness
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
|
||||
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment
|
||||
.center, // Center-aligns the row contents
|
||||
@ -2897,7 +3001,8 @@ class CardWidget extends StatelessWidget {
|
||||
: _getColorFromHex(response[1]['font_color']),
|
||||
),
|
||||
textAlign: TextAlign.center, // Ensure proper alignment
|
||||
overflow: TextOverflow.ellipsis, // Truncate if text overflows
|
||||
overflow:
|
||||
TextOverflow.ellipsis, // Truncate if text overflows
|
||||
),
|
||||
const SizedBox(width: 1), // Space between text and icon
|
||||
if (response[1]['font_color'] != '') ...[
|
||||
@ -2911,7 +3016,6 @@ class CardWidget extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
|
||||
|
||||
Text(
|
||||
// '(${response[1]['display_value'] ?? 'NA'})',
|
||||
RegExp(r'\d').hasMatch(response[1]['display_value'] ?? '')
|
||||
|
||||
@ -16,7 +16,7 @@ class ApiService {
|
||||
// static const String baseUrl = 'https://pb.venbait.in/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) async {
|
||||
List<dynamic> isChartData = [];
|
||||
List<dynamic> nonChartData = [];
|
||||
@ -28,14 +28,14 @@ class ApiService {
|
||||
// '$baseUrl?dataset=$dataSets&language=$locale&kpi=$kpi&filter_data=${Uri.encodeComponent(jsonEncode(filterData))}'
|
||||
// );
|
||||
|
||||
|
||||
final url = Uri.parse(baseUrl); // No query parameters in URL for POST
|
||||
|
||||
final Map<String, dynamic> requestBody = {
|
||||
'dataset': dataSets,
|
||||
'language': locale,
|
||||
'kpi': kpi.isNotEmpty ? kpi : null, // Avoid sending empty kpi
|
||||
'filter_data': filterData.isNotEmpty ? filterData : null, // Avoid empty list
|
||||
'filter_data':
|
||||
filterData.isNotEmpty ? filterData : [], // Avoid empty list
|
||||
};
|
||||
|
||||
// final url = Uri.https('$baseUrl?dataset=$dataSets&language=$locale');
|
||||
@ -66,8 +66,9 @@ class ApiService {
|
||||
nonChartData.add(item);
|
||||
}
|
||||
}
|
||||
final Map<String, dynamic> chartScreenData = jsonData['screen_heading_and_color'];
|
||||
|
||||
final Map<String, dynamic> chartScreenData =
|
||||
jsonData['screen_heading_and_color'];
|
||||
|
||||
// Save original data for reset
|
||||
// originalChartsData = List.from(isChartData); // Store original data
|
||||
// originalCardData = List.from(nonChartData); // Store original data
|
||||
@ -77,7 +78,7 @@ class ApiService {
|
||||
'isChartData': isChartData,
|
||||
'nonChartData': nonChartData,
|
||||
'filterData': jsonData['new_filter_data'],
|
||||
'chartScreenData' :chartScreenData
|
||||
'chartScreenData': chartScreenData
|
||||
// 'filterData': jsonData['filter_data']
|
||||
// 'originalChartsData': originalChartsData,
|
||||
// 'originalCardData': originalCardData,
|
||||
@ -195,4 +196,4 @@ class ApiService {
|
||||
return '$amount';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -75,7 +75,9 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
'India',
|
||||
'Canada'
|
||||
];
|
||||
final List<String> preferred_language = ['English', 'Arabic'];
|
||||
String? _selectedCountry;
|
||||
String? _selectedLanguage;
|
||||
bool isChecked = false;
|
||||
bool showError = false;
|
||||
final _picker = ImagePicker();
|
||||
@ -86,6 +88,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
late Future<RecordModel> userDetails;
|
||||
bool _isHoveringDate = false;
|
||||
bool _isHoveringDropdown = false;
|
||||
bool _isHoveringPreferredLang = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -187,10 +190,10 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
_isLoading = true; // Start loading
|
||||
});
|
||||
final XFile? pickedFile =
|
||||
await _picker.pickImage(source: ImageSource.gallery);
|
||||
await _picker.pickImage(source: ImageSource.gallery);
|
||||
if (pickedFile != null) {
|
||||
final String fileExtension =
|
||||
pickedFile.path.split('.').last.toLowerCase();
|
||||
pickedFile.path.split('.').last.toLowerCase();
|
||||
if (fileExtension == 'jpg' ||
|
||||
fileExtension == 'jpeg' ||
|
||||
fileExtension == 'png' ||
|
||||
@ -227,7 +230,8 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
builder: (context, child) {
|
||||
return Theme(
|
||||
data: Theme.of(context).copyWith(
|
||||
dialogBackgroundColor: Colors.white, // Background color of the date picker
|
||||
dialogBackgroundColor:
|
||||
Colors.white, // Background color of the date picker
|
||||
textButtonTheme: TextButtonThemeData(
|
||||
style: ButtonStyle(
|
||||
shape: WidgetStateProperty.all(RoundedRectangleBorder(
|
||||
@ -237,8 +241,10 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
),
|
||||
datePickerTheme: DatePickerThemeData(
|
||||
confirmButtonStyle: ButtonStyle(
|
||||
backgroundColor: WidgetStateProperty.all(Color(0xFFAA8E83)), // OK button background color
|
||||
foregroundColor: WidgetStateProperty.all(Colors.white), // OK button text color
|
||||
backgroundColor: WidgetStateProperty.all(
|
||||
Color(0xFFAA8E83)), // OK button background color
|
||||
foregroundColor: WidgetStateProperty.all(
|
||||
Colors.white), // OK button text color
|
||||
// minimumSize: WidgetStateProperty.all(Size(150, 50)),
|
||||
minimumSize: WidgetStateProperty.all(Size(100, 40)),
|
||||
shape: WidgetStateProperty.all(RoundedRectangleBorder(
|
||||
@ -247,12 +253,14 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
),
|
||||
cancelButtonStyle: ButtonStyle(
|
||||
// backgroundColor: WidgetStateProperty.all(Colors.white), // Cancel button background color
|
||||
foregroundColor: WidgetStateProperty.all(Color(0xFFAA8E83)), // Cancel button text color
|
||||
foregroundColor: WidgetStateProperty.all(
|
||||
Color(0xFFAA8E83)), // Cancel button text color
|
||||
// minimumSize: WidgetStateProperty.all(Size(150, 50)),
|
||||
minimumSize: WidgetStateProperty.all(Size(100, 40)),
|
||||
shape: WidgetStateProperty.all(RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12.0), // Rounded corners
|
||||
side: const BorderSide(color: Color(0xFFAA8E83), width: 2), // Outline color
|
||||
side: const BorderSide(
|
||||
color: Color(0xFFAA8E83), width: 2), // Outline color
|
||||
)),
|
||||
),
|
||||
),
|
||||
@ -262,7 +270,6 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
if (pickedDate != null && pickedDate != _selectedDate) {
|
||||
setState(() {
|
||||
_selectedDate = pickedDate;
|
||||
@ -282,7 +289,8 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
|
||||
// Check if the selected date is in the future
|
||||
if (selectedDate.isAfter(today)) {
|
||||
return context.translate('Date of birth cannot be in the future','لا يمكن أن يكون تاريخ الميلاد في المستقبل');
|
||||
return context.translate('Date of birth cannot be in the future',
|
||||
'لا يمكن أن يكون تاريخ الميلاد في المستقبل');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -315,6 +323,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
// String email = 'surendarsuri30@gmail.com';
|
||||
String dateOfBirth = _dateController.text; // in DD/MM/YYYY format
|
||||
String countryRegion = _selectedCountry ?? '';
|
||||
String preferredLang = _selectedLanguage == 'English' ? 'en' : 'ar';
|
||||
bool termsAccepted = isChecked;
|
||||
|
||||
// Parse the date from dd/MM/yyyy format and convert to yyyy-MM-dd
|
||||
@ -324,13 +333,14 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
|
||||
// Create a multipart request
|
||||
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);
|
||||
|
||||
// Add other fields
|
||||
request.fields['full_name'] = fullName;
|
||||
request.fields['dob'] = formattedDob;
|
||||
request.fields['country_region'] = countryRegion;
|
||||
request.fields['language'] = preferredLang;
|
||||
request.fields['is_profile_completed'] = 'True';
|
||||
|
||||
// Add the file, if available
|
||||
@ -371,6 +381,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
_fullNameController.clear();
|
||||
_dateController.clear();
|
||||
_selectedCountry = null;
|
||||
_selectedLanguage = null;
|
||||
isChecked = false;
|
||||
|
||||
// Reset profile image
|
||||
@ -399,14 +410,15 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
'Logout',
|
||||
'تسجيل الخروج',
|
||||
),
|
||||
style: TextStyle(color: Color(0xFF898C81),fontWeight: FontWeight.w700),
|
||||
style:
|
||||
TextStyle(color: Color(0xFF898C81), fontWeight: FontWeight.w700),
|
||||
),
|
||||
content: Text(
|
||||
context.translate(
|
||||
'Are you sure you want to logout?',
|
||||
'هل أنت متأكد أنك تريد تسجيل الخروج؟',
|
||||
),
|
||||
style: TextStyle(color:Color(0xFF898C81)),
|
||||
style: TextStyle(color: Color(0xFF898C81)),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
@ -414,7 +426,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
style: TextButton.styleFrom(
|
||||
// backgroundColor:
|
||||
// Color(0xFFAA8E83), // Set background color
|
||||
side: BorderSide(color: Color(0xFFAA8E83), width: 2),
|
||||
side: BorderSide(color: Color(0xFFAA8E83), width: 2),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10.0), // Set text color
|
||||
),
|
||||
@ -432,12 +444,10 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
TextButton(
|
||||
onPressed: () => logout(context), // Exit the app
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor:
|
||||
Color(0xFFAA8E83), // Set background color
|
||||
backgroundColor: Color(0xFFAA8E83), // Set background color
|
||||
// foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(10.0), // Set text color
|
||||
borderRadius: BorderRadius.circular(10.0), // Set text color
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
@ -560,7 +570,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
backgroundImage: _profileImage != null
|
||||
? FileImage(_profileImage!)
|
||||
: AssetImage("assets/edit_profile/profile.png")
|
||||
as ImageProvider,
|
||||
as ImageProvider,
|
||||
child: Align(
|
||||
alignment: Alignment.bottomRight,
|
||||
child: GestureDetector(
|
||||
@ -584,7 +594,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor:
|
||||
AlwaysStoppedAnimation<Color>(Colors.grey),
|
||||
AlwaysStoppedAnimation<Color>(Colors.grey),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -673,19 +683,18 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
r"^[a-zA-Z0-9'\-\u0627\u0639~\u00C0-\u00FF\s]+$");
|
||||
|
||||
if (!nameRegex.hasMatch(value)) {
|
||||
return AppLocalizations.of(context)!.invalid_characters;
|
||||
return AppLocalizations.of(context)!
|
||||
.invalid_characters;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
controller: _fullNameController,
|
||||
focusNode: _focusNodes[2],
|
||||
decoration: InputDecoration(
|
||||
enabledBorder:OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(10),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(
|
||||
color: MyTheme.topicColor(
|
||||
IndicatorTopic.economy)
|
||||
color: MyTheme.topicColor(IndicatorTopic.economy)
|
||||
.shade400,
|
||||
width: 1), // Enabled border
|
||||
),
|
||||
@ -695,7 +704,8 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
fontSize: 14,
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderSide:BorderSide(color: Color(0xFF7296BE),
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFF7296BE),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
@ -723,17 +733,17 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
controller: _dateController,
|
||||
focusNode: _focusNodes[3],
|
||||
decoration: InputDecoration(
|
||||
enabledBorder:OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(10),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(
|
||||
color: MyTheme.topicColor(
|
||||
IndicatorTopic.economy)
|
||||
.shade400,
|
||||
color:
|
||||
MyTheme.topicColor(IndicatorTopic.economy)
|
||||
.shade400,
|
||||
width: 1), // Enabled border
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderSide:BorderSide(color: Color(0xFF7296BE),
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFF7296BE),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
@ -748,10 +758,11 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
width: 45,
|
||||
padding: EdgeInsets.only(right: 1),
|
||||
alignment:
|
||||
Alignment.center, // Center the icon vertically
|
||||
Alignment.center, // Center the icon vertically
|
||||
child: Icon(
|
||||
Icons.keyboard_arrow_down_sharp,
|
||||
color: _isHoveringDate ? Colors.black : Colors.grey,
|
||||
color:
|
||||
_isHoveringDate ? Colors.black : Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -773,35 +784,37 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
MouseRegion(
|
||||
onEnter: (_) => setState(() => _isHoveringDropdown = true),
|
||||
onExit: (_) => setState(() => _isHoveringDropdown = false),
|
||||
onEnter: (_) =>
|
||||
setState(() => _isHoveringDropdown = true),
|
||||
onExit: (_) =>
|
||||
setState(() => _isHoveringDropdown = false),
|
||||
child: DropdownButtonFormField<String>(
|
||||
value: _selectedCountry,
|
||||
decoration: InputDecoration(
|
||||
enabledBorder:OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(10),
|
||||
borderSide: BorderSide(
|
||||
color: MyTheme.topicColor(
|
||||
IndicatorTopic.economy)
|
||||
.shade400,
|
||||
width: 1), // Enabled border
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderSide:BorderSide(color: Color(0xFF7296BE),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
MyTheme.topicColor(IndicatorTopic.economy)
|
||||
.shade400,
|
||||
width: 1), // Enabled border
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
labelText: context.translate('Select',' اختيار')
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFF7296BE),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
labelText: context.translate('Select', ' اختيار')),
|
||||
icon: Icon(Icons.keyboard_arrow_down_sharp,
|
||||
color:
|
||||
_isHoveringDropdown ? Colors.black : Colors.grey),
|
||||
color: _isHoveringDropdown
|
||||
? Colors.black
|
||||
: Colors.grey),
|
||||
items: _countries
|
||||
.map((item) => DropdownMenuItem<String>(
|
||||
value: item,
|
||||
child: Text(item),
|
||||
))
|
||||
value: item,
|
||||
child: Text(item),
|
||||
))
|
||||
.toList(),
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
@ -811,6 +824,59 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
validator: _validateDropdown,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
AppLocalizations.of(context)!.preferredLang,
|
||||
style: TextStyle(
|
||||
fontSize: 16, fontWeight: FontWeight.w500),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
MouseRegion(
|
||||
onEnter: (_) =>
|
||||
setState(() => _isHoveringPreferredLang = true),
|
||||
onExit: (_) =>
|
||||
setState(() => _isHoveringPreferredLang = false),
|
||||
child: DropdownButtonFormField<String>(
|
||||
value: _selectedLanguage,
|
||||
decoration: InputDecoration(
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
MyTheme.topicColor(IndicatorTopic.economy)
|
||||
.shade400,
|
||||
width: 1), // Enabled border
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFF7296BE),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
labelText: context.translate('Select', ' اختيار')),
|
||||
icon: Icon(Icons.keyboard_arrow_down_sharp,
|
||||
color: _isHoveringPreferredLang
|
||||
? Colors.black
|
||||
: Colors.grey),
|
||||
items: preferred_language
|
||||
.map((item) => DropdownMenuItem<String>(
|
||||
value: item,
|
||||
child: Text(item),
|
||||
))
|
||||
.toList(),
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
_selectedLanguage = newValue;
|
||||
});
|
||||
},
|
||||
validator: _validateDropdown,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
Row(
|
||||
children: [
|
||||
@ -823,53 +889,48 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
});
|
||||
},
|
||||
side: BorderSide(
|
||||
color:
|
||||
showError ? Color(0xFFb22222) : Color(0xFF7296BE),
|
||||
color: showError
|
||||
? Color(0xFFb22222)
|
||||
: Color(0xFF7296BE),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 14.0,),
|
||||
top: 14.0,
|
||||
),
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
text: AppLocalizations.of(
|
||||
context)!
|
||||
.agree,
|
||||
text: AppLocalizations.of(context)!.agree,
|
||||
// text: 'I agree to ',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14,
|
||||
color: Color(
|
||||
0xFF898C81,), // Change to your desired color
|
||||
0xFF898C81,
|
||||
), // Change to your desired color
|
||||
),
|
||||
children: [
|
||||
TextSpan(
|
||||
recognizer:TapGestureRecognizer()
|
||||
..onTap = () => context.push('/terms&conditions'),
|
||||
text: AppLocalizations.of(
|
||||
context)!
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () =>
|
||||
context.push('/terms&conditions'),
|
||||
text: AppLocalizations.of(context)!
|
||||
.terms_conditions,
|
||||
// text: 'Terms & Conditions',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
color:
|
||||
Color(0xFF985400),
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF985400),
|
||||
// Makes the text bold
|
||||
// decoration:
|
||||
// TextDecoration.underline,
|
||||
decorationColor:
|
||||
Color(0xFF985400),
|
||||
decorationThickness:
|
||||
1),
|
||||
decorationColor: Color(0xFF985400),
|
||||
decorationThickness: 1),
|
||||
),
|
||||
TextSpan(
|
||||
text: AppLocalizations.of(
|
||||
context)!
|
||||
.t_and,
|
||||
text: AppLocalizations.of(context)!.t_and,
|
||||
style: TextStyle(
|
||||
color: Color(
|
||||
0xFF898C81), // Change to your desired color
|
||||
@ -877,31 +938,26 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
),
|
||||
TextSpan(
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () => context.push('/privacy_policy'),
|
||||
text: AppLocalizations.of(
|
||||
context)!
|
||||
..onTap =
|
||||
() => context.push('/privacy_policy'),
|
||||
text: AppLocalizations.of(context)!
|
||||
.privacy_policy,
|
||||
style: TextStyle(
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14,
|
||||
fontFamily: 'Roboto',
|
||||
color:
|
||||
Color(0xFF985400),
|
||||
color: Color(0xFF985400),
|
||||
// decoration:
|
||||
// TextDecoration.underline,
|
||||
decorationColor:
|
||||
Color(0xFF648CBA),
|
||||
decorationThickness:
|
||||
1),
|
||||
decorationColor: Color(0xFF648CBA),
|
||||
decorationThickness: 1),
|
||||
),
|
||||
TextSpan(
|
||||
text: AppLocalizations.of(
|
||||
context)!
|
||||
text: AppLocalizations.of(context)!
|
||||
.conditions,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14,
|
||||
fontSize: 14,
|
||||
color: Color(
|
||||
0xFF898C81), // Change to your desired color
|
||||
),
|
||||
@ -918,13 +974,14 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 10.0, right: profileLocale
|
||||
?.languageCode ==
|
||||
'ar'
|
||||
? 15
|
||||
: 0.0,),
|
||||
padding: EdgeInsets.only(
|
||||
left: 10.0,
|
||||
right: profileLocale?.languageCode == 'ar'
|
||||
? 15
|
||||
: 0.0,
|
||||
),
|
||||
child: Text(
|
||||
context.translate('Required', 'مطلوب'),
|
||||
context.translate('Required', 'مطلوب'),
|
||||
style: TextStyle(
|
||||
color: Color(0xFFb22222),
|
||||
fontSize: 12,
|
||||
@ -960,7 +1017,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
hasValidated = true;
|
||||
hasValidated = true;
|
||||
});
|
||||
if ((_formKey.currentState?.validate() ?? false) &&
|
||||
(isChecked)) {
|
||||
@ -969,7 +1026,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
} else {
|
||||
setState(() {
|
||||
showError =
|
||||
!isChecked; // Show error if the checkbox is not checked
|
||||
!isChecked; // Show error if the checkbox is not checked
|
||||
});
|
||||
}
|
||||
},
|
||||
@ -982,7 +1039,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center, // Center the content
|
||||
MainAxisAlignment.center, // Center the content
|
||||
children: [
|
||||
Text(
|
||||
AppLocalizations.of(context)!.save,
|
||||
@ -1041,10 +1098,10 @@ class ConfirmationDialog extends StatelessWidget {
|
||||
TextSpan(
|
||||
text: AppLocalizations.of(context)!.name,
|
||||
style:
|
||||
TextStyle(fontWeight: FontWeight.w700), // Bold for "name"
|
||||
TextStyle(fontWeight: FontWeight.w700), // Bold for "name"
|
||||
),
|
||||
TextSpan(
|
||||
text: context.translate(' or ','أو'),
|
||||
text: context.translate(' or ', 'أو'),
|
||||
),
|
||||
TextSpan(
|
||||
text: AppLocalizations.of(context)!.dob,
|
||||
@ -1111,4 +1168,4 @@ class ConfirmationDialog extends StatelessWidget {
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,12 +7,14 @@ const Color environmentboldColor = Color(0xFF90B0D5);
|
||||
const TextStyle subtitleStyle = TextStyle(
|
||||
fontFamily: 'Roboto', // Font family set to Roboto
|
||||
fontWeight: FontWeight.w400, // Regular weight (w400)
|
||||
fontSize: 11,
|
||||
// fontSize: 11,
|
||||
fontSize: 11 * 1.2, // Increase by 20%
|
||||
color: Color(0xFF8E8E8E) // Font size 11
|
||||
);
|
||||
const TextStyle robotoRegular11 = TextStyle(
|
||||
fontFamily: 'Roboto', // Font family set to Roboto
|
||||
fontWeight: FontWeight.w400, // Regular weight (w400)
|
||||
fontSize: 11,
|
||||
fontSize: 11 * 1.1,
|
||||
color: Color(0xFF000000) // Font size 11
|
||||
|
||||
);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:external_repos/external_repos.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
@ -27,7 +28,6 @@ import 'package:pocketbase/pocketbase.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:uae_stat/config/api_config.dart';
|
||||
|
||||
|
||||
import '../../components/indicators/locale_provider.dart';
|
||||
import '../../components/my_toggle.dart';
|
||||
|
||||
@ -42,7 +42,8 @@ class LoginRoute extends HookConsumerWidget {
|
||||
dynamic userData;
|
||||
String? role;
|
||||
int? loginCount;
|
||||
|
||||
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
|
||||
// final FirebaseAuth _auth = FirebaseAuth.instance;
|
||||
static final formKey = GlobalKey<FormState>();
|
||||
|
||||
Future<bool> profileStatus(String userId) async {
|
||||
@ -97,6 +98,89 @@ class LoginRoute extends HookConsumerWidget {
|
||||
await prefs.setString('login_count', count.toString());
|
||||
}
|
||||
|
||||
// Future<void> getDeviceToken() async {
|
||||
// String? token = await FirebaseMessaging.instance.getToken();
|
||||
// print("FCM Token: $token");
|
||||
// }
|
||||
|
||||
Future<void> getDeviceToken(BuildContext context, String userId) async {
|
||||
try {
|
||||
// await _firebaseMessaging.requestPermission();
|
||||
print("FCM Token Entry");
|
||||
String? token = await FirebaseMessaging.instance.getToken();
|
||||
print("FCM Token: $token");
|
||||
|
||||
if (token != null) {
|
||||
await updateDeviceToken(userId, token);
|
||||
|
||||
// Automatically copy to clipboard
|
||||
// Clipboard.setData(ClipboardData(text: token));
|
||||
|
||||
// Show token in Alert Dialog
|
||||
// if (context.mounted) {
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (context) {
|
||||
// return AlertDialog(
|
||||
// title: Text("FCM Token"),
|
||||
// content: Column(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
// children: [
|
||||
// SelectableText(token), // Allows manual selection
|
||||
// SizedBox(height: 10),
|
||||
// Text(
|
||||
// "Token copied to clipboard ✅",
|
||||
// style: TextStyle(color: Colors.green),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// actions: [
|
||||
// TextButton(
|
||||
// onPressed: () => Navigator.pop(context),
|
||||
// child: Text("OK"),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error getting FCM Token: $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateDeviceToken(String userId, String token) async {
|
||||
final url = "${pb.baseUrl}/api/collections/users/records/$userId";
|
||||
|
||||
try {
|
||||
// Authenticate admin (Persist session globally instead)
|
||||
await pb.admins.authWithPassword(
|
||||
'pb@venbainfotech.com',
|
||||
'pb@venbainfotech.com',
|
||||
);
|
||||
|
||||
final response = await http.patch(
|
||||
Uri.parse(url),
|
||||
headers: {
|
||||
'Content-Type': 'application/json', // Add this
|
||||
'Authorization': pb.authStore.token, // Correct way to send auth token
|
||||
},
|
||||
body: jsonEncode({
|
||||
"device_token": token,
|
||||
}),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
print("✅ Device token updated successfully!");
|
||||
} else {
|
||||
print("❌ Failed to update device token: ${response.body}");
|
||||
}
|
||||
} catch (e) {
|
||||
print("🚨 Error updating device token: $e");
|
||||
}
|
||||
}
|
||||
|
||||
// Future<void> authenticateAndStoreData() async {
|
||||
// try {
|
||||
// // Perform authentication
|
||||
@ -244,15 +328,13 @@ class LoginRoute extends HookConsumerWidget {
|
||||
'تم إرسال بريد إلكتروني إلى $email يتضمن المزيد من التفاصيل.',
|
||||
),
|
||||
);
|
||||
|
||||
},
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.zero,
|
||||
// maximumSize: Size.zero,
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
visualDensity: VisualDensity.compact,
|
||||
overlayColor: Colors.white
|
||||
),
|
||||
overlayColor: Colors.white),
|
||||
child: Text(
|
||||
context.translate(
|
||||
'Forgot Password?',
|
||||
@ -273,7 +355,7 @@ class LoginRoute extends HookConsumerWidget {
|
||||
width: double.infinity,
|
||||
child: ElevatedButton(
|
||||
onPressed: () async {
|
||||
hasValidated.value=true;
|
||||
hasValidated.value = true;
|
||||
final isValid = formKey.currentState!.validate();
|
||||
if (!isValid) return;
|
||||
final session = await context.loaderWithErrorDialog(
|
||||
@ -367,6 +449,7 @@ class LoginRoute extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
await saveUserId(userId, loginCount);
|
||||
await getDeviceToken(context, userId);
|
||||
}
|
||||
try {
|
||||
final bool isProfileComplete = await profileStatus(userId);
|
||||
@ -451,14 +534,14 @@ class LoginRoute extends HookConsumerWidget {
|
||||
'Login',
|
||||
'تسجيل الدخول',
|
||||
),
|
||||
style: TextStyle(
|
||||
fontFamily: context.translate(
|
||||
'Roboto',
|
||||
'Roboto',
|
||||
),
|
||||
fontSize: locale?.languageCode == 'ar' ? 12: 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
style: TextStyle(
|
||||
fontFamily: context.translate(
|
||||
'Roboto',
|
||||
'Roboto',
|
||||
),
|
||||
fontSize: locale?.languageCode == 'ar' ? 12 : 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
6.horizontalSpace,
|
||||
const Icon(
|
||||
@ -478,16 +561,15 @@ class LoginRoute extends HookConsumerWidget {
|
||||
'Email',
|
||||
'بريد إلكتروني',
|
||||
),
|
||||
|
||||
validator: (value) {
|
||||
final emailRegex =
|
||||
r'^[a-zA-Z0-9àèìòùÀÈÌÒÙéàç~!#$%^&*()_+=-{}|;,.?<>]+@[a-zA-Z0-9àèìòùÀÈÌÒÙéàç~!#$%^&*()_+=-{}|;,.?<>]+\.[a-zA-Z]{2,}$';
|
||||
if (value == null || value.isEmpty) {
|
||||
return context.translate('Required', 'مطلوب');
|
||||
}
|
||||
else if (!RegExp(emailRegex).hasMatch(value)) {
|
||||
} else if (!RegExp(emailRegex).hasMatch(value)) {
|
||||
return AppLocalizations.of(context)!.invalid_email;
|
||||
} return null;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
imgPath: MiscIconAssetPath.person,
|
||||
controller: emailCtl,
|
||||
@ -662,48 +744,47 @@ class LoginRoute extends HookConsumerWidget {
|
||||
final listViewHorizontalPadding =
|
||||
screenWidth < 700 ? 30 : 30 + (screenWidth - 700) / 2;
|
||||
final scaffoldBody = SingleChildScrollView(
|
||||
child: Column(
|
||||
children:[
|
||||
Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
3.verticalSpace,
|
||||
Align(
|
||||
alignment: AlignmentDirectional.topEnd,
|
||||
child: MyToggle(
|
||||
isOn: locale?.languageCode == 'en',
|
||||
knobTextWhenOn: 'ع',
|
||||
knobTextWhenOff: 'EN',
|
||||
pathColorWhenOn: Colors.grey.shade300,
|
||||
pathColorWhenOff: Colors.grey.shade300,
|
||||
onTap: () {
|
||||
final formState = formKey.currentState;
|
||||
ref.read(localeProvider.notifier).toggleLocale();
|
||||
Future.delayed(Duration(milliseconds: 100), () {
|
||||
if (hasValidated.value && formState?.validate() == false) {
|
||||
formState?.validate();
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
34.verticalSpace,
|
||||
helloAndPleaseLoginTexts,
|
||||
40.verticalSpace,
|
||||
form,
|
||||
15.verticalSpace,
|
||||
dontHaveAnAccountRegisterBtn,
|
||||
// continueAsGuestBtn,
|
||||
// Spacer(),
|
||||
15.verticalSpace,
|
||||
fcscBanner,
|
||||
],
|
||||
child: Column(children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
3.verticalSpace,
|
||||
Align(
|
||||
alignment: AlignmentDirectional.topEnd,
|
||||
child: MyToggle(
|
||||
isOn: locale?.languageCode == 'en',
|
||||
knobTextWhenOn: 'ع',
|
||||
knobTextWhenOff: 'EN',
|
||||
pathColorWhenOn: Colors.grey.shade300,
|
||||
pathColorWhenOff: Colors.grey.shade300,
|
||||
onTap: () {
|
||||
final formState = formKey.currentState;
|
||||
ref.read(localeProvider.notifier).toggleLocale();
|
||||
Future.delayed(Duration(milliseconds: 100), () {
|
||||
if (hasValidated.value &&
|
||||
formState?.validate() == false) {
|
||||
formState?.validate();
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
]
|
||||
),
|
||||
34.verticalSpace,
|
||||
helloAndPleaseLoginTexts,
|
||||
40.verticalSpace,
|
||||
form,
|
||||
15.verticalSpace,
|
||||
dontHaveAnAccountRegisterBtn,
|
||||
// continueAsGuestBtn,
|
||||
// Spacer(),
|
||||
15.verticalSpace,
|
||||
fcscBanner,
|
||||
],
|
||||
),
|
||||
)
|
||||
]),
|
||||
);
|
||||
// final bgScaffold = Scaffold(
|
||||
// backgroundColor: Colors.white,
|
||||
@ -783,4 +864,4 @@ class LoginRoute extends HookConsumerWidget {
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1456,7 +1456,8 @@ class InfoCard extends StatelessWidget {
|
||||
child: Text(
|
||||
title,
|
||||
style: const TextStyle(
|
||||
fontSize: 11,
|
||||
// fontSize: 11,
|
||||
fontSize: 11 * 1.1,
|
||||
fontWeight: FontWeight.w400,
|
||||
// color: Colors.black,
|
||||
fontFamily: 'Roboto',
|
||||
@ -1478,7 +1479,8 @@ class InfoCard extends StatelessWidget {
|
||||
subtitle,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
fontSize: 11,
|
||||
// fontSize: 11,
|
||||
fontSize: 11 * 1.1,
|
||||
fontFamily: 'Roboto',
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF8E8E8E),
|
||||
|
||||
@ -204,7 +204,7 @@ class _EditProfileState extends State<EditProfile> {
|
||||
|
||||
if (avatarFilename.isNotEmpty && recordId.isNotEmpty) {
|
||||
_avatarUrl =
|
||||
'$apiUrl/$collectionId/$recordId/$avatarFilename';
|
||||
'$apiUrl/api/files/$collectionId/$recordId/$avatarFilename';
|
||||
} else {
|
||||
_avatarUrl = ''; // Reset to default or empty
|
||||
}
|
||||
@ -308,7 +308,8 @@ class _EditProfileState extends State<EditProfile> {
|
||||
|
||||
// Check if the selected date is in the future
|
||||
if (selectedDate.isAfter(today)) {
|
||||
return context.translate('Date of birth cannot be in the future','لا يمكن أن يكون تاريخ الميلاد في المستقبل');
|
||||
return context.translate('Date of birth cannot be in the future',
|
||||
'لا يمكن أن يكون تاريخ الميلاد في المستقبل');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -691,7 +692,8 @@ class _EditProfileState extends State<EditProfile> {
|
||||
enabled: false,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return context.translate('Required', 'مطلوب');
|
||||
return context.translate(
|
||||
'Required', 'مطلوب');
|
||||
}
|
||||
|
||||
//RegExp(r"^[a-zA-Z\s]+$");
|
||||
@ -699,7 +701,8 @@ class _EditProfileState extends State<EditProfile> {
|
||||
r"^[a-zA-Z0-9'\-\u0627\u0639~\u00C0-\u00FF\s]+$",
|
||||
);
|
||||
if (!nameRegex.hasMatch(value)) {
|
||||
return AppLocalizations.of(context)!.invalid_characters;
|
||||
return AppLocalizations.of(context)!
|
||||
.invalid_characters;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
@ -787,18 +790,19 @@ class _EditProfileState extends State<EditProfile> {
|
||||
),
|
||||
value: _selectedCountry,
|
||||
decoration: InputDecoration(
|
||||
enabledBorder:OutlineInputBorder(
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(10),
|
||||
BorderRadius.circular(10),
|
||||
borderSide: BorderSide(
|
||||
color: MyTheme.topicColor(
|
||||
IndicatorTopic.economy)
|
||||
IndicatorTopic.economy)
|
||||
.shade400,
|
||||
width: 1), // Enabled border
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderSide:BorderSide(color: Color(0xFF7296BE),
|
||||
),
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFF7296BE),
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius.circular(8),
|
||||
),
|
||||
@ -845,8 +849,9 @@ class _EditProfileState extends State<EditProfile> {
|
||||
color: showError
|
||||
? Color(0xFFb22222)
|
||||
: MyTheme.topicColor(
|
||||
IndicatorTopic.economy)
|
||||
.shade400,
|
||||
IndicatorTopic
|
||||
.economy)
|
||||
.shade400,
|
||||
width: 1.5,
|
||||
),
|
||||
),
|
||||
@ -880,8 +885,11 @@ class _EditProfileState extends State<EditProfile> {
|
||||
TextDecoration
|
||||
.underline,
|
||||
),
|
||||
recognizer:TapGestureRecognizer()
|
||||
..onTap = () => context.push('/terms&conditions'),
|
||||
recognizer:
|
||||
TapGestureRecognizer()
|
||||
..onTap = () =>
|
||||
context.push(
|
||||
'/terms&conditions'),
|
||||
),
|
||||
TextSpan(
|
||||
text: AppLocalizations
|
||||
@ -907,9 +915,11 @@ class _EditProfileState extends State<EditProfile> {
|
||||
TextDecoration
|
||||
.underline,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () => context.push('/privacy_policy'),
|
||||
|
||||
recognizer:
|
||||
TapGestureRecognizer()
|
||||
..onTap = () =>
|
||||
context.push(
|
||||
'/privacy_policy'),
|
||||
),
|
||||
TextSpan(
|
||||
text: AppLocalizations
|
||||
@ -1151,4 +1161,4 @@ class ConfirmationDialog extends StatelessWidget {
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -342,14 +342,18 @@ class _ManageUserRouterState extends State<ManageUserRouter> {
|
||||
padding: EdgeInsets.only(left: 12.0),
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search",
|
||||
hintStyle: TextStyle(color: Color(0xFF898C81)),
|
||||
prefixIconConstraints: BoxConstraints(maxWidth: 42, maxHeight: 42),
|
||||
hintText: AppLocalizations.of(context)!.search,
|
||||
hintStyle: TextStyle(color: Color(0xFFAA8E83)),
|
||||
// hintStyle: TextStyle(color: Color(0xFFAA8E83)),
|
||||
prefixIconConstraints:
|
||||
BoxConstraints(maxWidth: 42, maxHeight: 42),
|
||||
prefixIcon: Container(
|
||||
padding: EdgeInsets.only(right: 5),
|
||||
child: SvgPicture.asset(
|
||||
MiscIconAssetPath.Search,
|
||||
semanticsLabel: 'Search',
|
||||
colorFilter: ColorFilter.mode(
|
||||
Color(0xFFAA8E83), BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
|
||||
@ -359,7 +363,7 @@ class _ManageUserRouterState extends State<ManageUserRouter> {
|
||||
// ),
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
vertical: 8.0, horizontal: 18.0),
|
||||
vertical: 0.5, horizontal: 18.0),
|
||||
),
|
||||
onChanged: filterUsers,
|
||||
),
|
||||
|
||||
@ -1,22 +1,29 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:pocketbase/pocketbase.dart';
|
||||
import 'package:uae_stat/config/api_config.dart';
|
||||
import 'package:uae_stat/domain/use_cases/language.dart';
|
||||
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
|
||||
import '../../custom_drawer_routes.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class NotificationPage extends StatefulWidget {
|
||||
class NotificationPage extends ConsumerStatefulWidget {
|
||||
@override
|
||||
_NotificationPageState createState() => _NotificationPageState();
|
||||
}
|
||||
|
||||
class _NotificationPageState extends State<NotificationPage> {
|
||||
class _NotificationPageState extends ConsumerState<NotificationPage> {
|
||||
// Example notification data
|
||||
final _pb = PocketBase(apiUrl);
|
||||
List<Map<String, dynamic>> notifications = [];
|
||||
|
||||
// Current selected tab index
|
||||
int selectedTabIndex = 0;
|
||||
late final Locale locale;
|
||||
|
||||
// Tab categories
|
||||
final List<String> tabs = [
|
||||
@ -28,6 +35,13 @@ class _NotificationPageState extends State<NotificationPage> {
|
||||
"Favourites"
|
||||
];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
locale = ref.read(localeProvider) ?? const Locale('en');
|
||||
fetchNotifications(locale?.languageCode ?? 'en');
|
||||
}
|
||||
|
||||
String formatDate(String dateString) {
|
||||
try {
|
||||
DateTime dateTime =
|
||||
@ -39,36 +53,61 @@ class _NotificationPageState extends State<NotificationPage> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fetchNotifications() async {
|
||||
Future<void> fetchNotifications(locale) async {
|
||||
final baseUrl = apiUrl + '/api/getNotification';
|
||||
try {
|
||||
await _pb.admins
|
||||
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
|
||||
final response = await http.get(Uri.parse('$baseUrl?language=$locale'));
|
||||
|
||||
final result = await _pb.collection('notification').getFullList();
|
||||
if (response.statusCode == 200) {
|
||||
final Map<String, dynamic> jsonResponse =
|
||||
jsonDecode(response.body); // Decode JSON
|
||||
|
||||
setState(() {
|
||||
notifications = result.map((record) => record.toJson()).toList();
|
||||
});
|
||||
if (jsonResponse['message'] == 'Success') {
|
||||
setState(() {
|
||||
notifications = List<Map<String, dynamic>>.from(
|
||||
jsonResponse['data']); // Assign decoded data
|
||||
});
|
||||
} else {
|
||||
throw Exception('Failed to load data');
|
||||
}
|
||||
} else {
|
||||
throw Exception(
|
||||
'Failed to load data with status code ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error fetching notifications: $e');
|
||||
print('Error fetching data: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
fetchNotifications();
|
||||
}
|
||||
// Future<void> fetchNotifications() async {/api/getNotification?language=ar
|
||||
// try {
|
||||
// await _pb.admins
|
||||
// .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
|
||||
//
|
||||
// final result = await _pb.collection('notification').getFullList();
|
||||
//
|
||||
// setState(() {
|
||||
// notifications = result.map((record) => record.toJson()).toList();
|
||||
// });
|
||||
// } catch (e) {
|
||||
// print('Error fetching notifications: $e');
|
||||
// }
|
||||
// }
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
ref.listen<Locale?>(localeProvider, (previous, next) {
|
||||
final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null
|
||||
fetchNotifications(localeCode);
|
||||
});
|
||||
// Filter notifications based on the selected tab
|
||||
List<Map<String, dynamic>> filteredNotifications = selectedTabIndex == 0
|
||||
? notifications
|
||||
: notifications
|
||||
.where((notification) =>
|
||||
notification["category"] == tabs[selectedTabIndex])
|
||||
.toList();
|
||||
: notifications.where((notification) {
|
||||
print(
|
||||
"Comparing: '${notification["category"]}' with '${tabs[selectedTabIndex]}'");
|
||||
return notification["category"] == tabs[selectedTabIndex];
|
||||
}).toList();
|
||||
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
@ -77,7 +116,12 @@ class _NotificationPageState extends State<NotificationPage> {
|
||||
context.go('/myhomepage');
|
||||
},
|
||||
child: BaseScaffold(
|
||||
title: Text('Notification'),
|
||||
title: Text(
|
||||
context.translate(
|
||||
'Notification',
|
||||
'إشعار',
|
||||
),
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
TabBarHeader(
|
||||
@ -90,53 +134,41 @@ class _NotificationPageState extends State<NotificationPage> {
|
||||
},
|
||||
),
|
||||
Expanded(
|
||||
child: selectedTabIndex == 1
|
||||
child: filteredNotifications.isEmpty
|
||||
? Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset(
|
||||
'assets/backgrounds/Notification/Update_notific.png',
|
||||
height: 200,
|
||||
),
|
||||
Icon(Icons.info_outline,
|
||||
size: 100, color: Colors.grey[400]),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
filteredNotifications.isNotEmpty
|
||||
? filteredNotifications[0]['title']
|
||||
: 'No updates available.',
|
||||
'No notifications available.',
|
||||
style: TextStyle(fontSize: 16, color: Colors.grey),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: filteredNotifications.isEmpty
|
||||
? Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.info_outline,
|
||||
size: 100, color: Colors.grey[400]),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
'No notifications available.',
|
||||
style:
|
||||
TextStyle(fontSize: 16, color: Colors.grey),
|
||||
),
|
||||
],
|
||||
: ListView.builder(
|
||||
itemCount: filteredNotifications.length,
|
||||
itemBuilder: (context, index) {
|
||||
final notification = filteredNotifications[index];
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: Color(0xFFDEDEDE),
|
||||
width: 1), // Bottom border only
|
||||
),
|
||||
),
|
||||
)
|
||||
: ListView.builder(
|
||||
itemCount: filteredNotifications.length,
|
||||
itemBuilder: (context, index) {
|
||||
final notification = filteredNotifications[index];
|
||||
return NotificationTile(
|
||||
child: NotificationTile(
|
||||
title: notification['title'] ?? 'No Title',
|
||||
date: formatDate(notification['created'] ?? ''),
|
||||
category: notification['category'] ?? 'Unknown',
|
||||
);
|
||||
},
|
||||
),
|
||||
message: notification['message'] ?? ''),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -205,22 +237,43 @@ class TabBarHeader extends StatelessWidget {
|
||||
|
||||
class NotificationTile extends StatelessWidget {
|
||||
final String title;
|
||||
final String message;
|
||||
final String date;
|
||||
final String category;
|
||||
|
||||
const NotificationTile({
|
||||
required this.title,
|
||||
required this.message,
|
||||
required this.date,
|
||||
required this.category,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListTile(
|
||||
leading: Icon(Icons.circle,
|
||||
size: 12, color: category == "Social" ? Colors.red : Colors.grey),
|
||||
title: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||
subtitle: Text(date),
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
context.go('/notification_details', extra: {
|
||||
'title': title,
|
||||
'message': message,
|
||||
'date': date,
|
||||
'category': category,
|
||||
});
|
||||
},
|
||||
child: ListTile(
|
||||
// leading: Icon(Icons.circle,
|
||||
// size: 12, color: category == "Social" ? Colors.red : Colors.grey),
|
||||
leading: Icon(Icons.circle, size: 12, color: Colors.red),
|
||||
title: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||
subtitle: Text(
|
||||
date,
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF8E8E8E),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400),
|
||||
),
|
||||
trailing: const Icon(Icons.arrow_forward_ios,
|
||||
size: 16, color: Color(0xFF898C81)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,86 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:uae_stat/domain/use_cases/language.dart';
|
||||
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
|
||||
|
||||
class NotificationDetails extends ConsumerWidget {
|
||||
final String title;
|
||||
final String message;
|
||||
final String date;
|
||||
final String category;
|
||||
|
||||
const NotificationDetails({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.message,
|
||||
required this.date,
|
||||
required this.category,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, result) {
|
||||
if (didPop) return;
|
||||
context.go('/notification');
|
||||
},
|
||||
child: BaseScaffold(
|
||||
title: Text(
|
||||
context.translate(
|
||||
'Notification',
|
||||
'إشعار',
|
||||
),
|
||||
),
|
||||
showBackButton: true,
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF414042)),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset(
|
||||
category == 'App updates'
|
||||
? 'assets/backgrounds/Notification/App-Update.png'
|
||||
: 'assets/backgrounds/Notification/Update_notific.png',
|
||||
height: 200,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
message.isNotEmpty
|
||||
? message
|
||||
: "No additional details available.",
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF414042)),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
"Date: $date",
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF8E8E8E)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -8,7 +8,8 @@ import Foundation
|
||||
import connectivity_plus
|
||||
import file_selector_macos
|
||||
import firebase_core
|
||||
import flutter_secure_storage_macos
|
||||
import firebase_messaging
|
||||
import flutter_secure_storage_darwin
|
||||
import package_info_plus
|
||||
import path_provider_foundation
|
||||
import share_plus
|
||||
@ -21,12 +22,13 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
|
||||
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
|
||||
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
|
||||
FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
|
||||
FlutterSecureStorageDarwinPlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStorageDarwinPlugin"))
|
||||
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
|
||||
FLTWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "FLTWebViewFlutterPlugin"))
|
||||
WebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "WebViewFlutterPlugin"))
|
||||
}
|
||||
|
||||
383
pubspec.lock
383
pubspec.lock
@ -5,31 +5,34 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab"
|
||||
sha256: dc27559385e905ad30838356c5f5d574014ba39872d732111cd07ac0beff4c57
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "76.0.0"
|
||||
_macros:
|
||||
version: "80.0.0"
|
||||
_flutterfire_internals:
|
||||
dependency: transitive
|
||||
description: dart
|
||||
source: sdk
|
||||
version: "0.3.3"
|
||||
description:
|
||||
name: _flutterfire_internals
|
||||
sha256: "7fd72d77a7487c26faab1d274af23fb008763ddc10800261abbfb2c067f183d5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.53"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e"
|
||||
sha256: "192d1c5b944e7e53b24b5586db760db934b177d4147c42fbca8c8c5f1eb8d11e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.11.0"
|
||||
version: "7.3.0"
|
||||
analyzer_plugin:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer_plugin
|
||||
sha256: "9661b30b13a685efaee9f02e5d01ed9f2b423bd889d28a304d02d704aee69161"
|
||||
sha256: "1d460d14e3c2ae36dc2b32cef847c4479198cf87704f63c3c3c8150ee50c3916"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.11.3"
|
||||
version: "0.12.0"
|
||||
ansicolor:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -58,18 +61,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
|
||||
sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.11.0"
|
||||
version: "2.12.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
|
||||
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "2.1.2"
|
||||
boxy:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -82,50 +85,50 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build
|
||||
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
|
||||
sha256: cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
version: "2.4.2"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_config
|
||||
sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1
|
||||
sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
version: "1.1.2"
|
||||
build_daemon:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_daemon
|
||||
sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9"
|
||||
sha256: "8e928697a82be082206edb0b9c99c5a4ad6bc31c9e9b8b2f291ae65cd4a25daa"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.2"
|
||||
version: "4.0.4"
|
||||
build_resolvers:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_resolvers
|
||||
sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a"
|
||||
sha256: b9e4fda21d846e192628e7a4f6deda6888c36b5b69ba02ff291a01fd529140f0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
version: "2.4.4"
|
||||
build_runner:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d"
|
||||
sha256: "058fe9dce1de7d69c4b84fada934df3e0153dd000758c4d65964d0166779aa99"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.13"
|
||||
version: "2.4.15"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0
|
||||
sha256: "22e3aa1c80e0ada3722fe5b63fd43d9c8990759d0a2cf489c8c5d7b2bdebc021"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.3.2"
|
||||
version: "8.0.0"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -138,18 +141,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
sha256: "28a712df2576b63c6c005c465989a348604960c0958d28be5303ba9baa841ac2"
|
||||
sha256: "8b158ab94ec6913e480dc3f752418348b5ae099eb75868b5f4775f0572999c61"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.9.3"
|
||||
version: "8.9.4"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
|
||||
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.4.0"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -178,10 +181,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
|
||||
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
version: "1.1.2"
|
||||
code_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -194,18 +197,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
|
||||
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.19.0"
|
||||
version: "1.19.1"
|
||||
connectivity_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: connectivity_plus
|
||||
sha256: "8a68739d3ee113e51ad35583fdf9ab82c55d09d693d3c39da1aebab87c938412"
|
||||
sha256: "04bf81bb0b77de31557b58d052b24b3eee33f09a6e7a8c68a3e247c7df19ec27"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.1.2"
|
||||
version: "6.1.3"
|
||||
connectivity_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -266,42 +269,42 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: custom_lint
|
||||
sha256: "3486c470bb93313a9417f926c7dd694a2e349220992d7b9d14534dc49c15bba9"
|
||||
sha256: "021897cce2b6c783b2521543e362e7fe1a2eaab17bf80514d8de37f99942ed9e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.0"
|
||||
version: "0.7.3"
|
||||
custom_lint_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: custom_lint_builder
|
||||
sha256: "42cdc41994eeeddab0d7a722c7093ec52bd0761921eeb2cbdbf33d192a234759"
|
||||
sha256: e4235b9d8cef59afe621eba086d245205c8a0a6c70cd470be7cb17494d6df32d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.0"
|
||||
version: "0.7.3"
|
||||
custom_lint_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: custom_lint_core
|
||||
sha256: "02450c3e45e2a6e8b26c4d16687596ab3c4644dd5792e3313aa9ceba5a49b7f5"
|
||||
sha256: "6dcee8a017181941c51a110da7e267c1d104dc74bec8862eeb8c85b5c8759a9e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.0"
|
||||
version: "0.7.1"
|
||||
custom_lint_visitor:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: custom_lint_visitor
|
||||
sha256: bfe9b7a09c4775a587b58d10ebb871d4fe618237639b1e84d5ec62d7dfef25f9
|
||||
sha256: "36282d85714af494ee2d7da8c8913630aa6694da99f104fb2ed4afcf8fc857d8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0+6.11.0"
|
||||
version: "1.0.0+7.3.0"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dart_style
|
||||
sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab"
|
||||
sha256: "27eb0ae77836989a3bc541ce55595e8ceee0992807f14511552a898ddd0d88ac"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.7"
|
||||
version: "3.0.1"
|
||||
dartz:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -330,10 +333,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dio_web_adapter
|
||||
sha256: e485c7a39ff2b384fa1d7e09b4e25f755804de8384358049124830b04fc4f93a
|
||||
sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
equatable:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -369,26 +372,26 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
|
||||
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.1"
|
||||
version: "1.3.2"
|
||||
fast_immutable_collections:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: fast_immutable_collections
|
||||
sha256: c3c73f4f989d3302066e4ec94e6ec73b5dc872592d02194f49f1352d64126b8c
|
||||
sha256: "95a69b9380483dff49ae2c12c9eb92e2b4e1aeff481a33c2a20883471771598a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.2.4"
|
||||
version: "11.0.3"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
|
||||
sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
version: "2.1.4"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -425,18 +428,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_windows
|
||||
sha256: "8f5d2f6590d51ecd9179ba39c64f722edc15226cc93dcc8698466ad36a4a85a4"
|
||||
sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.3+3"
|
||||
version: "0.9.3+4"
|
||||
firebase_core:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_core
|
||||
sha256: "26de145bb9688a90962faec6f838247377b0b0d32cc0abecd9a4e43525fc856c"
|
||||
sha256: f4d8f49574a4e396f34567f3eec4d38ab9c3910818dec22ca42b2a467c685d8b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.32.0"
|
||||
version: "3.12.1"
|
||||
firebase_core_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -449,10 +452,34 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_web
|
||||
sha256: e47f5c2776de018fa19bc9f6f723df136bc75cdb164d64b65305babd715c8e41
|
||||
sha256: faa5a76f6380a9b90b53bc3bdcb85bc7926a382e0709b9b5edac9f7746651493
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.21.0"
|
||||
version: "2.21.1"
|
||||
firebase_messaging:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_messaging
|
||||
sha256: "5fc345c6341f9dc69fd0ffcbf508c784fd6d1b9e9f249587f30434dd8b6aa281"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "15.2.4"
|
||||
firebase_messaging_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_messaging_platform_interface
|
||||
sha256: a935924cf40925985c8049df4968b1dde5c704f570f3ce380b31d3de6990dd94
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.6.4"
|
||||
firebase_messaging_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_messaging_web
|
||||
sha256: fafebf6a1921931334f3f10edb5037a5712288efdd022881e2d093e5654a2fd4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.10.4"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -486,10 +513,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_hooks
|
||||
sha256: cde36b12f7188c85286fba9b38cc5a902e7279f36dd676967106c041dc9dde70
|
||||
sha256: b772e710d16d7a20c0740c4f855095026b31c7eb5ba3ab67d2bd52021cd9461d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.20.5"
|
||||
version: "0.21.2"
|
||||
flutter_launcher_icons:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@ -523,10 +550,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_plugin_android_lifecycle
|
||||
sha256: "615a505aef59b151b46bbeef55b36ce2b6ed299d160c51d84281946f0aa0ce0e"
|
||||
sha256: "5a1e6fb2c0561958d7e4c33574674bda7b77caaca7a33b758876956f2902eea3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.24"
|
||||
version: "2.0.27"
|
||||
flutter_rating_bar:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -547,50 +574,50 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_secure_storage
|
||||
sha256: "9cad52d75ebc511adfae3d447d5d13da15a55a92c9410e50f67335b6d21d16ea"
|
||||
sha256: f7eceb0bc6f4fd0441e29d43cab9ac2a1c5ffd7ea7b64075136b718c46954874
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.2.4"
|
||||
version: "10.0.0-beta.4"
|
||||
flutter_secure_storage_darwin:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_darwin
|
||||
sha256: f226f2a572bed96bc6542198ebaec227150786e34311d455a7e2d3d06d951845
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.0"
|
||||
flutter_secure_storage_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_linux
|
||||
sha256: bf7404619d7ab5c0a1151d7c4e802edad8f33535abfbeff2f9e1fe1274e2d705
|
||||
sha256: "9b4b73127e857cd3117d43a70fa3dddadb6e0b253be62e6a6ab85caa0742182c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
flutter_secure_storage_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_macos
|
||||
sha256: "6c0a2795a2d1de26ae202a0d78527d163f4acbb11cde4c75c670f3a0fc064247"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
version: "2.0.1"
|
||||
flutter_secure_storage_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_platform_interface
|
||||
sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8
|
||||
sha256: "8ceea1223bee3c6ac1a22dabd8feefc550e4729b3675de4b5900f55afcb435d6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "2.0.1"
|
||||
flutter_secure_storage_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_web
|
||||
sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9
|
||||
sha256: "4c3f233e739545c6cb09286eeec1cc4744138372b985113acc904f7263bef517"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
version: "2.0.0"
|
||||
flutter_secure_storage_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_windows
|
||||
sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709
|
||||
sha256: ff32af20f70a8d0e59b2938fc92de35b54a74671041c814275afd80e27df9f21
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
version: "4.0.0"
|
||||
flutter_staggered_grid_view:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -621,18 +648,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: fluttertoast
|
||||
sha256: "8971efe7e59585e9149052e33718d84bca51e806f063d1467622b3dcb2878b6c"
|
||||
sha256: "25e51620424d92d3db3832464774a6143b5053f15e382d8ffbfd40b6e795dcf1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.2.11"
|
||||
version: "8.2.12"
|
||||
freezed:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: freezed
|
||||
sha256: "44c19278dd9d89292cf46e97dc0c1e52ce03275f40a97c5a348e802a924bf40e"
|
||||
sha256: "59a584c24b3acdc5250bb856d0d3e9c0b798ed14a4af1ddb7dc1c7b41df91c9c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.5.7"
|
||||
version: "2.5.8"
|
||||
freezed_annotation:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -669,10 +696,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: go_router
|
||||
sha256: daf3ff5570f55396b2d2c9bf8136d7db3a8acf208ac0cef92a3ae2beb9a81550
|
||||
sha256: f02fd7d2a4dc512fec615529824fdd217fecb3a3d3de68360293a551f21634b3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.7.1"
|
||||
version: "14.8.1"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -725,10 +752,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
|
||||
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.2"
|
||||
version: "4.1.2"
|
||||
iconify_design:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -757,10 +784,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_android
|
||||
sha256: b62d34a506e12bb965e824b6db4fbf709ee4589cf5d3e99b45ab2287b008ee0c
|
||||
sha256: "82652a75e3dd667a91187769a6a2cc81bd8c111bbead698d8e938d2b63e5e89a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.12+20"
|
||||
version: "0.8.12+21"
|
||||
image_picker_for_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -821,10 +848,10 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: injectable_generator
|
||||
sha256: af403d76c7b18b4217335e0075e950cd0579fd7f8d7bd47ee7c85ada31680ba1
|
||||
sha256: b04673a4c88b3a848c0c77bf58b8309f9b9e064d9fe1df5450c8ee1675eaea1a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.2"
|
||||
version: "2.7.0"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -845,10 +872,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
||||
sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.7"
|
||||
version: "0.7.2"
|
||||
json_annotation:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -861,10 +888,10 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: json_serializable
|
||||
sha256: c2fcb3920cf2b6ae6845954186420fca40bc0a8abcc84903b7801f17d7050d7c
|
||||
sha256: "81f04dee10969f89f604e1249382d46b97a1ccad53872875369622b5bfc9e58a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.9.0"
|
||||
version: "6.9.4"
|
||||
jwt_decoder:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -877,18 +904,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
|
||||
sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.7"
|
||||
version: "10.0.8"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
|
||||
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.8"
|
||||
version: "3.0.9"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -901,10 +928,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lints
|
||||
sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413"
|
||||
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
version: "5.1.1"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -913,14 +940,6 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
macros:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: macros
|
||||
sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.3-main.0"
|
||||
mailer:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -941,10 +960,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
|
||||
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.16+1"
|
||||
version: "0.12.17"
|
||||
material_charts:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -965,10 +984,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
|
||||
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.15.0"
|
||||
version: "1.16.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1005,26 +1024,26 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: package_info_plus
|
||||
sha256: c447a3c3e7be4addf129b8f9ab6a4bd5d166b78918223e223b61fddf4d07e254
|
||||
sha256: "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.2.0"
|
||||
version: "8.3.0"
|
||||
package_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus_platform_interface
|
||||
sha256: "205ec83335c2ab9107bbba3f8997f9356d72ca3c715d2f038fc773d0366b4c76"
|
||||
sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
version: "3.2.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
|
||||
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.9.0"
|
||||
version: "1.9.1"
|
||||
path_parsing:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1085,10 +1104,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: petitparser
|
||||
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
|
||||
sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.2"
|
||||
version: "6.1.0"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1141,10 +1160,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
sha256: "81876843eb50dc2e1e5b151792c9a985c5ed2536914115ed04e9c8528f6647b0"
|
||||
sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
version: "1.5.0"
|
||||
recase:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1173,10 +1192,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: riverpod_analyzer_utils
|
||||
sha256: c6b8222b2b483cb87ae77ad147d6408f400c64f060df7a225b127f4afef4f8c8
|
||||
sha256: "837a6dc33f490706c7f4632c516bcd10804ee4d9ccc8046124ca56388715fdf3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.8"
|
||||
version: "0.5.9"
|
||||
riverpod_annotation:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -1189,18 +1208,18 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: riverpod_generator
|
||||
sha256: "63546d70952015f0981361636bf8f356d9cfd9d7f6f0815e3c07789a41233188"
|
||||
sha256: "120d3310f687f43e7011bb213b90a436f1bbc300f0e4b251a72c39bccb017a4f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.3"
|
||||
version: "2.6.4"
|
||||
riverpod_lint:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: riverpod_lint
|
||||
sha256: "83e4caa337a9840469b7b9bd8c2351ce85abad80f570d84146911b32086fbd99"
|
||||
sha256: b05408412b0f75dec954e032c855bc28349eeed2d2187f94519e1ddfdf8b3693
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.3"
|
||||
version: "2.6.4"
|
||||
rxdart:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1244,18 +1263,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: shared_preferences
|
||||
sha256: "688ee90fbfb6989c980254a56cb26ebe9bb30a3a2dff439a78894211f73de67a"
|
||||
sha256: "846849e3e9b68f3ef4b60c60cf4b3e02e9321bc7f4d8c4692cf87ffa82fc8a3a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.5.1"
|
||||
version: "2.5.2"
|
||||
shared_preferences_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_android
|
||||
sha256: "650584dcc0a39856f369782874e562efd002a9c94aec032412c9eb81419cce1f"
|
||||
sha256: a768fc8ede5f0c8e6150476e14f38e2417c0864ca36bb4582be8e21925a03c22
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.4"
|
||||
version: "2.4.6"
|
||||
shared_preferences_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1284,10 +1303,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_web
|
||||
sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e
|
||||
sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
version: "2.4.3"
|
||||
shared_preferences_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1300,18 +1319,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4
|
||||
sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
version: "1.4.2"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67
|
||||
sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
version: "3.0.0"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@ -1328,10 +1347,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_gen
|
||||
sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832"
|
||||
sha256: "35c8150ece9e8c8d263337a265153c3329667640850b9304861faea59fc98f6b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.0"
|
||||
version: "2.0.0"
|
||||
source_helper:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1344,10 +1363,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
|
||||
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
version: "1.10.1"
|
||||
sprintf:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1360,10 +1379,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
|
||||
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.12.0"
|
||||
version: "1.12.1"
|
||||
state_notifier:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1376,10 +1395,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
|
||||
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
version: "2.1.4"
|
||||
stream_transform:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1392,42 +1411,42 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
|
||||
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.4.1"
|
||||
syncfusion_flutter_charts:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: syncfusion_flutter_charts
|
||||
sha256: "672c17a7f4cb3020c06bb6a28d2d033623007b8e2a19704ad34b412e9bdd2dab"
|
||||
sha256: c53e8616368c1a88397b7b180d0ded7d9e960564cdba01509cc5fa2d503ed727
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "28.2.4+1"
|
||||
version: "28.2.9"
|
||||
syncfusion_flutter_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: syncfusion_flutter_core
|
||||
sha256: "3c1876b0a245de23de3b17a19e3106fed57d88f4fd2c8dc9bc1976705b1c31d5"
|
||||
sha256: "5a1a76eef118e511443b299925d4a802eb8259388d6a580e0ad6413d1a70f987"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "28.2.4"
|
||||
version: "28.2.9"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
|
||||
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
version: "1.2.2"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
|
||||
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.3"
|
||||
version: "0.7.4"
|
||||
the_validator:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -1448,10 +1467,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: tutorial_coach_mark
|
||||
sha256: df450c88d4c812bc221afd3ff948da3dc0f44c0b4fa5dbc046d6d86f2cfc9e71
|
||||
sha256: "2c77c0b00bbe7d5b8a6d31cb9e03d44bf77dfe7ba6514cc2b546886d024a9945"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.12"
|
||||
version: "1.2.13"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1520,10 +1539,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_web
|
||||
sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e"
|
||||
sha256: "3ba963161bd0fe395917ba881d320b9c4f6dd3c4a233da62ab18a5025c85f1e9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.3"
|
||||
version: "2.4.0"
|
||||
url_launcher_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1576,26 +1595,26 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: video_player
|
||||
sha256: "4a8c3492d734f7c39c2588a3206707a05ee80cef52e8c7f3b2078d430c84bc17"
|
||||
sha256: "48941c8b05732f9582116b1c01850b74dbee1d8520cd7e34ad4609d6df666845"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.9.2"
|
||||
version: "2.9.3"
|
||||
video_player_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: video_player_android
|
||||
sha256: "391e092ba4abe2f93b3e625bd6b6a6ec7d7414279462c1c0ee42b5ab8d0a0898"
|
||||
sha256: "7018dbcb395e2bca0b9a898e73989e67c0c4a5db269528e1b036ca38bcca0d0b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.7.16"
|
||||
version: "2.7.17"
|
||||
video_player_avfoundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: video_player_avfoundation
|
||||
sha256: "8a4e73a3faf2b13512978a43cf1cdda66feeeb900a0527f1fbfd7b19cf3458d3"
|
||||
sha256: "84b4752745eeccb6e75865c9aab39b3d28eb27ba5726d352d45db8297fbd75bc"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.7"
|
||||
version: "2.7.0"
|
||||
video_player_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1616,10 +1635,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
|
||||
sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.3.0"
|
||||
version: "14.3.1"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1632,10 +1651,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1664,10 +1683,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter_android
|
||||
sha256: d1ee28f44894cbabb1d94cc42f9980297f689ff844d067ec50ff88d86e27d63f
|
||||
sha256: "512c26ccc5b8a571fd5d13ec994b7509f142ff6faf85835e243dde3538fdc713"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.3.0"
|
||||
version: "4.3.2"
|
||||
webview_flutter_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1680,18 +1699,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter_wkwebview
|
||||
sha256: "4adc14ea9a770cc9e2c8f1ac734536bd40e82615bd0fa6b94be10982de656cc7"
|
||||
sha256: c49a98510080378b1525132f407a92c3dcd3b7145bef04fb8137724aadcf1cf0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.17.0"
|
||||
version: "3.18.4"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
sha256: daf97c9d80197ed7b619040e86c8ab9a9dad285e7671ee7390f9180cc828a51e
|
||||
sha256: b89e6e24d1454e149ab20fbb225af58660f0c0bf4475544650700d8e2da54aef
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.10.1"
|
||||
version: "5.11.0"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1717,5 +1736,5 @@ packages:
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.5.2 <4.0.0"
|
||||
flutter: ">=3.24.0"
|
||||
dart: ">=3.7.0 <4.0.0"
|
||||
flutter: ">=3.27.0"
|
||||
|
||||
12
pubspec.yaml
12
pubspec.yaml
@ -1,7 +1,7 @@
|
||||
name: uae_stat
|
||||
description: "View statistics about the UAE from the Federal Center for Statistics and Competitiveness."
|
||||
publish_to: "none"
|
||||
version: 1.0.27+28
|
||||
version: 1.0.30+31
|
||||
|
||||
environment:
|
||||
sdk: ">=3.2.3 <4.0.0"
|
||||
@ -9,9 +9,9 @@ environment:
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
fast_immutable_collections: ^10.1.0
|
||||
fast_immutable_collections: ^11.0.3
|
||||
# flutter_cache_manager: ^3.3.1
|
||||
flutter_hooks: ^0.20.4
|
||||
flutter_hooks: ^0.21.2
|
||||
flutter_riverpod: ^2.4.0
|
||||
get_it: ^8.0.1
|
||||
go_router: ^14.1.3
|
||||
@ -33,10 +33,10 @@ dependencies:
|
||||
csv: ^6.0.0
|
||||
excel: ^4.0.2
|
||||
intl: ^0.19.0
|
||||
firebase_core: ^2.27.0
|
||||
firebase_core: ^3.12.1
|
||||
the_validator: ^2.0.0
|
||||
pocketbase: ^0.18.1
|
||||
flutter_secure_storage: ^9.0.0
|
||||
flutter_secure_storage: ^10.0.0-beta.4
|
||||
jwt_decoder: ^2.0.1
|
||||
fluttertoast: ^8.2.11
|
||||
webview_flutter: ^4.5.0
|
||||
@ -66,6 +66,7 @@ dependencies:
|
||||
package_info_plus: ^8.2.0
|
||||
flutter_svg: ^2.0.17
|
||||
boxy: ^2.2.1
|
||||
firebase_messaging: ^15.2.4
|
||||
|
||||
dependency_overrides:
|
||||
fading_edge_scrollview: ^4.1.1
|
||||
@ -139,6 +140,7 @@ flutter:
|
||||
- assets/icons/misc/group.png
|
||||
- assets/icons/misc/search.png
|
||||
- assets/icons/bookmark/
|
||||
- assets/FCSC-GIF.gif
|
||||
|
||||
fonts:
|
||||
- family: Segoe
|
||||
|
||||
Loading…
Reference in New Issue
Block a user