import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../app/constant.dart'; import '../../app/route.dart'; import '../../models/auth_model.dart'; import '../../provider/current_user_provider.dart'; import '../../widget/sas_textfield.dart'; import 'login_provider.dart'; class LoginScreen extends HookConsumerWidget { const LoginScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final isPasswordObscured = useState(true); final ctrlUsername = useTextEditingController(text: ""); final ctrlPassword = useTextEditingController(text: ""); final focusNodeUsername = useFocusNode(); final focusNodePassword = useFocusNode(); final usernamehasFocus = useState(false); final passwordhasFocus = useState(false); final isRememberMe = useState(false); final errorMessage = useState(""); final isLoading = useState(false); final isSuccess = useState(false); final isValidEntry = useState(false); final usernameFromSharePref = useState(""); final passwordFromSharePref = useState(""); focusNodeUsername.addListener(() { if (focusNodeUsername.hasFocus) { usernamehasFocus.value = true; passwordhasFocus.value = false; } else { usernamehasFocus.value = false; } }); focusNodePassword.addListener(() { if (focusNodePassword.hasFocus) { usernamehasFocus.value = false; passwordhasFocus.value = true; } else { passwordhasFocus.value = false; } }); // aksi login ref.listen(loginProvider, (prev, next) async { if (next is LoginStateLoading) { isLoading.value = true; } else if (next is LoginStateError) { isLoading.value = false; errorMessage.value = next.message ?? ""; // print(errorMessage.value); Timer(const Duration(seconds: 3), () { errorMessage.value = ""; }); } else if (next is LoginStateDone) { isLoading.value = false; isSuccess.value = true; Navigator.of(context) .pushNamedAndRemoveUntil(menuRoute, (route) => false); } }); ctrlUsername.addListener( () { if (ctrlUsername.text.isEmpty || ctrlPassword.text.isEmpty) { isValidEntry.value = false; } else { isValidEntry.value = true; } }, ); ctrlPassword.addListener( () { if (ctrlUsername.text.isEmpty || ctrlPassword.text.isEmpty) { isValidEntry.value = false; } else { isValidEntry.value = true; } }, ); return GestureDetector( onTap: () => FocusManager.instance.primaryFocus?.unfocus(), child: Scaffold( resizeToAvoidBottomInset: true, backgroundColor: Constant.backgroundWhite, body: SizedBox( width: Constant.getActualX(context: context, x: 390), height: Constant.getActualY(context: context, y: 844), child: ListView( children: [ // bg login Padding( padding: EdgeInsets.only( top: Constant.getActualY(context: context, y: 80), left: Constant.getActualX(context: context, x: 16), right: Constant.getActualX(context: context, x: 16), ), child: Image.asset( "assets/bg_login.png", // fit: BoxFit.fill, // scale: 1, ), ), SizedBox( height: Constant.getActualY(context: context, y: 10), ), // Error From Backend Start if (errorMessage.value != "") Padding( padding: EdgeInsets.only( top: Constant.getActualY(context: context, y: 27), left: Constant.getActualX(context: context, x: 38), right: Constant.getActualX(context: context, x: 32), ), child: Align( alignment: Alignment.center, child: Text( "Peringatan : ${errorMessage.value}", style: Constant.body1(context: context) .copyWith(color: Constant.primaryRed), ), ), ), // Error From Backend End // loading if (isLoading.value) Padding( padding: EdgeInsets.only( top: Constant.getActualY(context: context, y: 10), left: Constant.getActualX(context: context, x: 38), right: Constant.getActualX(context: context, x: 32), ), child: Center( child: SizedBox( width: Constant.getActualX(context: context, x: 40), height: Constant.getActualY(context: context, y: 40), child: CircularProgressIndicator( color: Constant.primaryBlue, ), ), ), ), SizedBox( height: Constant.getActualY(context: context, y: 10), ), Padding( padding: EdgeInsets.only( top: Constant.getActualY(context: context, y: 27), left: Constant.getActualX(context: context, x: 38), right: Constant.getActualX(context: context, x: 32), ), child: SizedBox( width: Constant.getActualX(context: context, x: 320), height: Constant.getActualY(context: context, y: 412), // color: Colors.amber, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Login", style: Constant.heading2(context: context).copyWith( color: Constant.textPrimary, fontWeight: FontWeight.w600), ), SizedBox( height: Constant.getActualY(context: context, y: 20), ), SasTextField( hintText: "Username", labelText: "Username", controller: ctrlUsername, focusNode: focusNodeUsername, hasFocus: usernamehasFocus.value, style: Constant.body1(context: context) .copyWith(color: Constant.textBlack), ), SizedBox( height: Constant.getActualY(context: context, y: 16), ), SasTextFieldPassword( hintText: "Password", labelText: "Password", controller: ctrlPassword, focusNode: focusNodePassword, hasFocus: passwordhasFocus.value, onToggle: () { isPasswordObscured.value = !isPasswordObscured.value; }, obscureText: (isPasswordObscured.value == true) ? true : false, ), SizedBox( height: Constant.getActualY(context: context, y: 16), ), SizedBox( width: Constant.getActualX(context: context, x: 320), height: Constant.getActualY(context: context, y: 20), // color: Colors.green, child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Checkbox( value: isRememberMe.value, onChanged: (value) { if (value != null) { isRememberMe.value = value; // checkIsLogin(isRememberMe.value); } }, ), const SizedBox(width: 8.0), Text( "Ingat saya", style: Constant.caption1(context: context).copyWith( color: Constant.textPrimary, fontWeight: FontWeight.w400, ), ), ], ), ), SizedBox( height: Constant.getActualY(context: context, y: 32), ), // button login SizedBox( width: Constant.getActualX(context: context, x: 320), height: Constant.getActualY(context: context, y: 48), child: ElevatedButton( onPressed: (isLoading.value == true) ? null : () { if (ctrlUsername.text.isEmpty || ctrlPassword.text.isEmpty) { isLoading.value = false; errorMessage.value = 'Inputan harus diisi'; Timer(const Duration(seconds: 3), () { isLoading.value = false; errorMessage.value = ""; }); } else { ref.read(loginProvider.notifier).login( username: ctrlUsername.text, password: ctrlPassword.text, isRememberMe: isRememberMe.value, ); } }, style: ButtonStyle( backgroundColor: MaterialStateColor.resolveWith( (st) => Constant.primaryMain), shape: MaterialStateProperty.all< RoundedRectangleBorder>( RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), // side: BorderSide(color: Colors.red), ), ), shadowColor: MaterialStateProperty.all( const Color(0xffff48423d)), elevation: MaterialStateProperty.all(4.0), ), child: Align( alignment: Alignment.center, child: Text( 'Login', style: Constant.buttonLarge(context: context) .copyWith( color: Constant.backgroundWhite, fontWeight: FontWeight.w700, ), ), ), ), ), SizedBox( height: Constant.getActualY(context: context, y: 16), ), // Center( // child: InkWell( // onTap: () { // Navigator.of(context).pushNamedAndRemoveUntil( // problemLoginRoute, // (route) => true, // ); // }, // child: Text( // "Problem login", // style: Constant.caption1(context: context).copyWith( // color: Constant.errorDark, // fontWeight: FontWeight.w400), // ), // ), // ), ], ), ), ), ], ), ), ), ); } }