import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../controllers/auth_controller.dart'; import '../../../theme/app_colors.dart'; class RegistrationView extends GetView { const RegistrationView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.background, body: SafeArea( child: Stack( children: [ // Background gradient Positioned( top: -100, right: -100, child: Container( width: 300, height: 300, decoration: BoxDecoration( shape: BoxShape.circle, gradient: RadialGradient( colors: [ AppColors.primaryLight.withOpacity(0.2), AppColors.background.withOpacity(0), ], stops: const [0.0, 1.0], ), ), ), ), Positioned( bottom: -80, left: -80, child: Container( width: 200, height: 200, decoration: BoxDecoration( shape: BoxShape.circle, gradient: RadialGradient( colors: [ AppColors.accent.withOpacity(0.15), AppColors.background.withOpacity(0), ], stops: const [0.0, 1.0], ), ), ), ), // Content SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(24.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _buildBackButton(), const SizedBox(height: 20), _buildHeader(), const SizedBox(height: 24), _buildRegistrationForm(), const SizedBox(height: 32), _buildRegisterButton(), const SizedBox(height: 24), _buildImportantInfo(), const SizedBox(height: 24), _buildLoginLink(), ], ), ), ), ], ), ), ); } Widget _buildBackButton() { return Align( alignment: Alignment.topLeft, child: InkWell( onTap: () => Get.back(), borderRadius: BorderRadius.circular(50), child: Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: AppColors.surface, shape: BoxShape.circle, boxShadow: [ BoxShadow( color: AppColors.shadow, blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: const Icon( Icons.arrow_back, size: 20, color: AppColors.primary, ), ), ), ); } Widget _buildHeader() { return Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Hero( tag: 'logo', child: Container( width: 80, height: 80, decoration: BoxDecoration( color: AppColors.primarySoft, borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: AppColors.primary.withOpacity(0.2), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Icon( Icons.apartment_rounded, size: 40, color: AppColors.primary, ), ), ), const SizedBox(height: 24), Text( 'Daftar Akun', style: TextStyle( fontSize: 28, fontWeight: FontWeight.bold, color: AppColors.textPrimary, ), ), const SizedBox(height: 10), Text( 'Lengkapi data berikut untuk mendaftar', style: TextStyle(fontSize: 16, color: AppColors.textSecondary), textAlign: TextAlign.center, ), ], ); } Widget _buildImportantInfo() { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppColors.warningLight, borderRadius: BorderRadius.circular(16), border: Border.all(color: AppColors.warning.withOpacity(0.3)), ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: AppColors.warning.withOpacity(0.2), shape: BoxShape.circle, ), child: Icon(Icons.info_outline, size: 20, color: AppColors.warning), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Informasi Penting', style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: AppColors.warning, ), ), const SizedBox(height: 4), Text( 'Pendaftaran hanya dapat dilakukan oleh warga dan mitra yang sudah terverivikasi. Silahkan hubungi petugas atau kunjungi kantor untuk informasi lebih lanjut.', style: TextStyle( fontSize: 13, color: AppColors.textPrimary, height: 1.4, ), ), ], ), ), ], ), ); } Widget _buildRegistrationForm() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Email Input _buildInputLabel('Email'), const SizedBox(height: 8), _buildEmailField(), const SizedBox(height: 20), // Password Input _buildInputLabel('Password'), const SizedBox(height: 8), _buildPasswordField(), const SizedBox(height: 20), // NIK Input _buildInputLabel('NIK'), const SizedBox(height: 8), _buildNikField(), const SizedBox(height: 20), // Phone Number Input _buildInputLabel('No. Hp'), const SizedBox(height: 8), _buildPhoneField(), const SizedBox(height: 20), // Role Selection Dropdown Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Daftar Sebagai', style: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: Colors.black87, ), ), const SizedBox(height: 8), Container( decoration: BoxDecoration( color: Colors.grey[100], borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey[300]!, width: 1), ), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Obx( () => DropdownButtonHideUnderline( child: DropdownButton( isExpanded: true, value: controller.selectedRole.value, hint: const Text('Pilih Peran'), items: [ DropdownMenuItem( value: 'WARGA', child: const Text('Warga'), ), DropdownMenuItem( value: 'PETUGAS_MITRA', child: const Text('Mitra'), ), ], onChanged: (value) { controller.setRole(value); }, icon: const Icon(Icons.arrow_drop_down), style: const TextStyle( color: Colors.black87, fontSize: 14, ), ), ), ), ), ), ], ), const SizedBox(height: 20), // Error message Obx( () => controller.errorMessage.value.isNotEmpty ? Container( margin: const EdgeInsets.only(top: 8), 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( fontSize: 16, fontWeight: FontWeight.w600, color: AppColors.textPrimary, ), ); } Widget _buildEmailField() { return Container( decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: AppColors.shadow, blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: TextField( onChanged: (value) => controller.email.value = value, keyboardType: TextInputType.emailAddress, style: TextStyle(fontSize: 16, color: AppColors.textPrimary), decoration: InputDecoration( hintText: 'Masukkan email anda', hintStyle: TextStyle(color: AppColors.textLight), prefixIcon: Icon(Icons.email_outlined, color: AppColors.primary), border: InputBorder.none, contentPadding: const EdgeInsets.symmetric(vertical: 16), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(16), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(16), borderSide: BorderSide(color: AppColors.primary, width: 1.5), ), ), ), ); } Widget _buildPasswordField() { return Obx( () => Container( decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: AppColors.shadow, blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: TextField( onChanged: (value) => controller.password.value = value, obscureText: !controller.isPasswordVisible.value, style: TextStyle(fontSize: 16, color: AppColors.textPrimary), decoration: InputDecoration( hintText: 'Masukkan password anda', hintStyle: TextStyle(color: AppColors.textLight), prefixIcon: Icon(Icons.lock_outlined, color: AppColors.primary), suffixIcon: IconButton( icon: Icon( controller.isPasswordVisible.value ? Icons.visibility : Icons.visibility_off, color: AppColors.iconGrey, ), onPressed: controller.togglePasswordVisibility, ), border: InputBorder.none, contentPadding: const EdgeInsets.symmetric(vertical: 16), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(16), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(16), borderSide: BorderSide(color: AppColors.primary, width: 1.5), ), ), ), ), ); } Widget _buildNikField() { return Container( decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: AppColors.shadow, blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: TextField( onChanged: (value) => controller.nik.value = value, keyboardType: TextInputType.number, style: TextStyle(fontSize: 16, color: AppColors.textPrimary), decoration: InputDecoration( hintText: 'Masukkan NIK anda', hintStyle: TextStyle(color: AppColors.textLight), prefixIcon: Icon( Icons.credit_card_outlined, color: AppColors.primary, ), border: InputBorder.none, contentPadding: const EdgeInsets.symmetric(vertical: 16), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(16), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(16), borderSide: BorderSide(color: AppColors.primary, width: 1.5), ), ), ), ); } Widget _buildPhoneField() { return Container( decoration: BoxDecoration( color: AppColors.surface, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: AppColors.shadow, blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: TextField( onChanged: (value) => controller.phoneNumber.value = value, keyboardType: TextInputType.phone, style: TextStyle(fontSize: 16, color: AppColors.textPrimary), decoration: InputDecoration( hintText: 'Masukkan nomor HP anda', hintStyle: TextStyle(color: AppColors.textLight), prefixIcon: Icon(Icons.phone_outlined, color: AppColors.primary), border: InputBorder.none, contentPadding: const EdgeInsets.symmetric(vertical: 16), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(16), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(16), borderSide: BorderSide(color: AppColors.primary, width: 1.5), ), ), ), ); } Widget _buildRegisterButton() { return Obx( () => ElevatedButton( onPressed: controller.isLoading.value ? null : controller.registerUser, style: ElevatedButton.styleFrom( backgroundColor: AppColors.primary, foregroundColor: AppColors.buttonText, padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), elevation: 0, disabledBackgroundColor: AppColors.primary.withOpacity(0.6), ), child: controller.isLoading.value ? const SizedBox( height: 24, width: 24, child: CircularProgressIndicator( color: Colors.white, strokeWidth: 2, ), ) : const Text( 'Daftar', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), ), ); } Widget _buildLoginLink() { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Sudah punya akun? ', style: TextStyle(color: AppColors.textSecondary, fontSize: 14), ), GestureDetector( onTap: () { Get.back(); // Back to login page }, child: Text( 'Masuk', style: TextStyle( color: AppColors.primary, fontWeight: FontWeight.bold, fontSize: 14, ), ), ), ], ); } }