first commit
This commit is contained in:
376
lib/widgets/header.dart
Normal file
376
lib/widgets/header.dart
Normal file
@@ -0,0 +1,376 @@
|
||||
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:intl/date_symbol_data_local.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:mitra_corporate/provider/menu_provider.dart';
|
||||
import 'package:mitra_corporate/widgets/custom_text_field.dart';
|
||||
import 'package:loading_animation_widget/loading_animation_widget.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import '../app/constant.dart';
|
||||
import '../app/route.dart';
|
||||
import '../provider/auth_provider.dart';
|
||||
import '../screen/login/change_password_provider.dart';
|
||||
import '../screen/login/logout_provider.dart';
|
||||
import 'custom_snackbar_widget.dart';
|
||||
|
||||
class Header extends HookConsumerWidget {
|
||||
const Header({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final currentUser = ref.watch(authProvider);
|
||||
final isExpand = ref.watch(sideBarExpandProvider);
|
||||
final auth = ref.watch(authProvider);
|
||||
final date = useState("");
|
||||
ref.listen(logoutProvider, (prev, next) async {
|
||||
if (next is LogoutStateLoading) {
|
||||
} else if (next is LogoutStateError) {
|
||||
SanckbarWidget(context, next.message, snackbarType.error);
|
||||
} else if (next is LogoutStateDone) {
|
||||
if (next.message == "OK") {
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
await prefs.remove(Constant.tokenName);
|
||||
Navigator.pushNamed(context, loginRoute);
|
||||
} else {
|
||||
SanckbarWidget(context, "Logout Gagal", snackbarType.error);
|
||||
}
|
||||
}
|
||||
});
|
||||
useEffect(() {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
||||
DateTime now = DateTime.now();
|
||||
initializeDateFormatting('id', '').then((_) {
|
||||
date.value = DateFormat('EEEE, d MMMM yyyy', "id").format(now);
|
||||
print(DateFormat('EEEE, d MMMM yyyy', "id").format(now));
|
||||
});
|
||||
});
|
||||
return () {};
|
||||
}, []);
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
alignment: Alignment.center,
|
||||
width: Constant.getActualX(context: context, x: isExpand ? 1159 : 1344),
|
||||
height: Constant.getActualY(context: context, y: 90),
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 16, bottom: 16, left: 34, right: 34),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
// Center(
|
||||
// child: Icon(
|
||||
// EvaIcons.calendarOutline,
|
||||
// // size: 24,
|
||||
// size: Constant.getActualX(context: context, x: 24),
|
||||
// color: Constant.primaryRed,
|
||||
// ),
|
||||
// ),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Icon(EvaIcons.calendarOutline,
|
||||
color: Constant.textBlack, size: 24),
|
||||
),
|
||||
SizedBox(width: Constant.getActualX(context: context, x: 8)),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
date.value,
|
||||
style: Constant.body1_600(context: context)
|
||||
.copyWith(color: Constant.textBlack),
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
// Icon(EvaIcons.bell, size: 28, color: Constant.primaryRed),
|
||||
SizedBox(
|
||||
width: Constant.getActualX(context: context, x: 24),
|
||||
),
|
||||
// CircleAvatar(
|
||||
// child: Icon(EvaIcons.person),
|
||||
// ),
|
||||
MenuAnchor(
|
||||
style: MenuStyle(
|
||||
backgroundColor: WidgetStatePropertyAll(Colors.white),
|
||||
elevation: WidgetStatePropertyAll(5),
|
||||
padding: WidgetStatePropertyAll(EdgeInsets.all(10)),
|
||||
shape: WidgetStatePropertyAll(RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8))),
|
||||
side: WidgetStatePropertyAll(BorderSide.none)),
|
||||
builder: (BuildContext context, MenuController controller,
|
||||
Widget? child) {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
if (controller.isOpen) {
|
||||
controller.close();
|
||||
} else {
|
||||
controller.open();
|
||||
}
|
||||
},
|
||||
child: CircleAvatar(
|
||||
backgroundColor: Constant.primaryRed,
|
||||
child: Icon(
|
||||
EvaIcons.person,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
alignmentOffset: Offset(-190, 20),
|
||||
menuChildren: [
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 20),
|
||||
width: Constant.getActualX(context: context, x: 200),
|
||||
child: Column(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
backgroundColor: Constant.primaryRed,
|
||||
child: Icon(
|
||||
EvaIcons.person,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(bottom: 10),
|
||||
child: Center(
|
||||
child: Text(
|
||||
auth?.mUserUsername ?? "",
|
||||
style: Constant.body1_600(context: context),
|
||||
))),
|
||||
MenuItemButton(
|
||||
leadingIcon: Icon(
|
||||
EvaIcons.logOut,
|
||||
color: Constant.primaryRed,
|
||||
),
|
||||
onPressed: () {
|
||||
ref.read(logoutProvider.notifier).logout(
|
||||
M_UserID: currentUser!.mUserID ?? "0",
|
||||
M_UserUsername: currentUser.companyName ?? "0");
|
||||
},
|
||||
child: Text(
|
||||
'Logout',
|
||||
style: Constant.body3_400(context: context),
|
||||
),
|
||||
),
|
||||
MenuItemButton(
|
||||
leadingIcon: Icon(
|
||||
EvaIcons.shield,
|
||||
color: Constant.primaryRed,
|
||||
),
|
||||
onPressed: () {
|
||||
showDialog<String>(
|
||||
barrierDismissible: false,
|
||||
context: context,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20)),
|
||||
title: Text(
|
||||
'Ubah Password',
|
||||
style: Constant.body1_600(context: context),
|
||||
),
|
||||
content: ChangePassword(),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
'Ubah Password',
|
||||
style: Constant.body3_400(context: context),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 10, bottom: 10),
|
||||
child: Center(
|
||||
child: Text(Constant.version,
|
||||
style:
|
||||
Constant.caption1_600(context: context).copyWith(
|
||||
color: Constant.textGrey,
|
||||
)),
|
||||
),
|
||||
)
|
||||
])
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ChangePassword extends HookConsumerWidget {
|
||||
const ChangePassword({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final auth = ref.watch(authProvider);
|
||||
final currPassState = useState(true);
|
||||
final newPassState = useState(true);
|
||||
final newPassVerState = useState(true);
|
||||
final loading = useState(false);
|
||||
final updatekey = useState(0);
|
||||
final currPassCtr = useTextEditingController(text: "");
|
||||
final newPassCtr = useTextEditingController(text: "");
|
||||
final newPassVerCtr = useTextEditingController(text: "");
|
||||
newPassVerCtr.addListener(() {
|
||||
updatekey.value = updatekey.value + 1;
|
||||
});
|
||||
changePassword() {
|
||||
ref.read(ChangePasswordProvider.notifier).ChangePassword(
|
||||
token: auth?.token ?? "",
|
||||
current_password: currPassCtr.text,
|
||||
new_password: newPassCtr.text,
|
||||
password_confirmation: newPassVerCtr.text);
|
||||
}
|
||||
|
||||
ref.listen(ChangePasswordProvider, (prev, next) async {
|
||||
if (next is ChangePasswordStateInit) {
|
||||
loading.value = true;
|
||||
} else if (next is ChangePasswordStateLoading) {
|
||||
loading.value = true;
|
||||
} else if (next is ChangePasswordStateError) {
|
||||
SanckbarWidget(context, next.message, snackbarType.error);
|
||||
loading.value = false;
|
||||
Constant.autoLogout(context: context, msg: next.message);
|
||||
} else if (next is ChangePasswordStateDone) {
|
||||
// if (next.message == "OK") {
|
||||
// final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
// await prefs.remove(Constant.tokenName);
|
||||
// Navigator.pushNamed(context, loginRoute);
|
||||
// } else {
|
||||
// SanckbarWidget(context, "ChangePassword Gagal", snackbarType.error);
|
||||
// }
|
||||
ref.read(logoutProvider.notifier).logout(
|
||||
M_UserID: auth!.mUserID ?? "0",
|
||||
M_UserUsername: auth.companyName ?? "0");
|
||||
SanckbarWidget(context, next.message, snackbarType.success);
|
||||
}
|
||||
loading.value = false;
|
||||
});
|
||||
|
||||
return SizedBox(
|
||||
height: Constant.getActualY(context: context, y: 370),
|
||||
width: Constant.getActualX(context: context, x: 300),
|
||||
child: Column(
|
||||
children: [
|
||||
CustomPasswordField(
|
||||
controller: currPassCtr,
|
||||
isPassword: currPassState,
|
||||
hintText: "Current Password",
|
||||
labelText: "Current password"),
|
||||
SizedBox(
|
||||
height: Constant.getActualY(context: context, y: 24),
|
||||
),
|
||||
CustomPasswordField(
|
||||
controller: newPassCtr,
|
||||
isPassword: newPassState,
|
||||
validator: (String? value) {
|
||||
if (value != null) {
|
||||
if (value.isNotEmpty) {
|
||||
// if (value != newPassVerCtr.text) {
|
||||
// return "verifikasi password salah";
|
||||
// }
|
||||
if (!value.contains(RegExp(r'[A-Z]'))) {
|
||||
return " password harus mengandung 1 huruf besar";
|
||||
}
|
||||
if (!value.contains(RegExp(r'[a-z]'))) {
|
||||
return " password harus mengandung 1 huruf kecil";
|
||||
}
|
||||
if (!value.contains(RegExp(r'[0-9]'))) {
|
||||
return " password harus mengandung 1 angka";
|
||||
}
|
||||
if (value.length < 8) {
|
||||
return " password minimal 8 digit";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
hintText: "New Password",
|
||||
labelText: "New password"),
|
||||
SizedBox(
|
||||
height: Constant.getActualY(context: context, y: 24),
|
||||
),
|
||||
CustomPasswordField(
|
||||
controller: newPassVerCtr,
|
||||
isPassword: newPassVerState,
|
||||
validator: (String? value) {
|
||||
if (value != null) {
|
||||
if (value.isNotEmpty) {
|
||||
if (value != newPassCtr.text) {
|
||||
return "verifikasi password salah";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
hintText: "New Password verification",
|
||||
labelText: "New Password verification"),
|
||||
Spacer(),
|
||||
Row(
|
||||
children: [
|
||||
Spacer(),
|
||||
OutlinedButton(
|
||||
style: OutlinedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
side:
|
||||
BorderSide(color: Constant.primaryRed, width: 2),
|
||||
borderRadius: BorderRadius.circular(8))),
|
||||
onPressed: !loading.value
|
||||
? () {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
: null,
|
||||
child: Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 8),
|
||||
child: Text(
|
||||
"Batal",
|
||||
style: Constant.body3_600(context: context)
|
||||
.copyWith(color: Constant.primaryRed),
|
||||
),
|
||||
)),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
ElevatedButton(
|
||||
key: ValueKey(updatekey.value),
|
||||
onPressed: currPassCtr.text.isNotEmpty &&
|
||||
newPassCtr.text.isNotEmpty &&
|
||||
newPassVerCtr.text.isNotEmpty &&
|
||||
newPassCtr.text == newPassVerCtr.text &&
|
||||
loading.value == false
|
||||
? () {
|
||||
changePassword();
|
||||
}
|
||||
: null,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Constant.primaryRed,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8))),
|
||||
child: Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 8),
|
||||
child: loading.value
|
||||
? Center(
|
||||
child: LoadingAnimationWidget.staggeredDotsWave(
|
||||
color: Constant.primaryRed, size: 24),
|
||||
)
|
||||
: Text("Simpan",
|
||||
style: Constant.body3_600(context: context)
|
||||
.copyWith(color: Constant.textWhite)),
|
||||
))
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user