233 lines
7.2 KiB
Dart
233 lines
7.2 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:firebase_auth/firebase_auth.dart';
|
||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||
|
||
class RegisterScreen extends StatefulWidget {
|
||
const RegisterScreen({super.key});
|
||
|
||
@override
|
||
State<RegisterScreen> createState() => _RegisterScreenState();
|
||
}
|
||
|
||
class _RegisterScreenState extends State<RegisterScreen> {
|
||
|
||
final _nameController = TextEditingController();
|
||
final _emailController = TextEditingController();
|
||
final _passwordController = TextEditingController();
|
||
final _confirmController = TextEditingController();
|
||
|
||
bool isLoading = false;
|
||
bool _obscurePass = true;
|
||
bool _obscureConfirm = true;
|
||
|
||
Future<void> register() async {
|
||
|
||
if (_nameController.text.isEmpty ||
|
||
_emailController.text.isEmpty ||
|
||
_passwordController.text.isEmpty ||
|
||
_confirmController.text.isEmpty) {
|
||
ScaffoldMessenger.of(context).showSnackBar(
|
||
const SnackBar(content: Text("Semua field wajib diisi")),
|
||
);
|
||
return;
|
||
}
|
||
|
||
if (_passwordController.text != _confirmController.text) {
|
||
ScaffoldMessenger.of(context).showSnackBar(
|
||
const SnackBar(content: Text("Password tidak sama")),
|
||
);
|
||
return;
|
||
}
|
||
|
||
try {
|
||
setState(() => isLoading = true);
|
||
|
||
/// 1️⃣ Buat akun di Firebase Auth
|
||
UserCredential userCredential =
|
||
await FirebaseAuth.instance.createUserWithEmailAndPassword(
|
||
email: _emailController.text.trim(),
|
||
password: _passwordController.text.trim(),
|
||
);
|
||
|
||
/// 2️⃣ Simpan data ke Firestore
|
||
await FirebaseFirestore.instance
|
||
.collection("users")
|
||
.doc(userCredential.user!.uid)
|
||
.set({
|
||
"nama": _nameController.text.trim(),
|
||
"email": _emailController.text.trim(),
|
||
"createdAt": Timestamp.now(),
|
||
});
|
||
|
||
Navigator.pop(context);
|
||
|
||
ScaffoldMessenger.of(context).showSnackBar(
|
||
const SnackBar(content: Text("Akun berhasil dibuat")),
|
||
);
|
||
|
||
} on FirebaseAuthException catch (e) {
|
||
ScaffoldMessenger.of(context).showSnackBar(
|
||
SnackBar(content: Text(e.message ?? "Terjadi kesalahan")),
|
||
);
|
||
}
|
||
|
||
setState(() => isLoading = false);
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return Scaffold(
|
||
backgroundColor: const Color(0xFF34C759),
|
||
body: Stack(
|
||
children: [
|
||
|
||
/// BACK BUTTON
|
||
SafeArea(
|
||
child: Padding(
|
||
padding: const EdgeInsets.all(15),
|
||
child: GestureDetector(
|
||
onTap: () => Navigator.pop(context),
|
||
child: Container(
|
||
width: 40,
|
||
height: 40,
|
||
decoration: const BoxDecoration(
|
||
color: Colors.white,
|
||
shape: BoxShape.circle,
|
||
),
|
||
child: const Icon(Icons.arrow_back),
|
||
),
|
||
),
|
||
),
|
||
),
|
||
|
||
/// WHITE CARD
|
||
Align(
|
||
alignment: Alignment.center,
|
||
child: Container(
|
||
margin: const EdgeInsets.symmetric(horizontal: 25),
|
||
padding: const EdgeInsets.all(25),
|
||
decoration: BoxDecoration(
|
||
color: const Color(0xFFF2F2F2),
|
||
borderRadius: BorderRadius.circular(30),
|
||
),
|
||
child: SingleChildScrollView(
|
||
child: Column(
|
||
children: [
|
||
|
||
const Text(
|
||
"Buat akun",
|
||
style: TextStyle(
|
||
fontSize: 22,
|
||
fontWeight: FontWeight.bold,
|
||
),
|
||
),
|
||
|
||
const SizedBox(height: 5),
|
||
|
||
const Text(
|
||
"Buatlah agar tidak ribet setelahnya",
|
||
style: TextStyle(color: Colors.grey),
|
||
),
|
||
|
||
const SizedBox(height: 25),
|
||
|
||
/// NAMA
|
||
TextField(
|
||
controller: _nameController,
|
||
decoration: _inputDecoration("Nama Lengkap"),
|
||
),
|
||
|
||
const SizedBox(height: 15),
|
||
|
||
/// EMAIL
|
||
TextField(
|
||
controller: _emailController,
|
||
decoration: _inputDecoration("Email/No. Telepon"),
|
||
),
|
||
|
||
const SizedBox(height: 15),
|
||
|
||
/// PASSWORD
|
||
TextField(
|
||
controller: _passwordController,
|
||
obscureText: _obscurePass,
|
||
decoration: _inputDecoration("Kata Sandi").copyWith(
|
||
suffixIcon: IconButton(
|
||
icon: Icon(
|
||
_obscurePass
|
||
? Icons.visibility_off
|
||
: Icons.visibility,
|
||
),
|
||
onPressed: () {
|
||
setState(() {
|
||
_obscurePass = !_obscurePass;
|
||
});
|
||
},
|
||
),
|
||
),
|
||
),
|
||
|
||
const SizedBox(height: 15),
|
||
|
||
/// KONFIRMASI
|
||
TextField(
|
||
controller: _confirmController,
|
||
obscureText: _obscureConfirm,
|
||
decoration: _inputDecoration("Konfirmasi Kata Sandi")
|
||
.copyWith(
|
||
suffixIcon: IconButton(
|
||
icon: Icon(
|
||
_obscureConfirm
|
||
? Icons.visibility_off
|
||
: Icons.visibility,
|
||
),
|
||
onPressed: () {
|
||
setState(() {
|
||
_obscureConfirm = !_obscureConfirm;
|
||
});
|
||
},
|
||
),
|
||
),
|
||
),
|
||
|
||
const SizedBox(height: 30),
|
||
|
||
/// BUTTON
|
||
SizedBox(
|
||
width: double.infinity,
|
||
height: 45,
|
||
child: ElevatedButton(
|
||
style: ElevatedButton.styleFrom(
|
||
backgroundColor: const Color(0xFF34C759),
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(10),
|
||
),
|
||
),
|
||
onPressed: isLoading ? null : register,
|
||
child: isLoading
|
||
? const CircularProgressIndicator(
|
||
color: Colors.white)
|
||
: const Text("Continue"),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
InputDecoration _inputDecoration(String hint) {
|
||
return InputDecoration(
|
||
hintText: hint,
|
||
filled: true,
|
||
fillColor: Colors.white,
|
||
border: OutlineInputBorder(
|
||
borderRadius: BorderRadius.circular(10),
|
||
),
|
||
);
|
||
}
|
||
} |