import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../controllers/auth_controller.dart'; import '../../../theme/app_colors.dart'; import 'package:intl/intl.dart'; class RegistrationView extends GetView { const RegistrationView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { // Reset all registration fields when leaving the page controller.resetRegistrationFields(); return true; }, child: Scaffold( body: Stack( children: [ // Background gradient - same as login page Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [ AppColors.primaryLight.withOpacity(0.1), AppColors.background, AppColors.accentLight.withOpacity(0.1), ], ), ), ), // Pattern overlay - same as login page Opacity( opacity: 0.03, child: Container( decoration: BoxDecoration( color: Colors.blue[50], // Temporary solid color ), ), ), // Accent circles - same as login page Positioned( top: -40, right: -20, child: Container( width: 150, height: 150, decoration: BoxDecoration( shape: BoxShape.circle, gradient: RadialGradient( colors: [ AppColors.primary.withOpacity(0.2), Colors.transparent, ], ), ), ), ), Positioned( bottom: -50, left: -30, child: Container( width: 180, height: 180, decoration: BoxDecoration( shape: BoxShape.circle, gradient: RadialGradient( colors: [ AppColors.accent.withOpacity(0.2), Colors.transparent, ], ), ), ), ), // Main content SafeArea( child: SingleChildScrollView( physics: const BouncingScrollPhysics(), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 24.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const SizedBox(height: 20), _buildBackButton(), const SizedBox(height: 20), _buildHeader(), const SizedBox(height: 30), _buildRegistrationCard(), _buildLoginLink(), _buildCheckStatusLink(), const SizedBox(height: 30), ], ), ), ), ), ], ), ), ); } Widget _buildBackButton() { return Align( alignment: Alignment.topLeft, child: InkWell( onTap: () { // Reset all registration fields when going back controller.resetRegistrationFields(); Get.back(); }, borderRadius: BorderRadius.circular(50), child: Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: Colors.white, shape: BoxShape.circle, boxShadow: [ BoxShadow( color: AppColors.shadow, blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: Icon(Icons.arrow_back, size: 20, color: AppColors.primary), ), ), ); } Widget _buildHeader() { return Center( child: Hero( tag: 'logo', child: Image.asset( 'assets/images/logo.png', width: 150, height: 150, errorBuilder: (context, error, stackTrace) { return Icon( Icons.apartment_rounded, size: 120, color: AppColors.primary, ); }, ), ), ); } Widget _buildRegistrationCard() { return Card( elevation: 4, shadowColor: AppColors.shadow, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)), child: Padding( padding: const EdgeInsets.all(28.0), child: Form( key: controller.formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Welcome text Text( 'Daftar Akun', style: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: AppColors.textPrimary, ), ), const SizedBox(height: 8), Text( 'Lengkapi data berikut untuk mendaftar', style: TextStyle( fontSize: 14, color: AppColors.textSecondary, fontWeight: FontWeight.w400, ), ), const SizedBox(height: 24), // Account Credentials Section Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppColors.primaryLight.withOpacity(0.05), borderRadius: BorderRadius.circular(16), border: Border.all( color: AppColors.primaryLight.withOpacity(0.2), width: 1, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.account_circle_outlined, color: AppColors.primary, size: 20, ), const SizedBox(width: 8), Text( 'Informasi Akun', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: AppColors.primary, ), ), ], ), const SizedBox(height: 16), // Email field _buildInputLabel('Email'), const SizedBox(height: 8), _buildTextField( hintText: 'Masukkan email anda', prefixIcon: Icons.email_outlined, keyboardType: TextInputType.emailAddress, onChanged: (value) => controller.email.value = value, validator: controller.validateEmail, ), const SizedBox(height: 16), // Password field _buildInputLabel('Password'), const SizedBox(height: 8), Obx( () => _buildTextField( hintText: 'Masukkan password anda', prefixIcon: Icons.lock_outline, obscureText: !controller.isPasswordVisible.value, onChanged: (value) => controller.password.value = value, validator: controller.validatePassword, suffixIcon: IconButton( icon: Icon( controller.isPasswordVisible.value ? Icons.visibility : Icons.visibility_off, color: AppColors.iconGrey, ), onPressed: controller.togglePasswordVisibility, ), ), ), const SizedBox(height: 16), // Confirm Password field _buildInputLabel('Konfirmasi Password'), const SizedBox(height: 8), Obx( () => _buildTextField( controller: controller.confirmPasswordController, hintText: 'Masukkan ulang password anda', prefixIcon: Icons.lock_outline, obscureText: !controller.isConfirmPasswordVisible.value, validator: controller.validateConfirmPassword, suffixIcon: IconButton( icon: Icon( controller.isConfirmPasswordVisible.value ? Icons.visibility : Icons.visibility_off, color: AppColors.iconGrey, ), onPressed: controller.toggleConfirmPasswordVisibility, ), ), ), ], ), ), const SizedBox(height: 24), // Personal Data Section Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppColors.accentLight.withOpacity(0.05), borderRadius: BorderRadius.circular(16), border: Border.all( color: AppColors.accentLight.withOpacity(0.2), width: 1, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.person_outline, color: AppColors.accent, size: 20, ), const SizedBox(width: 8), Text( 'Data Diri', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: AppColors.accent, ), ), ], ), const SizedBox(height: 16), // Name field _buildInputLabel('Nama Lengkap'), const SizedBox(height: 8), _buildTextField( controller: controller.nameController, hintText: 'Masukkan nama lengkap anda', prefixIcon: Icons.person_outline, validator: controller.validateName, ), const SizedBox(height: 16), // NIK field _buildInputLabel('NIK'), const SizedBox(height: 8), _buildTextField( hintText: 'Masukkan NIK anda', prefixIcon: Icons.credit_card_outlined, keyboardType: TextInputType.number, onChanged: (value) => controller.nik.value = value, validator: (value) { if (value == null || value.isEmpty) { return 'NIK tidak boleh kosong'; } if (value.length != 16) { return 'NIK harus 16 digit'; } if (!RegExp(r'^[0-9]+$').hasMatch(value)) { return 'NIK hanya boleh berisi angka'; } return null; }, ), const SizedBox(height: 16), // Tanggal Lahir field _buildInputLabel('Tanggal Lahir'), const SizedBox(height: 8), Builder(builder: (context) => _buildDateField(context)), const SizedBox(height: 16), // Phone field _buildInputLabel('No HP'), const SizedBox(height: 8), _buildTextField( hintText: 'Masukkan nomor HP anda', prefixIcon: Icons.phone_outlined, keyboardType: TextInputType.phone, onChanged: (value) => controller.phoneNumber.value = value, validator: (value) { if (value == null || value.isEmpty) { return 'No HP tidak boleh kosong'; } if (!value.startsWith('08')) { return 'Nomor HP harus diawali dengan 08'; } if (value.length < 10 || value.length > 13) { return 'Nomor HP harus antara 10-13 digit'; } if (!RegExp(r'^[0-9]+$').hasMatch(value)) { return 'Nomor HP hanya boleh berisi angka'; } return null; }, ), const SizedBox(height: 16), // RT/RW field _buildInputLabel('RT/RW'), const SizedBox(height: 8), _buildTextField( hintText: 'Contoh: 001/002', prefixIcon: Icons.home_work_outlined, onChanged: (value) => controller.rtRw.value = value, validator: (value) { if (value == null || value.isEmpty) { return 'RT/RW tidak boleh kosong'; } if (!RegExp(r'^\d{1,3}\/\d{1,3}$').hasMatch(value)) { return 'Format RT/RW tidak valid (contoh: 001/002)'; } return null; }, ), const SizedBox(height: 16), // Kelurahan/Desa field _buildInputLabel('Kelurahan/Desa'), const SizedBox(height: 8), _buildTextField( hintText: 'Masukkan kelurahan/desa anda', prefixIcon: Icons.location_city_outlined, onChanged: (value) => controller.kelurahan.value = value, validator: (value) { if (value == null || value.isEmpty) { return 'Kelurahan/Desa tidak boleh kosong'; } if (value.length < 3) { return 'Kelurahan/Desa minimal 3 karakter'; } return null; }, ), const SizedBox(height: 16), // Kecamatan field _buildInputLabel('Kecamatan'), const SizedBox(height: 8), _buildTextField( hintText: 'Masukkan kecamatan anda', prefixIcon: Icons.location_on_outlined, onChanged: (value) => controller.kecamatan.value = value, validator: (value) { if (value == null || value.isEmpty) { return 'Kecamatan tidak boleh kosong'; } if (value.length < 3) { return 'Kecamatan minimal 3 karakter'; } return null; }, ), const SizedBox(height: 16), // Address field _buildInputLabel('Alamat Lengkap'), const SizedBox(height: 8), _buildTextField( hintText: 'Masukkan alamat lengkap anda', prefixIcon: Icons.home_outlined, onChanged: (value) => controller.alamatLengkap.value = value, validator: (value) { if (value == null || value.isEmpty) { return 'Alamat lengkap tidak boleh kosong'; } if (value.length < 5) { return 'Alamat terlalu pendek, minimal 5 karakter'; } return null; }, ), ], ), ), const SizedBox(height: 24), // Important info _buildImportantInfo(), const SizedBox(height: 24), // Register button Obx( () => SizedBox( width: double.infinity, height: 56, child: ElevatedButton( onPressed: controller.isLoading.value ? null : controller.registerUser, style: ElevatedButton.styleFrom( backgroundColor: AppColors.primary, foregroundColor: AppColors.buttonText, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), elevation: controller.isLoading.value ? 0 : 2, shadowColor: AppColors.primary.withOpacity(0.4), ), child: controller.isLoading.value ? const SizedBox( height: 24, width: 24, child: CircularProgressIndicator( color: Colors.white, strokeWidth: 2, ), ) : Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Daftar', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, letterSpacing: 0.5, ), ), const SizedBox(width: 8), const Icon(Icons.arrow_forward, size: 18), ], ), ), ), ), // Error message Obx( () => controller.errorMessage.value.isNotEmpty ? Container( margin: const EdgeInsets.only(top: 16), padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: AppColors.errorLight, borderRadius: BorderRadius.circular(12), ), child: Row( children: [ Icon( Icons.error_outline, color: AppColors.error, size: 20, ), const SizedBox(width: 8), Expanded( child: Text( controller.errorMessage.value, style: TextStyle( color: AppColors.error, fontSize: 13, ), ), ), ], ), ) : const SizedBox.shrink(), ), ], ), ), ), ); } Widget _buildInputLabel(String label) { return Text( label, style: TextStyle( fontWeight: FontWeight.w600, color: AppColors.textPrimary, fontSize: 15, ), ); } Widget _buildTextField({ TextEditingController? controller, required String hintText, required IconData prefixIcon, TextInputType keyboardType = TextInputType.text, bool obscureText = false, Widget? suffixIcon, Function(String)? onChanged, String? Function(String?)? validator, }) { return TextFormField( controller: controller, keyboardType: keyboardType, obscureText: obscureText, onChanged: onChanged, validator: validator, style: TextStyle(fontSize: 16, color: AppColors.textPrimary), decoration: InputDecoration( hintText: hintText, hintStyle: TextStyle(color: AppColors.textLight), prefixIcon: Icon(prefixIcon, color: AppColors.iconGrey, size: 22), suffixIcon: suffixIcon, filled: true, fillColor: AppColors.inputBackground, contentPadding: const EdgeInsets.symmetric(vertical: 16), border: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide.none, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide(color: AppColors.primary, width: 1.5), ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide(color: AppColors.error, width: 1.5), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide(color: AppColors.error, width: 1.5), ), ), ); } Widget _buildImportantInfo() { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppColors.warningLight, borderRadius: BorderRadius.circular(14), ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon(Icons.info_outline, size: 20, color: AppColors.warning), const SizedBox(width: 12), Expanded( child: Text( 'Setelah melakukan pendaftaran, silahkan simpan kode registrasi untuk cek status pendaftaran', style: TextStyle( fontSize: 13, color: AppColors.textPrimary, height: 1.4, ), ), ), ], ), ); } Widget _buildLoginLink() { return Center( child: Row( mainAxisSize: MainAxisSize.min, children: [ Text( "Sudah punya akun?", style: TextStyle(color: AppColors.textSecondary), ), TextButton( onPressed: () { // Reset all registration fields when going back to login controller.resetRegistrationFields(); Get.back(); }, style: TextButton.styleFrom( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), ), child: Text( 'Masuk', style: TextStyle( fontWeight: FontWeight.bold, color: AppColors.primary, ), ), ), ], ), ); } // Add button to check registration status Widget _buildCheckStatusLink() { return Center( child: Padding( padding: const EdgeInsets.only(top: 8.0), child: TextButton( onPressed: () => _showCheckStatusDialog(Get.context!), style: TextButton.styleFrom( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.search, size: 18, color: AppColors.accent), const SizedBox(width: 8), Text( 'Cek Status Pendaftaran', style: TextStyle( fontWeight: FontWeight.bold, color: AppColors.accent, fontSize: 14, ), ), ], ), ), ), ); } // Show dialog to check registration status void _showCheckStatusDialog(BuildContext context) { final TextEditingController codeController = TextEditingController(); final TextEditingController emailController = TextEditingController(); final authController = Get.find(); showDialog( context: context, builder: (BuildContext context) { return Dialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), child: Padding( padding: const EdgeInsets.all(20), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ // Dialog header Row( children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: AppColors.accent.withOpacity(0.1), shape: BoxShape.circle, ), child: Icon( Icons.search, color: AppColors.accent, size: 20, ), ), const SizedBox(width: 12), Expanded( child: Text( 'Cek Status Pendaftaran', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: AppColors.textPrimary, ), ), ), IconButton( icon: const Icon(Icons.close, size: 20), onPressed: () => Navigator.pop(context), padding: EdgeInsets.zero, constraints: const BoxConstraints(), splashRadius: 24, ), ], ), const SizedBox(height: 16), // Registration code field Text( 'Kode Registrasi', style: TextStyle( fontWeight: FontWeight.w600, color: AppColors.textPrimary, fontSize: 14, ), ), const SizedBox(height: 8), TextField( controller: codeController, decoration: InputDecoration( hintText: 'Masukkan kode registrasi', hintStyle: TextStyle(color: AppColors.textLight), prefixIcon: Icon( Icons.confirmation_number_outlined, color: AppColors.iconGrey, size: 22, ), filled: true, fillColor: AppColors.inputBackground, contentPadding: const EdgeInsets.symmetric(vertical: 16), border: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide.none, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide( color: AppColors.accent, width: 1.5, ), ), ), ), const SizedBox(height: 16), // Email field Text( 'Email', style: TextStyle( fontWeight: FontWeight.w600, color: AppColors.textPrimary, fontSize: 14, ), ), const SizedBox(height: 8), TextField( controller: emailController, keyboardType: TextInputType.emailAddress, decoration: InputDecoration( hintText: 'Masukkan email yang terdaftar', hintStyle: TextStyle(color: AppColors.textLight), prefixIcon: Icon( Icons.email_outlined, color: AppColors.iconGrey, size: 22, ), filled: true, fillColor: AppColors.inputBackground, contentPadding: const EdgeInsets.symmetric(vertical: 16), border: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide.none, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: BorderSide( color: AppColors.accent, width: 1.5, ), ), ), ), const SizedBox(height: 24), // Submit button SizedBox( width: double.infinity, height: 48, child: ElevatedButton( onPressed: () async { // Validasi input if (codeController.text.isEmpty || emailController.text.isEmpty) { Get.snackbar( 'Error', 'Kode registrasi dan Email harus diisi', snackPosition: SnackPosition.TOP, backgroundColor: AppColors.errorLight, colorText: AppColors.error, icon: Icon( Icons.error_outline, color: AppColors.error, ), duration: const Duration(seconds: 3), ); return; } // Simpan nilai input untuk digunakan nanti final String registerId = codeController.text.trim(); final String email = emailController.text.trim(); print( 'Checking registration status for ID: $registerId, Email: $email', ); // Tutup dialog input Navigator.pop(context); // Tampilkan loading indicator Get.dialog( const Center(child: CircularProgressIndicator()), barrierDismissible: false, ); try { // Cek status pendaftaran final result = await authController .checkRegistrationStatus(registerId, email); // Debug log print('Registration status check result: $result'); // Tutup dialog loading Get.back(); // Periksa hasil query if (result != null && result.isNotEmpty) { print('Valid result found, showing status dialog'); // Tambahkan delay kecil untuk memastikan UI diperbarui dengan benar // Ini membantu memastikan dialog status muncul setelah dialog loading ditutup Future.delayed(const Duration(milliseconds: 100), () { _showRegistrationStatusDialog(result); }); } else { print('No result found or empty result'); // Tampilkan pesan error Get.snackbar( 'Tidak Ditemukan', 'Data pendaftaran tidak ditemukan. Pastikan kode registrasi dan email yang dimasukkan benar.', snackPosition: SnackPosition.TOP, backgroundColor: AppColors.errorLight, colorText: AppColors.error, icon: Icon( Icons.error_outline, color: AppColors.error, ), duration: const Duration(seconds: 4), ); } } catch (e) { // Tutup dialog loading jika terjadi error Get.back(); print('Error checking registration status: $e'); // Tampilkan pesan error Get.snackbar( 'Error', 'Terjadi kesalahan saat memeriksa status. Silakan coba lagi nanti.', snackPosition: SnackPosition.TOP, backgroundColor: AppColors.errorLight, colorText: AppColors.error, icon: Icon( Icons.error_outline, color: AppColors.error, ), duration: const Duration(seconds: 4), ); } }, style: ElevatedButton.styleFrom( backgroundColor: AppColors.accent, foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), ), elevation: 0, ), child: const Text( 'Cek Status', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), ), ), ], ), ), ); }, ); } // Show dialog with registration status details void _showRegistrationStatusDialog(Map data) { // Log data yang diterima untuk debugging print('Showing registration status dialog with data: $data'); // Validasi data if (data.isEmpty) { print('Error: Empty data received in _showRegistrationStatusDialog'); Get.snackbar( 'Error', 'Data status pendaftaran tidak valid', snackPosition: SnackPosition.TOP, backgroundColor: AppColors.errorLight, colorText: AppColors.error, duration: const Duration(seconds: 3), ); return; } final String status = data['status'] ?? 'unknown'; final String namaLengkap = data['nama_lengkap'] ?? ''; final String keterangan = data['keterangan'] ?? ''; print('Processing status: $status, nama: $namaLengkap'); // Define status color and message based on status Color statusColor; String statusMessage; IconData statusIcon; switch (status) { case 'pending': statusColor = AppColors.warning; statusMessage = keterangan.isNotEmpty ? keterangan : 'Pendaftaran Anda sedang dalam proses verifikasi oleh petugas. Mohon tunggu konfirmasi lebih lanjut.'; statusIcon = Icons.hourglass_top; break; case 'active': statusColor = AppColors.success; statusMessage = keterangan.isNotEmpty ? keterangan : 'Pendaftaran Anda telah disetujui. Anda dapat login menggunakan email dan password yang telah didaftarkan.'; statusIcon = Icons.check_circle; break; case 'dibatalkan': statusColor = AppColors.error; statusMessage = keterangan.isNotEmpty ? keterangan : 'Maaf, pendaftaran Anda ditolak. Silakan hubungi admin untuk informasi lebih lanjut.'; statusIcon = Icons.cancel; break; case 'suspended': statusColor = AppColors.error; statusMessage = keterangan.isNotEmpty ? keterangan : 'Akun Anda saat ini dinonaktifkan. Silakan hubungi admin untuk informasi lebih lanjut.'; statusIcon = Icons.block; break; default: statusColor = AppColors.textSecondary; statusMessage = keterangan.isNotEmpty ? keterangan : 'Status pendaftaran tidak diketahui. Silakan hubungi admin untuk informasi lebih lanjut.'; statusIcon = Icons.help; } print('Preparing to show dialog with status: $status, color: $statusColor'); // Gunakan Get.dialog sebagai pengganti showDialog untuk menghindari masalah context Get.dialog( Dialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), child: Padding( padding: const EdgeInsets.all(24), child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( width: 80, height: 80, decoration: BoxDecoration( color: statusColor.withOpacity(0.1), shape: BoxShape.circle, ), child: Icon(statusIcon, color: statusColor, size: 40), ), const SizedBox(height: 24), Text( 'Status Pendaftaran', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: AppColors.textPrimary, ), ), const SizedBox(height: 8), Text( namaLengkap, style: TextStyle( fontSize: 16, fontWeight: FontWeight.w500, color: AppColors.textSecondary, ), ), const SizedBox(height: 16), Container( padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 8, ), decoration: BoxDecoration( color: statusColor.withOpacity(0.1), borderRadius: BorderRadius.circular(30), ), child: Text( status.toUpperCase(), style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: statusColor, ), ), ), const SizedBox(height: 24), Text( statusMessage, textAlign: TextAlign.center, style: TextStyle( fontSize: 15, color: AppColors.textSecondary, height: 1.5, ), ), // Tampilkan informasi tambahan jika ada if (data.containsKey('tanggal_update') && data['tanggal_update'] != null) ...[ const SizedBox(height: 16), Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: AppColors.infoLight.withOpacity(0.3), borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.info_outline, size: 16, color: AppColors.info, ), const SizedBox(width: 8), Text( 'Informasi Tambahan', style: TextStyle( fontWeight: FontWeight.bold, fontSize: 14, color: AppColors.info, ), ), ], ), const SizedBox(height: 8), Text( 'Terakhir diperbarui: ${_formatDate(data['tanggal_update'])}', style: TextStyle( fontSize: 13, color: AppColors.textSecondary, ), ), ], ), ), ], const SizedBox(height: 24), SizedBox( width: double.infinity, child: ElevatedButton( onPressed: () => Get.back(), style: ElevatedButton.styleFrom( backgroundColor: statusColor, foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), ), padding: const EdgeInsets.symmetric(vertical: 12), ), child: const Text( 'Tutup', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), ), ), ], ), ), ), barrierDismissible: true, ); print('Dialog setup completed'); } // New method to build date picker field Widget _buildDateField(BuildContext context) { return GestureDetector( onTap: () async { final DateTime? picked = await showDatePicker( context: context, initialDate: DateTime.now().subtract( const Duration(days: 365 * 18), ), // Default to 18 years ago firstDate: DateTime(1940), lastDate: DateTime.now(), builder: (BuildContext context, Widget? child) { return Theme( data: ThemeData.light().copyWith( colorScheme: ColorScheme.light( primary: AppColors.primary, onPrimary: Colors.white, surface: Colors.white, onSurface: AppColors.textPrimary, ), dialogBackgroundColor: Colors.white, ), child: child!, ); }, ); if (picked != null) { controller.tanggalLahir.value = picked; } }, child: Obx(() { final selectedDate = controller.tanggalLahir.value; final displayText = selectedDate != null ? '${selectedDate.day.toString().padLeft(2, '0')}-${selectedDate.month.toString().padLeft(2, '0')}-${selectedDate.year}' : 'Pilih tanggal lahir'; return Container( padding: const EdgeInsets.symmetric(vertical: 16), decoration: BoxDecoration( color: AppColors.inputBackground, borderRadius: BorderRadius.circular(14), ), child: Row( children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 12.0), child: Icon( Icons.calendar_today_outlined, color: AppColors.iconGrey, size: 22, ), ), Text( displayText, style: TextStyle( fontSize: 16, color: selectedDate != null ? AppColors.textPrimary : AppColors.textLight, ), ), ], ), ); }), ); } String _formatDate(dynamic date) { if (date is String) { try { final DateTime parsedDate = DateTime.parse(date); return DateFormat('dd MMM yyyy, HH:mm').format(parsedDate); } catch (e) { return date; } } else if (date is num) { final DateTime parsedDate = DateTime.fromMillisecondsSinceEpoch( date.toInt() * 1000, ); return DateFormat('dd MMM yyyy, HH:mm').format(parsedDate); } else if (date is DateTime) { return DateFormat('dd MMM yyyy, HH:mm').format(date); } else { return "Format tanggal tidak diketahui"; } } }