E32221349_Medibox/lib/signup_screen.dart

299 lines
10 KiB
Dart

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'toast.dart';
import 'login_screen.dart';
class SignUpScreen extends StatefulWidget {
const SignUpScreen({super.key});
@override
State<SignUpScreen> createState() => _SignUpScreenState();
}
class _SignUpScreenState extends State<SignUpScreen> {
final TextEditingController _usernameController = TextEditingController();
final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
final TextEditingController _confirmPasswordController =
TextEditingController();
bool _obscurePassword = true;
bool _obscureConfirm = true;
bool _isSigningUp = false;
@override
void dispose() {
_usernameController.dispose();
_emailController.dispose();
_passwordController.dispose();
_confirmPasswordController.dispose();
super.dispose();
}
Future<void> _signUp() async {
String username = _usernameController.text.trim();
String email = _emailController.text.trim();
String password = _passwordController.text;
String confirmPassword = _confirmPasswordController.text;
if (username.isEmpty || email.isEmpty || password.isEmpty) {
showToast(message: "Semua field wajib diisi.");
return;
}
if (password != confirmPassword) {
showToast(message: "Konfirmasi password tidak cocok.");
return;
}
setState(() {
_isSigningUp = true;
});
try {
// 1. Buat akun dengan Firebase Auth
UserCredential userCredential = await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: email, password: password);
// 2. Ambil UID pengguna
String uid = userCredential.user!.uid;
// 3. Simpan data user ke Firestore
await FirebaseFirestore.instance.collection('users').doc(uid).set({
'email': email,
'username': username,
'createdAt': Timestamp.now(),
});
showToast(message: "Akun berhasil dibuat!");
// 4. Navigasi ke Login Screen
if (mounted) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const LoginScreen()),
);
}
} on FirebaseAuthException catch (e) {
switch (e.code) {
case 'email-already-in-use':
showToast(message: "Email sudah digunakan.");
break;
case 'invalid-email':
showToast(message: "Format email tidak valid.");
break;
case 'weak-password':
showToast(message: "Password terlalu lemah (minimal 6 karakter).");
break;
default:
showToast(message: "Error: ${e.message}");
}
} catch (e) {
showToast(message: "Terjadi kesalahan saat mendaftar.");
} finally {
if (mounted) {
setState(() {
_isSigningUp = false;
});
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Column(
children: [
// Header
Container(
width: double.infinity,
padding: const EdgeInsets.only(top: 80, bottom: 30),
decoration: const BoxDecoration(
color: Color(0xFF3FA535),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(40),
bottomRight: Radius.circular(40),
),
),
child: Column(
children: [
Image.asset(
'assets/images/logoputih.png',
width: 50,
height: 50,
),
const SizedBox(height: 10),
const Text(
'Sign Up to Your Account',
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
const SizedBox(height: 5),
const Text(
'Enter your email and password to sign up',
style: TextStyle(fontSize: 14, color: Colors.white70),
),
],
),
),
// Form
Expanded(
child: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: Container(
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(24),
boxShadow: [
BoxShadow(
color: Colors.grey.shade300,
blurRadius: 10,
offset: const Offset(0, 5),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text(
'Sign Up',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 20),
// Username
TextField(
controller: _usernameController,
decoration: const InputDecoration(
prefixIcon: Icon(Icons.person_outline),
labelText: 'Username',
border: UnderlineInputBorder(),
),
),
const SizedBox(height: 16),
// Email
TextField(
controller: _emailController,
decoration: const InputDecoration(
prefixIcon: Icon(Icons.email_outlined),
labelText: 'Email',
border: UnderlineInputBorder(),
),
),
const SizedBox(height: 16),
// Password
TextField(
controller: _passwordController,
obscureText: _obscurePassword,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.lock_outline),
labelText: 'Password',
border: const UnderlineInputBorder(),
suffixIcon: IconButton(
icon: Icon(
_obscurePassword
? Icons.visibility_off
: Icons.visibility,
),
onPressed: () {
setState(() {
_obscurePassword = !_obscurePassword;
});
},
),
),
),
const SizedBox(height: 16),
// Confirm Password
TextField(
controller: _confirmPasswordController,
obscureText: _obscureConfirm,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.lock_outline),
labelText: 'Confirm Password',
border: const UnderlineInputBorder(),
suffixIcon: IconButton(
icon: Icon(
_obscureConfirm
? Icons.visibility_off
: Icons.visibility,
),
onPressed: () {
setState(() {
_obscureConfirm = !_obscureConfirm;
});
},
),
),
),
const SizedBox(height: 30),
// Button
ElevatedButton(
onPressed: _signUp,
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF3FA535),
padding: const EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
child:
_isSigningUp
? const CircularProgressIndicator(
color: Colors.white,
)
: const Text(
'Sign Up',
style: TextStyle(
fontSize: 16,
color: Colors.white,
),
),
),
const SizedBox(height: 20),
// Redirect ke Login
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text("Already have an account? "),
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: const Text(
'Sign In',
style: TextStyle(
color: Color(0xFF3FA535),
fontWeight: FontWeight.bold,
),
),
),
],
),
],
),
),
),
),
],
),
);
}
}