import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import '../../core/controllers/theme_controller.dart'; import '../../core/services/auth_service.dart'; import '../../core/services/api_service.dart'; import '../../core/utils/snackbar_util.dart'; class SettingsPage extends StatelessWidget { const SettingsPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Settings'), ), body: ListView( padding: EdgeInsets.all(16.w), children: [ // Theme Settings Section _buildSectionHeader('Appearance'), _buildThemeSettings(), SizedBox(height: 24.h), // Account Section _buildSectionHeader('Account'), _buildAccountSettings(), SizedBox(height: 24.h), // Payment Settings Section (Manager Only) Obx(() { final user = AuthService.to.currentUser.value; if (user?.role == 'manager') { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildSectionHeader('Payment Settings'), _buildPaymentSettings(), SizedBox(height: 24.h), ], ); } return const SizedBox.shrink(); }), // Notifications Section _buildSectionHeader('Notifications'), _buildNotificationSettings(), SizedBox(height: 24.h), // About Section _buildSectionHeader('About'), _buildAboutSettings(), SizedBox(height: 32.h), // Logout Button _buildLogoutButton(context), ], ), ); } Widget _buildSectionHeader(String title) { return Padding( padding: EdgeInsets.only(left: 8.w, bottom: 12.h), child: Text( title, style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w600, color: Colors.grey.shade600, letterSpacing: 0.5, ), ), ); } Widget _buildThemeSettings() { return Card( child: Column( children: [ // Theme Mode Selector Obx(() { return ListTile( leading: Container( padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: Colors.blue.shade50, borderRadius: BorderRadius.circular(12.r), ), child: Icon( ThemeController.to.getThemeIcon(), color: Colors.blue.shade600, size: 24.w, ), ), title: Text( 'Theme', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), subtitle: Text( ThemeController.to.getThemeModeString(), style: TextStyle(fontSize: 14.sp), ), trailing: Icon(Icons.arrow_forward_ios_rounded, size: 16.w), onTap: () => _showThemeDialog(), ); }), Divider(height: 1.h, indent: 72.w), // Quick Theme Toggle Obx(() { return SwitchListTile( secondary: Container( padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: Colors.orange.shade50, borderRadius: BorderRadius.circular(12.r), ), child: Icon( Icons.brightness_6_rounded, color: Colors.orange.shade600, size: 24.w, ), ), title: Text( 'Dark Mode', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), subtitle: Text( 'Override system settings', style: TextStyle(fontSize: 14.sp), ), value: ThemeController.to.isDarkMode, onChanged: (value) { ThemeController.to.toggleTheme(); }, activeColor: Colors.green.shade600, ); }), ], ), ); } Widget _buildAccountSettings() { return Card( child: Column( children: [ // Profile Obx(() { final user = AuthService.to.currentUser.value; return ListTile( leading: Container( padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: Colors.green.shade50, borderRadius: BorderRadius.circular(12.r), ), child: Icon( Icons.person_rounded, color: Colors.green.shade600, size: 24.w, ), ), title: Text( user?.fullName ?? 'User', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), subtitle: Text( user?.mobileNumber ?? '', style: TextStyle(fontSize: 14.sp), ), trailing: Icon(Icons.arrow_forward_ios_rounded, size: 16.w), onTap: () { SnackbarUtil.showInfo('Profile page coming soon'); }, ); }), Divider(height: 1.h, indent: 72.w), // Change Password ListTile( leading: Container( padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: Colors.purple.shade50, borderRadius: BorderRadius.circular(12.r), ), child: Icon( Icons.lock_rounded, color: Colors.purple.shade600, size: 24.w, ), ), title: Text( 'Change Password', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), subtitle: Text( 'Update your password', style: TextStyle(fontSize: 14.sp), ), trailing: Icon(Icons.arrow_forward_ios_rounded, size: 16.w), onTap: () { SnackbarUtil.showInfo('Change password feature coming soon'); }, ), ], ), ); } Widget _buildNotificationSettings() { return Card( child: Column( children: [ SwitchListTile( secondary: Container( padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: Colors.red.shade50, borderRadius: BorderRadius.circular(12.r), ), child: Icon( Icons.notifications_rounded, color: Colors.red.shade600, size: 24.w, ), ), title: Text( 'Push Notifications', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), subtitle: Text( 'Receive push notifications', style: TextStyle(fontSize: 14.sp), ), value: true, onChanged: (value) { SnackbarUtil.showInfo('Notification settings coming soon'); }, activeColor: Colors.green.shade600, ), Divider(height: 1.h, indent: 72.w), SwitchListTile( secondary: Container( padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: Colors.orange.shade50, borderRadius: BorderRadius.circular(12.r), ), child: Icon( Icons.payment_rounded, color: Colors.orange.shade600, size: 24.w, ), ), title: Text( 'Payment Reminders', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), subtitle: Text( 'Reminders for upcoming payments', style: TextStyle(fontSize: 14.sp), ), value: true, onChanged: (value) { SnackbarUtil.showInfo('Notification settings coming soon'); }, activeColor: Colors.green.shade600, ), Divider(height: 1.h, indent: 72.w), SwitchListTile( secondary: Container( padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: Colors.blue.shade50, borderRadius: BorderRadius.circular(12.r), ), child: Icon( Icons.casino_rounded, color: Colors.blue.shade600, size: 24.w, ), ), title: Text( 'Draw Notifications', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), subtitle: Text( 'Alerts for lottery draws', style: TextStyle(fontSize: 14.sp), ), value: true, onChanged: (value) { SnackbarUtil.showInfo('Notification settings coming soon'); }, activeColor: Colors.green.shade600, ), ], ), ); } Widget _buildPaymentSettings() { final apiService = ApiService(); return Card( child: Column( children: [ // UPI ID Setting FutureBuilder>( future: apiService.get('/payments/phonepe/settings/upi'), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return ListTile( leading: Container( padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: Colors.purple.shade50, borderRadius: BorderRadius.circular(12.r), ), child: Icon( Icons.account_balance_rounded, color: Colors.purple.shade600, size: 24.w, ), ), title: Text( 'UPI ID', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), subtitle: Text( 'Loading...', style: TextStyle(fontSize: 14.sp), ), ); } final upiId = snapshot.data?['data']?['upi_id'] ?? 'Not configured'; final isConfigured = snapshot.data?['data']?['is_configured'] ?? false; return ListTile( leading: Container( padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: isConfigured ? Colors.purple.shade50 : Colors.orange.shade50, borderRadius: BorderRadius.circular(12.r), ), child: Icon( Icons.account_balance_rounded, color: isConfigured ? Colors.purple.shade600 : Colors.orange.shade600, size: 24.w, ), ), title: Row( children: [ Text( 'UPI ID', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), if (isConfigured) ...[ SizedBox(width: 8.w), Container( padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 2.h), decoration: BoxDecoration( color: Colors.green.shade100, borderRadius: BorderRadius.circular(12.r), ), child: Text( 'Active', style: TextStyle( fontSize: 10.sp, fontWeight: FontWeight.w600, color: Colors.green.shade700, ), ), ), ], ], ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 4.h), SelectableText( upiId, style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w600, color: isConfigured ? Colors.purple.shade700 : Colors.orange.shade700, fontFamily: 'monospace', ), ), if (!isConfigured) ...[ SizedBox(height: 4.h), Text( 'Configure in backend/.env', style: TextStyle( fontSize: 12.sp, color: Colors.orange.shade600, fontStyle: FontStyle.italic, ), ), ], ], ), trailing: isConfigured ? IconButton( onPressed: () { Clipboard.setData(ClipboardData(text: upiId)); SnackbarUtil.showSuccess('UPI ID copied to clipboard'); }, icon: Icon( Icons.copy_rounded, size: 20.w, color: Colors.purple.shade600, ), tooltip: 'Copy UPI ID', ) : Icon( Icons.warning_rounded, size: 20.w, color: Colors.orange.shade600, ), onTap: () => _showUPIInfoDialog(upiId, isConfigured), ); }, ), Divider(height: 1.h, indent: 72.w), // Payment Statistics ListTile( leading: Container( padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: Colors.blue.shade50, borderRadius: BorderRadius.circular(12.r), ), child: Icon( Icons.payment_rounded, color: Colors.blue.shade600, size: 24.w, ), ), title: Text( 'Payment Statistics', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), subtitle: Text( 'View payment insights', style: TextStyle(fontSize: 14.sp), ), trailing: Icon(Icons.arrow_forward_ios_rounded, size: 16.w), onTap: () { SnackbarUtil.showInfo('Payment statistics coming soon'); }, ), Divider(height: 1.h, indent: 72.w), // Transaction Fees ListTile( leading: Container( padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: Colors.green.shade50, borderRadius: BorderRadius.circular(12.r), ), child: Icon( Icons.currency_rupee_rounded, color: Colors.green.shade600, size: 24.w, ), ), title: Text( 'Transaction Fees', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), subtitle: Text( '0% fees • Save lakhs per year!', style: TextStyle( fontSize: 14.sp, color: Colors.green.shade700, fontWeight: FontWeight.w600, ), ), trailing: Container( padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h), decoration: BoxDecoration( color: Colors.green.shade100, borderRadius: BorderRadius.circular(8.r), ), child: Text( 'FREE', style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w800, color: Colors.green.shade700, ), ), ), ), ], ), ); } void _showUPIInfoDialog(String upiId, bool isConfigured) { Get.dialog( AlertDialog( title: Row( children: [ Icon( Icons.account_balance_rounded, color: Colors.purple.shade600, size: 24.w, ), SizedBox(width: 12.w), const Text('UPI Payment Settings'), ], ), content: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ // Current UPI ID Text( 'Current UPI ID', style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w600, color: Colors.grey.shade700, ), ), SizedBox(height: 8.h), Container( width: double.infinity, padding: EdgeInsets.all(12.w), decoration: BoxDecoration( color: isConfigured ? Colors.purple.shade50 : Colors.orange.shade50, borderRadius: BorderRadius.circular(8.r), border: Border.all( color: isConfigured ? Colors.purple.shade200 : Colors.orange.shade200, ), ), child: Row( children: [ Expanded( child: SelectableText( upiId, style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w700, color: isConfigured ? Colors.purple.shade700 : Colors.orange.shade700, fontFamily: 'monospace', ), ), ), if (isConfigured) IconButton( onPressed: () { Clipboard.setData(ClipboardData(text: upiId)); SnackbarUtil.showSuccess('Copied!'); }, icon: Icon( Icons.copy_rounded, size: 20.w, color: Colors.purple.shade600, ), ), ], ), ), if (!isConfigured) ...[ SizedBox(height: 16.h), Container( padding: EdgeInsets.all(12.w), decoration: BoxDecoration( color: Colors.orange.shade50, borderRadius: BorderRadius.circular(8.r), ), child: Row( children: [ Icon( Icons.warning_rounded, color: Colors.orange.shade700, size: 20.w, ), SizedBox(width: 8.w), Expanded( child: Text( 'UPI ID not configured. Update backend/.env file.', style: TextStyle( fontSize: 12.sp, color: Colors.orange.shade700, ), ), ), ], ), ), ], SizedBox(height: 16.h), Divider(), SizedBox(height: 16.h), // How to Update Text( 'How to Update UPI ID', style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w600, color: Colors.grey.shade700, ), ), SizedBox(height: 12.h), _buildInfoStep('1', 'Open backend/.env file'), _buildInfoStep('2', 'Update PHONEPE_UPI_ID=your_upi@paytm'), _buildInfoStep('3', 'Restart backend server'), _buildInfoStep('4', 'Refresh this screen'), SizedBox(height: 16.h), Container( padding: EdgeInsets.all(12.w), decoration: BoxDecoration( color: Colors.blue.shade50, borderRadius: BorderRadius.circular(8.r), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.lightbulb_rounded, color: Colors.blue.shade700, size: 18.w, ), SizedBox(width: 8.w), Text( 'Pro Tip', style: TextStyle( fontSize: 13.sp, fontWeight: FontWeight.w600, color: Colors.blue.shade900, ), ), ], ), SizedBox(height: 8.h), Text( 'Members can pay using ANY UPI app (PhonePe, GPay, Paytm) directly to your personal UPI ID with 0% transaction fees!', style: TextStyle( fontSize: 12.sp, color: Colors.blue.shade800, height: 1.4, ), ), ], ), ), ], ), ), actions: [ TextButton( onPressed: () => Get.back(), child: const Text('Close'), ), ], ), ); } Widget _buildInfoStep(String number, String text) { return Padding( padding: EdgeInsets.only(bottom: 8.h), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 24.w, height: 24.w, decoration: BoxDecoration( color: Colors.purple.shade100, shape: BoxShape.circle, ), child: Center( child: Text( number, style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w700, color: Colors.purple.shade700, ), ), ), ), SizedBox(width: 12.w), Expanded( child: Padding( padding: EdgeInsets.only(top: 2.h), child: Text( text, style: TextStyle( fontSize: 13.sp, color: Colors.grey.shade700, height: 1.4, ), ), ), ), ], ), ); } Widget _buildAboutSettings() { return Card( child: Column( children: [ ListTile( leading: Container( padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: Colors.blue.shade50, borderRadius: BorderRadius.circular(12.r), ), child: Icon( Icons.info_rounded, color: Colors.blue.shade600, size: 24.w, ), ), title: Text( 'App Version', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), subtitle: Text( '1.0.0', style: TextStyle(fontSize: 14.sp), ), ), Divider(height: 1.h, indent: 72.w), ListTile( leading: Container( padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: Colors.green.shade50, borderRadius: BorderRadius.circular(12.r), ), child: Icon( Icons.privacy_tip_rounded, color: Colors.green.shade600, size: 24.w, ), ), title: Text( 'Privacy Policy', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), trailing: Icon(Icons.arrow_forward_ios_rounded, size: 16.w), onTap: () { SnackbarUtil.showInfo('Privacy policy page coming soon'); }, ), Divider(height: 1.h, indent: 72.w), ListTile( leading: Container( padding: EdgeInsets.all(10.w), decoration: BoxDecoration( color: Colors.purple.shade50, borderRadius: BorderRadius.circular(12.r), ), child: Icon( Icons.description_rounded, color: Colors.purple.shade600, size: 24.w, ), ), title: Text( 'Terms of Service', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), trailing: Icon(Icons.arrow_forward_ios_rounded, size: 16.w), onTap: () { SnackbarUtil.showInfo('Terms of service page coming soon'); }, ), ], ), ); } Widget _buildLogoutButton(BuildContext context) { return SizedBox( width: double.infinity, height: 52.h, child: ElevatedButton.icon( onPressed: () => _showLogoutDialog(context), icon: Icon(Icons.logout_rounded, size: 20.w), label: Text( 'Logout', style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), ), style: ElevatedButton.styleFrom( backgroundColor: Colors.red.shade600, foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.r), ), ), ), ); } void _showThemeDialog() { Get.dialog( AlertDialog( title: const Text('Choose Theme'), content: Column( mainAxisSize: MainAxisSize.min, children: [ RadioListTile( title: const Text('Light'), value: ThemeMode.light, groupValue: ThemeController.to.themeMode, onChanged: (value) { ThemeController.to.setLightTheme(); Get.back(); }, activeColor: Colors.green.shade600, ), RadioListTile( title: const Text('Dark'), value: ThemeMode.dark, groupValue: ThemeController.to.themeMode, onChanged: (value) { ThemeController.to.setDarkTheme(); Get.back(); }, activeColor: Colors.green.shade600, ), RadioListTile( title: const Text('System Default'), value: ThemeMode.system, groupValue: ThemeController.to.themeMode, onChanged: (value) { ThemeController.to.setSystemTheme(); Get.back(); }, activeColor: Colors.green.shade600, ), ], ), ), ); } void _showLogoutDialog(BuildContext context) { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Logout'), content: const Text('Are you sure you want to logout?'), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), child: const Text('Cancel'), ), ElevatedButton( onPressed: () { Navigator.of(context).pop(); AuthService.to.logout(); SnackbarUtil.showSuccess('Logged out successfully'); }, style: ElevatedButton.styleFrom( backgroundColor: Colors.red, foregroundColor: Colors.white, ), child: const Text('Logout'), ), ], ), ); } }