chart api changes and dev pocketbase url

This commit is contained in:
venbaittech 2025-02-28 09:01:52 +05:30
parent cfe5b5bf20
commit d7a1b5aa38
27 changed files with 386 additions and 577 deletions

View File

@ -15,12 +15,12 @@ if (localPropertiesFile.exists()) {
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
if (flutterVersionCode == null) {
flutterVersionCode = "27"
flutterVersionCode = "28"
}
def flutterVersionName = localProperties.getProperty("flutter.versionName")
if (flutterVersionName == null) {
flutterVersionName = "1.0.26"
flutterVersionName = "1.0.27"
}
def keystorePropertiesFile = rootProject.file("key.properties")

View File

@ -0,0 +1,3 @@
// api_config.dart
// const String apiUrl = 'http://192.168.1.26:8090';
const String apiUrl = 'https://pbdev.venbait.in/';

View File

@ -292,6 +292,8 @@
// return router;
// }
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:go_router/go_router.dart';
@ -414,11 +416,33 @@ final GoRouter router = GoRouter(
final mainTopic = state.uri.queryParameters['mainTopic'] ?? '';
final title = state.uri.queryParameters['title'] ?? '';
final key = state.uri.queryParameters['key'] ?? '';
final kpi = state.uri.queryParameters['kpi'] ?? ''; // Get kpi
// Parse filter_data as a JSON list
// Parse filter_data as a JSON list
List<Map<String, dynamic>> filterData = [];
if (state.uri.queryParameters.containsKey('filter_data') &&
state.uri.queryParameters['filter_data']!.isNotEmpty) {
try {
filterData = List<Map<String, dynamic>>.from(
jsonDecode(state.uri.queryParameters['filter_data']!)
);
} catch (e) {
print('Error parsing filter_data: $e');
filterData = []; // Assign an empty list to prevent null issues
}
} else {
filterData = []; // Ensure it's a valid list
}
print('Router dataSets: $dataSets');
print('Router bgColor: $bgColor');
print('Router mainTopic: $mainTopic');
print('Router title: $title');
print('Router filter: $filterData');
// Pass both values to the screen
return ChartScreen1(
@ -427,6 +451,8 @@ final GoRouter router = GoRouter(
mainTopic: mainTopic,
title: title,
keyParam: key,
kpi: kpi,
filter_data: filterData,
);
},
),

View File

@ -1,9 +1,11 @@
import 'dart:convert';
import 'package:pocketbase/pocketbase.dart';
import 'package:uae_stat/config/api_config.dart';
abstract class PocketBaseService {
static const _host = 'https://pb.venbait.in';
static const _host = apiUrl;
// static const _host = 'https://pb.venbait.in';
// static const _host = 'http://127.0.0.1:8090';
static final _pb = PocketBase(_host);
static final users = _pb.collection('users');

View File

@ -4,6 +4,7 @@
"social_title":"اجتماعي",
"environment_title":"البيئة",
"bookmarks": "الإشارات المرجعية",
"feedback_title": "تعليق",
"feedback_failed_msg": "لم يتم إرسال تعليقاتك. يرجى المحاولة مرة أخرى.",
"thankYou": "شكراً",

View File

@ -1,10 +1,10 @@
{
"all_bookmarks":"All Bookmarks",
"economy_title":"Economy",
"social_title":"Social",
"environment_title":"Environment",
"bookmarks": "Bookmarks",
"feedback_title": "Feedback",
"feedback_failed_msg": "Your feedback could not be \n submitted. Please try again",
"thankYou": "Thank you",

View File

@ -16,6 +16,8 @@ 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();
@ -89,6 +91,8 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
// }
// }
void main() async {
WidgetsFlutterBinding.ensureInitialized();
configureDependencies();
@ -102,10 +106,18 @@ void main() async {
class MainApp extends ConsumerWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final locale = ref.watch(localeProvider);
final connectivityProvider = Provider<bool>((ref) {
return true; // Replace with actual logic
});
// ref.listen<bool>(connectivityProvider, (previous, hasInternet) {
// print('Previous Internet Status: $previous');
// print('Current Internet Status: $hasInternet');

View File

@ -10,6 +10,8 @@ import 'package:uae_stat/presentation/routes/bottom_bar_routes/tab_routes/home_r
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
import 'package:uae_stat/presentation/components/constant/constant.dart';
import 'package:http/http.dart' as http;
import 'package:uae_stat/config/api_config.dart';
class UaeNumbers extends StatelessWidget {
const UaeNumbers({super.key});
@ -83,7 +85,7 @@ class _UaenumberWidgetState extends ConsumerState<uaenumberWidget> {
Future<void> fetchData(locale) async {
// const baseUrl = 'https://pb.venbait.in/api/getHomePageData';
const baseUrl = 'https://pb.venbait.in/api/getUAENumbersData';
const baseUrl = '$apiUrl/api/getUAENumbersData';
try {
final response = await http.get(Uri.parse(baseUrl + '?language=$locale'));
if (response.statusCode == 200) {

View File

@ -5,6 +5,7 @@ import 'package:go_router/go_router.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:pocketbase/pocketbase.dart';
import 'package:uae_stat/config/api_config.dart';
import 'otp_verification.dart';
class Changepassword extends StatefulWidget {
@ -17,7 +18,7 @@ class Changepassword extends StatefulWidget {
}
class _ResetPasswordScreenState extends State<Changepassword> {
final _pb = PocketBase('https://pb.venbait.in');
final _pb = PocketBase(apiUrl);
// final pb = PocketBase('http://127.0.0.1:8090');
final _formKey = GlobalKey<FormState>();
final _emailController = TextEditingController();
@ -46,7 +47,7 @@ class _ResetPasswordScreenState extends State<Changepassword> {
// Check if email exists in the user collection
final userCheckResponse = await http.get(
Uri.parse(
'https://pb.venbait.in/api/collections/users/records?filter=email="$email"'),
'$apiUrl/api/collections/users/records?filter=email="$email"'),
headers: {
'Authorization': 'Bearer $authToken',
},
@ -63,7 +64,7 @@ class _ResetPasswordScreenState extends State<Changepassword> {
// Proceed with OTP request
final otpResponse = await http.post(
Uri.parse(
'https://pb.venbait.in/api/collections/otp_requests/records'),
'$apiUrl/api/collections/otp_requests/records'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $authToken',

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:pocketbase/pocketbase.dart';
import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/presentation/Screens/profilepage.dart';
class ConfirmPassword extends StatefulWidget {
@ -12,7 +13,7 @@ class ConfirmPassword extends StatefulWidget {
}
class _ConfirmPasswordState extends State<ConfirmPassword> {
final _pb = PocketBase('https://pb.venbait.in');
final _pb = PocketBase(apiUrl);
// final pb = PocketBase('http://127.0.0.1:8090');
final _formKey = GlobalKey<FormState>();
bool _obscurePassword = true;

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:pocketbase/pocketbase.dart';
import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/my_router.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';
@ -26,7 +27,7 @@ class CreateNewPw extends ConsumerStatefulWidget {
}
class _CreateNewPwState extends ConsumerState<CreateNewPw> {
final _pb = PocketBase('https://pb.venbait.in');
final _pb = PocketBase(apiUrl);
final _formKey = GlobalKey<FormState>();
bool _obscureOldPassword = true;
bool _obscureNewPassword = true;

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:pocketbase/pocketbase.dart';
import 'package:uae_stat/config/api_config.dart';
import 'confirm_password.dart';
@ -24,7 +25,7 @@ class EmailVerificationScreen extends StatefulWidget {
class _EmailVerificationScreenState extends State<EmailVerificationScreen> {
// final pb = PocketBase('http://127.0.0.1:8090');
final _pb = PocketBase('https://pb.venbait.in');
final _pb = PocketBase(apiUrl);
final List<TextEditingController> _otpControllers =
List.generate(4, (_) => TextEditingController());
int _secondsRemaining = 120; // 2 minutes timer

View File

@ -5,6 +5,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:pocketbase/pocketbase.dart';
import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/my_theme.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/banner_asset_path.dart';
@ -38,7 +39,7 @@ class _RegisterScreenState extends ConsumerState<RegisterScreen> {
bool isRegistering = false;
dynamic userID;
final pb = PocketBase('https://pb.venbait.in');
final pb = PocketBase(apiUrl);
// final pb = PocketBase('http://127.0.0.1:8090');
// Add focus nodes and hint states

View File

@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -8,6 +10,7 @@ import 'package:pocketbase/pocketbase.dart';
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/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';
@ -31,6 +34,8 @@ class ChartScreen1 extends ConsumerStatefulWidget {
final String mainTopic;
final String title;
final String? keyParam; // Nullable String
final String kpi;
final List<Map<String, dynamic>> filter_data;
const ChartScreen1({
Key? key,
@ -39,13 +44,16 @@ class ChartScreen1 extends ConsumerStatefulWidget {
required this.mainTopic,
required this.title,
required this.keyParam,
required this.kpi,
required this.filter_data,
});
@override
ConsumerState<ChartScreen1> createState() => _ChartScreen1State();
}
class _ChartScreen1State extends ConsumerState<ChartScreen1> {
final _pb = PocketBase('https://pb.venbait.in');
// 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();
@ -67,6 +75,9 @@ 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 _tabsData = [];
// List<Map<String, dynamic>> _tabsData = [];
@ -85,11 +96,12 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
super.initState();
final String bgColor = widget.bgColor;
print(' bgColor $bgColor');
// fetchChartData(widget.dataSets);
checkIfBookmarked();
locale = ref.read(localeProvider) ?? const Locale('en');
fetchChartData(widget.dataSets, locale?.languageCode ?? 'en').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']);
}
@ -1202,6 +1214,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
// }
void processChartData(chartsData) {
print("PROCESSING FILTER CHART DATa");
// Group data by 'kpi'
Map<String, List<Map<String, dynamic>>> groupedData = {};
@ -1231,7 +1245,6 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
? word[0].toUpperCase() + word.substring(1)
: '') // Capitalize
.join(' '); // Join words with space
return {'id': kpi, 'name': tabHeading, 'order': tabOrder.toString()};
}).toList();
@ -1244,7 +1257,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
print('Sorted Tabs: $_tabs');
print('Grouped Data: $groupedData');
// print('Grouped Data: $groupedData');
print('Tabs: $_tabs');
setState(() {
@ -1252,8 +1265,13 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
});
}
Future<void> fetchChartData(String dataSets, locale) async {
var data = await apiService.fetchChartData(dataSets, locale);
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');
if (data.containsKey('filterData')) {
var filterData = data['filterData'];
@ -1281,18 +1299,71 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
processChartData(chartsData);
onTabSelected(tabFilteredKpi);
print('chartsData :- $chartsData');
print('cardData :- $cardData');
print('chartScreenData :- $chartScreenData');
// print('filterData :- $filterData');
isLoading = false;
});
print('chartsData -$chartsData');
print('cardData -$cardData');
// print('chartsData -$chartsData');
// print('cardData -$cardData');
}
void applyFilters(BuildContext context, List filters, List data,
List dataCard, List selectedFilters) {
print('applyFilters called');
print('Selected ApplyFilters: $selectedFilters');
if (selectedFilters.every((filter) => filter['filter_data'].isEmpty)) {
setState(() {
chartsData =
List.from(originalTabChartsData); // Restore the original data
// cardData = List.from(originalTabCardData); // Restore the original data
});
print('Returning as no filters are selected');
Navigator.pop(context);
return; // Exit early since all filter_data are empty
}
// Transform the selectedFilters list into the required format
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()
};
}).toList();
print('Formatted Filters1: $formattedFilters');
// Convert to JSON format
String selectedFormatFilters = jsonEncode({
'kpi': tabWiseKpi,
'filter_data': formattedFilters
});
print('Formatted Filters2: $selectedFormatFilters');
// Call fetchChartData with correct parameters
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);
selectedFiltersStorage = List.from(selectedFilters);
print('selectedFiltersStoraged- $selectedFiltersStorage');
}
void applyFilters1(BuildContext context, List filters, List data,
List dataCard, List selectedFilters) {
print("applyFilters called");
print("Selected ApplyFilters: $selectedFilters");
print("Selected data: $data");
@ -1429,6 +1500,9 @@ 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
List<Map<String, dynamic>> selectedFilters =
selectedFiltersStorage.isNotEmpty
@ -1437,6 +1511,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
return {"filter_key": filter["filter_key"], "filter_data": []};
}).toList(); // Or initialize empty filters
print('selectedFiltersStoragedrgt- $selectedFiltersStorage');
showModalBottomSheet(
context: context,
isScrollControlled: true,
@ -1706,6 +1782,13 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
cardData = List.from(originalTabCardData);
});
selectedFiltersStorage.clear();
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(
@ -1738,6 +1821,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
onPressed: () {
print(
"Selected Filters before applying: $selectedFilters");
setState(() {
chartsData = originalTabChartsData;
cardData = originalTabCardData;
@ -1745,7 +1829,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
applyFilters(context, filters, chartsData, cardData,
selectedFilters);
selectedFiltersStorage = List.from(selectedFilters);
// selectedFiltersStorage = List.from(selectedFilters);
},
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFF92722A),
@ -1787,8 +1871,10 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
}
void onTabSelected(String tabId) {
print('Selected Tab: $tabId');
selectedFiltersStorage.clear();
print('Selected Tab on: $tabId');
tabWiseKpi = tabId;
// selectedFiltersStorage.clear();
// Filter the filterDataSet
filterData = filterDataSet
.where((item) => item['key'] == tabId)
@ -1824,7 +1910,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
}
void performActionForTab(String tabId) {
print('Selected Tab: $tabId');
print('Selected Tab perform: $tabId');
// Filter the chartsData array based on the tabId
tabFilteredChartData = chartsData.where((chart) {
@ -1920,12 +2007,18 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null
// fetchChartData(widget.dataSets, localeCode);
fetchChartData(widget.dataSets, localeCode).then((_) {
final List<Map<String, dynamic>> safeFilterData = widget.filter_data ?? [];
final String safeKpi = widget.kpi ?? '';
fetchChartData(widget.dataSets,localeCode, safeKpi, safeFilterData).then((_) {
print('DEBUG KPI: $safeKpi');
if (_tabsData.isNotEmpty) {
// Call onTabSelected for the first tab
onTabSelected(_tabsData[0]['id']);
}
});
});
double myheight = MediaQuery.of(context).size.height;
double mywidth = MediaQuery.of(context).size.width;
@ -2303,483 +2396,6 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
},
),
),
// Padding(
// padding: const EdgeInsets.all(3.34),
// child: GridView.builder(
// key: cardKey,
// itemCount: cardData.length,
// shrinkWrap: true,
// physics: const NeverScrollableScrollPhysics(),
// gridDelegate:
// SliverGridDelegateWithFixedCrossAxisCount(
// crossAxisCount: 2,
// // crossAxisCount: cardData.length % 2 == 0 ? 2 : 3,
//
// crossAxisSpacing: 2,
//
// mainAxisSpacing: 5,
//
// childAspectRatio: MediaQuery.of(context)
// .size
// .width /
// (MediaQuery.of(context).size.height /
// (cardData.length % 2 == 0 ? 2 : 2)),
// ),
//
// // Sort and filter the cardData
//
// itemBuilder: (context, index) {
// final item = cardData[index];
// print('item item item $item');
// final chart_type = item['chart_type'];
// final chart_heading = item['chart_heading'];
// final card_full_length =
// item['card_full_length'];
// print('cardfulllength $card_full_length');
// final response =
// item['response'] as List<dynamic>? ??
// [];
// final card_logo = item['card_logo'];
// final data =
// apiService.processNonChartData(item);
// print('processNonChartData');
//
// double cardHeight =
// (chart_type == 'totals' ||
// chart_type == 'averages')
// ? 180.0
// : 130.0;
// // double myheight = MediaQuery.of(context).size.height;
// // double mywidth = MediaQuery.of(context).size.width;
// // final cardWidth = rowItems.length == 1 ? myWidth : (myWidth - 16) / 2.6;
// print('find width $cardData');
// final itemdata = cardData[index];
// // bool isOddLength = cardData.length % 2 != 0;
// // bool isLastSingleCard = isOddLength &&
// // index == cardData.length - 1;
// // print('isLastSingleCard $isLastSingleCard');
//
// if (response.isEmpty) {
// return const SizedBox.shrink();
// // return Container(
// // color: Colors.redAccent,
// // );
// }
// if (response.length == 1) {
// return Container(
// margin: const EdgeInsets.all(10),
// width: card_full_length
// ? double.infinity
// : null,
// decoration: BoxDecoration(
// borderRadius:
// BorderRadius.circular(12),
// border: Border.all(
// color: Color(int.parse(
// (chartScreenData[
// 'border_color'] ??
// '#898C81')
// .replaceFirst(
// '#', '0xff'))),
// // Dynamic border color
// width:
// 1, // Adjust border thickness
// ),
// ),
// child: Card(
// margin: const EdgeInsets.all(0),
// shape: RoundedRectangleBorder(
// borderRadius:
// BorderRadius.circular(12),
// ),
// elevation: 2,
// child: Container(
// height: cardHeight,
// padding: const EdgeInsets.only(
// left: 16.0,
// right: 16.0,
// bottom: 1.0,
// top: 1.0),
// decoration: BoxDecoration(
// color: Colors
// .white, // Move color inside BoxDecoration
// borderRadius: BorderRadius.circular(
// 12), // Ensure border radius is applied
// ),
// child: Column(
// mainAxisSize: MainAxisSize.min,
// mainAxisAlignment:
// MainAxisAlignment.center,
// children: [
// Image.network(
// card_logo ?? '',
// width: 30,
// height: 30,
// errorBuilder: (context,
// error, stackTrace) {
// return Icon(Icons.public,
// color:
// Color(0xFF90B0D5),
// size:
// 30); // Fallback icon
// },
// ),
// const SizedBox(height: 1),
// MouseRegion(
// onEnter: (event) {
// // Show tooltip on hover
// final overlay = Overlay
// .of(context)
// .context
// .findRenderObject()
// as RenderBox;
// final entry =
// OverlayEntry(
// builder: (context) =>
// Positioned(
// left: overlay
// .localToGlobal(
// Offset.zero)
// .dx,
// top: overlay
// .localToGlobal(
// Offset.zero)
// .dy,
// child: Material(
// color: Colors
// .transparent,
// child: Container(
// padding:
// EdgeInsets
// .all(8),
// decoration:
// BoxDecoration(
// color: Colors
// .black87,
// borderRadius:
// BorderRadius
// .circular(
// 4),
// ),
// child: Text(
// chart_heading ??
// 'NA',
// style: TextStyle(
// color: Colors
// .white),
// ),
// ),
// ),
// ),
// );
// Overlay.of(context)
// .insert(entry);
// Future.delayed(
// Duration(seconds: 2),
// () => entry.remove());
// },
// child: Text(
// chart_heading ?? 'NA',
// textAlign:
// TextAlign.center,
// maxLines: 2,
// overflow: TextOverflow
// .ellipsis, // Truncate text with '...'
// style: TextStyle(
// fontSize: 11,
// fontWeight:
// FontWeight.w400,
// color: Colors.black87,
// ),
// ),
// ),
// const SizedBox(height: 5),
// Text(
// RegExp(r'\d').hasMatch(
// response[0][
// 'display_value'] ??
// '')
// ? '(${response[0]['display_value'] ?? 'NA'})'
// : '${response[0]['display_value'] ?? 'NA'}',
// style: const TextStyle(
// fontSize: 11,
// color: Colors.grey,
// overflow: TextOverflow
// .ellipsis, // Truncate if text overflows
// ),
// maxLines:
// 1, // Limit to one line to prevent overflow
// textAlign: TextAlign
// .center, // Ensure proper alignment
// ),
// const SizedBox(height: 1),
// Row(
// mainAxisAlignment:
// MainAxisAlignment
// .center, // Center-aligns the row contents
// children: [
// Text(
// response[0]['value'] ??
// 'NA',
// textAlign: TextAlign
// .center, // Ensures text is centered
// style: TextStyle(
// fontSize: 23,
// fontWeight:
// FontWeight.w800,
// color: (response[0][
// 'font_color'] ??
// '')
// .isEmpty
// ? bodyColor
// : _getColorFromHex(
// response[0][
// 'font_color']),
// ),
// ),
// const SizedBox(
// width:
// 4), // Space between text and icon
// if (response[0]
// ['calculation'] ==
// 'different') ...[
// if (response[0][
// 'font_color'] ==
// '#D83731')
// const Icon(
// Icons
// .arrow_downward,
// color: Colors.red,
// size: 20)
// else if (response[0][
// 'font_color'] ==
// '#11AF22')
// const Icon(
// Icons
// .arrow_upward,
// color:
// Colors.green,
// size: 20),
// ],
// ],
// )
// ],
// ),
// ),
// ));
// } else {
// return Container(
// margin: const EdgeInsets.all(10),
// width: card_full_length
// ? double.infinity
// : null,
// decoration: BoxDecoration(
// borderRadius:
// BorderRadius.circular(12),
// border: Border.all(
// color: Color(int.parse((chartScreenData[
// 'border_color'] ??
// '#898C81')
// .replaceFirst('#',
// '0xff'))), // Dynamic border color
// width: 1, // Adjust border thickness
// ),
// ),
// child: Card(
// margin: const EdgeInsets.all(0),
// shape: RoundedRectangleBorder(
// borderRadius:
// BorderRadius.circular(12),
// ),
// elevation:
// 0, // Remove shadow to keep only the outli
//
// child: Container(
// height: cardHeight,
// padding: const EdgeInsets.all(10.0),
// decoration: BoxDecoration(
// color: Colors
// .white, // Move color inside BoxDecoration
// borderRadius: BorderRadius.circular(
// 12), // Ensure border radius is applied
// ),
// child: Column(
// mainAxisSize: MainAxisSize
// .min, // Adjust card height based on content
// mainAxisAlignment:
// MainAxisAlignment.center,
// children: [
// // const Icon(Icons.public,
// // color: Color(0xFF90B0D5), size: 30),
// Image.network(
// card_logo ?? '',
// width: 30,
// height: 30,
// errorBuilder: (context, error,
// stackTrace) {
// return Icon(Icons.public,
// color:
// Color(0xFF90B0D5),
// size:
// 30); // Fallback icon
// },
// ),
// const SizedBox(height: 3),
// MouseRegion(
// onEnter: (event) {
// final overlay =
// Overlay.of(context);
// final entry = OverlayEntry(
// builder: (context) =>
// Positioned(
// left: event.position.dx,
// top: event.position.dy +
// 10, // Adjust tooltip position
// child: Material(
// color: Colors
// .transparent,
// child: Container(
// padding:
// EdgeInsets.all(
// 8),
// decoration:
// BoxDecoration(
// color: Colors
// .black87,
// borderRadius:
// BorderRadius
// .circular(
// 4),
// ),
// child: Text(
// chart_heading ??
// 'NA',
// style: TextStyle(
// color: Colors
// .white,
// fontSize: 10),
// ),
// ),
// ),
// ),
// );
// overlay.insert(entry);
// Future.delayed(
// Duration(seconds: 2),
// () => entry.remove());
// },
// child: SizedBox(
// width: double
// .infinity, // Ensures it uses available space
// child: Text(
// chart_heading ?? 'NA',
// textAlign:
// TextAlign.center,
// maxLines: 2,
// overflow: TextOverflow
// .ellipsis, // Truncate with '...'
// style: TextStyle(
// fontSize: 11,
// fontWeight:
// FontWeight.w400,
// color: Colors.black87,
// ),
// ),
// ),
// ),
// const SizedBox(height: 1),
// Text(
// // '(${response[0]['display_value'] ?? 'NA'})',
//
// RegExp(r'\d').hasMatch(response[
// 0][
// 'display_value'] ??
// '')
// ? '(${response[0]['display_value'] ?? 'NA'})'
// : '${response[0]['display_value'] ?? 'NA'}',
//
// style: const TextStyle(
// fontSize: 11,
// color: Colors.grey,
// overflow:
// TextOverflow.ellipsis,
// ),
// ),
// const SizedBox(height: 1),
// Text(
// response[0]['value'] ?? 'NA',
// overflow: TextOverflow
// .ellipsis, // Truncate text if it overflows
// maxLines:
// 1, // Ensures text stays in a single line
// style: TextStyle(
// fontSize: 23,
// fontWeight: FontWeight.w900,
// color: (response[0][
// 'font_color'] ??
// '')
// .isEmpty
// ? bodyColor
// : _getColorFromHex(
// response[0]
// ['font_color']),
// ),
// ),
// SizedBox(
// height:
// 2, // Height of the divider
// child: Divider(
// color: Color(0xFFBBBCBD),
// thickness:
// 1, // Divider line thickness
// ),
// ),
// Text(
// response[1]['value'] ?? 'NA',
// style: TextStyle(
// fontSize: 16,
// fontWeight: FontWeight.w600,
// color: (response[1][
// 'font_color'] ??
// '')
// .isEmpty
// ? const Color(
// 0xFFD83731)
// : _getColorFromHex(
// response[1]
// ['font_color']),
// ),
// textAlign: TextAlign
// .center, // Ensure proper alignment
// overflow: TextOverflow
// .ellipsis, // Truncate if text overflows
// ),
// Text(
// // '(${response[1]['display_value'] ?? 'NA'})',
// RegExp(r'\d').hasMatch(response[
// 1][
// 'display_value'] ??
// '')
// ? '(${response[1]['display_value'] ?? 'NA'})'
// : '${response[1]['display_value'] ?? 'NA'}',
// style: const TextStyle(
// fontSize: 8,
// fontWeight: FontWeight.w500,
// color: Colors.grey,
// overflow:
// TextOverflow.ellipsis,
// ),
// ),
// ],
// ),
// ),
// ),
// );
// }
// },
// ),
// ),
// chartsData Cards
ListView.builder(
itemCount: chartsData.length,
shrinkWrap: true,
@ -2818,7 +2434,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
? 500
: (chartsData[index][
'chart_type'] ==
'bar_chart_horizontal')
'bar_chart_horizontal')
? 370
: (chartsData[index]['chart_type'] == 'fl_stacked_bar')
? 390
@ -2980,7 +2596,12 @@ class CardWidget extends StatelessWidget {
),
);
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,
@ -3117,7 +2738,7 @@ class CardWidget extends StatelessWidget {
margin: const EdgeInsets.all(10),
// width: card_full_length ? double.infinity : null,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Color(int.parse(
(chartScreenData['border_color'] ?? '#898C81')
@ -3341,4 +2962,4 @@ class CardWidget extends StatelessWidget {
// ),
// );
}
}
}

View File

@ -2,6 +2,8 @@ import 'dart:convert';
import 'package:http/http.dart' as http;
import 'dart:collection';
import 'package:uae_stat/config/api_config.dart';
class ChartData {
final DateTime? xDateTime;
final String? x; // Optional for non-DateTime-based charts
@ -11,19 +13,49 @@ class ChartData {
}
class ApiService {
static const String baseUrl = 'https://pb.venbait.in/api/getDataSet';
// 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) async {
Future<Map<String, dynamic>> fetchChartData(String dataSets, locale,kpi,
List<Map<String, dynamic>> filterData) async {
List<dynamic> isChartData = [];
List<dynamic> nonChartData = [];
List<dynamic> originalChartsData = [];
List<dynamic> originalCardData = [];
final url = Uri.parse('$baseUrl?dataset=$dataSets&language=$locale');
// final url = Uri.parse('$baseUrl?dataset=$dataSets&language=$locale');
// final url = Uri.parse(
// '$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
};
// final url = Uri.https('$baseUrl?dataset=$dataSets&language=$locale');
print('APISErvice - $url');
try {
final response = await http.get(url);
print('data');
final response = await http.post(
url,
headers: {'Content-Type': 'application/json'},
body: jsonEncode(requestBody),
);
print('Response Status: ${response.statusCode}');
print('Response Body: ${response.body}');
print('data -$response');
print('API Request URL: $url');
print('Filter Data: ${jsonEncode(filterData)}');
if (response.statusCode == 200) {
final Map<String, dynamic> jsonData = jsonDecode(response.body);
// Variables to store filtered data

View File

@ -91,6 +91,18 @@ class ChartWidget extends StatelessWidget {
}).toList();
}
Color adjustColor(Color baseColor, int index) {
final HSLColor hsl = HSLColor.fromColor(baseColor);
// Lightness variation (keeping it light, between 0.6 and 0.9)
double lightnessFactor = 0.6 + (index % 4) * 0.1; // Varies between 0.6 to 0.8
final HSLColor adjustedHSL = hsl.withLightness(
lightnessFactor.clamp(0.6, 0.9), // Ensures light shades only
);
return adjustedHSL.toColor();
}
List<PieChartSectionData> parsePieChartData(
dynamic chartData,
double totalValue,
@ -111,7 +123,7 @@ class ChartWidget extends StatelessWidget {
if (rawValue is String) {
value = double.tryParse(rawValue) ?? 0.0;
} else if (rawValue is int) {
} else if (rawValue is num) {
value = rawValue.toDouble();
} else if (rawValue is double) {
value = rawValue;
@ -125,7 +137,8 @@ class ChartWidget extends StatelessWidget {
return PieChartSectionData(
value: value,
color: Colors.primaries[index % Colors.primaries.length],
// color: Colors.primaries[index % Colors.primaries.length],
color: adjustColor(bodyColor, index), // Adjust alpha dynamically
title: '${percentage.toStringAsFixed(1)}%',
radius: isTouched ? 60 : 50,
@ -157,7 +170,7 @@ class ChartWidget extends StatelessWidget {
width: 10,
height: 10,
decoration: BoxDecoration(
color: color,
color: adjustColor(bodyColor, index),
shape: BoxShape.circle,
),
),
@ -404,6 +417,7 @@ class ChartWidget extends StatelessWidget {
List<String> groupByValuesList = groupByValues.toList();
int chunkSize = 5;
List<List<String>> chunkedGroupByValues = [];
print('flStackedBar1');
for (int i = 0; i < groupByValuesList.length; i += chunkSize) {
chunkedGroupByValues.add(
groupByValuesList.sublist(
@ -452,6 +466,8 @@ class ChartWidget extends StatelessWidget {
getTooltipItem:
(groupData, groupIndex, rodData, rodIndex) {
// Get the list of group names dynamically
List<String> groupNames = [];
for (var entry in chartData['response']) {
String groupValue = entry['ObsKey'][groupByKey];
@ -459,7 +475,6 @@ class ChartWidget extends StatelessWidget {
groupNames.add(groupValue);
}
}
// Accessing the stacked rod items and calculating the tooltip text
List<BarChartRodStackItem> rodStackItems =
rodData.rodStackItems;
@ -486,6 +501,8 @@ class ChartWidget extends StatelessWidget {
Color groupColor = _getColorForGroup(
i); // Replace with your color logic
// Add a TextSpan for the colored circle and the group name with value
tooltipTextSpans.addAll([
TextSpan(
@ -682,18 +699,8 @@ class ChartWidget extends StatelessWidget {
} else if (RegExp(r'^\d{4}-[A-Za-z]{3}$').hasMatch(timePeriod)) {
// Year-MonthAbbr (2019-Nov)
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
'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8,
'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12
};
List<String> parts = timePeriod.split('-');
@ -951,9 +958,13 @@ class ChartWidget extends StatelessWidget {
(entry) => double.parse(entry['ObsKey']['TIME_PERIOD']))
.toSet();
print('uniqueXValuesLineTrend2- $uniqueXValues');
// Generate line bars for the chart
List<LineChartBarData> lineBars = lineBarsData2(filteredData);
return Column(children: [
Text(
chartData['chart_heading'] ?? '',
@ -979,8 +990,7 @@ class ChartWidget extends StatelessWidget {
scrollDirection: Axis.horizontal, // Enable horizontal scrolling
padding: const EdgeInsets.only(right: 40, top: 20),
child: SizedBox(
width: (uniqueXValues.length * 50) +
50, // Adjust width dynamically
width: (uniqueXValues.length * 50) + 50, // Adjust width dynamically
child: LineChart(
LineChartData(
lineTouchData: lineTouchData1(),
@ -1227,7 +1237,7 @@ class ChartWidget extends StatelessWidget {
}
return Container();
},
reservedSize: 80,
reservedSize: 110,
),
),
topTitles: AxisTitles(
@ -1253,13 +1263,13 @@ class ChartWidget extends StatelessWidget {
barRods: [
BarChartRodData(
toY: yAxisData[index],
color: Colors.blueAccent,
color: bodyColor,
borderRadius: BorderRadius.circular(4),
width: 20,
),
],
showingTooltipIndicators: [0],
),
),
),
),
))
@ -1268,8 +1278,36 @@ class ChartWidget extends StatelessWidget {
// Extract groupBy values and their corresponding y-axis values
List<String> xAxisData = [];
List<double> yAxisData = [];
List<Map<String, dynamic>> sortedData = [];
for (var entry in chartData['response']) {
String? timePeriod = entry['ObsKey']['TIME_PERIOD'];
if (timePeriod != null) {
// Check if it contains a month (i.e., has "-" and follows "YYYY-MM" format)
bool hasMonth = RegExp(r'^\d{4}-\d{2}$').hasMatch(timePeriod);
if (hasMonth) {
print('Yes-TIME_PERIOD: $timePeriod');
sortedData.add(entry);
} else {
print('No-TIME_PERIOD: $timePeriod');
}
}
}
// Sort the data based on year and month
sortedData.sort((a, b) {
String timeA = a['ObsKey']['TIME_PERIOD'];
String timeB = b['ObsKey']['TIME_PERIOD'];
return timeA.compareTo(timeB); // Lexicographical sorting works for YYYY-MM
});
// If no valid TIME_PERIOD with a month is found, return original response
List<Map<String, dynamic>> finalData = sortedData.isNotEmpty ? sortedData : List.from(chartData['response']);
for (var entry in finalData) {
var xValue = entry['ObsKey'][groupByKey];
var yValue = entry['ObsValue']['Value'];
if (xValue != null && yValue != null) {
@ -1277,8 +1315,11 @@ class ChartWidget extends StatelessWidget {
yAxisData.add(double.tryParse(yValue.toString()) ?? 0.0);
}
}
print("chartData['chart_heading']");
print(chartData['chart_heading']);
print('RESpns- ${chartData['chart_heading']}');
print(chartData['response']);
int rotationTurns = 1;
return Column(children: [
Text(
@ -1424,6 +1465,9 @@ class ChartWidget extends StatelessWidget {
const double barWidth = 30; // Width for each bar, including spacing
return totalBars * barWidth; // Calculate total chart width
}
print('multi_bar');
String cropKey = chartData['chart_type_json']['x_sub_group'];
// Group crops by CROP_TYPE
Map<String, List<String>> groupedCrops = {};
@ -1462,6 +1506,8 @@ class ChartWidget extends StatelessWidget {
//
// print('groupedCropsflmutli- $groupedCrops');
print('hormulti_bar');
return Center(
child: Column(children: [
Text(
@ -1503,7 +1549,7 @@ class ChartWidget extends StatelessWidget {
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 40, // Added space for rotated titles
reservedSize: 80, // Added space for rotated titles
getTitlesWidget: (value, meta) {
if (value < groupByValues.length) {
String title =
@ -1514,12 +1560,11 @@ class ChartWidget extends StatelessWidget {
: title;
return Padding(
padding: const EdgeInsets.only(top: 8.0),
padding: const EdgeInsets.only(top: 8.0,left: 30.0),
child: SizedBox(
width:
60, // Limit width to force wrapping
width: 60, // Limit width to force wrapping
child: Transform.rotate(
angle: -0.5,
angle: -1.5,
child: TooltipTheme(
data: TooltipThemeData(
decoration: BoxDecoration(
@ -1529,15 +1574,15 @@ class ChartWidget extends StatelessWidget {
8), // Optional: rounded corners
),
textStyle: TextStyle(
color: Colors
.white), // Change text color
color: Colors.white), // Change text color
),
child: Tooltip(
message: title,
child: Text(
displayTitle,
softWrap: true,
// style: TextStyle(backgroundColor: Colors.blueGrey[800]),
maxLines:2 ,
style: TextStyle(fontSize: 10),
overflow: TextOverflow.ellipsis,
)),
),
@ -1973,6 +2018,7 @@ class ChartWidget extends StatelessWidget {
for (var entry in filteredData) {
int year = int.tryParse(entry['ObsKey']['TIME_PERIOD'].toString()) ?? 0;
String gender = entry['ObsKey']['GENDER'];
double value =
double.tryParse(entry['ObsValue']['Value'].toString()) ?? 0.0;
@ -1980,9 +2026,9 @@ class ChartWidget extends StatelessWidget {
yearGenderMap[year] = {'M': 0.0, 'F': 0.0};
}
if (gender == 'Male') {
if (gender == 'Male'|| gender == 'ذكر') {
yearGenderMap[year]!['M'] = value;
} else if (gender == 'Female') {
} else if (gender == 'Female' || gender == 'أنثى') {
yearGenderMap[year]!['F'] = value;
}
}
@ -1996,6 +2042,7 @@ class ChartWidget extends StatelessWidget {
}
});
// Add a line for the ratio data
lineBars.add(
LineChartBarData(
@ -2105,7 +2152,22 @@ class ChartWidget extends StatelessWidget {
// Use the timePeriod directly as a string for x-axis
double xValue = parseTimePeriod(timePeriod);
double yValue = double.parse(entry['ObsValue']['Value']);
print('spotss');
// double yValue = double.parse(entry['ObsValue']['Value']);
double yValue;
var value = entry['ObsValue']['Value'];
if (value is int) {
yValue = value.toDouble();
} else if (value is double) {
yValue = value;
} else if (value is String) {
yValue = double.tryParse(value) ?? 0.0; // Handle invalid strings safely
} else {
throw Exception("Unexpected value type: ${value.runtimeType}");
}
return FlSpot(xValue, yValue);
}).toList();
@ -2194,7 +2256,7 @@ class ChartWidget extends StatelessWidget {
}
FlTitlesData titlesData1(Set<double> xValues) {
print('tileDATa1xvalue - $xValues');
print('tileDATa1xvalueline2 - $xValues');
double findClosest(double value, Set<double> values) {
return values
@ -2209,10 +2271,13 @@ class ChartWidget extends StatelessWidget {
getTitlesWidget: (value, meta) {
// Format values as millions (M)
String formattedValue;
print('LineTrend2val1 - $value ');
if (value % 10 == 0) {
// Check if the value is in the millions or thousands range
if (kDebugMode) {
print('LineTrend2valKmode - $value ');
}
if (value >= 1000000000000) {
formattedValue =
'${(value / 1000000000000).toStringAsFixed(0)}T';
@ -2244,7 +2309,7 @@ class ChartWidget extends StatelessWidget {
return const SizedBox.shrink();
// return Text(
// formattedValue,
// 'LINETRENTD2',
// style: TextStyle(color: Colors.black, fontSize: 12),
// );
},
@ -2256,13 +2321,13 @@ class ChartWidget extends StatelessWidget {
interval: null,
// interval: 10, // Ensure each year is shown only once
getTitlesWidget: (value, meta) {
print('BtmTiles :-$value');
print('BtmTilesmeta :-$meta');
// print('BtmTiles :-$value');
// print('BtmTilesmeta :-$meta');
// if (xValues.contains(value))
double closestValue = findClosest(value, xValues);
if ((closestValue - value).abs() < 0.15) {
print("Bottomtiles");
print(value);
// print("Bottomtiles");
// print(value);
return Padding(
padding: const EdgeInsets.only(top: 1.1),
child: Transform.rotate(
@ -2321,12 +2386,26 @@ class ChartWidget extends StatelessWidget {
List<BarChartGroupData> _generateBarGroups(
BuildContext context, dynamic chartData, String groupByKey) {
Map<String, Map<String, double>> groupedData = {};
print('flStackedBar3');
// Group data by `group_by` and `TIME_PERIOD`, accumulating the values for each group and year
for (var entry in chartData['response']) {
String groupValue = entry['ObsKey'][groupByKey];
String timePeriod = entry['ObsKey']['TIME_PERIOD'];
double value = double.tryParse(entry['ObsValue']['Value']) ?? 0.0;
// double value = double.tryParse(entry['ObsValue']['Value']) ?? 0.0;
double value;
var rawValue = entry['ObsValue']['Value'];
if (rawValue is num) {
value = rawValue.toDouble();
} else if (rawValue is double) {
value = rawValue;
} else {
value = double.tryParse(rawValue.toString()) ?? 0.0;
}
print('flStackedBar3.1');
// print('fl_groupValue $groupValue');
// print('fl_timePeriod $timePeriod');
@ -2335,6 +2414,7 @@ class ChartWidget extends StatelessWidget {
if (!groupedData.containsKey(groupValue)) {
groupedData[groupValue] = {};
}
if (!groupedData[groupValue]!.containsKey(timePeriod)) {
groupedData[groupValue]![timePeriod] = 0.0;
}
@ -2347,6 +2427,7 @@ class ChartWidget extends StatelessWidget {
List<String> timePeriods = groupedData.values.first.keys.toList();
print('timePeriods $timePeriods');
// double barWidth = calculateBarWidth(context, timePeriods.length);
// For each time period, generate a BarChartGroupData
@ -2360,7 +2441,6 @@ class ChartWidget extends StatelessWidget {
int groupIndex = 0; // Track group index for color assignment
for (var group in groupedData.keys) {
double value = groupedData[group]![timePeriods[i]] ?? 0.0;
// Add stacked item with current `toY` value and the incremented one
rodStackItems.add(
BarChartRodStackItem(
@ -2496,11 +2576,17 @@ class ChartWidget extends StatelessWidget {
double _calculateMaxY(dynamic chartData) {
// Dynamically calculate the maximum Y value
print('hormulti_bar2');
List<dynamic> response = chartData['response'] ?? [];
double maxY = 0;
for (var entry in response) {
double value = double.tryParse(entry['ObsValue']['Value'] ?? '0') ?? 0;
// double value = double.tryParse(entry['ObsValue']['Value'] ?? '0') ?? 0;
double value = (entry['ObsValue']['Value'] as num?)?.toDouble() ?? 0;
if (value > maxY) {
maxY = value;
}
@ -2514,6 +2600,9 @@ class ChartWidget extends StatelessWidget {
List<dynamic> responseData = chartData['response'];
List<BarChartGroupData> barGroups = [];
int colorIndex = 0;
print('hormulti_bar1.1');
// Iterate through groupByValues and populate BarChartGroupData
for (int i = 0; i < groupByValues.length; i++) {
String groupValue = groupByValues.elementAt(i);
@ -2528,7 +2617,7 @@ class ChartWidget extends StatelessWidget {
// Ensure to retrieve and parse 'ObsValue' value (which should be a double)
double value =
double.tryParse(data['ObsValue']['Value'].toString()) ?? 0.0;
print('multi_bar1.1');
final List<Color> uniqueColorsForTwo = [
Color(0xFF648CBA),
Color(0xFF90B0D5),
@ -2647,4 +2736,4 @@ class ChartData {
final String? x;
final double y;
final DateTime? xDateTime;
}
}

View File

@ -12,6 +12,7 @@ import 'package:image_picker/image_picker.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/config/my_theme.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/data/p_auth_repo.dart';
@ -34,7 +35,7 @@ class ProfileScreen extends ConsumerStatefulWidget {
}
class _ProfileScreenState extends ConsumerState<ProfileScreen> {
final _pb = PocketBase('https://pb.venbait.in');
final _pb = PocketBase(apiUrl);
// final _pb = PocketBase('http://127.0.0.1:8090');
// Add focus nodes and hint states

View File

@ -25,13 +25,15 @@ import 'package:http/http.dart' as http;
import '../../Screens/auth_verification/registration.dart';
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';
class LoginRoute extends HookConsumerWidget {
final pb = PocketBase('https://pb.venbait.in');
// final pb = PocketBase('https://pb.venbait.in');
final pb = PocketBase(apiUrl);
final FlutterSecureStorage _secureStorage = const FlutterSecureStorage();
// final _pb = PocketBase('http://127.0.0.1:8090');
// final bool isLoginScreen; // Pass `true` if this is the login screen
@ -342,7 +344,8 @@ class LoginRoute extends HookConsumerWidget {
final userId = session.id;
if (userId.isNotEmpty) {
final url =
Uri.parse("https://pb.venbait.in/api/login_success?id=$userId");
// Uri.parse("https://pb.venbait.in/api/login_success?id=$userId");
Uri.parse('$apiUrl/api/login_success?id=$userId');
try {
final response = await http.get(url);

View File

@ -167,6 +167,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
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/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';
@ -176,6 +177,7 @@ import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:http/http.dart' as http;
import 'package:uae_stat/config/api_config.dart';
class MyHomePage extends ConsumerStatefulWidget {
const MyHomePage({super.key});
@ -344,7 +346,8 @@ class EconomyStatsWidget extends ConsumerStatefulWidget {
class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
List<dynamic> data = [];
final _pb = PocketBase('https://pb.venbait.in');
// final _pb = PocketBase('https://pb.venbait.in');
final _pb = PocketBase(apiUrl);
bool isLoading = true;
final GlobalKey cardTopicKey = GlobalKey();
@ -1077,7 +1080,8 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
// }
Future<void> fetchData(locale) async {
const baseUrl = 'https://pb.venbait.in/api/getHomePageData';
// const baseUrl = 'https://pb.venbait.in/api/getHomePageData';
const baseUrl = '$apiUrl/api/getHomePageData';
try {
final response = await http.get(Uri.parse(baseUrl + '?language=$locale'));
if (response.statusCode == 200) {

View File

@ -6,6 +6,7 @@ import 'package:dio/dio.dart';
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/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';
@ -21,7 +22,7 @@ class BookMark extends ConsumerStatefulWidget {
}
class _BookMarkState extends ConsumerState<BookMark> {
final _pb = PocketBase('https://pb.venbait.in');
final _pb = PocketBase(apiUrl);
List<Map<String, dynamic>> dataList = [];
bool isLoading = true;
@ -77,7 +78,7 @@ class _BookMarkState extends ConsumerState<BookMark> {
}
final response = await Dio().get(
'https://pb.venbait.in/api/getUserBookmark',
'$apiUrl/api/getUserBookmark',
queryParameters: {'user_id': userID, 'language': locale},
);
@ -514,4 +515,4 @@ class TabBarHeader extends StatelessWidget {
),
);
}
}
}

View File

@ -12,6 +12,7 @@ import 'package:intl/intl.dart';
import 'package:pocketbase/pocketbase.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:uae_stat/config/api_config.dart';
import 'package:uae_stat/config/my_theme.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';
@ -25,7 +26,7 @@ class EditProfile extends StatefulWidget {
}
class _EditProfileState extends State<EditProfile> {
final _pb = PocketBase('https://pb.venbait.in');
final _pb = PocketBase(apiUrl);
// final _pb = PocketBase('http://127.0.0.1:8090');
bool _isProfileCompleted = false;
bool _isLoading = false;
@ -203,7 +204,7 @@ class _EditProfileState extends State<EditProfile> {
if (avatarFilename.isNotEmpty && recordId.isNotEmpty) {
_avatarUrl =
'https://pb.venbait.in/api/files/$collectionId/$recordId/$avatarFilename';
'$apiUrl/$collectionId/$recordId/$avatarFilename';
} else {
_avatarUrl = ''; // Reset to default or empty
}

View File

@ -7,6 +7,7 @@ import 'package:intl/intl.dart';
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/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/feedback_asset_path.dart';
@ -30,7 +31,7 @@ class FeedbackForm extends StatefulWidget {
class _FeedbackFormState extends State<FeedbackForm>
with WidgetsBindingObserver {
final _pb =
PocketBase('https://pb.venbait.in'); // Initialize PocketBase client
PocketBase(apiUrl); // Initialize PocketBase client
// final _pb =
// PocketBase('http://127.0.0.1:8090'); // Initialize PocketBase client

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.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/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart';
import 'package:uae_stat/presentation/components/my_bottom_nav_bar.dart';
@ -16,7 +17,7 @@ class ManageUserRouter extends StatefulWidget {
}
class _ManageUserRouterState extends State<ManageUserRouter> {
final _pb = PocketBase('https://pb.venbait.in');
final _pb = PocketBase(apiUrl);
List<User> userData = [];
int _sortColumnIndex = 0;
bool _isAscending = true;

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.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 '../../custom_drawer_routes.dart';
class NotificationPage extends StatefulWidget {
@ -11,7 +12,7 @@ class NotificationPage extends StatefulWidget {
class _NotificationPageState extends State<NotificationPage> {
// Example notification data
final _pb = PocketBase('https://pb.venbait.in');
final _pb = PocketBase(apiUrl);
List<Map<String, dynamic>> notifications = [];
// Current selected tab index

View File

@ -24,6 +24,7 @@ import 'package:uae_stat/presentation/components/my_toggle.dart';
import 'package:uae_stat/presentation/Screens/app_tour/Target_content.dart';
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
import 'package:uae_stat/presentation/components/my_toggle.dart';
import 'package:uae_stat/config/api_config.dart';
class BaseScaffold extends ConsumerStatefulWidget {
const BaseScaffold({
@ -58,7 +59,8 @@ class BaseScaffold extends ConsumerStatefulWidget {
}
class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
final _pb = PocketBase('https://pb.venbait.in');
// final _pb = PocketBase('https://pb.venbait.in');
final _pb = PocketBase(apiUrl);
String _avatarUrl = '';
dynamic userId;
String? userName;
@ -658,7 +660,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
if (userAvatar!.isNotEmpty && recordId.isNotEmpty) {
_avatarUrl =
'https://pb.venbait.in/api/files/$collectionId/$recordId/$userAvatar';
'$apiUrl/api/files/$collectionId/$recordId/$userAvatar';
} else {
_avatarUrl = ''; // Reset to default or empty
}
@ -704,7 +706,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
title: Padding(
padding: EdgeInsets.only(top: 10),
child: Align(
alignment: Alignment.centerLeft,
alignment: (locale?.languageCode == 'ar') ? Alignment.centerRight : Alignment.centerLeft,
child: DefaultTextStyle(
style: TextStyle(
color: widget.colorChange ? Colors.white : Color(0xFF414042),

View File

@ -6,6 +6,7 @@ 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/infrastructure/services/packages/go_router.dart';
import 'package:uae_stat/presentation/components/my_drawer.dart';
@ -28,7 +29,7 @@ class FeedbackForm extends StatefulWidget {
class _FeedbackFormState extends State<FeedbackForm>
with WidgetsBindingObserver {
final _pb =
PocketBase('https://pb.venbait.in'); // Initialize PocketBase client
PocketBase(apiUrl); // Initialize PocketBase client
// final _pb =
// PocketBase('http://127.0.0.1:8090'); // Initialize PocketBase client

View File

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