Files
kdr_kurir_app_v2/lib/screen/login/login_screen.dart

326 lines
13 KiB
Dart

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<bool>(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),
// ),
// ),
// ),
],
),
),
),
],
),
),
),
);
}
}