From ee702da5c75b255e1f5bf9b8c41f9483b96883b8 Mon Sep 17 00:00:00 2001 From: sindhu Date: Mon, 15 Jan 2024 16:29:28 +0700 Subject: [PATCH] step 12 : add proteksi login di tiap page --- app_petty_cash/lib/main.dart | 4 +- .../lib/screen/home/home_screen.dart | 18 +++++ .../lib/screen/login/logout_provider.dart | 66 ++++++++++++++++++ .../lib/screen/report/report_screen.dart | 22 +++++- .../screen/transaksi/transaksi_screen.dart | 24 ++++++- .../lib/screen/user/user_screen.dart | 17 +++++ app_petty_cash/lib/widget/custom_drawer.dart | 67 ++++++++++++++++++- 7 files changed, 209 insertions(+), 9 deletions(-) create mode 100644 app_petty_cash/lib/screen/login/logout_provider.dart diff --git a/app_petty_cash/lib/main.dart b/app_petty_cash/lib/main.dart index f3acc47..175c9fe 100644 --- a/app_petty_cash/lib/main.dart +++ b/app_petty_cash/lib/main.dart @@ -38,9 +38,9 @@ class MyApp extends StatelessWidget { }, ), debugShowCheckedModeBanner: false, - initialRoute: loginRoute, + // initialRoute: loginRoute, // initialRoute: splashScreen, - // initialRoute: transaksiRoute, + initialRoute: transaksiRoute, // initialRoute: reportRoute, // initialRoute: testFilePickerRoute, onGenerateRoute: AppRoute.generateRoute, diff --git a/app_petty_cash/lib/screen/home/home_screen.dart b/app_petty_cash/lib/screen/home/home_screen.dart index cf5fc39..606c5b2 100644 --- a/app_petty_cash/lib/screen/home/home_screen.dart +++ b/app_petty_cash/lib/screen/home/home_screen.dart @@ -1,7 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import '../../app/constant.dart'; +import '../../app/route.dart'; +import '../../provider/current_user_provider.dart'; import '../../widget/custom_drawer.dart'; class HomeScreen extends HookConsumerWidget { @@ -9,6 +12,21 @@ class HomeScreen extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + useEffect(() { + WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { + final userID = ref.read(currentUserProvider)?.model.M_UserID ?? "0"; + if (userID == "0") { + //not login + Navigator.of(context) + .pushNamedAndRemoveUntil(loginRoute, (route) => true); + + // Navigator.popAndPushNamed(context, loginRoute); + return; + } + }); + return () {}; + }, []); + return Padding( padding: EdgeInsets.only( top: Constant.getActualYPhone(context: context, y: 30), diff --git a/app_petty_cash/lib/screen/login/logout_provider.dart b/app_petty_cash/lib/screen/login/logout_provider.dart new file mode 100644 index 0000000..f9094c5 --- /dev/null +++ b/app_petty_cash/lib/screen/login/logout_provider.dart @@ -0,0 +1,66 @@ + + +import 'package:equatable/equatable.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import '../../provider/dio_provider.dart'; +import '../../repository/auth_repository.dart'; +import '../../repository/base_repository.dart'; + +// 3. state provider +final logoutProvider = StateNotifierProvider( + (ref) => LogoutNotifier(ref: ref)); + +// 2. notifier +class LogoutNotifier extends StateNotifier { + final Ref ref; + LogoutNotifier({required this.ref}) : super(LogoutStateInit()); + void logout({ + required String M_UserID, + required String M_UserUsername, + }) async { + try { + state = LogoutStateLoading(); + final resp = await AuthRepository(dio: ref.read(dioProvider)) + .logout(M_UserID: M_UserID, M_UserUsername: M_UserUsername); + + // print(resp); + state = LogoutStateDone(message: resp); + } catch (e) { + if (e is BaseRepositoryException) { + state = LogoutStateError(message: e.message); + } else { + state = LogoutStateError(message: e.toString()); + } + } + } +} + +// 1. state +abstract class LogoutState extends Equatable { + final DateTime date; + const LogoutState(this.date); + @override + List get props => [date]; +} + +class LogoutStateInit extends LogoutState { + LogoutStateInit() : super(DateTime.now()); +} + +class LogoutStateLoading extends LogoutState { + LogoutStateLoading() : super(DateTime.now()); +} + +class LogoutStateError extends LogoutState { + final String message; + LogoutStateError({ + required this.message, + }) : super(DateTime.now()); +} + +class LogoutStateDone extends LogoutState { + final String message; + LogoutStateDone({ + required this.message, + }) : super(DateTime.now()); +} diff --git a/app_petty_cash/lib/screen/report/report_screen.dart b/app_petty_cash/lib/screen/report/report_screen.dart index bedbeb2..bb7d928 100644 --- a/app_petty_cash/lib/screen/report/report_screen.dart +++ b/app_petty_cash/lib/screen/report/report_screen.dart @@ -1,4 +1,4 @@ -import 'package:app_petty_cash/widget/sankbar_widget.dart'; +import '../../widget/sankbar_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -6,6 +6,8 @@ import 'package:intl/intl.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../app/constant.dart'; +import '../../app/route.dart'; +import '../../provider/current_user_provider.dart'; import '../../widget/custom_drawer.dart'; class ReportScreen extends HookConsumerWidget { @@ -24,6 +26,21 @@ class ReportScreen extends HookConsumerWidget { final tglAkhir = useState(DateTime.now()); final tglAkhirTmp = useState(""); + useEffect(() { + WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { + final userID = ref.read(currentUserProvider)?.model.M_UserID ?? "0"; + if (userID == "0") { + //not login + Navigator.of(context) + .pushNamedAndRemoveUntil(loginRoute, (route) => true); + + // Navigator.popAndPushNamed(context, loginRoute); + return; + } + }); + return () {}; + }, []); + return Padding( padding: EdgeInsets.only( top: Constant.getActualYPhone(context: context, y: 30), @@ -245,7 +262,8 @@ class ReportScreen extends HookConsumerWidget { String url = "https://pub.dev/packages?q=url+launcher"; if (!await launchUrl(Uri.parse(url))) { // throw Exception('Could not launch $url'); - SanckbarWidget(context, 'Could not launch $url', snackbarType.error); + SanckbarWidget(context, 'Could not launch $url', + snackbarType.error); } }, ), diff --git a/app_petty_cash/lib/screen/transaksi/transaksi_screen.dart b/app_petty_cash/lib/screen/transaksi/transaksi_screen.dart index 5f10a17..f2c6375 100644 --- a/app_petty_cash/lib/screen/transaksi/transaksi_screen.dart +++ b/app_petty_cash/lib/screen/transaksi/transaksi_screen.dart @@ -13,6 +13,7 @@ import 'package:intl/intl.dart'; import '../../app/constant.dart'; import '../../model/list_category_model.dart'; +import '../../provider/current_user_provider.dart'; import '../../widget/custom_drawer.dart'; import '../../widget/sankbar_widget.dart'; import '../login/custom_text_field.dart'; @@ -143,6 +144,21 @@ class TransaksiScreen extends HookConsumerWidget { }, ); + useEffect(() { + WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { + final userID = ref.read(currentUserProvider)?.model.M_UserID ?? "0"; + if (userID == "0") { + //not login + Navigator.of(context) + .pushNamedAndRemoveUntil(loginRoute, (route) => true); + + // Navigator.popAndPushNamed(context, loginRoute); + return; + } + }); + return () {}; + }, []); + useEffect(() { WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { // list Type Provider @@ -308,7 +324,8 @@ class TransaksiScreen extends HookConsumerWidget { child: Row( children: [ Radio( - activeColor: Constant.confirmed, + activeColor: + Constant.pcBtnBackgroundColor, value: listTypeData.value[i], groupValue: selectedListTypeData.value, @@ -681,13 +698,14 @@ class TransaksiScreen extends HookConsumerWidget { top: Constant.getActualYPhone(context: context, y: 10), ), child: BottomAppBar( + elevation: 2.0, child: Container( width: Constant.getActualXPhone(context: context, x: 336), height: Constant.getActualYPhone(context: context, y: 42), child: ElevatedButton( style: ButtonStyle( - backgroundColor: MaterialStateColor.resolveWith((st) => - Constant.pcBtnBackgroundColor), + backgroundColor: MaterialStateColor.resolveWith( + (st) => Constant.pcBtnBackgroundColor), shape: MaterialStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), diff --git a/app_petty_cash/lib/screen/user/user_screen.dart b/app_petty_cash/lib/screen/user/user_screen.dart index fc6b3c5..3f48330 100644 --- a/app_petty_cash/lib/screen/user/user_screen.dart +++ b/app_petty_cash/lib/screen/user/user_screen.dart @@ -1,7 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import '../../app/constant.dart'; +import '../../app/route.dart'; +import '../../provider/current_user_provider.dart'; import '../../widget/custom_drawer.dart'; class UserScreen extends HookConsumerWidget { @@ -9,6 +12,20 @@ class UserScreen extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + useEffect(() { + WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { + final userID = ref.read(currentUserProvider)?.model.M_UserID ?? "0"; + if (userID == "0") { + //not login + Navigator.of(context) + .pushNamedAndRemoveUntil(loginRoute, (route) => true); + + // Navigator.popAndPushNamed(context, loginRoute); + return; + } + }); + return () {}; + }, []); return Padding( padding: EdgeInsets.only( top: Constant.getActualYPhone(context: context, y: 30), diff --git a/app_petty_cash/lib/widget/custom_drawer.dart b/app_petty_cash/lib/widget/custom_drawer.dart index 13f29f5..d25b359 100644 --- a/app_petty_cash/lib/widget/custom_drawer.dart +++ b/app_petty_cash/lib/widget/custom_drawer.dart @@ -1,8 +1,14 @@ +import 'dart:async'; + 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 '../provider/current_user_provider.dart'; +import '../screen/login/logout_provider.dart'; class CustomDrawer extends HookConsumerWidget { const CustomDrawer({ @@ -11,6 +17,53 @@ class CustomDrawer extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + final selectedUser = ref.read(currentUserProvider); + final isLoading = useState(false); + final errorMessage = useState(""); + final successMessage = useState(""); + + useEffect(() { + WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { + final userID = ref.read(currentUserProvider)?.model.M_UserID ?? "0"; + if (userID == "0") { + //not login + Navigator.of(context) + .pushNamedAndRemoveUntil(loginRoute, (route) => true); + + // Navigator.popAndPushNamed(context, loginRoute); + return; + } + }); + return () {}; + }, []); + + ref.listen(logoutProvider, (prev, next) async { + if (next is LogoutStateLoading) { + isLoading.value = true; + } else if (next is LogoutStateError) { + isLoading.value = false; + errorMessage.value = next.message; + Timer(const Duration(seconds: 3), () { + errorMessage.value = ""; + }); + } else if (next is LogoutStateDone) { + isLoading.value = false; + final shared = await SharedPreferences.getInstance(); + final bearerString = shared.get(Constant.bearerName).toString(); + // print(bearerString); + if (bearerString.isNotEmpty) { + shared.remove(bearerString); + shared.clear(); + // Navigator.popAndPushNamed(context, loginRoute); + + Navigator.of(context) + .pushNamedAndRemoveUntil(loginRoute, (route) => false); + } + Timer(const Duration(seconds: 3), () async { + successMessage.value = ""; + }); + } + }); return Drawer( child: ListView( padding: EdgeInsets.only( @@ -45,6 +98,14 @@ class CustomDrawer extends HookConsumerWidget { Navigator.pushNamed(context, transaksiRoute); }, ), + ListTile( + title: Text('Report'), + onTap: () { + // Handle navigation to Transaksi screen + Navigator.pop(context); + Navigator.pushNamed(context, reportRoute); + }, + ), ListTile( title: Text('User'), onTap: () { @@ -56,8 +117,10 @@ class CustomDrawer extends HookConsumerWidget { ListTile( title: Text('Logout'), onTap: () { - // Handle logout logic - Navigator.pop(context); + ref.read(logoutProvider.notifier).logout( + M_UserID: selectedUser?.model.M_UserID ?? "", + M_UserUsername: selectedUser?.model.M_UserUsername ?? "", + ); }, ), ],