step 12 : add proteksi login di tiap page

This commit is contained in:
sindhu
2024-01-15 16:29:28 +07:00
parent 24353ba729
commit ee702da5c7
7 changed files with 209 additions and 9 deletions

View File

@@ -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,

View File

@@ -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),

View File

@@ -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<LogoutNotifier, LogoutState>(
(ref) => LogoutNotifier(ref: ref));
// 2. notifier
class LogoutNotifier extends StateNotifier<LogoutState> {
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<Object?> 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());
}

View File

@@ -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>(DateTime.now());
final tglAkhirTmp = useState<String>("");
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);
}
},
),

View File

@@ -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<ListType>(
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>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),

View File

@@ -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),

View File

@@ -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 ?? "",
);
},
),
],