bug fix and notification
This commit is contained in:
parent
f9a16ec99a
commit
cbe243ea1d
@ -20,12 +20,12 @@ if (project.hasProperty('google-services.json')) {
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = "33"
|
||||
flutterVersionCode = "34"
|
||||
}
|
||||
|
||||
def flutterVersionName = localProperties.getProperty("flutter.versionName")
|
||||
if (flutterVersionName == null) {
|
||||
flutterVersionName = "1.0.32"
|
||||
flutterVersionName = "1.0.33"
|
||||
}
|
||||
|
||||
def keystorePropertiesFile = rootProject.file("key.properties")
|
||||
|
||||
15
lib/config/connectivity_provider.dart
Normal file
15
lib/config/connectivity_provider.dart
Normal file
@ -0,0 +1,15 @@
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:internet_connection_checker/internet_connection_checker.dart';
|
||||
|
||||
final connectivityProvider = StreamProvider<bool>((ref) async* {
|
||||
await for (var result in Connectivity().onConnectivityChanged) {
|
||||
bool isConnected = result != ConnectivityResult.none;
|
||||
|
||||
if (isConnected) {
|
||||
isConnected = await InternetConnectionChecker.instance.hasConnection;
|
||||
}
|
||||
|
||||
yield isConnected;
|
||||
}
|
||||
});
|
||||
@ -377,7 +377,7 @@ final GoRouter router = GoRouter(
|
||||
// ),
|
||||
GoRoute(
|
||||
path: '/internetcheck',
|
||||
builder: (context, state) => InternetCheck(),
|
||||
builder: (context, state) => InternetCheckScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/login',
|
||||
@ -653,7 +653,8 @@ final GoRouter router = GoRouter(
|
||||
],
|
||||
redirect: (context, state) async {
|
||||
if (state.uri.path == '/SessionCheckScreen' ||
|
||||
state.uri.path == '/login') {
|
||||
state.uri.path == '/login' ||
|
||||
state.uri.path == '/register') {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:uae_stat/config/connectivity_provider.dart';
|
||||
import 'package:uae_stat/domain/use_cases/language.dart';
|
||||
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart';
|
||||
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
|
||||
@ -170,10 +171,20 @@ class _UaenumberWidgetState extends ConsumerState<uaenumberWidget> {
|
||||
}
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
final isConnected = ref.watch(connectivityProvider);
|
||||
|
||||
// If no internet, redirect to InternetCheckScreen
|
||||
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
|
||||
if (hasInternet.value == false) {
|
||||
context.go('/internetcheck');
|
||||
}
|
||||
});
|
||||
|
||||
ref.listen<Locale?>(localeProvider, (previous, next) {
|
||||
final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null
|
||||
fetchData(localeCode);
|
||||
});
|
||||
|
||||
double myheight = MediaQuery.of(context).size.height;
|
||||
double mywidth = MediaQuery.of(context).size.width;
|
||||
|
||||
@ -362,6 +373,16 @@ class _UaenumberWidgetState extends ConsumerState<uaenumberWidget> {
|
||||
colorPattern,
|
||||
double mywidth,
|
||||
String mainTopic) {
|
||||
print('UAE Numbers $value , $title');
|
||||
// Check if title is "Population Growth"
|
||||
bool isPopulationGrowth = title == "Population Growth";
|
||||
|
||||
// Convert value to double for checking positive or negative (only for Population Growth)
|
||||
double parsedValue = isPopulationGrowth
|
||||
? double.tryParse(value.replaceAll('%', '')) ?? 0.0
|
||||
: 0.0;
|
||||
bool isPositive = parsedValue >= 0;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
// print('checking data');
|
||||
@ -403,13 +424,28 @@ class _UaenumberWidgetState extends ConsumerState<uaenumberWidget> {
|
||||
SizedBox(height: 0.1),
|
||||
Text(subtitle, textAlign: TextAlign.center, style: subtitleStyle),
|
||||
SizedBox(height: 0.3),
|
||||
Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
color: boldColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
color: isPopulationGrowth
|
||||
? (isPositive ? Colors.green : Colors.red)
|
||||
: boldColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
if (isPopulationGrowth) ...[
|
||||
const SizedBox(width: 5),
|
||||
Icon(
|
||||
isPositive ? Icons.arrow_upward : Icons.arrow_downward,
|
||||
color: isPositive ? Colors.green : Colors.red,
|
||||
size: 20,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,7 @@ import 'package:screenshot/screenshot.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:tutorial_coach_mark/tutorial_coach_mark.dart';
|
||||
import 'package:uae_stat/config/api_config.dart';
|
||||
import 'package:uae_stat/config/connectivity_provider.dart';
|
||||
import 'package:uae_stat/config/toast_util.dart';
|
||||
import 'package:uae_stat/domain/use_cases/language.dart';
|
||||
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/uae_numbers_asset_path.dart';
|
||||
@ -2098,6 +2099,15 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
final locale = ref.watch(localeProvider);
|
||||
final localeNotifier = ref.read(localeProvider.notifier);
|
||||
|
||||
final isConnected = ref.watch(connectivityProvider);
|
||||
|
||||
// If no internet, redirect to InternetCheckScreen
|
||||
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
|
||||
if (hasInternet.value == false) {
|
||||
context.go('/internetcheck');
|
||||
}
|
||||
});
|
||||
|
||||
ref.listen<Locale?>(localeProvider, (previous, next) {
|
||||
final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null
|
||||
|
||||
@ -2330,7 +2340,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () => shareCurrentPage(context, _isSharing),
|
||||
onTap: () =>
|
||||
shareCurrentPage(context, _isSharing),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
@ -2343,19 +2354,20 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
SizedBox(width: 5),
|
||||
_isSharing
|
||||
? SizedBox(
|
||||
width: 24,
|
||||
height: 24,
|
||||
child: CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
) // Show loading spinner
|
||||
width: 24,
|
||||
height: 24,
|
||||
child:
|
||||
CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
) // Show loading spinner
|
||||
: SvgPicture.asset(
|
||||
UaeNumbersAssetPath.share,
|
||||
semanticsLabel: 'share',
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
UaeNumbersAssetPath.share,
|
||||
semanticsLabel: 'share',
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -2664,7 +2676,7 @@ Future<void> shareCurrentPage(BuildContext context, bool _isSharing) async {
|
||||
height: 200,
|
||||
);
|
||||
final Uint8List? capturedImage =
|
||||
await screenshotController.captureFromWidget(
|
||||
await screenshotController.captureFromWidget(
|
||||
Material(child: svgWidget),
|
||||
);
|
||||
|
||||
|
||||
@ -2684,6 +2684,8 @@ class ChartWidget extends StatelessWidget {
|
||||
|
||||
print('spots - $spots');
|
||||
|
||||
// lineChartLabel = spots;
|
||||
|
||||
// List<FlSpot> spots = filteredData
|
||||
// .where((entry) => entry['ObsKey'][groupByKey] == group)
|
||||
// .map<FlSpot>((entry) {
|
||||
|
||||
@ -1,54 +1,75 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:uae_stat/presentation/components/constant/constant.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:internet_connection_checker/internet_connection_checker.dart';
|
||||
import 'package:uae_stat/config/connectivity_provider.dart';
|
||||
|
||||
class InternetCheck extends StatelessWidget {
|
||||
const InternetCheck({super.key});
|
||||
class InternetCheckScreen extends ConsumerWidget {
|
||||
const InternetCheckScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
double myheight = MediaQuery.of(context).size.height;
|
||||
double mywidth = MediaQuery.of(context).size.width;
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
// Listen to changes in connectivity and navigate back to Home if online
|
||||
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
|
||||
if (hasInternet.value == true) {
|
||||
Navigator.pop(context);
|
||||
// context.go('/myhomepage');
|
||||
}
|
||||
});
|
||||
|
||||
double myHeight = MediaQuery.of(context).size.height;
|
||||
|
||||
return Scaffold(
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Container(
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image(image: AssetImage('assets/logos/no-internet.png')),
|
||||
SizedBox(height: myheight/40,),
|
||||
Text("No Internet Connection",style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold)),
|
||||
Text("Please check with your Wi-Fi or Mobile",style: TextStyle(fontSize: 15,fontWeight: FontWeight.w500)),
|
||||
Text("Data connection and try again",style: TextStyle(fontSize: 15,fontWeight: FontWeight.w500)),
|
||||
SizedBox(height: myheight/40,),
|
||||
ElevatedButton(
|
||||
onPressed: (){
|
||||
Navigator.pop(context);
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(
|
||||
0xFFA7887A), // Brownish color for Register
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"Retry",
|
||||
style: TextStyle(
|
||||
fontSize: 16, color: Colors.white),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset('assets/logos/no-internet.png', width: 150),
|
||||
SizedBox(height: myHeight / 40),
|
||||
Text("No Internet Connection",
|
||||
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold)),
|
||||
Text("Please check your Wi-Fi or Mobile Data",
|
||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500)),
|
||||
Text("connection and try again",
|
||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500)),
|
||||
SizedBox(height: myHeight / 40),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
bool hasInternet =
|
||||
await InternetConnectionChecker.instance.hasConnection;
|
||||
|
||||
if (hasInternet) {
|
||||
Navigator.pop(
|
||||
context); // Redirect to home if internet is available
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content:
|
||||
Text("No internet connection. Please try again."),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Icon(Icons.arrow_forward_ios_outlined,size: 12,
|
||||
color: Colors.white),
|
||||
],
|
||||
);
|
||||
}
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFFA7887A),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text("Retry",
|
||||
style: TextStyle(fontSize: 16, color: Colors.white)),
|
||||
SizedBox(width: 8),
|
||||
Icon(Icons.refresh, size: 16, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -13,6 +13,7 @@ import 'package:intl/intl.dart';
|
||||
import 'package:pocketbase/pocketbase.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:uae_stat/config/api_config.dart';
|
||||
import 'package:uae_stat/config/connectivity_provider.dart';
|
||||
import 'package:uae_stat/config/my_theme.dart';
|
||||
import 'package:uae_stat/domain/use_cases/language.dart';
|
||||
import 'package:uae_stat/infrastructure/data/p_auth_repo.dart';
|
||||
@ -467,6 +468,14 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isConnected = ref.watch(connectivityProvider);
|
||||
|
||||
// If no internet, redirect to InternetCheckScreen
|
||||
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
|
||||
if (hasInternet.value == false) {
|
||||
context.go('/internetcheck');
|
||||
}
|
||||
});
|
||||
final profileLocale = ref.watch(localeProvider);
|
||||
return PopScope(
|
||||
canPop: false, // Allow back navigation only if not login screen
|
||||
|
||||
@ -209,6 +209,21 @@ class LoginRoute extends HookConsumerWidget {
|
||||
// }
|
||||
// }
|
||||
|
||||
emailValidation({String? message, String? requiredMessage}) {
|
||||
return (fieldValue) {
|
||||
if (fieldValue == null || fieldValue.trim().isEmpty) {
|
||||
return requiredMessage ?? "Email is required";
|
||||
}
|
||||
if (!Validator.isEmail(fieldValue)) {
|
||||
if (fieldValue.contains(" ")) {
|
||||
return "Space is present, email is not correct";
|
||||
}
|
||||
return message ?? "Email is not correct";
|
||||
}
|
||||
return null; // Validation passed
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final hasValidated = useState(false);
|
||||
@ -241,7 +256,7 @@ class LoginRoute extends HookConsumerWidget {
|
||||
content: Form(
|
||||
key: forgotPwFormKey,
|
||||
child: TextFormField(
|
||||
validator: FieldValidator.email(),
|
||||
validator: emailValidation(),
|
||||
controller: emailCtl,
|
||||
decoration: InputDecoration(
|
||||
labelText: context.translate(
|
||||
@ -456,7 +471,8 @@ class LoginRoute extends HookConsumerWidget {
|
||||
print("Is Profile Complete: $isProfileComplete");
|
||||
|
||||
// Extract intendedPath from query parameters (if coming from redirect)
|
||||
final String? intendedPath = GoRouterState.of(context).uri.queryParameters['intendedPath'];
|
||||
final String? intendedPath =
|
||||
GoRouterState.of(context).uri.queryParameters['intendedPath'];
|
||||
print("Extracted intendedPath after login: $intendedPath");
|
||||
|
||||
if (!context.mounted) return;
|
||||
|
||||
@ -168,6 +168,7 @@ import 'package:go_router/go_router.dart';
|
||||
import 'package:pocketbase/pocketbase.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:uae_stat/config/api_config.dart';
|
||||
import 'package:uae_stat/config/connectivity_provider.dart';
|
||||
import 'package:uae_stat/domain/use_cases/language.dart';
|
||||
import 'package:uae_stat/infrastructure/data/p_auth_repo.dart';
|
||||
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
|
||||
@ -1134,6 +1135,16 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null
|
||||
fetchData(localeCode);
|
||||
});
|
||||
|
||||
final isConnected = ref.watch(connectivityProvider);
|
||||
|
||||
// If no internet, redirect to InternetCheckScreen
|
||||
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
|
||||
if (hasInternet.value == false) {
|
||||
context.go('/internetcheck');
|
||||
}
|
||||
});
|
||||
|
||||
double myheight = MediaQuery.of(context).size.height;
|
||||
double mywidth = MediaQuery.of(context).size.width;
|
||||
|
||||
|
||||
@ -7,13 +7,13 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:pocketbase/pocketbase.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:uae_stat/config/api_config.dart';
|
||||
import 'package:uae_stat/config/connectivity_provider.dart';
|
||||
import 'package:uae_stat/domain/use_cases/language.dart';
|
||||
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/bookmark_asset_path.dart';
|
||||
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/uae_numbers_asset_path.dart';
|
||||
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
|
||||
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
|
||||
|
||||
|
||||
class BookMark extends ConsumerStatefulWidget {
|
||||
const BookMark({super.key});
|
||||
|
||||
@ -35,7 +35,6 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
super.initState();
|
||||
final locale = ref.read(localeProvider);
|
||||
fetchBookmarks(locale?.languageCode ?? 'en');
|
||||
|
||||
}
|
||||
|
||||
String colorToHex(Color color) {
|
||||
@ -43,6 +42,7 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
'${color.green.toRadixString(16).padLeft(2, '0').toUpperCase()}'
|
||||
'${color.blue.toRadixString(16).padLeft(2, '0').toUpperCase()}';
|
||||
}
|
||||
|
||||
// Function to convert hex color string to int
|
||||
Color _parseColor(String? colorString) {
|
||||
if (colorString == null || colorString.isEmpty) {
|
||||
@ -105,26 +105,26 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
String? mainTopic = item['main_topic'];
|
||||
String subtitle = item['subtitle'];
|
||||
|
||||
|
||||
// Ignore if main_topic is null
|
||||
if (mainTopic == null) continue;
|
||||
|
||||
// If main_topic doesn't exist in groupedMap, create a new entry
|
||||
if (!groupedMap.containsKey(mainTopic)) {
|
||||
groupedMap[mainTopic] = {'main_topic': mainTopic,
|
||||
groupedMap[mainTopic] = {
|
||||
'main_topic': mainTopic,
|
||||
'valueColor': item['valueColor'],
|
||||
'SubTopic': []
|
||||
};
|
||||
}
|
||||
|
||||
// Add subtitle as a key with its corresponding map value
|
||||
groupedMap[mainTopic]!['SubTopic'].add ({
|
||||
groupedMap[mainTopic]!['SubTopic'].add({
|
||||
'subtitle': subtitle,
|
||||
'isBookmark': item['isBookmark'],
|
||||
'value': item['value'],
|
||||
'title':item['title'],
|
||||
'value_source':item['value_source'],
|
||||
'data_set':item['data_set'],
|
||||
'title': item['title'],
|
||||
'value_source': item['value_source'],
|
||||
'data_set': item['data_set'],
|
||||
'id': item['id'],
|
||||
});
|
||||
}
|
||||
@ -170,7 +170,7 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
content: Text(
|
||||
'Unable to remove from bookmarks. Please try again',
|
||||
style:
|
||||
TextStyle(color: Color(0xFFEB5F24), fontWeight: FontWeight.w600),
|
||||
TextStyle(color: Color(0xFFEB5F24), fontWeight: FontWeight.w600),
|
||||
),
|
||||
backgroundColor: Color(0xFFD6E9C6),
|
||||
duration: Duration(seconds: 2),
|
||||
@ -253,7 +253,8 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
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(
|
||||
@ -264,7 +265,6 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
],
|
||||
),
|
||||
);
|
||||
@ -272,12 +272,32 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isConnected = ref.watch(connectivityProvider);
|
||||
|
||||
// If no internet, redirect to InternetCheckScreen
|
||||
ref.listen<AsyncValue<bool>>(connectivityProvider, (previous, hasInternet) {
|
||||
if (hasInternet.value == false) {
|
||||
context.go('/internetcheck');
|
||||
}
|
||||
});
|
||||
|
||||
final List<Map<String, dynamic>> tabs = [
|
||||
{ 'title':AppLocalizations.of(context)!.all_bookmarks, 'color': Colors.black},
|
||||
{ 'title': AppLocalizations.of(context)!.economy_title, 'color': Color(0xFF90B0D5)},
|
||||
{ 'title':AppLocalizations.of(context)!.social_title, 'color': Color(0xFFAA8E83)},
|
||||
{ 'title': AppLocalizations.of(context)!.environment_title, 'color': Color(0xFF7DAFBC)},
|
||||
{
|
||||
'title': AppLocalizations.of(context)!.all_bookmarks,
|
||||
'color': Colors.black
|
||||
},
|
||||
{
|
||||
'title': AppLocalizations.of(context)!.economy_title,
|
||||
'color': Color(0xFF90B0D5)
|
||||
},
|
||||
{
|
||||
'title': AppLocalizations.of(context)!.social_title,
|
||||
'color': Color(0xFFAA8E83)
|
||||
},
|
||||
{
|
||||
'title': AppLocalizations.of(context)!.environment_title,
|
||||
'color': Color(0xFF7DAFBC)
|
||||
},
|
||||
];
|
||||
|
||||
ref.listen<Locale?>(localeProvider, (previous, next) {
|
||||
@ -285,23 +305,26 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
fetchBookmarks(localeCode);
|
||||
});
|
||||
|
||||
List<Map<String, dynamic>> bookmarks = dataList.where((item) => item['isBookmark'] == true).toList();
|
||||
List<Map<String, dynamic>> filteredBookmarks = dataList
|
||||
.where((bookmark) {
|
||||
List<Map<String, dynamic>> bookmarks =
|
||||
dataList.where((item) => item['isBookmark'] == true).toList();
|
||||
List<Map<String, dynamic>> filteredBookmarks = dataList.where((bookmark) {
|
||||
String mainTopic = bookmark['main_topic'].toString().trim().toLowerCase();
|
||||
String selectedTabTitle = tabs[selectedTabIndex]['title'].toString().trim().toLowerCase();
|
||||
String selectedTabTitle =
|
||||
tabs[selectedTabIndex]['title'].toString().trim().toLowerCase();
|
||||
|
||||
// Debugging prints
|
||||
print("main_topic: '$mainTopic', selected_tab_title: '$selectedTabTitle'");
|
||||
print(
|
||||
"main_topic: '$mainTopic', selected_tab_title: '$selectedTabTitle'");
|
||||
|
||||
return mainTopic == selectedTabTitle;
|
||||
})
|
||||
.toList();
|
||||
}).toList();
|
||||
// print( 'filtered one :${filteredBookmarks['main_topic']} , Tabs : ${tabs[selectedTabIndex]["title"]}');
|
||||
List<Map<String, dynamic>> transformedList = groupedMap.values.toList();
|
||||
// print('filtered $filteredBookmarks');
|
||||
return BaseScaffold(
|
||||
title: Text(AppLocalizations.of(context)!.bookmarks,),
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!.bookmarks,
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
TabBarHeader(
|
||||
@ -316,134 +339,143 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
Expanded(
|
||||
child: selectedTabIndex == 0
|
||||
? (bookmarks.isNotEmpty
|
||||
? SingleChildScrollView(
|
||||
child: Column(
|
||||
children: List.generate(transformedList.length, (i) {
|
||||
final mainTopic = transformedList[i];
|
||||
print('oustside1 $mainTopic');
|
||||
final list=List.from(mainTopic['SubTopic'] ?? []);
|
||||
print('oustside2 $list');
|
||||
return CustomExpandableTile(
|
||||
index: i,
|
||||
isExpanded: expandedIndex == i,
|
||||
onTap: (int index) { // 🔹 Expecting an index
|
||||
setState(() {
|
||||
expandedIndex = (expandedIndex == index) ? null : index;
|
||||
});
|
||||
},
|
||||
title: mainTopic['main_topic'] ?? 'No Topic',
|
||||
childWidget:
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
// borderRadius: BorderRadius.all(Radius.circular(20))
|
||||
),
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: GridView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
gridDelegate:
|
||||
const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
crossAxisSpacing: 10.0,
|
||||
mainAxisSpacing: 10.0,
|
||||
mainAxisExtent: 100,
|
||||
? SingleChildScrollView(
|
||||
child: Column(
|
||||
children: List.generate(transformedList.length, (i) {
|
||||
final mainTopic = transformedList[i];
|
||||
print('oustside1 $mainTopic');
|
||||
final list = List.from(mainTopic['SubTopic'] ?? []);
|
||||
print('oustside2 $list');
|
||||
return CustomExpandableTile(
|
||||
index: i,
|
||||
isExpanded: expandedIndex == i,
|
||||
onTap: (int index) {
|
||||
// 🔹 Expecting an index
|
||||
setState(() {
|
||||
expandedIndex =
|
||||
(expandedIndex == index) ? null : index;
|
||||
});
|
||||
},
|
||||
title: mainTopic['main_topic'] ?? 'No Topic',
|
||||
childWidget: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
// borderRadius: BorderRadius.all(Radius.circular(20))
|
||||
),
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: GridView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
gridDelegate:
|
||||
const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
crossAxisSpacing: 10.0,
|
||||
mainAxisSpacing: 10.0,
|
||||
mainAxisExtent: 100,
|
||||
),
|
||||
itemCount: list.length,
|
||||
itemBuilder: (context, index) {
|
||||
return _buildBoxes(
|
||||
mainTopic['SubTopic'][index],
|
||||
context,
|
||||
mainTopic['valueColor']);
|
||||
},
|
||||
),
|
||||
),
|
||||
filteredBookmarks:
|
||||
List.from(mainTopic['SubTopic'] ?? []),
|
||||
titleBackgroundColor: mainTopic['valueColor'],
|
||||
// Ensure it's a new list
|
||||
);
|
||||
}),
|
||||
),
|
||||
)
|
||||
: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.info_outline,
|
||||
size: 100, color: Colors.grey[400]),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
context.translate('No BookMark Added',
|
||||
'لم يتم إضافة أي علامة مرجعية'),
|
||||
style:
|
||||
TextStyle(fontSize: 16, color: Colors.grey),
|
||||
),
|
||||
],
|
||||
),
|
||||
))
|
||||
: filteredBookmarks.isEmpty
|
||||
? Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.info_outline,
|
||||
size: 100, color: Colors.grey[400]),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
'No Bookmark is added',
|
||||
style:
|
||||
TextStyle(fontSize: 16, color: Colors.grey),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: tabs[selectedTabIndex]['color'],
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(35))),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 16, bottom: 5, top: 5, right: 10),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
tabs[selectedTabIndex]['title'],
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Expanded(
|
||||
child: GridView.builder(
|
||||
gridDelegate:
|
||||
const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
crossAxisSpacing: 10.0,
|
||||
mainAxisSpacing: 10.0,
|
||||
mainAxisExtent: 100,
|
||||
),
|
||||
itemCount: filteredBookmarks.length,
|
||||
itemBuilder: (context, index) {
|
||||
return _buildBox(
|
||||
filteredBookmarks[index], context);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
itemCount:list.length,
|
||||
itemBuilder: (context, index) {
|
||||
return _buildBoxes(mainTopic['SubTopic'][index], context,mainTopic['valueColor']);
|
||||
},
|
||||
),
|
||||
),
|
||||
filteredBookmarks: List.from(mainTopic['SubTopic'] ?? []), titleBackgroundColor: mainTopic['valueColor'],
|
||||
// Ensure it's a new list
|
||||
);
|
||||
}),
|
||||
),
|
||||
)
|
||||
: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.info_outline,
|
||||
size: 100, color: Colors.grey[400]),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
context.translate('No BookMark Added','لم يتم إضافة أي علامة مرجعية'),
|
||||
style:
|
||||
TextStyle(fontSize: 16, color: Colors.grey),
|
||||
),
|
||||
],
|
||||
),
|
||||
))
|
||||
:filteredBookmarks.isEmpty
|
||||
? Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.info_outline,
|
||||
size: 100, color: Colors.grey[400]),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
'No Bookmark is added',
|
||||
style:
|
||||
TextStyle(fontSize: 16, color: Colors.grey),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: tabs[selectedTabIndex]['color'],
|
||||
borderRadius: BorderRadius.all(Radius.circular(35))
|
||||
),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 16, bottom: 5, top: 5, right: 10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
tabs[selectedTabIndex]['title'],
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20,),
|
||||
Expanded(
|
||||
child: GridView.builder(
|
||||
gridDelegate:
|
||||
const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
crossAxisSpacing: 10.0,
|
||||
mainAxisSpacing: 10.0,
|
||||
mainAxisExtent: 100,
|
||||
),
|
||||
itemCount: filteredBookmarks.length,
|
||||
itemBuilder: (context, index) {
|
||||
return _buildBox(filteredBookmarks[index], context);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
),
|
||||
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBox(Map<String, dynamic> data, BuildContext context) {
|
||||
// Color borderColor = data['valueColor'];
|
||||
return GestureDetector(
|
||||
@ -501,10 +533,9 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
child: SvgPicture.asset(
|
||||
BookmarkAssetPath.delete,
|
||||
semanticsLabel: 'share',
|
||||
width:23,
|
||||
width: 23,
|
||||
height: 20,
|
||||
)
|
||||
),
|
||||
)),
|
||||
|
||||
// GestureDetector(
|
||||
// onTap: () {
|
||||
@ -543,7 +574,8 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBoxes(Map<String, dynamic> data, BuildContext context, Color styleColor) {
|
||||
Widget _buildBoxes(
|
||||
Map<String, dynamic> data, BuildContext context, Color styleColor) {
|
||||
// Color borderColor = data['valueColor'];
|
||||
print('inside function $data');
|
||||
return GestureDetector(
|
||||
@ -555,7 +587,8 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
final encodedTitle = data['title'];
|
||||
String hexColor = colorToHex(styleColor);
|
||||
|
||||
debugPrint( '/chartScreen/$data_set?bgColor=$hexColor&mainTopic=$encodedMainTopic&title=$encodedTitle');
|
||||
debugPrint(
|
||||
'/chartScreen/$data_set?bgColor=$hexColor&mainTopic=$encodedMainTopic&title=$encodedTitle');
|
||||
|
||||
// String hexColor = colorToHex(colorPattern); // Get hex string
|
||||
// print(hexColor); // Prints: 0xFFAA8E83
|
||||
@ -573,8 +606,7 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(color: styleColor),
|
||||
),
|
||||
child:
|
||||
Align(
|
||||
child: Align(
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@ -603,10 +635,9 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
child: SvgPicture.asset(
|
||||
BookmarkAssetPath.delete,
|
||||
semanticsLabel: 'share',
|
||||
width:23,
|
||||
width: 23,
|
||||
height: 20,
|
||||
)
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
@ -630,11 +661,10 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TabBarHeader extends StatelessWidget {
|
||||
final List<Map<String, dynamic>> tabs;
|
||||
final List<Map<String, dynamic>> tabs;
|
||||
final int selectedIndex;
|
||||
final ValueChanged<int> onTabSelected;
|
||||
|
||||
@ -662,7 +692,7 @@ class TabBarHeader extends StatelessWidget {
|
||||
onPressed: () => onTabSelected(index),
|
||||
style: ButtonStyle(
|
||||
foregroundColor:
|
||||
MaterialStateProperty.resolveWith((states) {
|
||||
MaterialStateProperty.resolveWith((states) {
|
||||
return selectedIndex == index
|
||||
? entry.value['color']
|
||||
: Colors.grey[700];
|
||||
@ -715,7 +745,6 @@ class CustomExpandableTile extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _CustomExpandableTileState extends State<CustomExpandableTile> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState(); // Initialize isExpanded based on widget's property
|
||||
@ -733,13 +762,13 @@ class _CustomExpandableTileState extends State<CustomExpandableTile> {
|
||||
onTap: () => widget.onTap(widget.index),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white, // Ensuring the background outside the rounded container is white
|
||||
color: Colors
|
||||
.white, // Ensuring the background outside the rounded container is white
|
||||
),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: widget.titleBackgroundColor,
|
||||
borderRadius: BorderRadius.all(Radius.circular(35))
|
||||
),
|
||||
borderRadius: BorderRadius.all(Radius.circular(35))),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 16, bottom: 5, top: 5, right: 10),
|
||||
child: Row(
|
||||
@ -771,37 +800,37 @@ class _CustomExpandableTileState extends State<CustomExpandableTile> {
|
||||
curve: Curves.easeInOut,
|
||||
width: double.infinity,
|
||||
color: Colors.white,
|
||||
height:widget.isExpanded ? myheight * 0.4 : 0,
|
||||
child:widget.isExpanded
|
||||
// height: widget.isExpanded ? myheight * 0.4 : 0,
|
||||
child: widget.isExpanded
|
||||
? SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
widget.childWidget,
|
||||
// Container(
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
// // borderRadius: BorderRadius.all(Radius.circular(20))
|
||||
// ),
|
||||
// padding: const EdgeInsets.all(16),
|
||||
// child: GridView.builder(
|
||||
// shrinkWrap: true,
|
||||
// physics: NeverScrollableScrollPhysics(),
|
||||
// gridDelegate:
|
||||
// const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
// crossAxisCount: 2,
|
||||
// crossAxisSpacing: 10.0,
|
||||
// mainAxisSpacing: 10.0,
|
||||
// mainAxisExtent: 100,
|
||||
// ),
|
||||
// itemCount: widget.filteredBookmarks.length,
|
||||
// itemBuilder: (context, index) {
|
||||
// return _buildBox(widget.filteredBookmarks[index], context,widget.titleBackgroundColor);
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
)
|
||||
child: Column(
|
||||
children: [
|
||||
widget.childWidget,
|
||||
// Container(
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
// // borderRadius: BorderRadius.all(Radius.circular(20))
|
||||
// ),
|
||||
// padding: const EdgeInsets.all(16),
|
||||
// child: GridView.builder(
|
||||
// shrinkWrap: true,
|
||||
// physics: NeverScrollableScrollPhysics(),
|
||||
// gridDelegate:
|
||||
// const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
// crossAxisCount: 2,
|
||||
// crossAxisSpacing: 10.0,
|
||||
// mainAxisSpacing: 10.0,
|
||||
// mainAxisExtent: 100,
|
||||
// ),
|
||||
// itemCount: widget.filteredBookmarks.length,
|
||||
// itemBuilder: (context, index) {
|
||||
// return _buildBox(widget.filteredBookmarks[index], context,widget.titleBackgroundColor);
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
|
||||
@ -5,6 +5,7 @@ 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:shared_preferences/shared_preferences.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';
|
||||
@ -21,28 +22,67 @@ class _NotificationPageState extends ConsumerState<NotificationPage> {
|
||||
// Example notification data
|
||||
final _pb = PocketBase(apiUrl);
|
||||
List<Map<String, dynamic>> notifications = [];
|
||||
List<String> pushedNotification = [];
|
||||
|
||||
// Current selected tab index
|
||||
int selectedTabIndex = 0;
|
||||
late final Locale locale;
|
||||
dynamic userID;
|
||||
|
||||
// Tab categories
|
||||
final List<String> tabs = [
|
||||
"All updates",
|
||||
"App updates",
|
||||
"Social",
|
||||
"Economy",
|
||||
"Environment",
|
||||
"Favourites"
|
||||
];
|
||||
// final List<String> tabs = [
|
||||
// "All updates",
|
||||
// "App updates",
|
||||
// "Social",
|
||||
// "Economy",
|
||||
// "Environment",
|
||||
// "Favourites"
|
||||
// ];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
locale = ref.read(localeProvider) ?? const Locale('en');
|
||||
_fetchUserData();
|
||||
fetchNotifications(locale?.languageCode ?? 'en');
|
||||
}
|
||||
|
||||
Future<String?> getUserId() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getString('userId'); // Retrieve the userId
|
||||
}
|
||||
|
||||
Future<void> _fetchUserData() async {
|
||||
try {
|
||||
String? fetchedUserId = await getUserId();
|
||||
userID = fetchedUserId;
|
||||
final adminAuth = await _pb.admins
|
||||
.authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
|
||||
final adminToken = adminAuth.token;
|
||||
print('adminToken- ${adminToken}');
|
||||
final userDetailsResponse = await _pb.collection('users').getOne(
|
||||
fetchedUserId!,
|
||||
headers: {
|
||||
'Authorization': 'Bearer $adminToken',
|
||||
},
|
||||
);
|
||||
print('userDetails: $userDetailsResponse');
|
||||
setState(() {
|
||||
print('In');
|
||||
// Extract pushed_notification from response
|
||||
List<dynamic> notifications =
|
||||
userDetailsResponse.data['pushed_notification'];
|
||||
|
||||
// Convert to List<String>
|
||||
pushedNotification = List<String>.from(notifications);
|
||||
|
||||
print('pushedNotification: $pushedNotification');
|
||||
});
|
||||
} catch (e) {
|
||||
print('Error fetching user details: $e');
|
||||
}
|
||||
}
|
||||
|
||||
String formatDate(String dateString) {
|
||||
try {
|
||||
DateTime dateTime =
|
||||
@ -81,21 +121,6 @@ class _NotificationPageState extends ConsumerState<NotificationPage> {
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
@ -177,6 +202,8 @@ class _NotificationPageState extends ConsumerState<NotificationPage> {
|
||||
category: notification['category'] ?? 'Unknown',
|
||||
message: notification['message'] ?? '',
|
||||
id: notification['id'],
|
||||
pushedNotification: pushedNotification,
|
||||
userID: userID,
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -253,6 +280,8 @@ class NotificationTile extends StatelessWidget {
|
||||
final String date;
|
||||
final String category;
|
||||
final String id;
|
||||
final String userID;
|
||||
final List<String> pushedNotification;
|
||||
|
||||
const NotificationTile({
|
||||
required this.title,
|
||||
@ -260,37 +289,83 @@ class NotificationTile extends StatelessWidget {
|
||||
required this.date,
|
||||
required this.category,
|
||||
required this.id,
|
||||
required this.userID,
|
||||
required this.pushedNotification,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
bool isPushed = pushedNotification.contains(id);
|
||||
print('isPushed $isPushed , $id');
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
final encodedKey = Uri.encodeQueryComponent('notification');
|
||||
context.go('/notification_details', extra: {
|
||||
'title': title,
|
||||
'message': message,
|
||||
'date': date,
|
||||
'category': category,
|
||||
'id': id,
|
||||
'backNavigation': encodedKey
|
||||
});
|
||||
},
|
||||
onTap: isPushed
|
||||
? () {
|
||||
readedNotification(userID, id);
|
||||
final encodedKey = Uri.encodeQueryComponent('notification');
|
||||
context.go('/notification_details', extra: {
|
||||
'title': title,
|
||||
'message': message,
|
||||
'date': date,
|
||||
'category': category,
|
||||
'id': id,
|
||||
'backNavigation': encodedKey
|
||||
});
|
||||
}
|
||||
: null,
|
||||
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)),
|
||||
leading: isPushed
|
||||
? const Icon(Icons.circle, size: 12, color: Color(0xFFFF274E))
|
||||
: const Icon(Icons.circle, size: 12, color: Color(0x99414042)),
|
||||
title: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: isPushed ? const Color(0xFF414042) : const Color(0x99414042),
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
subtitle: Text(
|
||||
date,
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF8E8E8E),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400),
|
||||
style: TextStyle(
|
||||
color: isPushed ? const Color(0xFF8E8E8E) : const Color(0x998E8E8E),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
trailing: const Icon(Icons.arrow_forward_ios,
|
||||
size: 16, color: Color(0xFF898C81)),
|
||||
trailing: isPushed
|
||||
? const Icon(Icons.arrow_forward_ios,
|
||||
size: 16, color: Color(0xFF898C81))
|
||||
: null,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
final pb = PocketBase(apiUrl);
|
||||
Future<void> readedNotification(String userId, String notificationId) async {
|
||||
await pb.admins.authWithPassword(
|
||||
'pb@venbainfotech.com',
|
||||
'pb@venbainfotech.com',
|
||||
);
|
||||
|
||||
final url =
|
||||
"${pb.baseUrl}api/removeNotification?user_id=$userId¬ification_id=$notificationId";
|
||||
|
||||
try {
|
||||
final response = await http.get(
|
||||
Uri.parse(url),
|
||||
headers: {
|
||||
'Content-Type': 'application/json', // Add this
|
||||
'Authorization': pb.authStore.token, // Correct way to send auth token
|
||||
},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
print("✅ updated successfully!");
|
||||
} else {
|
||||
print("❌ Failed to update : ${response.body}");
|
||||
}
|
||||
} catch (e) {
|
||||
print("🚨 Error updating : $e");
|
||||
}
|
||||
}
|
||||
|
||||
40
pubspec.lock
40
pubspec.lock
@ -173,10 +173,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
sha256: "8b158ab94ec6913e480dc3f752418348b5ae099eb75868b5f4775f0572999c61"
|
||||
sha256: ea90e81dc4a25a043d9bee692d20ed6d1c4a1662a28c03a96417446c093ed6b4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.9.4"
|
||||
version: "8.9.5"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -824,10 +824,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image_picker_android
|
||||
sha256: "82652a75e3dd667a91187769a6a2cc81bd8c111bbead698d8e938d2b63e5e89a"
|
||||
sha256: "8bd392ba8b0c8957a157ae0dc9fcf48c58e6c20908d5880aea1d79734df090e9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.12+21"
|
||||
version: "0.8.12+22"
|
||||
image_picker_for_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -892,6 +892,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.7.0"
|
||||
internet_connection_checker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: internet_connection_checker
|
||||
sha256: ee08f13d8b13b978affe226e9274ca3ba7a9bed07c9479e8ae245f785b7a488a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -1104,10 +1112,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2"
|
||||
sha256: "0ca7359dad67fd7063cb2892ab0c0737b2daafd807cf1acecd62374c8fae6c12"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.15"
|
||||
version: "2.2.16"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1192,10 +1200,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd"
|
||||
sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
version: "2.2.0"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1311,10 +1319,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_android
|
||||
sha256: a768fc8ede5f0c8e6150476e14f38e2417c0864ca36bb4582be8e21925a03c22
|
||||
sha256: "3ec7210872c4ba945e3244982918e502fa2bfb5230dff6832459ca0e1879b7ad"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.6"
|
||||
version: "2.4.8"
|
||||
shared_preferences_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1539,10 +1547,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_android
|
||||
sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193"
|
||||
sha256: "1d0eae19bd7606ef60fe69ef3b312a437a16549476c42321d5dc1506c9ca3bf4"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.14"
|
||||
version: "6.3.15"
|
||||
url_launcher_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1643,10 +1651,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: video_player_android
|
||||
sha256: "7018dbcb395e2bca0b9a898e73989e67c0c4a5db269528e1b036ca38bcca0d0b"
|
||||
sha256: d949a83d1a333178eb3a9683f70afa41b7771c2bfa4cedd894fe836942de06b1
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.7.17"
|
||||
version: "2.8.1"
|
||||
video_player_avfoundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1723,10 +1731,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter_android
|
||||
sha256: "512c26ccc5b8a571fd5d13ec994b7509f142ff6faf85835e243dde3538fdc713"
|
||||
sha256: "631093a7fbd93e9690ac61d8c8f3e857efbc189fc33f712b9ad6c01a623517ef"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.3.2"
|
||||
version: "4.3.3"
|
||||
webview_flutter_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@ -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.32+33
|
||||
version: 1.0.33+34
|
||||
|
||||
environment:
|
||||
sdk: ">=3.2.3 <4.0.0"
|
||||
@ -68,6 +68,7 @@ dependencies:
|
||||
flutter_svg: ^2.0.17
|
||||
boxy: ^2.2.1
|
||||
firebase_messaging: ^15.2.4
|
||||
internet_connection_checker: ^3.0.1
|
||||
|
||||
dependency_overrides:
|
||||
fading_edge_scrollview: ^4.1.1
|
||||
|
||||
Loading…
Reference in New Issue
Block a user