Saving local changes before pulling

This commit is contained in:
Juki-shiba 2025-03-03 14:45:00 +05:30
commit d4ad4852a8
40 changed files with 1751 additions and 810 deletions

View File

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

View File

@ -0,0 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2033_12443)">
<path d="M13.7881 8.13281C13.7686 8.62109 13.6953 9.10449 13.5684 9.58301C13.4463 10.0566 13.2583 10.4888 13.0044 10.8794C12.7554 11.2651 12.4355 11.5752 12.0449 11.8096C11.6543 12.0391 11.1831 12.1538 10.6313 12.1538C10.3091 12.1538 10.021 12.0977 9.76709 11.9854C9.51318 11.873 9.30078 11.7119 9.12988 11.502C8.95898 11.2871 8.83447 11.0308 8.75635 10.7329C8.67822 10.4302 8.65137 10.0933 8.67578 9.72217L9.04932 5.54004H10.4263L10.0601 9.72217C10.0308 10.0005 10.0356 10.2275 10.0747 10.4033C10.1138 10.5791 10.1748 10.7158 10.2578 10.8135C10.3408 10.9062 10.436 10.9722 10.5435 11.0112C10.6558 11.0503 10.7656 11.0698 10.873 11.0698C11.1221 11.0698 11.3467 10.9966 11.5469 10.8501C11.752 10.6987 11.9277 10.4912 12.0742 10.2275C12.2207 9.96387 12.3354 9.65869 12.4185 9.31201C12.5015 8.96045 12.5503 8.58203 12.5649 8.17676C12.5942 7.50781 12.5601 6.89014 12.4624 6.32373C12.3696 5.75732 12.2085 5.25195 11.979 4.80762C11.7495 4.36328 11.4517 3.9873 11.0854 3.67969C10.7192 3.36719 10.2847 3.12793 9.78174 2.96191C9.27881 2.7959 8.7002 2.71289 8.0459 2.71289C7.44531 2.71289 6.89111 2.80811 6.3833 2.99854C5.87549 3.18408 5.41895 3.4502 5.01367 3.79688C4.61328 4.14355 4.26904 4.55859 3.98096 5.04199C3.69287 5.52539 3.46582 6.06494 3.2998 6.66064C3.13867 7.25635 3.04346 7.89355 3.01416 8.57227C2.97998 9.29004 3.0166 9.94434 3.12402 10.5352C3.23633 11.1211 3.41455 11.6387 3.65869 12.0879C3.90771 12.5371 4.22021 12.9155 4.59619 13.2231C4.97217 13.5308 5.40918 13.7627 5.90723 13.9189C6.40527 14.0752 6.95703 14.1533 7.5625 14.1533C7.9873 14.1533 8.41943 14.1045 8.85889 14.0068C9.30322 13.9092 9.67676 13.7847 9.97949 13.6333L10.2578 14.666C9.91602 14.8857 9.48877 15.0493 8.97607 15.1567C8.46826 15.2642 7.9873 15.3179 7.5332 15.3179C6.7666 15.3179 6.06592 15.2227 5.43115 15.0322C4.80127 14.8418 4.24463 14.5586 3.76123 14.1826C3.27783 13.8066 2.875 13.3477 2.55273 12.8057C2.23047 12.2637 1.99365 11.6387 1.84229 10.9307C1.69092 10.2227 1.63232 9.43652 1.6665 8.57227C1.70068 7.77148 1.82275 7.01953 2.03271 6.31641C2.24268 5.6084 2.5332 4.96631 2.9043 4.39014C3.27539 3.81396 3.71729 3.31836 4.22998 2.90332C4.74756 2.4834 5.32861 2.16113 5.97314 1.93652C6.61768 1.71191 7.31836 1.59961 8.0752 1.59961C8.83691 1.59961 9.52783 1.69971 10.1479 1.8999C10.7681 2.1001 11.3125 2.38818 11.7812 2.76416C12.25 3.14014 12.6382 3.59668 12.9458 4.13379C13.2534 4.6709 13.478 5.27637 13.6196 5.9502C13.7612 6.61914 13.8174 7.34668 13.7881 8.13281ZM6.36865 8.87256C6.33936 9.19482 6.33936 9.48535 6.36865 9.74414C6.39795 9.99805 6.4541 10.2104 6.53711 10.3813C6.625 10.5522 6.73975 10.6841 6.88135 10.7769C7.02295 10.8647 7.18896 10.9087 7.37939 10.9087C7.4917 10.9087 7.61377 10.8818 7.74561 10.8281C7.87744 10.7695 8.00684 10.6768 8.13379 10.5498C8.26562 10.418 8.39014 10.2422 8.50732 10.0225C8.62939 9.79785 8.73193 9.51709 8.81494 9.18018L9.40088 9.86865C9.28857 10.2446 9.14697 10.5742 8.97607 10.8574C8.81006 11.1406 8.61963 11.3774 8.40479 11.5679C8.18994 11.7583 7.95801 11.9023 7.70898 12C7.45996 12.0928 7.19873 12.1392 6.92529 12.1392C6.56885 12.1392 6.25146 12.061 5.97314 11.9048C5.69482 11.7485 5.46533 11.5288 5.28467 11.2456C5.104 10.9575 4.97461 10.6133 4.89648 10.2129C4.81836 9.8125 4.80371 9.36572 4.85254 8.87256C4.90625 8.36963 5.00146 7.90576 5.13818 7.48096C5.27979 7.05127 5.45557 6.66797 5.66553 6.33105C5.87549 5.99414 6.1123 5.7085 6.37598 5.47412C6.64453 5.23486 6.93262 5.0542 7.24023 4.93213C7.55273 4.81006 7.87744 4.74902 8.21436 4.74902C8.771 4.74902 9.20801 4.82959 9.52539 4.99072C9.84277 5.14697 10.1431 5.33008 10.4263 5.54004L9.7085 6.48486C9.56689 6.35303 9.38135 6.22852 9.15186 6.11133C8.92725 5.98926 8.65869 5.92822 8.34619 5.92822C8.06299 5.92822 7.80908 5.9917 7.58447 6.11865C7.36475 6.24561 7.17188 6.43359 7.00586 6.68262C6.83984 6.93164 6.70312 7.23926 6.5957 7.60547C6.48828 7.9668 6.4126 8.38916 6.36865 8.87256Z" fill="#878787"/>
</g>
<defs>
<clipPath id="clip0_2033_12443">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.6667 2.00033V14.0003H8.66667V11.667H7.33333V14.0003H3.33333V2.00033H12.6667ZM10 4.66699H11.3333V3.33366H10V4.66699ZM7.33333 4.66699H8.66667V3.33366H7.33333V4.66699ZM4.66667 4.66699H6V3.33366H4.66667V4.66699ZM10 7.33366H11.3333V6.00033H10V7.33366ZM7.33333 7.33366H8.66667V6.00033H7.33333V7.33366ZM4.66667 7.33366H6V6.00033H4.66667V7.33366ZM10 10.0003H11.3333V8.66699H10V10.0003ZM7.33333 10.0003H8.66667V8.66699H7.33333V10.0003ZM4.66667 10.0003H6V8.66699H4.66667V10.0003ZM10 12.667H11.3333V11.3337H10V12.667ZM4.66667 12.667H6V11.3337H4.66667V12.667ZM14 0.666992H2V15.3337H14V0.666992Z" fill="#878787"/>
</svg>

After

Width:  |  Height:  |  Size: 717 B

View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.02552 12.9998V6.33314H5.53818V3.23047H11.5382V6.33314H13.6915V12.9998H5.02552ZM1.92285 13.6665H4.51218V5.66647H1.92285V13.6665ZM6.20485 6.33314H10.8715V3.89714H6.20485V6.33314ZM6.02485 11.3331H8.69152V7.9998H6.02485V11.3331ZM9.35818 9.33314H10.6915V7.9998H9.35818V9.33314ZM11.2302 9.33314H12.5635V7.9998H11.2302V9.33314ZM9.35818 11.3331H10.6915V9.9998H9.35818V11.3331ZM11.2302 11.3331H12.5635V9.9998H11.2302V11.3331Z" fill="#878787"/>
</svg>

After

Width:  |  Height:  |  Size: 550 B

View File

@ -0,0 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2033_12439)">
<path d="M4.57143 0C4.64881 0 4.71577 0.0282738 4.77232 0.0848214C4.82887 0.141369 4.85714 0.208333 4.85714 0.285714V13.4286C4.85714 13.5476 4.80655 13.631 4.70536 13.6786L0.419643 15.9643C0.377976 15.9881 0.333333 16 0.285714 16C0.208333 16 0.141369 15.9717 0.0848214 15.9152C0.0282738 15.8586 0 15.7917 0 15.7143V2.57143C0 2.45238 0.0505952 2.36905 0.151786 2.32143L4.4375 0.0357143C4.47917 0.0119048 4.52381 0 4.57143 0ZM15.7143 0C15.7917 0 15.8586 0.0282738 15.9152 0.0848214C15.9717 0.141369 16 0.208333 16 0.285714V13.4286C16 13.5476 15.9494 13.631 15.8482 13.6786L11.5625 15.9643C11.5208 15.9881 11.4762 16 11.4286 16C11.3512 16 11.2842 15.9717 11.2277 15.9152C11.1711 15.8586 11.1429 15.7917 11.1429 15.7143V2.57143C11.1429 2.45238 11.1935 2.36905 11.2946 2.32143L15.5804 0.0357143C15.622 0.0119048 15.6667 0 15.7143 0ZM5.71429 0C5.76191 0 5.80357 0.00892857 5.83929 0.0267857L10.4107 2.3125C10.5179 2.37202 10.5714 2.45833 10.5714 2.57143V15.7143C10.5714 15.7917 10.5432 15.8586 10.4866 15.9152C10.4301 15.9717 10.3631 16 10.2857 16C10.2381 16 10.1964 15.9911 10.1607 15.9732L5.58929 13.6875C5.48214 13.628 5.42857 13.5417 5.42857 13.4286V0.285714C5.42857 0.208333 5.45685 0.141369 5.51339 0.0848214C5.56994 0.0282738 5.63691 0 5.71429 0Z" fill="#878787"/>
</g>
<defs>
<clipPath id="clip0_2033_12439">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 3C1 2.46957 1.21071 1.96086 1.58579 1.58579C1.96086 1.21071 2.46957 1 3 1H3.91467C4.488 1 4.988 1.39067 5.12733 1.94667L5.864 4.89533C5.92325 5.13401 5.91098 5.38484 5.82871 5.61659C5.74644 5.84834 5.59781 6.05077 5.40133 6.19867L4.53933 6.84533C4.44933 6.91267 4.43 7.01133 4.45533 7.08C4.83178 8.10312 5.426 9.03226 6.19687 9.80313C6.96774 10.574 7.89688 11.1682 8.92 11.5447C8.98867 11.57 9.08667 11.5507 9.15467 11.4607L9.80133 10.5987C9.94923 10.4022 10.1517 10.2536 10.3834 10.1713C10.6152 10.089 10.866 10.0767 11.1047 10.136L14.0533 10.8727C14.6093 11.012 15 11.512 15 12.086V13C15 13.5304 14.7893 14.0391 14.4142 14.4142C14.0391 14.7893 13.5304 15 13 15H11.5C5.70133 15 1 10.2987 1 4.5V3Z" fill="#878787"/>
</svg>

After

Width:  |  Height:  |  Size: 871 B

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M23.1191 21.8809L17.6427 16.4056C19.2299 14.5 20.0214 12.0558 19.8525 9.58143C19.6836 7.10709 18.5672 4.79313 16.7357 3.12091C14.9041 1.4487 12.4984 0.546971 10.0189 0.603321C7.53944 0.65967 5.17715 1.66976 3.42345 3.42345C1.66976 5.17715 0.65967 7.53944 0.603321 10.0189C0.546971 12.4984 1.4487 14.9041 3.12091 16.7357C4.79313 18.5672 7.10709 19.6836 9.58143 19.8525C12.0558 20.0214 14.5 19.2299 16.4056 17.6427L21.8809 23.1191C21.9622 23.2004 22.0588 23.2649 22.165 23.3088C22.2712 23.3528 22.385 23.3755 22.5 23.3755C22.615 23.3755 22.7288 23.3528 22.835 23.3088C22.9413 23.2649 23.0378 23.2004 23.1191 23.1191C23.2004 23.0378 23.2649 22.9413 23.3088 22.835C23.3528 22.7288 23.3755 22.615 23.3755 22.5C23.3755 22.385 23.3528 22.2712 23.3088 22.165C23.2649 22.0588 23.2004 21.9622 23.1191 21.8809ZM2.37501 10.25C2.37501 8.69248 2.83687 7.16993 3.70218 5.87489C4.5675 4.57985 5.79741 3.57049 7.23637 2.97445C8.67534 2.37841 10.2587 2.22246 11.7863 2.52632C13.3139 2.83018 14.7171 3.5802 15.8185 4.68154C16.9198 5.78288 17.6698 7.18607 17.9737 8.71367C18.2775 10.2413 18.1216 11.8247 17.5256 13.2636C16.9295 14.7026 15.9202 15.9325 14.6251 16.7978C13.3301 17.6631 11.8075 18.125 10.25 18.125C8.16214 18.1227 6.16044 17.2923 4.6841 15.8159C3.20775 14.3396 2.37732 12.3379 2.37501 10.25Z" fill="#9EA2A9"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.125 3L10.325 11.6637V18.1683L13.925 20V11.6637L21.125 3H3.125Z" stroke="white" stroke-width="2" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 237 B

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';
@ -304,6 +306,7 @@ import 'package:uae_stat/presentation/Screens/charts/chart.dart';
import 'package:uae_stat/presentation/Screens/charts/screens/chart_screen.dart';
import 'package:uae_stat/presentation/Screens/demo_home2.dart';
import 'package:uae_stat/presentation/Screens/online_offline_verification/internet_check.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/contactUs.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/notification/notification.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/user_guide/AboutTheApp/AboutFCSC.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/Drawer%20Items/user_guide/AboutTheApp/getStarted.dart';
@ -414,11 +417,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 +452,8 @@ final GoRouter router = GoRouter(
mainTopic: mainTopic,
title: title,
keyParam: key,
kpi: kpi,
filter_data: filterData,
);
},
),
@ -605,5 +632,10 @@ final GoRouter router = GoRouter(
path: '/marriages',
builder: (context, state) => Marriages(),
),
GoRoute(
path: '/contact',
builder: (context, state) => Contact(),
),
],
);

View File

@ -0,0 +1,8 @@
abstract class EnquiryAssetIconPath {
static const _basePath = 'assets/icons/enquiry';
static const at = '$_basePath/at.svg';
static const building = '$_basePath/building.svg';
static const fax = '$_basePath/fax.svg';
static const map = '$_basePath/map.svg';
static const phone = '$_basePath/phone.svg';
}

View File

@ -12,5 +12,5 @@ abstract class MiscIconAssetPath {
static const save = '$_basePath/save.png';
static const group = '$_basePath/group.png';
static const search = '$_basePath/search.png';
static const Search = '$_basePath/Search.svg';
}

View File

@ -6,5 +6,6 @@ abstract class UaeNumbersAssetPath {
// static const bookmarksSelectedUae = '$_basePath/bookmarksSelectedUae.png';
// static const shareUae = '$_basePath/share.png';
static const share = '$_basePath/share.svg';
static const filterUae = '$_basePath/filters.png';
static const filterUae = '$_basePath/filters.png';
static const filterCharts = '$_basePath/Filter.svg';
}

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

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

View File

@ -1,7 +1,11 @@
{
"all_bookmarks":"All Bookmarks",
"economy_title":"Economy",
"social_title":"Social",
"environment_title":"Environment",
"bookmarks": "Bookmarks",
"feedback_title": "Feedback",
"feedback_title": "Feedback",
"feedback_failed_msg": "Your feedback could not be \n submitted. Please try again",
"thankYou": "Thank you",
"feedback_message": "For your valuable feedback, we truly appreciate your input!",

View File

@ -15,6 +15,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();
@ -88,6 +90,8 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
// }
// }
void main() async {
WidgetsFlutterBinding.ensureInitialized();
configureDependencies();
@ -100,10 +104,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

@ -2,6 +2,7 @@ import 'dart:convert';
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/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart';
@ -10,6 +11,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 +86,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) {
@ -197,11 +200,13 @@ class _UaenumberWidgetState extends ConsumerState<uaenumberWidget> {
decoration: InputDecoration(
hintText: "Search",
hintStyle: TextStyle(color: Color(0xFF898C81)),
prefixIcon: Image(
image: ExactAssetImage(MiscIconAssetPath.search),
width: 24,
height: 24,
prefixIconConstraints: BoxConstraints(maxWidth: 42, maxHeight: 42),
prefixIcon: Container(
padding: EdgeInsets.only(right: 5),
child: SvgPicture.asset(
MiscIconAssetPath.Search,
semanticsLabel: 'Search',
),
),
// prefixIcon: Image.asset(

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,8 +3,10 @@ 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/banner_asset_path.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/misc_icon_asset_path.dart';
import 'package:uae_stat/presentation/Screens/profilepage.dart';
import 'package:uae_stat/presentation/components/indicators/locale_provider.dart';
@ -12,7 +14,7 @@ import 'package:uae_stat/presentation/components/my_toggle.dart';
import 'package:uae_stat/presentation/components/space.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import '../../../config/my_theme.dart';
import 'package:uae_stat/config/my_theme.dart';
class CreateNewPw extends ConsumerStatefulWidget {
final String userId;
@ -26,17 +28,22 @@ 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;
bool _obscureConfirmPassword = true;
bool _isPasswordUpdated = false; // Variable to toggle UI
bool hasValidated = false;
String? _oldPassword;
String? _newPassword;
String? _confirmPassword;
final fcscBanner = Image.asset(
BannerAssetPath.fcsc,
height: 40,
);
String? _validateOldPassword(String? value) {
if (value == null || value.isEmpty) {
return AppLocalizations.of(context)!.old_password_is_required;
@ -242,10 +249,12 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
pathColorWhenOn: Colors.grey.shade300,
pathColorWhenOff: Colors.grey.shade300,
onTap: () {
print('has validated $hasValidated');
final formState = _formKey.currentState;
ref.read(localeProvider.notifier).toggleLocale();
Future.delayed(Duration(milliseconds: 100), () {
if (formState?.validate() == false) {
if (hasValidated && formState?.validate() == false) {
print('has validated $hasValidated');
formState?.validate();
}
});
@ -581,6 +590,9 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
width: screenWidth / 1.1,
child: ElevatedButton(
onPressed: () async {
setState(() {
hasValidated=true;
});
if ((_formKey.currentState?.validate() ?? false)) {
await updatePassword(
widget.userId,
@ -618,16 +630,17 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
),
SizedBox(height: screenHeight / 5),
Center(
child: Container(
height: screenHeight / 16,
width: screenWidth / 2.5,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/splash_screen/logo.png"),
fit: BoxFit.fill,
),
),
),
// child: Container(
// height: screenHeight / 16,
// width: screenWidth / 2.5,
// decoration: BoxDecoration(
// image: DecorationImage(
// image: AssetImage("assets/splash_screen/logo.png"),
// fit: BoxFit.fill,
// ),
// ),
// ),
child: fcscBanner,
),
],
),
@ -712,16 +725,17 @@ class _CreateNewPwState extends ConsumerState<CreateNewPw> {
),
SizedBox(height: screenHeight / 2.2),
Center(
child: Container(
height: 40,
width: screenWidth / 2.5,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/splash_screen/logo.png"),
fit: BoxFit.fill,
),
),
),
// child: Container(
// height: 40,
// width: screenWidth / 2.5,
// decoration: BoxDecoration(
// image: DecorationImage(
// image: AssetImage("assets/splash_screen/logo.png"),
// fit: BoxFit.fill,
// ),
// ),
// ),
child: fcscBanner,
),
],
),

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';
@ -27,7 +28,7 @@ class _RegisterScreenState extends ConsumerState<RegisterScreen> {
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
final _confirmpasswordController = TextEditingController();
bool hasValidated = false;
bool _obscurePassword = true;
bool _obscureConfirmPassword = true;
bool isChecked = false;
@ -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
@ -216,6 +217,9 @@ class _RegisterScreenState extends ConsumerState<RegisterScreen> {
}
Future<void> _registerUser() async {
setState(() {
hasValidated = true;
});
if (_formKey.currentState?.validate() ?? false) {
if (isChecked) {
setState(() {
@ -386,7 +390,7 @@ class _RegisterScreenState extends ConsumerState<RegisterScreen> {
final formState = _formKey.currentState;
ref.read(localeProvider.notifier).toggleLocale();
Future.delayed(Duration(milliseconds: 100), () {
if (formState?.validate() == false) {
if (hasValidated && formState?.validate() == false) {
formState?.validate();
}
});
@ -1110,11 +1114,11 @@ class _RegisterScreenState extends ConsumerState<RegisterScreen> {
?.languageCode ==
'ar'
? 0
: 30.0,
: 40.0,
right: registerLocale
?.languageCode ==
'ar'
? 40
? 45
: 0.0,),
child: Text(
context.translate('Required', 'مطلوب'),

File diff suppressed because it is too large Load Diff

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

@ -34,7 +34,7 @@ class ChartWidget extends StatelessWidget {
}
String formatNumberConversion(
double value, String chartConversion, String numberFormat) {
double value, String chartConversion, String numberFormat,) {
// Convert the input value to base unit (actual value)
double baseValue = value;
@ -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,
),
),
@ -175,16 +188,15 @@ class ChartWidget extends StatelessWidget {
message: title, // Full text on hover
child: ConstrainedBox(
// Constrain width to allow wrapping
constraints: BoxConstraints(maxWidth: 130),
constraints: BoxConstraints(maxWidth: 200),
child: Text(
title,
style: TextStyle(
fontSize: 12,
),
softWrap: true,
maxLines: 2,
overflow:
TextOverflow.ellipsis, // Ensures text doesn't overflow
// softWrap: true,
// maxLines: 2,
overflow: TextOverflow.ellipsis, // Ensures text doesn't overflow
),
),
),
@ -365,31 +377,39 @@ class ChartWidget extends StatelessWidget {
},
),
),
SizedBox(height: 105),
SizedBox(height: 45),
Expanded(
// child: SingleChildScrollView(
// scrollDirection: Axis.horizontal,
//
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
width: double.infinity,
constraints:
BoxConstraints(minHeight: 3), // Allow dynamic height
child: Padding(
padding: const EdgeInsets.only(
left: 0.0, right: 0.0, bottom: 8.0, top: 1.0),
child: Wrap(
spacing: 2,
runSpacing: 5,
children:
generateIndicators(chartData, chartData['group_by']),
// child: SingleChildScrollView(
// scrollDirection: Axis.vertical,
child: Center(
child: Container(
width: double.infinity,
constraints:
BoxConstraints(minHeight: 3), // Allow dynamic height
child: Padding(
padding: const EdgeInsets.only(
left: 2.0, right: 2.0, bottom: 8.0, top: 1.0),
child: Column( // Change Row to Column
crossAxisAlignment: CrossAxisAlignment.start,
children: generateIndicators(chartData, chartData['group_by']),
),
// child: Wrap(
// spacing: 2,
// runSpacing: 5,
// children:
// generateIndicators(chartData, chartData['group_by']),
// ),
),
),
),
),
),
// ),
],
);
case 'fl_stacked_bar':
@ -397,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(
@ -445,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];
@ -452,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;
@ -479,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(
@ -568,10 +592,11 @@ class ChartWidget extends StatelessWidget {
),
textStyle: TextStyle(color: Colors.white),
child: Text(
group.length > 10
? '${group.substring(0, 10)}...'
: group,
overflow: TextOverflow.ellipsis,
group,
// group.length > 10
// ? '${group.substring(0, 10)}...'
// : group,
// overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 11),
),
)
@ -674,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('-');
@ -943,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'] ?? '',
@ -971,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(),
@ -1219,7 +1237,7 @@ class ChartWidget extends StatelessWidget {
}
return Container();
},
reservedSize: 80,
reservedSize: 110,
),
),
topTitles: AxisTitles(
@ -1245,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],
),
),
),
),
))
@ -1260,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) {
@ -1269,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(
@ -1416,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 = {};
@ -1454,6 +1506,8 @@ class ChartWidget extends StatelessWidget {
//
// print('groupedCropsflmutli- $groupedCrops');
print('hormulti_bar');
return Center(
child: Column(children: [
Text(
@ -1495,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 =
@ -1506,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(
@ -1521,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,
)),
),
@ -1965,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;
@ -1972,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;
}
}
@ -1988,6 +2042,7 @@ class ChartWidget extends StatelessWidget {
}
});
// Add a line for the ratio data
lineBars.add(
LineChartBarData(
@ -2097,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();
@ -2186,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
@ -2201,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';
@ -2227,12 +2300,16 @@ class ChartWidget extends StatelessWidget {
_lastFormattedValue = formattedValue;
// print('formattedValueLine - $formattedValue');
return Text(formattedValue, style: TextStyle(fontSize: 10));
return Text(formattedValue, textAlign: TextAlign.center,
style: TextStyle(
fontSize: 10,
));
}
return const SizedBox.shrink();
// return Text(
// formattedValue,
// 'LINETRENTD2',
// style: TextStyle(color: Colors.black, fontSize: 12),
// );
},
@ -2244,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(
@ -2309,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');
@ -2323,6 +2414,7 @@ class ChartWidget extends StatelessWidget {
if (!groupedData.containsKey(groupValue)) {
groupedData[groupValue] = {};
}
if (!groupedData[groupValue]!.containsKey(timePeriod)) {
groupedData[groupValue]![timePeriod] = 0.0;
}
@ -2335,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
@ -2348,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(
@ -2374,8 +2466,7 @@ class ChartWidget extends StatelessWidget {
width: 20,
// width: barWidth,
borderRadius: BorderRadius.zero,
color:
Colors.black // This will act as a container for stacked items
color: Colors.black // This will act as a container for stacked items
),
],
);
@ -2485,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;
}
@ -2503,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);
@ -2517,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),

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,9 +35,9 @@ 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');
bool hasValidated = false;
// Add focus nodes and hint states
final List<FocusNode> _focusNodes = List.generate(4, (_) => FocusNode());
final List<bool> _showHints = [
@ -456,6 +457,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
@override
Widget build(BuildContext context) {
final profileLocale = ref.watch(localeProvider);
return PopScope(
canPop: false, // Allow back navigation only if not login screen
onPopInvokedWithResult: (didPop, result) {
@ -488,7 +490,13 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
pathColorWhenOn: Colors.grey.shade300,
pathColorWhenOff: Colors.grey.shade300,
onTap: () {
final formState = _formKey.currentState;
ref.read(localeProvider.notifier).toggleLocale();
Future.delayed(Duration(milliseconds: 100), () {
if (hasValidated && formState?.validate() == false) {
formState?.validate();
}
});
},
);
},
@ -784,7 +792,7 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
),
borderRadius: BorderRadius.circular(8),
),
labelText: 'Select',
labelText: context.translate('Select',' اختيار')
),
icon: Icon(Icons.keyboard_arrow_down_sharp,
color:
@ -910,7 +918,11 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(left: 10.0),
padding: EdgeInsets.only(left: 10.0, right: profileLocale
?.languageCode ==
'ar'
? 15
: 0.0,),
child: Text(
context.translate('Required', 'مطلوب'),
style: TextStyle(
@ -947,6 +959,9 @@ class _ProfileScreenState extends ConsumerState<ProfileScreen> {
// ElevatedButton.icon(
ElevatedButton(
onPressed: () {
setState(() {
hasValidated = true;
});
if ((_formKey.currentState?.validate() ?? false) &&
(isChecked)) {
_formKey.currentState?.save();
@ -1003,7 +1018,7 @@ class ConfirmationDialog extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: [
Text(
"Are you sure you want to save this page?",
AppLocalizations.of(context)!.sure_save_page,
style: const TextStyle(
fontSize: 14,
color: Color(0xFF898C81),
@ -1015,7 +1030,7 @@ class ConfirmationDialog extends StatelessWidget {
SizedBox(height: 8),
Text.rich(
TextSpan(
text: "Once saved, you will not be able to change your ",
text: AppLocalizations.of(context)!.not_able_to_change,
style: TextStyle(
fontSize: 14,
color: Color(0xFF898C81),
@ -1024,15 +1039,15 @@ class ConfirmationDialog extends StatelessWidget {
),
children: [
TextSpan(
text: "Name",
text: AppLocalizations.of(context)!.name,
style:
TextStyle(fontWeight: FontWeight.w700), // Bold for "name"
),
TextSpan(
text: " or ",
text: context.translate(' or ','أو'),
),
TextSpan(
text: "Date of birth",
text: AppLocalizations.of(context)!.dob,
style: TextStyle(
fontWeight: FontWeight.w700), // Bold for "date of birth"
),

View File

@ -45,7 +45,7 @@ class ThemedFormField extends HookWidget {
final inputDecoration = InputDecoration(
filled: true,
fillColor: Colors.white,
contentPadding: const EdgeInsets.symmetric(vertical: 14),
contentPadding: const EdgeInsets.symmetric(vertical: 14, horizontal: 15),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(

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
@ -125,6 +127,7 @@ class LoginRoute extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final hasValidated = useState(false);
final locale = ref.watch(localeProvider);
final emailCtl = useTextEditingController();
final pwCtl = useTextEditingController();
@ -270,6 +273,7 @@ class LoginRoute extends HookConsumerWidget {
width: double.infinity,
child: ElevatedButton(
onPressed: () async {
hasValidated.value=true;
final isValid = formKey.currentState!.validate();
if (!isValid) return;
final session = await context.loaderWithErrorDialog(
@ -342,7 +346,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);
@ -677,7 +682,7 @@ class LoginRoute extends HookConsumerWidget {
final formState = formKey.currentState;
ref.read(localeProvider.notifier).toggleLocale();
Future.delayed(Duration(milliseconds: 100), () {
if (formState?.validate() == false) {
if (hasValidated.value && formState?.validate() == false) {
formState?.validate();
}
});

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

@ -3,14 +3,17 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart';
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';
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});
@ -19,26 +22,20 @@ 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;
Map<String, Map<String, dynamic>> groupedMap = {};
int? expandedIndex = 0;
// Current selected tab index
int selectedTabIndex = 0;
// Tab categories
final List<String> tabs = [
'All Bookmarks',
'Economy',
'Social',
'Environment',
];
@override
void initState() {
super.initState();
final locale = ref.read(localeProvider);
fetchBookmarks(locale?.languageCode ?? 'en');
}
String colorToHex(Color color) {
@ -73,7 +70,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},
);
@ -101,8 +98,36 @@ class _BookMarkState extends ConsumerState<BookMark> {
'id': item['id'],
};
}).toList();
print('dataList $dataList');
// print('dataList $dataList');
});
groupedMap = {};
for (var item in dataList) {
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,
'valueColor': item['valueColor'],
'SubTopic': []
};
}
// Add subtitle as a key with its corresponding map value
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'],
'id': item['id'],
});
}
}
}
} catch (e) {
@ -126,18 +151,6 @@ class _BookMarkState extends ConsumerState<BookMark> {
await _pb.collection('bookmark').delete(bookmarkId!, headers: {
'Authorization': adminToken,
});
// Show success SnackBar
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text(
// 'Removed from Bookmark.',
// style: TextStyle(
// color: Color(0xFF2F692C), fontWeight: FontWeight.w600),
// ),
// backgroundColor: Color(0xFFD6E9C6),
// duration: Duration(seconds: 2),
// ),
// );
final locale = ref.read(localeProvider);
fetchBookmarks(locale?.languageCode ?? 'en');
// ToastUtil.showSuccessToast("Removed from Bookmark.");
@ -145,11 +158,8 @@ class _BookMarkState extends ConsumerState<BookMark> {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Removed From Bookmark',
style: TextStyle(color: Color(0xFF2F692C),
fontWeight: FontWeight.w500),
AppLocalizations.of(context)!.removed_from_Bookmark,
),
backgroundColor: Color(0xFFD6E9C6),
duration: Duration(seconds: 2),
),
);
@ -263,15 +273,35 @@ class _BookMarkState extends ConsumerState<BookMark> {
@override
Widget build(BuildContext context) {
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)},
];
ref.listen<Locale?>(localeProvider, (previous, next) {
final localeCode = next?.languageCode ?? 'en'; // Default to 'en' if null
fetchBookmarks(localeCode);
});
List<Map<String, dynamic>> bookmarks = dataList.where((item) => item['isBookmark'] == true).toList();
List<Map<String, dynamic>> filteredBookmarks = dataList
.where((bookmark) =>
bookmark['main_topic'].toString().trim().toLowerCase() == tabs[selectedTabIndex].toString().trim().toLowerCase())
.toList();
.where((bookmark) {
String mainTopic = bookmark['main_topic'].toString().trim().toLowerCase();
String selectedTabTitle = tabs[selectedTabIndex]['title'].toString().trim().toLowerCase();
print('filtered $filteredBookmarks');
// Debugging prints
print("main_topic: '$mainTopic', selected_tab_title: '$selectedTabTitle'");
return mainTopic == selectedTabTitle;
})
.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('Bookmarks'),
title: Text(AppLocalizations.of(context)!.bookmarks,),
body: Column(
children: [
TabBarHeader(
@ -285,23 +315,68 @@ class _BookMarkState extends ConsumerState<BookMark> {
),
Expanded(
child: selectedTabIndex == 0
? Padding(
padding: const EdgeInsets.all(8.0),
child: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
mainAxisExtent: 100,
),
itemCount: bookmarks.length,
itemBuilder: (context, index) {
return _buildBox(bookmarks[index], context);
},
? (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,
),
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
);
}),
),
):filteredBookmarks.isEmpty
)
: 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,
@ -319,20 +394,47 @@ class _BookMarkState extends ConsumerState<BookMark> {
)
: Padding(
padding: const EdgeInsets.all(8.0),
child: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
mainAxisExtent: 100,
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,
),
),
itemCount: filteredBookmarks.length,
itemBuilder: (context, index) {
return _buildBox(filteredBookmarks[index], context);
},
],
),
),
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);
},
),
),
],
),
),
),
],
@ -355,7 +457,7 @@ class _BookMarkState extends ConsumerState<BookMark> {
print(hexColor); // Prints: 0xFFAA8E83
debugPrint("Box clicked: ${data['title']}");
context.go(
context.push(
'/chartScreen/$data_set?bgColor=$hexColor&mainTopic=$encodedMainTopic&title=$encodedTitle');
},
child: Container(
@ -440,10 +542,99 @@ class _BookMarkState extends ConsumerState<BookMark> {
),
);
}
Widget _buildBoxes(Map<String, dynamic> data, BuildContext context, Color styleColor) {
// Color borderColor = data['valueColor'];
print('inside function $data');
return GestureDetector(
onTap: () {
final data_set = data['data_set'];
// final Color colorPattern = data['valueColor'];
final encodedMainTopic = data['main_topic'];
final encodedTitle = data['title'];
String hexColor = colorToHex(styleColor);
debugPrint( '/chartScreen/$data_set?bgColor=$hexColor&mainTopic=$encodedMainTopic&title=$encodedTitle');
// String hexColor = colorToHex(colorPattern); // Get hex string
// print(hexColor); // Prints: 0xFFAA8E83
// debugPrint("Box clicked: ${data['title']}");
context.push(
'/chartScreen/$data_set?bgColor=$hexColor&mainTopic=$encodedMainTopic&title=$encodedTitle');
},
child: Container(
width: MediaQuery.of(context).size.width * 0.4,
height: 100,
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
border: Border.all(color: styleColor),
),
child:
Align(
alignment: Alignment.center,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Align(
alignment: Alignment.center,
child: Text(
data['title'] ?? '',
style: const TextStyle(fontWeight: FontWeight.w500),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
),
GestureDetector(
onTap: () {
debugPrint("Icon clicked in: ${data['title']}");
showRemoveBookmarkDialog(data['id']);
},
child: SvgPicture.asset(
BookmarkAssetPath.delete,
semanticsLabel: 'share',
width:23,
height: 20,
)
),
],
),
Text(
data['value_source'] ?? '',
style: const TextStyle(
fontWeight: FontWeight.w500, color: Colors.grey),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
Text(
data['value'] ?? '',
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
color: styleColor,
),
),
],
),
),
),
);
}
}
class TabBarHeader extends StatelessWidget {
final List<String> tabs;
final List<Map<String, dynamic>> tabs;
final int selectedIndex;
final ValueChanged<int> onTabSelected;
@ -464,7 +655,7 @@ class TabBarHeader extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
children: tabs.asMap().entries.map((entry) {
int index = entry.key;
String text = entry.value;
String text = entry.value['title'];
return Row(
children: [
TextButton(
@ -473,7 +664,7 @@ class TabBarHeader extends StatelessWidget {
foregroundColor:
MaterialStateProperty.resolveWith((states) {
return selectedIndex == index
? Colors.black
? entry.value['color']
: Colors.grey[700];
}),
),
@ -489,7 +680,7 @@ class TabBarHeader extends StatelessWidget {
}
Widget buildDivider() {
return Container(
return SizedBox(
height: 20,
child: const VerticalDivider(
color: Colors.grey,
@ -499,3 +690,123 @@ class TabBarHeader extends StatelessWidget {
);
}
}
class CustomExpandableTile extends StatefulWidget {
final String title;
final Color titleBackgroundColor;
final List filteredBookmarks;
final int index;
final bool isExpanded;
final ValueChanged<int> onTap;
final Widget childWidget;
const CustomExpandableTile({
required this.title,
required this.titleBackgroundColor,
required this.filteredBookmarks,
required this.index,
required this.isExpanded,
required this.onTap,
required this.childWidget,
});
@override
_CustomExpandableTileState createState() => _CustomExpandableTileState();
}
class _CustomExpandableTileState extends State<CustomExpandableTile> {
@override
void initState() {
super.initState(); // Initialize isExpanded based on widget's property
}
@override
Widget build(BuildContext context) {
double myheight = MediaQuery.of(context).size.height;
// print(widget.filteredBookmarks);
return Card(
elevation: 0,
child: Column(
children: [
GestureDetector(
onTap: () => widget.onTap(widget.index),
child: Container(
decoration: BoxDecoration(
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))
),
padding: const EdgeInsets.only(
left: 16, bottom: 5, top: 5, right: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
widget.title,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 20,
),
),
Icon(
widget.isExpanded
? Icons.keyboard_arrow_up
: Icons.keyboard_arrow_down,
color: Colors.white,
size: 28.0,
),
],
),
),
),
),
ClipRRect(
child: AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
width: double.infinity,
color: Colors.white,
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);
// },
// ),
// ),
],
),
)
: null,
),
),
],
),
);
}
}

View File

@ -0,0 +1,145 @@
import 'package:flutter/material.dart';
import 'package:uae_stat/domain/use_cases/language.dart';
import 'package:uae_stat/infrastructure/services/img_asset_paths/icons/enquiry_asset_icon_path.dart';
import 'package:uae_stat/presentation/routes/drawer_routes/custom_drawer_routes.dart';
import 'package:flutter_svg/flutter_svg.dart';
class Contact extends StatefulWidget {
const Contact({super.key});
@override
State<Contact> createState() => _ContactState();
}
class _ContactState extends State<Contact> {
@override
Widget build(BuildContext context) {
final double screenWidth= MediaQuery.of(context).size.width;
final double screenHeight= MediaQuery.of(context).size.height;
return BaseScaffold(
body: Container(
color: Colors.grey[200],
width: screenWidth,
padding: EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
children: [
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4.0), // Slight curve
),
padding: EdgeInsets.all(7.0),
height: screenHeight*0.35,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(context.translate('DUBAI - EMIRATES TOWER -32ND FLOOR','دبي - أبراج الإمارات - الطابق 32'),
style: TextStyle(
color: Color(0xFF265E84),
fontSize: 20,
fontFamily: 'Roboto',
fontWeight: FontWeight.w500,
),
),
buildTextRow(EnquiryAssetIconPath.building,context.translate('Office : Dubai - Emirates Tower -32nd Floor','المقر الرئيسي : دبي - أبراج الإمارات - الطابق 32')),
buildTextRow(EnquiryAssetIconPath.phone,context.translate('Tel : 00971 46080000','الهاتف : 0097146080000'),),
buildTextRow(EnquiryAssetIconPath.fax, context.translate('Fax : 0097143273535','فاكس : 0097143273535')),
buildTextRow(EnquiryAssetIconPath.map, context.translate('P.O.Box : 127000 Dubai','ص.ب: : 127000 دبي')),
buildTextRow(EnquiryAssetIconPath.at, context.translate('Email Address : info@fcsc.gov.ae','البريد الإلكتروني : info@fcsc.gov.ae')),
buildTextRow(EnquiryAssetIconPath.map,context.translate( 'Latitude : 25.223926','خط العرض : 25.223926')),
buildTextRow(EnquiryAssetIconPath.map, context.translate('Longitude : 55.350526','خط الطول : 55.350526')),
],
),
),
SizedBox(height: 10,),
Container(
padding: EdgeInsets.all(7.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4.0), // Slight curve
),
height: screenHeight*0.34,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(context.translate('MEDIA SECTION','قسم الاعلام'),
style: TextStyle(
color: Color(0xFF265E84),
fontSize: 20,
fontFamily: 'Roboto',
fontWeight: FontWeight.w500,
),
),
buildTextRow(EnquiryAssetIconPath.building,context.translate('Office : Media Section','المقر الرئيسي : قسم الاعلام')),
buildTextRow(EnquiryAssetIconPath.phone,context.translate('Tel : 00971 46080000','الهاتف : 0097146080000'),),
buildTextRow(EnquiryAssetIconPath.fax, context.translate('Fax : 0097143273535','فاكس : 0097143273535')),
buildTextRow(EnquiryAssetIconPath.map, context.translate('P.O.Box : 127000 Dubai','ص.ب: : 127000 دبي')),
buildTextRow(EnquiryAssetIconPath.at, context.translate('Email Address : GCO@fcsc.gov.ae','البريد الإلكتروني : GCO@fcsc.gov.ae')),
buildTextRow(EnquiryAssetIconPath.map,context.translate( 'Latitude : 25.223926','خط العرض : 25.223926')),
buildTextRow(EnquiryAssetIconPath.map, context.translate('Longitude : 55.350526','خط الطول : 55.350526')),
],
),
),
SizedBox(height: 10,),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4.0), // Slight curve
),
padding: EdgeInsets.all(7.0),
height: screenHeight*0.34,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(context.translate('SGDS','أهداف التنمية المستدامة'),
style: TextStyle(
color: Color(0xFF265E84),
fontSize: 20,
fontFamily: 'Roboto',
fontWeight: FontWeight.w500,
),
),
buildTextRow(EnquiryAssetIconPath.building,context.translate('Office : SDGs','المقر الرئيسي : أهداف التنمية المستدامة')),
buildTextRow(EnquiryAssetIconPath.phone,context.translate('Tel : 00971 46080000','الهاتف : 0097146080000'),),
buildTextRow(EnquiryAssetIconPath.fax, context.translate('Fax : 0097143273535','فاكس : 0097143273535')),
buildTextRow(EnquiryAssetIconPath.map, context.translate('P.O.Box : 127000 Dubai','ص.ب: : 127000 دبي')),
buildTextRow(EnquiryAssetIconPath.at, context.translate('Email Address : sdgs@fcsc.gov.ae','البريد الإلكتروني : sdgs@fcsc.gov.ae')),
buildTextRow(EnquiryAssetIconPath.map,context.translate( 'Latitude : 25.223926','خط العرض : 25.223926')),
buildTextRow(EnquiryAssetIconPath.map, context.translate('Longitude : 55.350526','خط الطول : 55.350526')),
],
),
),
],
),
),
), title: Text(context.translate('Contact Us','اتصل بنا')),);
}
Widget buildTextRow(String iconName, String text) {
return Padding(
padding: const EdgeInsets.only(top:8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SvgPicture.asset(
iconName,
semanticsLabel: 'Filter',
width: 24,
height: 24,
),
SizedBox(width: 8), // Add spacing if needed
Text(
text, // Dynamic text
style: TextStyle(
fontSize: 16,
color: Color(0xFF878787),
),
),
],
),
);
}
}

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

@ -1,7 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.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 +18,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;
@ -342,11 +344,14 @@ class _ManageUserRouterState extends State<ManageUserRouter> {
decoration: InputDecoration(
hintText: "Search",
hintStyle: TextStyle(color: Color(0xFF898C81)),
prefixIcon: Image(
image: ExactAssetImage(MiscIconAssetPath.search),
width: 24,
height: 24,
color: Color(0xFFAA8E83)),
prefixIconConstraints: BoxConstraints(maxWidth: 42, maxHeight: 42),
prefixIcon: Container(
padding: EdgeInsets.only(right: 5),
child: SvgPicture.asset(
MiscIconAssetPath.Search,
semanticsLabel: 'Search',
),
),
// prefixIcon: Image.asset(
// MiscIconAssetPath.search,

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

@ -7,7 +7,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class Userguide extends StatefulWidget {
const Userguide({super.key});
Userguide({super.key});
@override
State<Userguide> createState() => _UserguideState();
@ -20,6 +20,7 @@ class _UserguideState extends State<Userguide> {
{'routePath':'faq','color': Color(0xFF7296BE), 'text': 'FAQs', 'icon': 'mdi:faq', 'text-ar': 'لأسئلة الشائعة'},
];
@override
Widget buildDynamicWidget(dynamic icons, Color color) {
if (icons is IconData) {
return Icon(
@ -46,41 +47,41 @@ class _UserguideState extends State<Userguide> {
}
}
@override
Widget build(BuildContext context) {
return PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) {
if (didPop) return;
context.go('/myhomepage');
},
child: BaseScaffold(
showDivider: true,
bottomColor: Colors.white,
dividerColor: Colors.grey[300],
appbarColor: Colors.white,
title: Text(AppLocalizations.of(context)!.guide_title) ,
body: Container(
color: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 16 , vertical: 20),
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, // Two columns
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
mainAxisExtent:MediaQuery.of(context).size.height* 0.15 ,
canPop: false,
onPopInvokedWithResult: (didPop, result) {
if (didPop) return;
context.go('/myhomepage');
},
child: BaseScaffold(
showDivider: true,
bottomColor: Colors.white,
dividerColor: Colors.grey[300],
appbarColor: Colors.white,
title: Text(AppLocalizations.of(context)!.guide_title) ,
body: Container(
color: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 16 , vertical: 20),
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
childAspectRatio: 1.7,
// mainAxisExtent:MediaQuery.of(context).size.height* 0.15 ,
),
itemCount: guideList.length,
itemBuilder: (context, index) {
return HoverContainer(
iconName: guideList[index]['icon'],
title: context.translate(guideList[index]['text'], guideList[index]['text-ar']),
routePath: guideList[index]['routePath'],
);
},
),
itemCount: guideList.length,
itemBuilder: (context, index) {
return HoverContainer(
iconName: guideList[index]['icon'],
title: context.translate(guideList[index]['text'], guideList[index]['text-ar']),
routePath: guideList[index]['routePath'],
);
},
),
),
),
);
}
@ -108,69 +109,69 @@ class _HoverContainerState extends State<HoverContainer> {
return GestureDetector(
onTap: () { context.push('/user-guide/${widget.routePath}');},
child: MouseRegion(
onEnter: (_) => setState(() => isHovered = true),
onExit: (_) => setState(() => isHovered = true),
child : Container(
padding: EdgeInsets.only(top: 4, right: 4, left: 4, bottom: 6),
height: screenHeight* 0.23 ,
width: screenWidth*0.30,
margin: EdgeInsets.all(1),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: isHovered
? [
BoxShadow(
color: Colors.black.withValues(alpha:0.2),
blurRadius:2,
spreadRadius: 1,
offset: Offset(0, 4),
),
]
: [],
border: Border.all(
color: Color(0xFF7DAFBC),
width: 1.0,
),
),
alignment: Alignment.center,
// duration: Duration(milliseconds: 200),
onEnter: (_) => setState(() => isHovered = true),
onExit: (_) => setState(() => isHovered = true),
child : Container(
padding: EdgeInsets.only(top: 4, right: 4, left: 4, bottom: 6),
child: LayoutBuilder(builder: (context, constraints){
double containerWidth = constraints.maxWidth;
// double containerHeight = constraints.maxHeight;
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconifyIcon(icon: widget.iconName,
color: Color((0xFF7DAFBC)),
size: containerWidth * 0.25,),
// buildDynamicWidget(data['icon'], Color(0xFF7DAFBC)),
SizedBox(width: 10,height: containerWidth * 0.04,), // Space between icon and text
Container(
width: containerWidth* 0.85,
padding: EdgeInsets.symmetric(horizontal: 4, vertical: 4),
margin: EdgeInsets.only(bottom: 3),
decoration: BoxDecoration(
color: Color(0xFF7DAFBC),
borderRadius: BorderRadius.circular(5),
border: Border.all(color: Color(0xFF7DAFBC)),
),
child: Text(
widget.title,
style: TextStyle(
color: Colors.white, // Text color
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
width: screenWidth*0.30,
margin: EdgeInsets.all(1),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: isHovered
? [
BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius:2,
spreadRadius: 1,
offset: Offset(0, 4),
),
]
: [],
border: Border.all(
color: Color(0xFF7DAFBC),
width: 1.0
),
],
);
},),
),
alignment: Alignment.center,
// duration: Duration(milliseconds: 200),
child: LayoutBuilder(builder: (context, constraints){
double containerWidth = constraints.maxWidth;
double containerHeight = constraints.maxHeight;
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconifyIcon(icon: widget.iconName,
color: Color((0xFF7DAFBC)),
size: containerHeight * 0.45,),
// buildDynamicWidget(data['icon'], Color(0xFF7DAFBC)),
SizedBox(width: 10,height: containerHeight * 0.04,), // Space between icon and text
Container(
width: containerWidth* 0.85,
padding: EdgeInsets.symmetric(horizontal: 4, vertical: 4),
margin: EdgeInsets.only(bottom: 3),
decoration: BoxDecoration(
color: Color(0xFF7DAFBC),
borderRadius: BorderRadius.circular(5),
border: Border.all(color: Color(0xFF7DAFBC))
),
child: Text(
widget.title,
style: TextStyle(
color: Colors.white, // Text color
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
),
],
);
})
),
),
),

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),
@ -972,6 +974,11 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
title: Text(AppLocalizations.of(context)!.guide_title),
onTap: () => _navigateTo(context, '/user-guide'),
),
ListTile(
leading: Icon(Icons.phone),
title: const Text('Contact'),
onTap: () => context.push('/contact'),
),
if (userId != 'guest')
ListTile(
leading: Icon(Icons.logout),

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.25+26
version: 1.0.27+28
environment:
sdk: ">=3.2.3 <4.0.0"
@ -141,6 +141,7 @@ flutter:
- assets/icons/misc/group.png
- assets/icons/misc/search.png
- assets/icons/bookmark/
- assets/icons/enquiry/
fonts:
- family: Segoe