import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_database/firebase_database.dart'; import '../widgets/fade_in_up.dart'; class RegisterPage extends StatefulWidget { const RegisterPage({super.key}); @override State createState() => _RegisterPageState(); } class _RegisterPageState extends State { final usernameController = TextEditingController(); final emailController = TextEditingController(); final passwordController = TextEditingController(); final confirmPasswordController = TextEditingController(); bool isLoading = false; bool obscurePassword = true; bool obscureConfirm = true; Future registerUser() async { final username = usernameController.text.trim(); final emailText = emailController.text.trim(); final password = passwordController.text.trim(); final confirmPassword = confirmPasswordController.text.trim(); if (username.isEmpty || emailText.isEmpty || password.isEmpty || confirmPassword.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("Semua kolom harus diisi")), ); return; } if (password != confirmPassword) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("Password dan Konfirmasi Password tidak cocok")), ); return; } // Jika user memasukkan username sebagai email (tidak mengandung @) String email = emailText; if (!emailText.contains('@')) { email = "$emailText@safebite.com"; } setState(() => isLoading = true); try { // 1. Create Firebase Auth user final userCredential = await FirebaseAuth.instance.createUserWithEmailAndPassword( email: email, password: password, ); // 2. Update display name await userCredential.user?.updateDisplayName(username); // 3. Save user profile to Realtime Database under users/ final db = FirebaseDatabase.instance.ref(); await db.child("users").child(userCredential.user!.uid).set({ "username": username, "email": email, "createdAt": DateTime.now().millisecondsSinceEpoch, }); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("Pendaftaran berhasil! Silakan login.")), ); Navigator.pushReplacementNamed(context, '/login'); } } on FirebaseAuthException catch (e) { String errorMessage = "Pendaftaran gagal"; if (e.code == 'email-already-in-use') { errorMessage = "Email atau Username sudah terdaftar."; } else if (e.code == 'weak-password') { errorMessage = "Password terlalu lemah (minimal 6 karakter)."; } else if (e.code == 'invalid-email') { errorMessage = "Format email tidak valid."; } else { errorMessage = e.message ?? "Pendaftaran gagal: ${e.code}"; } if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(errorMessage)), ); } } catch (e) { debugPrint("Register Error: $e"); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("Terjadi kesalahan: $e")), ); } } finally { if (mounted) { setState(() => isLoading = false); } } } @override Widget build(BuildContext context) { return Scaffold( body: Container( width: double.infinity, height: double.infinity, decoration: const BoxDecoration( gradient: LinearGradient( colors: [Colors.white, Color(0xFFE3F2FD), Color(0xFF42A5F5), Color(0xFF1565C0)], begin: Alignment.topLeft, end: Alignment.bottomRight, stops: [0.1, 0.4, 0.8, 1.0], ), ), child: SafeArea( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 30), child: SingleChildScrollView( child: Column( children: [ const SizedBox(height: 50), /// ===== LOGO ===== FadeInUp( delay: 200, child: Hero( tag: 'app_logo', child: Image.asset('assets/images/logo_formalin.png', height: 160), ), ), const SizedBox(height: 40), /// ===== INPUT ===== FadeInUp( delay: 300, child: Column( children: [ _buildTextField(usernameController, "Username", Icons.person), const SizedBox(height: 15), _buildTextField(emailController, "Email", Icons.email), const SizedBox(height: 15), _buildTextField( passwordController, "Password", Icons.lock, isPassword: true, isConfirm: false, ), const SizedBox(height: 15), _buildTextField( confirmPasswordController, "Confirm Password", Icons.lock, isPassword: true, isConfirm: true, ), ], ), ), const SizedBox(height: 40), /// ===== BUTTON ===== FadeInUp( delay: 500, child: Container( width: double.infinity, height: 55, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(30), boxShadow: [ BoxShadow( color: const Color(0xFF1565C0).withOpacity(0.3), blurRadius: 15, offset: const Offset(0, 8), ), ], ), child: ElevatedButton( onPressed: isLoading ? null : registerUser, style: ElevatedButton.styleFrom( backgroundColor: Colors.transparent, shadowColor: Colors.transparent, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30), ), ), child: isLoading ? const CircularProgressIndicator(color: Color(0xFF1565C0)) : const Text( "Sign Up", style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Color(0xFF1565C0), letterSpacing: 1.2, ), ), ), ), ), const SizedBox(height: 25), /// ===== LOGIN TEXT ===== Row( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text( "Already have an Account? ", style: TextStyle(color: Colors.white70), ), GestureDetector( onTap: () { Navigator.pushNamed(context, '/login'); }, child: const Text( "Login", style: TextStyle( color: Colors.white, decoration: TextDecoration.underline, decorationColor: Colors.white, ), ), ), ], ), const SizedBox(height: 30), ], ), ), ), ), ), ); } /// ===== TEXTFIELD ===== Widget _buildTextField( TextEditingController controller, String hint, IconData icon, { bool isPassword = false, bool isConfirm = false, }) { return Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(25), boxShadow: [ BoxShadow( color: const Color(0xFF1565C0).withOpacity(0.15), blurRadius: 15, offset: const Offset(0, 8), ), ], ), child: TextField( controller: controller, obscureText: isPassword ? (isConfirm ? obscureConfirm : obscurePassword) : false, decoration: InputDecoration( prefixIcon: Icon(icon, color: const Color(0xFF1565C0)), hintText: hint, hintStyle: const TextStyle(color: Colors.grey), border: InputBorder.none, contentPadding: const EdgeInsets.symmetric(vertical: 20), suffixIcon: isPassword ? IconButton( icon: Icon( (isConfirm ? obscureConfirm : obscurePassword) ? Icons.visibility_off : Icons.visibility, color: Colors.grey, ), onPressed: () { setState(() { if (isConfirm) { obscureConfirm = !obscureConfirm; } else { obscurePassword = !obscurePassword; } }); }, ) : null, ), ), ); } }