MIF_E31221269/lib/screens/login.dart

304 lines
12 KiB
Dart

import 'package:flutter/material.dart';
import 'dashboard.dart'; // Pastikan untuk mengimpor halaman dashboard
import 'package:firebase_auth/firebase_auth.dart'; // Import Firebase Auth
class LoginScreen extends StatefulWidget {
@override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> with SingleTickerProviderStateMixin {
final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
bool _isLoading = false;
bool _obscurePassword = true;
late AnimationController _animationController;
late Animation<double> _fadeAnimation;
// Initialize Firebase Auth
final FirebaseAuth _auth = FirebaseAuth.instance;
@override
void initState() {
super.initState();
_animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 1500),
);
_fadeAnimation = CurvedAnimation(
parent: _animationController,
curve: Curves.easeIn,
);
_animationController.forward();
}
@override
void dispose() {
_animationController.dispose();
_emailController.dispose();
_passwordController.dispose();
super.dispose();
}
// Fungsi login (diperbarui untuk menggunakan Firebase Auth)
void _login() async {
if (_formKey.currentState!.validate()) {
setState(() {
_isLoading = true;
});
try {
// Menggunakan Firebase Auth untuk login
await _auth.signInWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
);
// Pindah ke halaman dashboard setelah login berhasil
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => DashboardPage()),
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Login berhasil!'),
backgroundColor: Colors.green,
),
);
} catch (e) {
// Menangani kesalahan login
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Login gagal: ${e.toString()}'),
backgroundColor: Colors.red,
),
);
} finally {
setState(() {
_isLoading = false;
});
}
}
}
// Fungsi untuk mengirim email reset password
void _resetPassword() async {
String email = _emailController.text;
if (email.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Masukkan email untuk reset password'),
backgroundColor: Colors.orange,
),
);
return;
}
try {
await _auth.sendPasswordResetEmail(email: email);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Email reset password telah dikirim!'),
backgroundColor: Colors.green,
),
);
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Gagal mengirim email: ${e.toString()}'),
backgroundColor: Colors.red,
),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Colors.white, Color(0xFFFDEDEE)],
),
),
child: Center(
child: SingleChildScrollView(
padding: const EdgeInsets.all(24.0),
child: FadeTransition(
opacity: _fadeAnimation,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Hero(
tag: 'logo',
child: Image.asset('assets/Logo.jpg', width: 180, height: 180),
),
SizedBox(height: 20),
Text(
"JAGO",
style: TextStyle(
fontSize: 36,
fontWeight: FontWeight.bold,
color: Color(0xFFA82429),
letterSpacing: 2.0,
),
),
SizedBox(height: 10),
Text(
"Selamat Datang",
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.black87,
),
),
SizedBox(height: 8),
Text(
"Silahkan masuk untuk melanjutkan",
style: TextStyle(fontSize: 16, color: Colors.grey[600]),
),
SizedBox(height: 40),
Card(
elevation: 8,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Form(
key: _formKey,
child: Column(
children: [
// Input Email
TextFormField(
controller: _emailController,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Email',
labelStyle: TextStyle(color: Color(0xFFA82429)),
hintText: 'Masukkan email anda',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Color(0xFFA82429)),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Color(0xFFA82429), width: 2),
),
prefixIcon: Icon(Icons.email, color: Color(0xFFA82429)),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Email tidak boleh kosong';
}
if (!RegExp(r'^[^@]+@[^@]+\.[^@]+').hasMatch(value)) {
return 'Format email tidak valid';
}
return null;
},
),
SizedBox(height: 20),
// Input Password
TextFormField(
controller: _passwordController,
obscureText: _obscurePassword,
decoration: InputDecoration(
labelText: 'Password',
labelStyle: TextStyle(color: Color(0xFFA82429)),
hintText: 'Masukkan password anda',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Color(0xFFA82429)),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Color(0xFFA82429), width: 2),
),
prefixIcon: Icon(Icons.lock, color: Color(0xFFA82429)),
suffixIcon: IconButton(
icon: Icon(
_obscurePassword ? Icons.visibility_off : Icons.visibility,
color: Color(0xFFA82429),
),
onPressed: () {
setState(() {
_obscurePassword = !_obscurePassword;
});
},
),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Password tidak boleh kosong';
}
if (value.length < 6) {
return 'Password minimal 6 karakter';
}
return null;
},
),
SizedBox(height: 10),
// Tautan Lupa Password
Align(
alignment: Alignment.centerRight,
child: TextButton(
onPressed: _resetPassword,
child: Text(
"Lupa password?",
style: TextStyle(
color: Color(0xFFA82429),
fontWeight: FontWeight.w600,
),
),
),
),
SizedBox(height: 24),
// Tombol Login
SizedBox(
width: double.infinity,
height: 55,
child: ElevatedButton(
onPressed: _isLoading ? null : _login,
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFFA82429),
foregroundColor: Colors.white,
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: _isLoading
? CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
)
: Text(
'MASUK',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
letterSpacing: 1.0,
),
),
),
),
],
),
),
),
),
],
),
),
),
),
),
);
}
}