import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:siopas/theme.dart'; import '../models/user_model.dart'; import '../providers/auth_provider.dart'; import '../widget/loading_button.dart'; class SignInPage extends StatefulWidget { @override State createState() => _SignInPageState(); } class _SignInPageState extends State { TextEditingController emailController = TextEditingController(text: ''); TextEditingController passwordController = TextEditingController(text: ''); bool isLoading = false; bool _isPasswordVisible = false; @override Widget build(BuildContext context) { final bool isSmallScreen = MediaQuery.of(context).size.width < 600; AuthProvider authProvider = Provider.of(context); UserModel user = authProvider.user; return Scaffold( body: Center( child: isSmallScreen ? SingleChildScrollView( reverse: true, scrollDirection: Axis.vertical, // Tambahkan ini child: Column( mainAxisSize: MainAxisSize.min, children: const [ _Logo(), _FormContent(), ], ), ) : Container( padding: const EdgeInsets.all(30.0), constraints: const BoxConstraints(maxWidth: 800), child: Row( children: const [ Expanded(child: _Logo()), Expanded( child: Center(child: _FormContent()), ), ], ), ))); } } class _Logo extends StatelessWidget { const _Logo({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final bool isSmallScreen = MediaQuery.of(context).size.width < 600; return Column( mainAxisSize: MainAxisSize.min, children: [ Container( margin: EdgeInsets.only(top: 30), child: Image.asset( 'assets/img/logo_siopas.png', height: isSmallScreen ? 135 : 200, ), ), Padding( padding: const EdgeInsets.all(16.0), child: Text( "Welcome To Siopas!", textAlign: TextAlign.center, style: TextStyle( fontSize: isSmallScreen ? 18 : 22, fontWeight: semiBold, color: Colors.black, ), ), ), ], ); } } class _FormContent extends StatefulWidget { const _FormContent({Key? key}) : super(key: key); @override State<_FormContent> createState() => __FormContentState(); } class __FormContentState extends State<_FormContent> { TextEditingController emailController = TextEditingController(text: ''); TextEditingController passwordController = TextEditingController(text: ''); final GlobalKey _formKey = GlobalKey(); bool isLoading = false; bool _isPasswordVisible = false; @override Widget build(BuildContext context) { AuthProvider authProvider = Provider.of(context); UserModel user = authProvider.user; handleSignIn() async { setState(() { isLoading = true; }); if (await authProvider.login( email: emailController.text, password: passwordController.text, )) { UserModel user = authProvider.user; // Simpan token pengguna ke SharedPreferences SharedPreferences prefs = await SharedPreferences.getInstance(); prefs.setString('token', user.token!); // Pastikan user.token tidak null print('token dapat login: ${user.token}'); if (user.role_id == 2) { print('Berhasil login HALAMAN USER'); Navigator.pushNamed(context, '/home'); } else { print('Tidak ada informasi peran (roles) yang tersedia'); } } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar( backgroundColor: alertColor, content: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.warning, color: Colors.white, ), SizedBox(width: 8), // Jarak antara ikon dan teks Text( 'Gagal Login, Email dan Password anda salah', textAlign: TextAlign.center, ), ], ), ), ); Future.delayed(Duration(seconds: 3), () { ScaffoldMessenger.of(context).hideCurrentSnackBar(); }); } setState(() { isLoading = false; }); } return Container( constraints: const BoxConstraints(maxWidth: 300), child: Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ TextFormField( validator: (value) { // add email validation if (value == null || value.isEmpty) { return 'Silakan masukkan email anda'; } bool emailValid = RegExp( r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+") .hasMatch(value); if (!emailValid) { return 'Tolong masukkan email yang benar'; } return null; }, controller: emailController, decoration: const InputDecoration( labelText: 'Email', hintText: 'Masukkan email Anda', prefixIcon: Icon(Icons.email_outlined), border: OutlineInputBorder(), ), ), _gap(), TextFormField( validator: (value) { if (value == null || value.isEmpty) { return 'Silakan masukkan password anda'; } if (value.length < 6) { return 'Kata sandi minimal harus 6 karakter'; } return null; }, obscureText: !_isPasswordVisible, controller: passwordController, decoration: InputDecoration( labelText: 'Password', hintText: 'Masukkan kata sandi Anda', prefixIcon: const Icon(Icons.lock_outline_rounded), border: const OutlineInputBorder(), suffixIcon: IconButton( icon: Icon(_isPasswordVisible ? Icons.visibility_off : Icons.visibility), onPressed: () { setState(() { _isPasswordVisible = !_isPasswordVisible; }); }, )), ), _gap(), SizedBox( width: double.infinity, child: ElevatedButton( style: ElevatedButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(4)), ), child: const Padding( padding: EdgeInsets.all(10.0), child: Text( 'Login', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), ), onPressed: () { if (_formKey.currentState!.validate()) { if (emailController.text.isEmpty || passwordController.text.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( backgroundColor: alertColor, content: Row( children: [ Icon( Icons.warning, color: Colors.white, ), SizedBox(width: 8), // Jarak antara ikon dan teks Text( 'Email dan Password tidak boleh kosong', textAlign: TextAlign.center, ), ], ), ), ); Future.delayed(Duration(seconds: 2), () { ScaffoldMessenger.of(context).hideCurrentSnackBar(); }); } else { handleSignIn(); } } }, ), ), ], ), ), ); } Widget _gap() => const SizedBox(height: 16); }