TKK_E32231193/lib/screens/login_screen.dart

358 lines
12 KiB
Dart

import 'package:flutter/material.dart';
import '../services/auth_service.dart';
import 'register_screen.dart';
import 'dashboard_screen.dart';
class LoginScreen extends StatefulWidget {
const LoginScreen({super.key});
@override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final AuthService _auth = AuthService();
final emailController = TextEditingController();
final passwordController = TextEditingController();
bool isLoading = false;
bool isPasswordHidden = true;
@override
void initState() {
super.initState();
isLoading = false;
}
/// 🔥 LOGIN FUNCTION
void login() async {
/// VALIDASI INPUT
if (emailController.text.trim().isEmpty ||
passwordController.text.trim().isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("Email dan Password wajib diisi"),
),
);
return;
}
setState(() => isLoading = true);
try {
/// 🔥 PROSES LOGIN
await _auth.login(
emailController.text.trim(),
passwordController.text.trim(),
);
/// 🔥 JIKA BERHASIL
if (mounted) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => const DashboardScreen(),
),
);
}
} catch (e) {
if (mounted) {
/// 🔥 DEBUG FIREBASE ERROR
print("ERROR FIREBASE = ${e.toString()}");
String errorMessage = e.toString().toLowerCase();
String customMessage = "Terjadi kesalahan";
/// 🔥 EMAIL BELUM TERDAFTAR
if (errorMessage.contains('user-not-found') ||
errorMessage.contains('no user record') ||
errorMessage.contains('invalid-credential') ||
errorMessage.contains('credential is incorrect')) {
customMessage = "Maaf, Email Anda belum terdaftar";
}
/// 🔥 PASSWORD SALAH
else if (errorMessage.contains('wrong-password')) {
customMessage = "Password yang anda masukkan salah";
}
/// 🔥 EMAIL INVALID
else if (errorMessage.contains('invalid-email')) {
customMessage = "Format email tidak valid";
}
/// 🔥 INTERNET ERROR
else if (errorMessage.contains('network-request-failed')) {
customMessage = "Koneksi internet bermasalah";
}
/// 🔥 TERLALU BANYAK REQUEST
else if (errorMessage.contains('too-many-requests')) {
customMessage = "Terlalu banyak percobaan login. Coba lagi nanti";
}
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(customMessage)),
);
}
} finally {
if (mounted) {
setState(() => isLoading = false);
}
}
}
/// 🔥 STYLE BORDER
OutlineInputBorder buildBorder() {
return OutlineInputBorder(
borderRadius: BorderRadius.circular(18),
borderSide: const BorderSide(
color: Colors.black,
width: 1.6,
),
);
}
@override
void dispose() {
emailController.dispose();
passwordController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
/// 🔥 BACKGROUND
Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/1.png"),
fit: BoxFit.cover,
),
),
),
/// 🔥 OVERLAY
Container(
color: Colors.black.withOpacity(0.6),
),
/// 🔥 CONTENT
Center(
child: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 30),
child: Column(
children: [
/// 🔥 LOGO
Image.asset(
"assets/images/2.png",
height: 100,
),
const SizedBox(height: 20),
/// 🔥 TITLE
const Text(
"Selada Hidroponik",
style: TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
color: Colors.white,
letterSpacing: 1,
),
),
const SizedBox(height: 40),
/// 🔥 CARD LOGIN
Container(
padding: const EdgeInsets.all(28),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(30),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.25),
blurRadius: 30,
offset: const Offset(0, 15),
),
],
),
child: Column(
children: [
const Text(
"Masuk sebagai pengguna terdaftar",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
letterSpacing: 1,
color: Color(0xFF2E7D32),
),
),
const SizedBox(height: 30),
/// 🔥 EMAIL
TextField(
controller: emailController,
keyboardType: TextInputType.emailAddress,
autofillHints: const [
AutofillHints.email,
],
decoration: InputDecoration(
labelText: "Email",
prefixIcon: const Icon(Icons.email_outlined),
enabledBorder: buildBorder(),
focusedBorder: buildBorder(),
),
),
const SizedBox(height: 20),
/// 🔥 PASSWORD
TextField(
controller: passwordController,
obscureText: isPasswordHidden,
autofillHints: const [
AutofillHints.password,
],
decoration: InputDecoration(
labelText: "Password",
prefixIcon: const Icon(Icons.lock_outline),
enabledBorder: buildBorder(),
focusedBorder: buildBorder(),
suffixIcon: IconButton(
icon: Icon(
isPasswordHidden
? Icons.visibility_off
: Icons.visibility,
),
onPressed: () {
setState(() {
isPasswordHidden = !isPasswordHidden;
});
},
),
),
),
const SizedBox(height: 10),
/// 🔥 LUPA PASSWORD
Align(
alignment: Alignment.centerRight,
child: TextButton(
onPressed: () async {
if (emailController.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
"Masukkan email dulu",
),
),
);
return;
}
try {
await _auth.resetPassword(
emailController.text.trim(),
);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
"Link reset dikirim ke email",
),
),
);
}
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
e.toString(),
),
),
);
}
}
},
child: const Text(
"Lupa Password?",
),
),
),
const SizedBox(height: 25),
/// 🔥 BUTTON LOGIN
SizedBox(
width: double.infinity,
height: 55,
child: ElevatedButton(
onPressed: isLoading ? null : login,
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18),
),
elevation: 6,
backgroundColor: const Color(0xFF2E7D32),
disabledBackgroundColor: Colors.grey,
),
child: isLoading
? const CircularProgressIndicator(
color: Colors.white,
)
: const Text(
"Sign In",
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
],
),
),
const SizedBox(height: 25),
/// 🔥 REGISTER
TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const RegisterScreen(),
),
);
},
child: const Text(
"Belum memiliki akun? Daftar sekarang!",
style: TextStyle(
color: Colors.white,
fontSize: 14,
),
),
),
],
),
),
),
],
),
);
}
}