import 'dart:io'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; // ⭐ REQUIRED import 'package:nearle/views/Dashboard/profile/informations/help_center.dart'; import 'package:nearle/views/Dashboard/profile/informations/profile.dart'; import 'package:nearle/views/Dashboard/profile/informations/saved_address.dart'; import 'package:nearle/views/Dashboard/profile/informations/faq.dart'; import 'package:nearle/views/Dashboard/profile/informations/notifications_page.dart'; import 'package:nearle/views/Dashboard/profile/informations/support_ticket.dart'; import 'package:nearle/views/helpers/constants/Colorconstants.dart'; import 'package:nearle/views/helpers/constants/Font_constant.dart'; import 'package:nearle/views/onboardscreens/Sign_in.dart'; import 'package:nearle/controllers/profile_controller.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:nearle/views/Dashboard/profile/informations/order_alert_sound.dart'; import 'package:nearle/controllers/rewards_controller.dart'; import 'package:nearle/views/Dashboard/profile/rewards_card.dart'; import 'package:nearle/views/Dashboard/profile/informations/rider_rewards_page.dart'; import 'package:nearle/utils/mqtt_service.dart'; class ProfilePage extends StatefulWidget { const ProfilePage({super.key}); @override State createState() => _ProfilePageState(); } class _ProfilePageState extends State { late final ProfileController _profileController = Get.isRegistered() ? Get.find() : Get.put(ProfileController(), permanent: true); final RewardsController _rewardsController = Get.put(RewardsController()); String _name = ''; String _email = ''; String _contact = ''; @override void initState() { super.initState(); _loadProfilePrefs(); ever(_profileController.userName, (_) => _assignFromController()); ever(_profileController.userEmail, (_) => _assignFromController()); ever(_profileController.userContact, (_) => _assignFromController()); ever(_profileController.userAddress, (_) => _assignFromController()); _profileController.loadFromPrefs(); } Future _loadProfilePrefs() async { final prefs = await SharedPreferences.getInstance(); setState(() { _name = prefs.getString('user_name') ?? ''; _email = prefs.getString('user_email') ?? ''; _contact = prefs.getString('contactno') ?? ''; _contact = prefs.getString('contactno') ?? ''; }); final userId = prefs.getInt('userid') ?? 0; if (userId > 0) { _rewardsController.fetchBonusSummary(userId); } } void _assignFromController() { setState(() { if (_profileController.userName.value.trim().isNotEmpty) { _name = _profileController.userName.value.trim(); } if (_profileController.userEmail.value.trim().isNotEmpty) { _email = _profileController.userEmail.value.trim(); } if (_profileController.userContact.value.trim().isNotEmpty) { _contact = _profileController.userContact.value.trim(); } }); } @override Widget build(BuildContext context) { return SafeArea( child: Scaffold( backgroundColor: Colors.grey.shade200, appBar: AppBar( backgroundColor: Colors.grey.shade200, elevation: 0, toolbarHeight: 70.h, // ⭐ responsive title: Padding( padding: EdgeInsets.only(top: 12.h), child: Text( "PROFILE", style: TextStyle( fontSize: FontConstants.xxxLarge(context).sp, fontWeight: FontWeight.bold, fontFamily: FontConstants.fontFamily, color: Colors.black, ), ), ), bottom: PreferredSize( preferredSize: Size.fromHeight(1.h), child: Divider(height: 1.h, color: Colors.grey), ), ), body: SingleChildScrollView( physics: const ClampingScrollPhysics(), child: Padding( padding: EdgeInsets.symmetric(horizontal: 16.w), child: Padding( padding: EdgeInsets.only(bottom: 40.h), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 20.h), /// ⭐ PROFILE CARD RESPONSIVE Container( padding: EdgeInsets.all(16.r), decoration: BoxDecoration( color: ColorConstants.primaryColor, borderRadius: BorderRadius.circular(20.r), ), child: Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.person, color: Colors.white, size: 22.sp, ), SizedBox(width: 6.w), Flexible( child: Text( _name.isNotEmpty ? _name : "—", style: TextStyle( color: Colors.white, fontSize: 18.sp, fontWeight: FontWeight.bold, ), overflow: TextOverflow.ellipsis, ), ), ], ), SizedBox(height: 12.h), Row( children: [ Icon( Icons.phone, color: Colors.white, size: 20.sp, ), SizedBox(width: 6.w), Flexible( child: Text( _contact.isNotEmpty ? _contact : "—", style: TextStyle( color: Colors.white, fontSize: 16.sp, ), ), ), ], ), SizedBox(height: 12.h), Row( children: [ Icon( Icons.email, color: Colors.white, size: 20.sp, ), SizedBox(width: 6.w), Flexible( child: Text( _email.isNotEmpty ? _email : "—", style: TextStyle( color: Colors.white, fontSize: 16.sp, ), overflow: TextOverflow.ellipsis, ), ), ], ), ], ), ), /// ⭐ Circle Avatar Responsive Obx(() { final path = _profileController.imagePath.value; final hasImage = path.isNotEmpty && File(path).existsSync(); return CircleAvatar( radius: 40.r, backgroundColor: Colors.grey.shade300, backgroundImage: hasImage ? FileImage(File(path)) : null, child: !hasImage ? Icon( Icons.person, color: Colors.white, size: 40.sp, ) : null, ); }), ], ), ), SizedBox(height: 20.h), // ⭐ REWARDS SECTION RewardsCard(controller: _rewardsController), SizedBox(height: 20.h), _buildHeader("Your Information"), _buildBox([ _buildInfoTile(Icons.person, "Profile"), Divider(), _buildInfoTile(Icons.location_on, "Saved Address"), Divider(), _buildInfoTile(Icons.card_giftcard, "Rewards"), Divider(), _buildInfoTile(Icons.notifications, "Notification"), ]), SizedBox(height: 20.h), _buildHeader("Support"), _buildBox([ _buildInfoTile(Icons.support_agent, "Help Centre"), Divider(), _buildInfoTile(Icons.local_activity, "Support tickets"), ]), SizedBox(height: 20.h), _buildHeader("Other Information"), _buildBox([ _buildInfoTile(Icons.translate, "Faq"), Divider(), // _buildInfoTile(Icons.sticky_note_2, "Terms & Conditions"), // Divider(), _buildInfoTile( Icons.notifications_active, "Order alert sound", ), ]), SizedBox(height: 55.h), /// ⭐ Logout Button Responsive SizedBox( height: 55.h, width: double.infinity, child: OutlinedButton( onPressed: () => _showLogoutDialog(context), style: OutlinedButton.styleFrom( backgroundColor: ColorConstants.secondaryColor, side: BorderSide(color: Colors.black, width: 0.2.w), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.r), ), ), child: Text( "Logout", style: TextStyle( fontSize: 20.sp, fontWeight: FontWeight.bold, color: Colors.black, fontFamily: FontConstants.fontFamily, ), ), ), ), SizedBox(height: 15.h), Center( child: Text( "App Version 1.2.19", style: TextStyle( fontSize: 16.sp, color: Colors.grey.shade600, fontFamily: FontConstants.fontFamily, ), ), ), ], ), ), ), ), ), ); } Widget _buildHeader(String title) { return Padding( padding: EdgeInsets.all(8.r), child: Text( title, style: TextStyle( fontSize: 22.sp, fontWeight: FontWeight.bold, fontFamily: FontConstants.fontFamily, color: Colors.black, ), ), ); } Widget _buildBox(List children) { return Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12.r), ), child: Column(children: children), ); } Widget _buildInfoTile(IconData icon, String title) { return ListTile( leading: Icon(icon, size: 26.sp), title: Text( title, style: TextStyle( fontSize: 19.sp, fontWeight: FontWeight.w500, fontFamily: FontConstants.fontFamily, ), ), trailing: Icon(Icons.arrow_forward_ios, size: 22.sp), onTap: () => _handleNavigation(title), ); } void _handleNavigation(String title) { switch (title) { case "Profile": Get.to(() => Profile()); break; case "Saved Address": Get.to(() => const SavedAddressPage()); break; case "Notification": Get.to(() => const NotificationsPage()); break; case "Help Centre": Get.to(() => HelpCenter()); break; case "Support tickets": Get.to(() => SupportTicket()); break; case "Rewards": Get.to(() => const RiderRewardsPage()); break; case "Faq": Get.to(() => const FaqPage()); break; // case "Terms & Conditions": // Get.to(() => const TermsCondition()); // break; case "Order alert sound": Get.to(() => const OrderAlertSoundPage()); break; default: debugPrint("Tapped on $title — no page linked yet."); } } } void _showLogoutDialog(BuildContext context) { showDialog( context: context, barrierDismissible: true, builder: (BuildContext context) { return Center( child: FittedBox( child: AlertDialog( backgroundColor: ColorConstants.secondaryColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20.r), ), title: Text( "Logout", style: TextStyle( fontSize: 22.sp, fontWeight: FontWeight.bold, fontFamily: FontConstants.fontFamily, ), ), content: Text( "Are you sure you want to logout?", style: TextStyle( fontSize: 19.sp, fontFamily: FontConstants.fontFamily, ), ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: Text( "No", style: TextStyle( fontSize: 19.sp, color: Colors.grey, fontFamily: FontConstants.fontFamily, ), ), ), ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: const Color.fromARGB(255, 153, 121, 167), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.r), ), ), onPressed: () async { final prefs = await SharedPreferences.getInstance(); final userId = prefs.getInt('userid') ?? prefs.getInt('userId') ?? 0; if (userId != 0) { await prefs.remove('skipped_orders_cache_$userId'); } NearleMqttService().disconnect(); prefs.setBool('logged_out', true); Get.offAll(() => const SignIn()); }, child: Text( "Yes", style: TextStyle( fontSize: 19.sp, color: Colors.black, fontFamily: FontConstants.fontFamily, ), ), ), ], ), ), ); }, ); }