import 'package:flutter/material.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'signin_page.dart'; class SignUpPage extends StatefulWidget { const SignUpPage({super.key}); @override State createState() => _SignUpPageState(); } class _SignUpPageState extends State { bool obscurePassword = true; bool obscureConfirm = true; bool isLoading = false; final TextEditingController usernameController = TextEditingController(); final TextEditingController emailController = TextEditingController(); final TextEditingController passwordController = TextEditingController(); final TextEditingController confirmController = TextEditingController(); Future signUp() async { String username = usernameController.text.trim(); String email = emailController.text.trim(); String password = passwordController.text.trim(); String confirm = confirmController.text.trim(); if (password != confirm) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text("Password tidak sama"), ), ); return; } if (username.isEmpty || email.isEmpty || password.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text("Semua field harus diisi"), ), ); return; } setState(() { isLoading = true; }); try { UserCredential userCredential = await FirebaseAuth.instance .createUserWithEmailAndPassword( email: email, password: password, ); String uid = userCredential.user!.uid; await FirebaseFirestore.instance .collection("users") .doc(uid) .set({ "username": username, "email": email, "created_at": Timestamp.now(), }); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text("Akun berhasil dibuat"), ), ); Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => const SigninPage(), ), ); } on FirebaseAuthException catch (e) { String message = "Terjadi kesalahan"; if (e.code == 'email-already-in-use') { message = "Email sudah digunakan"; } else if (e.code == 'weak-password') { message = "Password terlalu lemah"; } else if (e.code == 'invalid-email') { message = "Format email tidak valid"; } ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(message)), ); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("Error: $e")), ); } setState(() { isLoading = false; }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF5F1EE), body: SafeArea( child: SingleChildScrollView( child: Column( children: [ /// HEADER Container( width: double.infinity, padding: const EdgeInsets.symmetric( horizontal: 25, vertical: 45, ), decoration: const BoxDecoration( gradient: LinearGradient( colors: [ Color(0xFF6F4E37), Color(0xFF8D6E63), ], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.only( bottomLeft: Radius.circular(35), bottomRight: Radius.circular(35), ), ), child: Column( children: [ /// LOGO Container( padding: const EdgeInsets.all(18), decoration: BoxDecoration( color: Colors.white.withOpacity(0.15), shape: BoxShape.circle, ), child: Image.asset( "assets/logo.png", height: 90, ), ), const SizedBox(height: 20), const Text( "Create Account", style: TextStyle( color: Colors.white, fontSize: 28, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 8), const Text( "Daftar untuk menggunakan Coffee Dryer", style: TextStyle( color: Colors.white70, fontSize: 15, ), ), ], ), ), const SizedBox(height: 35), /// FORM CARD Container( margin: const EdgeInsets.symmetric( horizontal: 22), padding: const EdgeInsets.all(25), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(30), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 20, offset: const Offset(0, 10), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( "Sign Up", style: TextStyle( fontSize: 28, fontWeight: FontWeight.bold, color: Color(0xFF6D4C41), ), ), const SizedBox(height: 8), Text( "Buat akun baru anda", style: TextStyle( color: Colors.grey.shade600, fontSize: 15, ), ), const SizedBox(height: 30), /// USERNAME buildTextField( controller: usernameController, hint: "Username", icon: Icons.person_outline, ), const SizedBox(height: 20), /// EMAIL buildTextField( controller: emailController, hint: "Email", icon: Icons.email_outlined, ), const SizedBox(height: 20), /// PASSWORD TextField( controller: passwordController, obscureText: obscurePassword, decoration: InputDecoration( hintText: "Password", prefixIcon: const Icon( Icons.lock_outline, ), suffixIcon: IconButton( icon: Icon( obscurePassword ? Icons.visibility_off : Icons.visibility, ), onPressed: () { setState(() { obscurePassword = !obscurePassword; }); }, ), filled: true, fillColor: Colors.grey.shade100, contentPadding: const EdgeInsets.symmetric( vertical: 18, ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(18), borderSide: BorderSide.none, ), ), ), const SizedBox(height: 20), /// CONFIRM PASSWORD TextField( controller: confirmController, obscureText: obscureConfirm, decoration: InputDecoration( hintText: "Confirm Password", prefixIcon: const Icon( Icons.lock_reset_outlined, ), suffixIcon: IconButton( icon: Icon( obscureConfirm ? Icons.visibility_off : Icons.visibility, ), onPressed: () { setState(() { obscureConfirm = !obscureConfirm; }); }, ), filled: true, fillColor: Colors.grey.shade100, contentPadding: const EdgeInsets.symmetric( vertical: 18, ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(18), borderSide: BorderSide.none, ), ), ), const SizedBox(height: 30), /// BUTTON SIGNUP SizedBox( width: double.infinity, height: 55, child: ElevatedButton( onPressed: isLoading ? null : signUp, style: ElevatedButton.styleFrom( elevation: 0, backgroundColor: const Color(0xFF6D4C41), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(18), ), ), child: isLoading ? const CircularProgressIndicator( color: Colors.white, ) : const Text( "Create Account", style: TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold, ), ), ), ), const SizedBox(height: 25), /// LOGIN Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( "Sudah punya akun?", style: TextStyle( color: Colors.grey.shade700, ), ), const SizedBox(width: 5), GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const SigninPage(), ), ); }, child: const Text( "Sign In", style: TextStyle( color: Color(0xFF6D4C41), fontWeight: FontWeight.bold, ), ), ), ], ) ], ), ), const SizedBox(height: 30), ], ), ), ), ); } Widget buildTextField({ required TextEditingController controller, required String hint, required IconData icon, }) { return TextField( controller: controller, decoration: InputDecoration( hintText: hint, prefixIcon: Icon(icon), filled: true, fillColor: Colors.grey.shade100, contentPadding: const EdgeInsets.symmetric( vertical: 18, ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(18), borderSide: BorderSide.none, ), ), ); } }