step 12 : add proteksi login di tiap page
This commit is contained in:
@@ -38,9 +38,9 @@ class MyApp extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
initialRoute: loginRoute,
|
// initialRoute: loginRoute,
|
||||||
// initialRoute: splashScreen,
|
// initialRoute: splashScreen,
|
||||||
// initialRoute: transaksiRoute,
|
initialRoute: transaksiRoute,
|
||||||
// initialRoute: reportRoute,
|
// initialRoute: reportRoute,
|
||||||
// initialRoute: testFilePickerRoute,
|
// initialRoute: testFilePickerRoute,
|
||||||
onGenerateRoute: AppRoute.generateRoute,
|
onGenerateRoute: AppRoute.generateRoute,
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
|
||||||
import '../../app/constant.dart';
|
import '../../app/constant.dart';
|
||||||
|
import '../../app/route.dart';
|
||||||
|
import '../../provider/current_user_provider.dart';
|
||||||
import '../../widget/custom_drawer.dart';
|
import '../../widget/custom_drawer.dart';
|
||||||
|
|
||||||
class HomeScreen extends HookConsumerWidget {
|
class HomeScreen extends HookConsumerWidget {
|
||||||
@@ -9,6 +12,21 @@ class HomeScreen extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
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(
|
return Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
top: Constant.getActualYPhone(context: context, y: 30),
|
top: Constant.getActualYPhone(context: context, y: 30),
|
||||||
|
|||||||
66
app_petty_cash/lib/screen/login/logout_provider.dart
Normal file
66
app_petty_cash/lib/screen/login/logout_provider.dart
Normal 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());
|
||||||
|
}
|
||||||
@@ -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/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.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 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
import '../../app/constant.dart';
|
import '../../app/constant.dart';
|
||||||
|
import '../../app/route.dart';
|
||||||
|
import '../../provider/current_user_provider.dart';
|
||||||
import '../../widget/custom_drawer.dart';
|
import '../../widget/custom_drawer.dart';
|
||||||
|
|
||||||
class ReportScreen extends HookConsumerWidget {
|
class ReportScreen extends HookConsumerWidget {
|
||||||
@@ -24,6 +26,21 @@ class ReportScreen extends HookConsumerWidget {
|
|||||||
final tglAkhir = useState<DateTime>(DateTime.now());
|
final tglAkhir = useState<DateTime>(DateTime.now());
|
||||||
final tglAkhirTmp = useState<String>("");
|
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(
|
return Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
top: Constant.getActualYPhone(context: context, y: 30),
|
top: Constant.getActualYPhone(context: context, y: 30),
|
||||||
@@ -245,7 +262,8 @@ class ReportScreen extends HookConsumerWidget {
|
|||||||
String url = "https://pub.dev/packages?q=url+launcher";
|
String url = "https://pub.dev/packages?q=url+launcher";
|
||||||
if (!await launchUrl(Uri.parse(url))) {
|
if (!await launchUrl(Uri.parse(url))) {
|
||||||
// throw Exception('Could not launch $url');
|
// throw Exception('Could not launch $url');
|
||||||
SanckbarWidget(context, 'Could not launch $url', snackbarType.error);
|
SanckbarWidget(context, 'Could not launch $url',
|
||||||
|
snackbarType.error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import 'package:intl/intl.dart';
|
|||||||
|
|
||||||
import '../../app/constant.dart';
|
import '../../app/constant.dart';
|
||||||
import '../../model/list_category_model.dart';
|
import '../../model/list_category_model.dart';
|
||||||
|
import '../../provider/current_user_provider.dart';
|
||||||
import '../../widget/custom_drawer.dart';
|
import '../../widget/custom_drawer.dart';
|
||||||
import '../../widget/sankbar_widget.dart';
|
import '../../widget/sankbar_widget.dart';
|
||||||
import '../login/custom_text_field.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(() {
|
useEffect(() {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
||||||
// list Type Provider
|
// list Type Provider
|
||||||
@@ -308,7 +324,8 @@ class TransaksiScreen extends HookConsumerWidget {
|
|||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Radio<ListType>(
|
Radio<ListType>(
|
||||||
activeColor: Constant.confirmed,
|
activeColor:
|
||||||
|
Constant.pcBtnBackgroundColor,
|
||||||
value: listTypeData.value[i],
|
value: listTypeData.value[i],
|
||||||
groupValue:
|
groupValue:
|
||||||
selectedListTypeData.value,
|
selectedListTypeData.value,
|
||||||
@@ -681,13 +698,14 @@ class TransaksiScreen extends HookConsumerWidget {
|
|||||||
top: Constant.getActualYPhone(context: context, y: 10),
|
top: Constant.getActualYPhone(context: context, y: 10),
|
||||||
),
|
),
|
||||||
child: BottomAppBar(
|
child: BottomAppBar(
|
||||||
|
elevation: 2.0,
|
||||||
child: Container(
|
child: Container(
|
||||||
width: Constant.getActualXPhone(context: context, x: 336),
|
width: Constant.getActualXPhone(context: context, x: 336),
|
||||||
height: Constant.getActualYPhone(context: context, y: 42),
|
height: Constant.getActualYPhone(context: context, y: 42),
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
backgroundColor: MaterialStateColor.resolveWith((st) =>
|
backgroundColor: MaterialStateColor.resolveWith(
|
||||||
Constant.pcBtnBackgroundColor),
|
(st) => Constant.pcBtnBackgroundColor),
|
||||||
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
|
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
|
||||||
RoundedRectangleBorder(
|
RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
|
||||||
import '../../app/constant.dart';
|
import '../../app/constant.dart';
|
||||||
|
import '../../app/route.dart';
|
||||||
|
import '../../provider/current_user_provider.dart';
|
||||||
import '../../widget/custom_drawer.dart';
|
import '../../widget/custom_drawer.dart';
|
||||||
|
|
||||||
class UserScreen extends HookConsumerWidget {
|
class UserScreen extends HookConsumerWidget {
|
||||||
@@ -9,6 +12,20 @@ class UserScreen extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
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(
|
return Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
top: Constant.getActualYPhone(context: context, y: 30),
|
top: Constant.getActualYPhone(context: context, y: 30),
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
import '../app/constant.dart';
|
import '../app/constant.dart';
|
||||||
import '../app/route.dart';
|
import '../app/route.dart';
|
||||||
|
import '../provider/current_user_provider.dart';
|
||||||
|
import '../screen/login/logout_provider.dart';
|
||||||
|
|
||||||
class CustomDrawer extends HookConsumerWidget {
|
class CustomDrawer extends HookConsumerWidget {
|
||||||
const CustomDrawer({
|
const CustomDrawer({
|
||||||
@@ -11,6 +17,53 @@ class CustomDrawer extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
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(
|
return Drawer(
|
||||||
child: ListView(
|
child: ListView(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
@@ -45,6 +98,14 @@ class CustomDrawer extends HookConsumerWidget {
|
|||||||
Navigator.pushNamed(context, transaksiRoute);
|
Navigator.pushNamed(context, transaksiRoute);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
ListTile(
|
||||||
|
title: Text('Report'),
|
||||||
|
onTap: () {
|
||||||
|
// Handle navigation to Transaksi screen
|
||||||
|
Navigator.pop(context);
|
||||||
|
Navigator.pushNamed(context, reportRoute);
|
||||||
|
},
|
||||||
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('User'),
|
title: Text('User'),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@@ -56,8 +117,10 @@ class CustomDrawer extends HookConsumerWidget {
|
|||||||
ListTile(
|
ListTile(
|
||||||
title: Text('Logout'),
|
title: Text('Logout'),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
// Handle logout logic
|
ref.read(logoutProvider.notifier).logout(
|
||||||
Navigator.pop(context);
|
M_UserID: selectedUser?.model.M_UserID ?? "",
|
||||||
|
M_UserUsername: selectedUser?.model.M_UserUsername ?? "",
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user