diff --git a/assets/icons/drawer/logout.png b/assets/icons/drawer/logout.png new file mode 100644 index 00000000..a0b94ff7 Binary files /dev/null and b/assets/icons/drawer/logout.png differ diff --git a/lib/config/my_router.dart b/lib/config/my_router.dart index edcd04f0..a1e75699 100644 --- a/lib/config/my_router.dart +++ b/lib/config/my_router.dart @@ -302,6 +302,7 @@ import '../presentation/Screens/auth_verification/changepassword.dart'; import '../presentation/Screens/auth_verification/confirm_password.dart'; import '../presentation/Screens/auth_verification/create_new_pw.dart'; import '../presentation/Screens/auth_verification/otp_verification.dart'; +import '../presentation/Screens/demo_home.dart'; import '../presentation/Screens/profilepage.dart'; import '../presentation/routes/auth_routes/login_route.dart'; import '../presentation/routes/bottom_bar_routes/tab_routes/home_route.dart'; @@ -324,6 +325,10 @@ final GoRouter router = GoRouter( path: '/register', builder: (context, state) => RegisterScreen(), ), + GoRoute( + path: '/DemoHome', + builder: (context, state) => ChartPage(), + ), GoRoute( path: '/mailverification', builder: (context, state) => EmailVerificationScreen( diff --git a/lib/presentation/Screens/auth_verification/registration.dart b/lib/presentation/Screens/auth_verification/registration.dart index d83f2db4..0ec33c48 100644 --- a/lib/presentation/Screens/auth_verification/registration.dart +++ b/lib/presentation/Screens/auth_verification/registration.dart @@ -233,30 +233,6 @@ class _RegisterScreenState extends State { if (_formKey.currentState?.validate() ?? false) { if (isChecked) { try { - final existingUsers = await pb.collection('users').getList( - filter: 'email="${_emailController.text}"', - ); - - if (existingUsers.items.isNotEmpty) { - // Email already exists - showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: Text('Email Exists'), - content: Text( - 'Email ID already exists. Please use a different email.'), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context), - child: Text('OK'), - ), - ], - ); - }, - ); - return; // Stop registration process - } final adminAuth = await pb.admins .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); @@ -287,10 +263,33 @@ class _RegisterScreenState extends State { throw Exception('User registration failed: missing user ID'); } } catch (e) { - setState(() { - registrationFailed = true; - registrationSuccess = false; - }); + // Check if the error is due to an invalid or already used email + if (e + .toString() + .contains('The email is invalid or already in use.')) { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text('Email Exists'), + content: Text( + 'Email ID already exists. Please use a different email.'), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text('OK'), + ), + ], + ); + }, + ); + } else { + // Handle other types of errors + setState(() { + registrationFailed = true; + registrationSuccess = false; + }); + } } } else { setState(() { @@ -452,7 +451,7 @@ class _RegisterScreenState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - SizedBox(height: screenheight / 6), + SizedBox(height: screenheight / 15), Text( 'Register', style: TextStyle( @@ -662,7 +661,7 @@ class _RegisterScreenState extends State { width: screenwidth / 1.3, child: ElevatedButton( onPressed: () { - // Add your login logic here + context.go('/'); }, style: ElevatedButton.styleFrom( backgroundColor: Color( @@ -671,44 +670,41 @@ class _RegisterScreenState extends State { borderRadius: BorderRadius.circular(10), ), ), - // child: Row( - // mainAxisSize: MainAxisSize.min, - // children: [ - // Text( - // "Login", - // style: TextStyle( - // fontSize: 16, color: Colors.white - // ), - // - // - // ), - // SizedBox(width: 8), - // Icon(Icons.arrow_forward, - // color: Colors.white), - // ], - // ), - - child: GestureDetector( - onTap: () { - // Navigate to LoginRoute - context.go('/'); - }, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "Login", - style: TextStyle( - fontSize: 16, - color: Colors.white, - ), - ), - SizedBox(width: 8), - Icon(Icons.arrow_forward, - color: Colors.white), - ], - ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "Login", + style: TextStyle( + fontSize: 16, color: Colors.white), + ), + SizedBox(width: 8), + Icon(Icons.arrow_forward, + color: Colors.white), + ], ), + + // child: GestureDetector( + // onTap: () { + // // Navigate to LoginRoute + // context.go('/'); + // }, + // child: Row( + // mainAxisSize: MainAxisSize.min, + // children: [ + // Text( + // "Login", + // style: TextStyle( + // fontSize: 16, + // color: Colors.white, + // ), + // ), + // SizedBox(width: 8), + // Icon(Icons.arrow_forward, + // color: Colors.white), + // ], + // ), + // ), ), ), SizedBox( diff --git a/lib/presentation/Screens/demo_home.dart b/lib/presentation/Screens/demo_home.dart index 402bc535..225f1b1b 100644 --- a/lib/presentation/Screens/demo_home.dart +++ b/lib/presentation/Screens/demo_home.dart @@ -1,29 +1,262 @@ +import 'dart:convert'; import 'package:flutter/material.dart'; -import 'dart:async'; +import 'package:go_router/go_router.dart'; +import 'package:intl/intl.dart'; +import 'package:syncfusion_flutter_charts/charts.dart'; // Import Syncfusion charts package +import 'package:http/http.dart' as http; -import 'package:uae_stat/domain/use_cases/language.dart'; - -import '../components/my_drawer.dart'; - -class DemoHome extends StatefulWidget { - @override - State createState() => _DemoHomeState(); +void main() { + runApp(MyApp()); } -class _DemoHomeState extends State { +class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return Scaffold( - drawer: const MyDrawer(), - appBar: AppBar( - backgroundColor: const Color(0xFFf8f9ff), - title: Text(context.translate('Home', 'نموذج الملاحظات')), - ), - body: Padding( - padding: const EdgeInsets.all(16.0), - child: Center( - child: Text('Home Page'), - )), + return MaterialApp( + home: ChartPage(), ); } } + +class ChartPage extends StatefulWidget { + @override + ChartPageState createState() => ChartPageState(); +} + +class ChartPageState extends State { + List chartsData = []; + bool isLoading = true; + + @override + void initState() { + super.initState(); + fetchChartData(); + } + + Future fetchChartData() async { + const baseUrl = + 'https://pb.venbait.in/api/custom/apicall'; // Replace with your server URL + final url = Uri.parse('$baseUrl?dataset=hotels'); + + try { + final response = await http.get(url); + if (response.statusCode == 200) { + setState(() { + chartsData = jsonDecode(response.body); + isLoading = false; + }); + } else { + throw Exception('Failed to load data'); + } + } catch (error) { + setState(() { + isLoading = false; + }); + print('Error fetching data: $error'); + } + } + + List parseLineChartData(List response) { + return response.map((entry) { + // Attempt to fetch the TIMEPERIOD + final rawTimePeriod = + entry['ObsKey']?['Year'] ?? entry['ObsKey']?['TIME_PERIOD']; + final formattedTimePeriod = rawTimePeriod != null + ? rawTimePeriod.toString() // Use as-is if valid + : 'Unknown'; // Fallback value if null + + // Parse the value or fallback to 0.0 + final value = + double.tryParse(entry['ObsValue']?['Value']?.toString() ?? '0.0') ?? + 0.0; + + return ChartData( + timePeriod: formattedTimePeriod, + value: value, + ); + }).toList(); + } + + List parseBarChartData(List response) { + return response + .asMap() + .entries + .map((entry) => ChartData( + timePeriod: entry.value['ObsKey']['TIME_PERIOD'] ?? + 'Unknown', // Fallback to 'Unknown' if null + value: double.tryParse( + entry.value['ObsValue']['Value'].toString()) ?? + 0.0, // Handle null/invalid value + )) + .toList(); + } + + Widget buildChart(dynamic chartData) { + print('chartData $chartData'); + switch (chartData['chart_type']) { + case 'line': + return SfCartesianChart( + primaryXAxis: CategoryAxis( + title: AxisTitle(text: 'Year'), + labelRotation: 45, // Rotate labels if they overlap + ), + title: ChartTitle(text: 'Hotel Estabhlishments'), + legend: Legend(isVisible: true), + tooltipBehavior: TooltipBehavior( + enable: true, + builder: (dynamic data, dynamic point, dynamic series, + int pointIndex, int seriesIndex) { + return Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(5), + ), + child: Text( + '${data.timePeriod}: ${formatNumber(data.value)}', + style: const TextStyle(color: Colors.black), + ), + ); + }, + ), + series: >[ + LineSeries( + dataSource: parseLineChartData(chartData['response']), + xValueMapper: (ChartData data, _) => data.timePeriod, + yValueMapper: (ChartData data, _) => data.value, + name: chartData['dataset'], + color: Colors.red, + dataLabelSettings: DataLabelSettings( + isVisible: true, + builder: (dynamic data, dynamic point, dynamic series, + int pointIndex, int seriesIndex) { + return Text( + formatNumber(data.value), + style: const TextStyle(fontSize: 12, color: Colors.black), + ); + }, + ), + ), + ], + ); + case 'bar': + return SfCartesianChart( + primaryXAxis: CategoryAxis(), + title: ChartTitle(text: 'Hotel Occupancy Rate'), + tooltipBehavior: TooltipBehavior( + enable: true, + builder: (dynamic data, dynamic point, dynamic series, + int pointIndex, int seriesIndex) { + return Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(5), + ), + child: Text( + '${data.timePeriod}: ${formatNumber(data.value)}', + style: const TextStyle(color: Colors.black), + ), + ); + }, + ), + series: >[ + BarSeries( + dataSource: parseBarChartData(chartData['response']), + xValueMapper: (ChartData data, _) => data.timePeriod, + yValueMapper: (ChartData data, _) => data.value, + name: chartData['dataset'], + color: Colors.red, + dataLabelSettings: DataLabelSettings( + isVisible: true, + builder: (dynamic data, dynamic point, dynamic series, + int pointIndex, int seriesIndex) { + return Text( + formatNumber(data.value), + style: const TextStyle(fontSize: 12, color: Colors.black), + ); + }, + ), + // isTrackVisible: true, + // trackColor: Colors.red + ), + ], + ); + default: + return Center(child: Text('Unknown chart type')); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF7DAFBC), + appBar: AppBar( + backgroundColor: Color(0xFF7DAFBC), + elevation: 0, + leading: IconButton( + icon: Icon(Icons.arrow_back_ios_new, color: Colors.white), + onPressed: () { + context.go('/myhomepage'); + }, + ), + title: Text( + 'Charts', + style: TextStyle(color: Colors.white), + ), + ), + body: isLoading + ? Center(child: CircularProgressIndicator()) + : ListView.builder( + itemCount: chartsData.length, + itemBuilder: (context, index) { + return Card( + margin: EdgeInsets.all(10), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Text( + // 'Chart: ${chartsData[index]['chart_type']}', + // style: TextStyle( + // fontSize: 18, fontWeight: FontWeight.bold), + // ), + // SizedBox(height: 10), + Container( + height: 300, + child: buildChart(chartsData[index]), + ), + ], + ), + ), + ); + }, + ), + ); + } +} + +class ChartData { + final String timePeriod; + final double value; + final String formattedValue; + + ChartData({required this.timePeriod, required this.value}) + : formattedValue = formatNumber(value); +} + +String formatNumber(double value) { + if (value >= 1e12) { + return '${(value / 1e12).toStringAsFixed(2)} T'; // Trillions + } else if (value >= 1e9) { + return '${(value / 1e9).toStringAsFixed(2)} B'; // Billions + } else if (value >= 1e6) { + return '${(value / 1e6).toStringAsFixed(2)} M'; // Millions + } else if (value >= 1e5) { + return '${(value / 1e5).toStringAsFixed(2)} L'; // Lakhs + } else if (value >= 1e3) { + return '${(value / 1e3).toStringAsFixed(2)} K'; // Thousands + } + return value.toStringAsFixed(2); // Default to two decimal places +} diff --git a/lib/presentation/Screens/profilepage.dart b/lib/presentation/Screens/profilepage.dart index 9c94e6ee..e003a18f 100644 --- a/lib/presentation/Screens/profilepage.dart +++ b/lib/presentation/Screens/profilepage.dart @@ -156,17 +156,39 @@ class _ProfileScreenState extends State { } } + // void _pickImage() async { + // final XFile? pickedFile = + // await _picker.pickImage(source: ImageSource.gallery); + // if (pickedFile != null) { + // setState(() { + // _profileImage = File(pickedFile.path); + // }); + // } + // } + + // Function to open the date picker + void _pickImage() async { final XFile? pickedFile = await _picker.pickImage(source: ImageSource.gallery); if (pickedFile != null) { - setState(() { - _profileImage = File(pickedFile.path); - }); + final String fileExtension = + pickedFile.path.split('.').last.toLowerCase(); + if (fileExtension == 'jpg' || + fileExtension == 'jpeg' || + fileExtension == 'png' || + fileExtension == "heic") { + setState(() { + _profileImage = File(pickedFile.path); + }); + } else { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Please select a JPG, JPEG, or PNG file.')), + ); + } } } - // Function to open the date picker Future _pickDate() async { final DateTime today = DateTime.now(); final DateTime initialDate = _selectedDate ?? @@ -273,11 +295,12 @@ class _ProfileScreenState extends State { _resetFormFields(); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("Profile updated successfully!"))); - if (role == 'admin') { - context.go('/manageuser'); - } else { - context.go('/myhomepage'); - } + // if (role == 'admin') { + // context.go('/manageuser'); + // } else { + // context.go('/myhomepage'); + // } + context.go('/myhomepage'); } catch (error) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("Failed to update profile: $error"))); @@ -370,8 +393,10 @@ class _ProfileScreenState extends State { children: [ Text( "User Name", - style: - TextStyle(fontSize: 16, fontWeight: FontWeight.w500), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.grey), ), ], ), @@ -380,7 +405,7 @@ class _ProfileScreenState extends State { controller: _usernameController, focusNode: _focusNodes[0], decoration: InputDecoration( - hintText: _showHints[0] ? 'Mohammad Hassan' : null, + hintText: _showHints[0] ? 'Enter the User Name' : null, hintStyle: TextStyle(color: Colors.grey), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), @@ -393,9 +418,11 @@ class _ProfileScreenState extends State { mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - "E-mail", - style: - TextStyle(fontSize: 16, fontWeight: FontWeight.w500), + "Email ID", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.grey), ), ], ), @@ -418,7 +445,7 @@ class _ProfileScreenState extends State { mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - "Full Name", + "Full Name*", style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500), ), @@ -444,7 +471,7 @@ class _ProfileScreenState extends State { controller: _fullNameController, focusNode: _focusNodes[2], decoration: InputDecoration( - hintText: _showHints[2] ? 'Enter the Full Name' : null, + hintText: _showHints[2] ? 'Enter the name' : null, hintStyle: TextStyle(color: Colors.grey), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), @@ -473,9 +500,9 @@ class _ProfileScreenState extends State { border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), - hintText: - _showHints[3] ? 'Select your Date of Birth' : null, - //hintText: 'Select your Date of Birth', + hintText: _showHints[3] ? 'DD/MM/YYYY' : null, + //_showHints[3] ? 'Select your Date of Birth' : null, + hintStyle: TextStyle(color: Colors.grey), suffixIcon: const Icon(Icons.arrow_drop_down_sharp), ), readOnly: true, diff --git a/lib/presentation/routes/auth_routes/login_route.dart b/lib/presentation/routes/auth_routes/login_route.dart index 7e56df9f..41dc0b37 100644 --- a/lib/presentation/routes/auth_routes/login_route.dart +++ b/lib/presentation/routes/auth_routes/login_route.dart @@ -256,12 +256,12 @@ class LoginRoute extends HookConsumerWidget { print(isProfileComplete); if (isProfileComplete) { print('home'); - if (role == 'admin') { - context.go('/manageuser'); - } else { - context.go('/myhomepage'); - } - // context.go('/myhomepage'); + // if (role == 'admin') { + // context.go('/myhomepage'); + // } else { + // context.go('/myhomepage'); + // } + context.go('/myhomepage'); } else { print('profile'); if (userId != null && userId.isNotEmpty) { diff --git a/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart b/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart index 1c2fe332..cc4702c4 100644 --- a/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart +++ b/lib/presentation/routes/bottom_bar_routes/tab_routes/home_route.dart @@ -161,6 +161,7 @@ // } // } import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; import '../../drawer_routes/custom_drawer_routes.dart'; class MyHomePage extends StatefulWidget { @@ -176,16 +177,16 @@ class _MyHomePageState extends State { double myheight = MediaQuery.of(context).size.height; double mywidth = MediaQuery.of(context).size.width; return BaseScaffold( - title: Center(child: SizedBox(height : myheight/5, width : mywidth/3,child: Image(image: AssetImage('assets/logos/uae_stat.png')))), + title: Center( + child: SizedBox( + height: myheight / 5, + width: mywidth / 3, + child: Image(image: AssetImage('assets/logos/uae_stat.png')))), body: EconomyStats(), ); } } - - - - class EconomyStats extends StatelessWidget { const EconomyStats({Key? key}) : super(key: key); @@ -193,24 +194,26 @@ class EconomyStats extends StatelessWidget { Widget build(BuildContext context) { return SingleChildScrollView( child: Padding( - padding: EdgeInsets.only(left: 10,right: 10), + padding: EdgeInsets.only(left: 10, right: 10), child: Column( children: [ // Header Section - RoundedCornerContainer( - text: 'ECONOMY', - backgroundColor: Color(0xFF7DAFBC), - textStyle: const TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, - color: Colors.white, - ), - ), + RoundedCornerContainer( + text: 'ECONOMY', + backgroundColor: Color(0xFF7DAFBC), + textStyle: const TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), // Grid Section // ECONOMY DETAILS Padding( - padding: const EdgeInsets.only(top: 10,), + padding: const EdgeInsets.only( + top: 10, + ), child: Column( children: [ // First Row @@ -224,11 +227,12 @@ class EconomyStats extends StatelessWidget { bordercolor: Color(0xFF7DAFBC), textcolor: Color(0xFF7DAFBC), ), - InfoCard( + InfoCard( title: 'Inflation Rate', subtitle: '(2022)', value: '4.82%', - bordercolor: Color(0xFF7DAFBC), textcolor: Color(0xFF7DAFBC), + bordercolor: Color(0xFF7DAFBC), + textcolor: Color(0xFF7DAFBC), ), ], ), @@ -236,18 +240,20 @@ class EconomyStats extends StatelessWidget { // Second Row Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ + children: [ InfoCard( title: 'Trade Value', subtitle: '(Jan - Jan 2024) - AED', value: '215.4B', - bordercolor: Color(0xFF7DAFBC), textcolor: Color(0xFF7DAFBC), + bordercolor: Color(0xFF7DAFBC), + textcolor: Color(0xFF7DAFBC), ), InfoCard( title: 'Hotel Guests', subtitle: '(2022)', value: '25.21M', - bordercolor: Color(0xFF7DAFBC), textcolor: Color(0xFF7DAFBC), + bordercolor: Color(0xFF7DAFBC), + textcolor: Color(0xFF7DAFBC), ), ], ), @@ -264,7 +270,9 @@ class EconomyStats extends StatelessWidget { // SOCIAL DETAILS Padding( - padding: const EdgeInsets.only(top: 10,), + padding: const EdgeInsets.only( + top: 10, + ), child: Column( children: [ // First Row @@ -291,7 +299,7 @@ class EconomyStats extends StatelessWidget { // Second Row Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ + children: [ InfoCard( title: 'Hospitals (Gov )', subtitle: '(Jan - Jan 2024) - AED', @@ -321,12 +329,15 @@ class EconomyStats extends StatelessWidget { // ENVIRONMENT DETAILS Padding( - padding: const EdgeInsets.only(top: 10,), + padding: const EdgeInsets.only( + top: 10, + ), child: Column( children: [ // First Row Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, children: [ InfoCard( title: 'Electricity', @@ -347,8 +358,9 @@ class EconomyStats extends StatelessWidget { const SizedBox(height: 10), // Second Row Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ InfoCard( title: 'Export of oil', subtitle: '(Jan - Jan 2024) - AED', @@ -386,13 +398,11 @@ class RoundedCornerContainer extends StatelessWidget { final Color backgroundColor; final TextStyle? textStyle; - const RoundedCornerContainer({ Key? key, required this.text, this.backgroundColor = Colors.blue, this.textStyle, - }) : super(key: key); @override @@ -417,7 +427,6 @@ class RoundedCornerContainer extends StatelessWidget { } } - class InfoCard extends StatelessWidget { final String title; final String subtitle; @@ -425,60 +434,66 @@ class InfoCard extends StatelessWidget { final Color bordercolor; final Color? textcolor; - const InfoCard({ + const InfoCard({ Key? key, required this.title, required this.subtitle, - required this.value, required this.bordercolor,this.textcolor, + required this.value, + required this.bordercolor, + this.textcolor, }) : super(key: key); @override Widget build(BuildContext context) { double myheight = MediaQuery.of(context).size.height; double mywidth = MediaQuery.of(context).size.width; + return Expanded( - child: - Container( - height: myheight/9, - width: mywidth/4, - margin: const EdgeInsets.symmetric(horizontal: 8), - decoration: BoxDecoration( - border: Border.all(color: bordercolor), - borderRadius: BorderRadius.circular(8), - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Expanded( - child: Text( - title, - //textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Colors.black, + child: GestureDetector( + onTap: () { + context.go('/DemoHome'); + }, + child: Container( + height: myheight / 9, + width: mywidth / 4, + margin: const EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + border: Border.all(color: bordercolor), + borderRadius: BorderRadius.circular(8), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + child: Text( + title, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.black, + ), ), ), - ), - const SizedBox(height: 2), - Text( - subtitle, - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 12, - color: Colors.grey, + const SizedBox(height: 2), + Text( + subtitle, + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 12, + color: Colors.grey, + ), ), - ), - const SizedBox(height: 2), - Text( - value, - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, - color: textcolor ?? Colors.black + const SizedBox(height: 2), + Text( + value, + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: textcolor ?? Colors.black, + ), ), - ), - ], + ], + ), ), ), ); diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart b/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart index 00d0c486..8c513234 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/edit_profile.dart @@ -194,17 +194,39 @@ class _EditProfileState extends State { } } + // void _pickImage() async { + // final XFile? pickedFile = + // await _picker.pickImage(source: ImageSource.gallery); + // if (pickedFile != null) { + // setState(() { + // _profileImage = File(pickedFile.path); + // }); + // } + // } + + // Function to open the date picker + void _pickImage() async { final XFile? pickedFile = await _picker.pickImage(source: ImageSource.gallery); if (pickedFile != null) { - setState(() { - _profileImage = File(pickedFile.path); - }); + final String fileExtension = + pickedFile.path.split('.').last.toLowerCase(); + if (fileExtension == 'jpg' || + fileExtension == 'jpeg' || + fileExtension == 'png' || + fileExtension == "heic") { + setState(() { + _profileImage = File(pickedFile.path); + }); + } else { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Please select a JPG, JPEG, or PNG file.')), + ); + } } } - // Function to open the date picker Future _pickDate() async { final DateTime today = DateTime.now(); final DateTime initialDate = _selectedDate ?? @@ -398,7 +420,9 @@ class _EditProfileState extends State { Text( "User Name", style: TextStyle( - fontSize: 16, fontWeight: FontWeight.w500), + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.grey), ), ], ), @@ -407,7 +431,7 @@ class _EditProfileState extends State { controller: _usernameController, focusNode: _focusNodes[0], decoration: InputDecoration( - hintText: _showHints[0] ? 'Mohammad Hassan' : null, + // hintText: _showHints[0] ? 'Mohammad Hassan' : null, hintStyle: TextStyle(color: Colors.grey), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), @@ -420,9 +444,11 @@ class _EditProfileState extends State { mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - "E-mail", + "Email ID", style: TextStyle( - fontSize: 16, fontWeight: FontWeight.w500), + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.grey), ), ], ), @@ -431,10 +457,7 @@ class _EditProfileState extends State { controller: _emailController, focusNode: _focusNodes[1], decoration: InputDecoration( - hintText: _showHints[1] - ? 'mohammad.hassan@fcsc.gov.ae' - : null, - hintStyle: TextStyle(color: Colors.grey), + // hintText: _showHints[1]? 'mohammad.hassan@fcsc.gov.ae': null, border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), @@ -446,9 +469,11 @@ class _EditProfileState extends State { mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - "Full Name", + "Full Name*", style: TextStyle( - fontSize: 16, fontWeight: FontWeight.w500), + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.grey), ), ], ), @@ -471,7 +496,7 @@ class _EditProfileState extends State { controller: _fullNameController, focusNode: _focusNodes[2], decoration: InputDecoration( - hintText: _showHints[2] ? 'Mohammad' : null, + // hintText: _showHints[2] ? 'Mohammad' : null, hintStyle: TextStyle(color: Colors.grey), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), @@ -490,7 +515,9 @@ class _EditProfileState extends State { Text( "Date of Birth*", style: TextStyle( - fontSize: 16, fontWeight: FontWeight.w500), + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.grey), ), ], ), @@ -502,10 +529,8 @@ class _EditProfileState extends State { border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), - hintText: _showHints[3] - ? 'Select your Date of Birth' - : null, - //hintText: 'Select your Date of Birth', + // hintText: _showHints[3] ? 'Select your Date of Birth' : null, + hintStyle: TextStyle(color: Colors.grey), suffixIcon: const Icon(Icons.arrow_drop_down_sharp), enabled: !_isProfileCompleted, ), diff --git a/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart b/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart index deab917f..8652db61 100644 --- a/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart +++ b/lib/presentation/routes/drawer_routes/Drawer Items/manage_users.dart @@ -43,7 +43,9 @@ class _ManageUserRouterState extends State { try { await _pb.admins .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com'); - final result = await _pb.collection('users').getFullList(); + final result = await _pb.collection('users').getFullList( + filter: 'role="user"', + ); setState(() { userData = result.map((record) { diff --git a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart index 981a32fe..8aa0afea 100644 --- a/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart +++ b/lib/presentation/routes/drawer_routes/custom_drawer_routes.dart @@ -199,6 +199,15 @@ class _BaseScaffoldState extends State { title: Text('Manage User'), onTap: () => context.go('/manageuser'), ), + ListTile( + leading: SizedBox( + height: myheight / 15, + width: mywidth / 15, + child: Image( + image: AssetImage('assets/icons/drawer/logout.png'))), + title: Text('Logout'), + onTap: () => context.go('/'), + ), ], ), ), diff --git a/pubspec.lock b/pubspec.lock index 67247bd5..7d1ab196 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -841,6 +841,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.12.16+1" + material_charts: + dependency: "direct main" + description: + name: material_charts + sha256: "3950a910eeb8f5dca7040a68d526a086a9512f87da5c2b172495a5fcab0f6dc3" + url: "https://pub.dev" + source: hosted + version: "0.0.23" material_color_utilities: dependency: transitive description: @@ -1501,5 +1509,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.5.0 <4.0.0" + dart: ">=3.5.2 <4.0.0" flutter: ">=3.24.0" diff --git a/pubspec.yaml b/pubspec.yaml index 3fac9859..ebd8679b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -55,6 +55,7 @@ dependencies: mailer: ^6.2.0 image_picker: ^1.1.2 syncfusion_flutter_charts: ^28.1.33 + material_charts: ^0.0.23 dependency_overrides: fading_edge_scrollview: ^4.1.1