TKK_E32231533/lib/page/signup_page.dart

482 lines
13 KiB
Dart

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<SignUpPage> createState() => _SignUpPageState();
}
class _SignUpPageState extends State<SignUpPage> {
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<void> 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,
),
),
);
}
}