import 'package:coffedryer/page/signup_page.dart'; import 'package:coffedryer/page/dashboard_page.dart'; import 'package:flutter/material.dart'; import 'package:firebase_auth/firebase_auth.dart'; class SigninPage extends StatefulWidget { const SigninPage({super.key}); @override State createState() => _LoginPageState(); } class _LoginPageState extends State { bool isHidden = true; bool isLoading = false; final emailController = TextEditingController(); final passwordController = TextEditingController(); final FirebaseAuth _auth = FirebaseAuth.instance; /// LOGIN Future loginUser() async { setState(() { isLoading = true; }); try { await _auth .signInWithEmailAndPassword( email: emailController.text.trim(), password: passwordController.text.trim(), ); if (mounted) { Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => const DashboardPage(), ), ); } } catch (e) { ScaffoldMessenger.of(context) .showSnackBar( SnackBar( backgroundColor: Colors.red, content: Text( "Login gagal: $e", ), ), ); } setState(() { isLoading = false; }); } /// RESET PASSWORD Future showForgotPasswordDialog() async { final resetController = TextEditingController(); showDialog( context: context, builder: (context) { return AlertDialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), title: const Text( "Reset Password", style: TextStyle( fontWeight: FontWeight.bold, ), ), content: Column( mainAxisSize: MainAxisSize.min, children: [ const Icon( Icons.lock_reset, size: 60, color: Color(0xFF6D4C41), ), const SizedBox(height: 15), const Text( "Masukkan email akun anda", textAlign: TextAlign.center, ), const SizedBox(height: 15), TextField( controller: resetController, keyboardType: TextInputType .emailAddress, decoration: InputDecoration( hintText: "Email", prefixIcon: const Icon( Icons.email, ), filled: true, fillColor: Colors.grey .shade100, border: OutlineInputBorder( borderRadius: BorderRadius .circular( 15), borderSide: BorderSide .none, ), ), ), ], ), actions: [ TextButton( onPressed: () { Navigator.pop( context); }, child: const Text("Batal"), ), ElevatedButton( style: ElevatedButton .styleFrom( backgroundColor: const Color( 0xFF6D4C41), ), onPressed: () async { try { await FirebaseAuth .instance .sendPasswordResetEmail( email: resetController .text .trim(), ); Navigator.pop( context); ScaffoldMessenger.of( context) .showSnackBar( const SnackBar( content: Text( "Link reset password berhasil dikirim", ), ), ); } on FirebaseAuthException catch (e) { String message = "Terjadi kesalahan"; if (e.code == 'user-not-found') { message = "Email tidak ditemukan"; } if (e.code == 'invalid-email') { message = "Format email tidak valid"; } ScaffoldMessenger.of( context) .showSnackBar( SnackBar( content: Text(message), ), ); } }, child: const Text( "Kirim", style: TextStyle( color: Colors.white, ), ), ), ], ); }, ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF5F1EE), body: SafeArea( child: SingleChildScrollView( child: Column( children: [ /// TOP 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( "Coffee Dryer", style: TextStyle( color: Colors.white, fontSize: 28, fontWeight: FontWeight.bold, ), ), const SizedBox( height: 8), const Text( "Monitoring & Control System", style: TextStyle( color: Colors.white70, fontSize: 15, ), ), ], ), ), const SizedBox(height: 35), /// LOGIN 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 In", style: TextStyle( fontSize: 28, fontWeight: FontWeight.bold, color: Color( 0xFF6D4C41), ), ), const SizedBox( height: 8), Text( "Masuk ke akun anda", style: TextStyle( color: Colors.grey .shade600, fontSize: 15, ), ), const SizedBox( height: 30), /// EMAIL buildTextField( controller: emailController, hint: "Email", icon: Icons .email_outlined, ), const SizedBox( height: 20), /// PASSWORD TextField( controller: passwordController, obscureText: isHidden, decoration: InputDecoration( hintText: "Password", prefixIcon: const Icon( Icons .lock_outline, ), suffixIcon: IconButton( icon: Icon( isHidden ? Icons .visibility_off : Icons .visibility, ), onPressed: () { setState(() { isHidden = !isHidden; }); }, ), filled: true, fillColor: Colors.grey .shade100, contentPadding: const EdgeInsets .symmetric( vertical: 18, ), border: OutlineInputBorder( borderRadius: BorderRadius .circular( 18), borderSide: BorderSide .none, ), ), ), const SizedBox( height: 12), /// LUPA PASSWORD Align( alignment: Alignment .centerRight, child: GestureDetector( onTap: () { showForgotPasswordDialog(); }, child: const Text( "Lupa Password?", style: TextStyle( color: Color( 0xFF6D4C41), fontWeight: FontWeight .bold, ), ), ), ), const SizedBox( height: 25), /// BUTTON LOGIN SizedBox( width: double.infinity, height: 55, child: ElevatedButton( onPressed: isLoading ? null : loginUser, style: ElevatedButton .styleFrom( elevation: 0, backgroundColor: const Color( 0xFF6D4C41), shape: RoundedRectangleBorder( borderRadius: BorderRadius .circular( 18), ), ), child: isLoading ? const CircularProgressIndicator( color: Colors .white, ) : const Text( "Sign In", style: TextStyle( color: Colors .white, fontSize: 16, fontWeight: FontWeight .bold, ), ), ), ), const SizedBox( height: 25), /// REGISTER Row( mainAxisAlignment: MainAxisAlignment .center, children: [ Text( "Belum punya akun?", style: TextStyle( color: Colors .grey .shade700, ), ), const SizedBox( width: 5), GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const SignUpPage(), ), ); }, child: const Text( "Daftar", 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, ), ), ); } }