Browse Source

fix context get & post

Yulian 2 tháng trước cách đây
mục cha
commit
c88361e6f5

+ 1 - 0
lib/app_router.dart

@@ -8,6 +8,7 @@ import 'package:telnow_mobile_new/src/utils/U.dart';
 
 @AutoRouterConfig(replaceInRouteName: 'Screen|Page,Route')
 class AppRouter extends RootStackRouter {
+  AppRouter({super.navigatorKey});
   final SharedPreferencesManager _sharedPreferencesManager = locator<SharedPreferencesManager>();
 
   @override

+ 22 - 22
lib/main.dart

@@ -29,6 +29,7 @@ import 'package:http/http.dart' as http;
 import 'package:telnow_mobile_new/src/api/jwt_token.dart';
 
 import 'app_router.dart';
+import 'package:telnow_mobile_new/src/utils/ui_service.dart';
 
 // final SharedPreferencesManager _sharedPreferencesManager = locator<SharedPreferencesManager>();
 var isDebug = true;
@@ -68,8 +69,6 @@ void main() async{
     await setupLocator();
     SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
     HttpOverrides.global = MyHttpOverrides();
-    // WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
-    // FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
     runApp(
         EasyLocalization(
             path: 'assets/lang',
@@ -96,7 +95,6 @@ void main() async{
 }
 
 class MyCustomScrollBehavior extends MaterialScrollBehavior {
-  // Override behavior methods and getters like dragDevices
   @override
   Set<PointerDeviceKind> get dragDevices {
     return {
@@ -106,11 +104,10 @@ class MyCustomScrollBehavior extends MaterialScrollBehavior {
   }
 }
 
+final _appRouter = AppRouter(navigatorKey: UIService.navigatorKey);
 class MyApp extends StatelessWidget {
-  MyApp({super.key});
-  final _appRouter = AppRouter();
+  const MyApp({super.key});
 
-  // This widget is the root of your application.
   @override
   Widget build(BuildContext context) {
     return MultiProvider(
@@ -123,6 +120,8 @@ class MyApp extends StatelessWidget {
         ChangeNotifierProvider(create: (_) => MessageModule()),
       ],
       child: MaterialApp.router(
+        // routerDelegate: _appRouter.delegate(),
+        // routeInformationParser: _appRouter.defaultRouteParser(),
         scrollBehavior: MyCustomScrollBehavior(),
         debugShowCheckedModeBanner: false,
         localizationsDelegates: context.localizationDelegates,
@@ -161,9 +160,9 @@ class _HomeGuardPageState extends State<HomeGuardPage> {
   @override
   Widget build(BuildContext context) {
     eventBus.on().listen((event) {
-      // print("eventBus => ${event.toString()}");
-      if(mounted && event.toString() == 'logout') {
-        context.navigateToPath('/end-session');
+      if(event.toString() == 'logout') {
+        UIService.navigateTo('/end-session');
+        // context.navigateToPath('/end-session');
       }
     });
     // TODO: implement build
@@ -187,6 +186,8 @@ class NotificationClass {
   final ApiAuthProvider _apiAuthProvider = ApiAuthProvider();
 
   initFirebaseMessaging(BuildContext context) {
+    final locale = context.locale.toString();
+
     FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
       var mid = message.data['mid'];
       var token = await U.getFcmToken();
@@ -199,7 +200,7 @@ class NotificationClass {
       if(kIsWeb){
         QuickNotify.notify(
           title: message.data['subject'],
-          content: context.locale.toString() == 'id' ? message.data['description'] : message.data['descriptionEn'],
+          content: locale == 'id' ? message.data['description'] : message.data['descriptionEn'],
         );
       }
       else{
@@ -230,21 +231,24 @@ class NotificationClass {
         );
         var platformChannelSpecifics = NotificationDetails(android: androidPlatformChannelSpecifics);
         U.flutterLocalNotificationsPlugin.show(0, message.data['subject'],
-            context.locale.toString() == 'id' ? message.data['description'] : message.data['descriptionEn'], platformChannelSpecifics,
+            locale == 'id' ? message.data['description'] : message.data['descriptionEn'], platformChannelSpecifics,
             payload: jsonEncode(message.data));
       }
     });
 
     FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
+
     FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) {
       if (message != null && !U.hidePayload) {
-        // print(message.data);
-        goNotification(message.data, context);
+        // goNotification(message.data, context);
+        UIService.goNotification(message.data);
       }
     });
+
     FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
       U.setHidePayload(false);
-      goNotification(message.data, context);
+      UIService.goNotification(message.data);
+      // goNotification(message.data, context);
     });
   }
 
@@ -254,10 +258,11 @@ class NotificationClass {
   }
 
   startNotification(BuildContext context, {code}) async {
+    final locale = context.locale.toString();
     var token = await U.getFcmToken();
     if (token != null) {
-      Map data = {'token': token, 'language': code ?? context.locale.toString().toUpperCase()};
-      var res = _apiAuthProvider.postData('/api/fcmTokens/register', null, data, context);
+      Map data = {'token': token, 'language': code ?? locale.toUpperCase()};
+      var res = _apiAuthProvider.postData('/api/fcmTokens/register', null, data);
       return res;
     }
   }
@@ -265,7 +270,7 @@ class NotificationClass {
   stopNotification(BuildContext context) async {
     var token = await U.getFcmToken();
     if (token != null) {
-      var res = _apiAuthProvider.postData('/api/fcmTokens/remove/$token', null, null, context);
+      var res = _apiAuthProvider.postData('/api/fcmTokens/remove/$token', null, null);
       return res;
     }
   }
@@ -283,11 +288,6 @@ class NotificationClass {
       context.router.removeLast();
       context.navigateToPath("/app/$pid/menu/history");
     }
-    // if (list['type'] == 'FORUM') {
-    //   Navigator.push(context, PageTransition(type: PageTransitionType.rightToLeft, child: Forum(list['info'], list['currentStatus'] == 'DIMULAI' || list['currentStatus'] == 'DISELESAIKAN' ? true : false)));
-    // } else {
-    //   Navigator.push(context, PageTransition(type: PageTransitionType.rightToLeft, child: DetailMisi(list['info'])));
-    // }
   }
 }
 

+ 38 - 27
lib/src/api/api_auth_provider.dart

@@ -9,6 +9,7 @@ import 'package:telnow_mobile_new/src/model/refreshtoken/refresh_token_body.dart
 import 'package:telnow_mobile_new/src/model/token/token.dart';
 import 'package:telnow_mobile_new/src/layouts/components/template.dart';
 import 'package:telnow_mobile_new/src/storage/sharedpreferences/shared_preferences_manager.dart';
+import 'package:telnow_mobile_new/src/utils/ui_service.dart';
 import 'package:telnow_mobile_new/src/utils/dio_logging_interceptors.dart';
 import 'package:telnow_mobile_new/src/utils/U.dart';
 import 'package:easy_localization/easy_localization.dart';
@@ -180,7 +181,7 @@ class ApiAuthProvider {
           handlingError(context, 2); //error connection
         } else {
           await Future.delayed(Duration(milliseconds: 200));
-          return getData(path, params, context, secondCheck: true);
+          return getData(path, params, secondCheck: true);
         }
         //error server
       } else if (error.response?.statusCode == 401) {
@@ -191,7 +192,7 @@ class ApiAuthProvider {
           handlingError(context, 2); //error connection
         } else {
           await Future.delayed(Duration(milliseconds: 200));
-          return getData(path, params, context, secondCheck: true);
+          return getData(path, params, secondCheck: true);
         }
       }
       return Future.error(error);
@@ -202,7 +203,7 @@ class ApiAuthProvider {
     }
   }
 
-  Future getData(String path, var params, BuildContext context, {bool secondCheck = false}) async {
+  Future getData(String path, var params, {bool secondCheck = false}) async {
     try {
       Response<String> response = await _dio.getUri(
         Uri(path: path, queryParameters: params),
@@ -212,31 +213,28 @@ class ApiAuthProvider {
           },
         ),
       );
-//      print(response.data);
       return json.decode(response.data!);
     } on DioException catch (error) {
-      // print(error.response!.statusCode);
-      bool isOpen = ModalRoute.of(context)?.isCurrent != true;
+      bool isOpen = UIService.isCurrentRouteInactive;
       if (error.response == null) {
         try {
           final result = await InternetAddress.lookup('google.com');
           if (!isOpen && result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
-            handlingError(context, 1); //error server
+            UIService.handlingError(ErrorType.noInternet); //error server
           }
         } on SocketException catch (_) {
-          // if(!isOpen) handlingError(context, 0); //no internet
         }
+
       } else if (!isOpen && error.response!.statusCode! >= 500) {
-        handlingError(context, 1); //error server
+        UIService.handlingError(ErrorType.serverError); //error server
       } else if (!isOpen && error.response?.statusCode == 401) {
-        handlingError(context, 3); //error auth
+        UIService.handlingError(ErrorType.invalidAccount); //error auth
       } else {
         if(!isOpen){
           if (secondCheck) {
-            // print('secondCheck');
-            handlingError(context, 2); //error connection
+            UIService.handlingError(ErrorType.connectionError); //error connection
           } else {
-            return getData(path, params, context, secondCheck: true);
+            return getData(path, params, secondCheck: true);
           }
         }
       }
@@ -244,7 +242,7 @@ class ApiAuthProvider {
     }
   }
 
-  Future postData(String path, var params, var data, context) async {
+  Future postData(String path, var params, var data) async {
     try {
       Response response = await _dio.postUri(
         Uri(path: path, queryParameters: params),
@@ -263,37 +261,50 @@ class ApiAuthProvider {
         try {
           final result = await InternetAddress.lookup('google.com');
           if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
-            showError(context, 'errorConnection'.tr());
+            UIService.showError('errorConnection'.tr());
+            // showError(context, 'errorConnection'.tr());
           }
         } on SocketException catch (_) {
-          showError(context, 'noInternet'.tr());
+          UIService.showError('noInternet'.tr());
+          // showError(context, 'noInternet'.tr());
         }
       } else if (error.response!.statusCode! >= 500) {
-        showError(context, 'errorConnection'.tr());
+        UIService.showError('errorConnection'.tr());
+        // showError(context, 'errorConnection'.tr());
       } else if (error.response?.statusCode == 401) {
-        handlingError(context, 3); //error auth
+        UIService.handlingError(ErrorType.invalidAccount);
+        // handlingError(context, 3); //error auth
       } else if (error.response?.statusCode == 422) {
         if(error.response?.data['message'] == 'Worktime did not found'){
-          showError(context, 'notFoundWorktime'.tr());
+          UIService.showError('notFoundWorktime'.tr());
+          // showError(context, 'notFoundWorktime'.tr());
         } else if(error.response?.data['message'] == 'Cant send broadcast message, you have not permission.'){
-          showError(context, 'broadcastPermission'.tr());
+          UIService.showError('broadcastPermission'.tr());
+          // showError(context, 'broadcastPermission'.tr());
         } else if(error.response?.data['message'] == 'Cant send broadcast message, you have not permission.'){
-          showError(context, 'broadcastPermission'.tr());
+          UIService.showError('broadcastPermission'.tr());
+          // showError(context, 'broadcastPermission'.tr());
         } else if(error.response?.data['message'] == 'request did not match informant rights'){
-          showError(context, 'idNotMatch'.tr().replaceAll("#ID", data['user_id']));
+          UIService.showError('idNotMatch'.tr().replaceAll("#ID", data['user_id']));
+          // showError(context, 'idNotMatch'.tr().replaceAll("#ID", data['user_id']));
         } else if(error.response?.data['message'] == 'Informant user id not found.' ||
             error.response?.data['message'] == 'invalid user informant requested'
         ){
-          showError(context, 'idNotFound'.tr());
+          UIService.showError('idNotFound'.tr());
+          // showError(context, 'idNotFound'.tr());
         } else if(error.response?.data['message'] == 'You are not registered as receptionist or room attendant.'){
-          showError(context, 'informantNotRegistered'.tr());
+          UIService.showError('informantNotRegistered'.tr());
+          // showError(context, 'informantNotRegistered'.tr());
         } else if(error.response?.data['message'] == 'invalid parent ticket'){
-          showError(context, 'invalidParentTicket'.tr());
+          UIService.showError('invalidParentTicket'.tr());
+          // showError(context, 'invalidParentTicket'.tr());
         } else {
-          showError(context, error.response?.data['message']);
+          UIService.showError(error.response?.data['message']);
+          // showError(context, error.response?.data['message']);
         }
       } else {
-        showError(context, 'errorServer'.tr());
+        UIService.showError('errorServer'.tr());
+        // showError(context, 'errorServer'.tr());
       }
       return null;
     }

+ 1 - 1
lib/src/api/jwt_token.dart

@@ -76,7 +76,7 @@ class JwtToken{
       Map<String, dynamic>? user;
 
       if(U.getInternetStatus()){
-        user = await _apiAuthProvider.getData(url, null, context);
+        user = await _apiAuthProvider.getData(url, null);
       }
       else{
         var val = await CacheMan.readData(url);

+ 1 - 1
lib/src/layouts/auth/change_code.dart

@@ -168,7 +168,7 @@ class _ChangeCodePageState extends State<ChangeCodePage> {
                                       context.navigateToPath("/app/$rawPid/login");
                                     } else {
                                       var param = {'token': tkn, 'whiteListToken': false};
-                                      var res = await _apiAuthProvider.postData('/api/fcmTokens/remove/', null, param, context);
+                                      var res = await _apiAuthProvider.postData('/api/fcmTokens/remove/', null, param);
                                       if (res != null && res['success']) {
                                         token.logout();
                                         context.router.removeLast();

+ 13 - 8
lib/src/layouts/auth/login.dart

@@ -16,6 +16,7 @@ import 'package:telnow_mobile_new/src/model/login/login_body.dart';
 import 'package:telnow_mobile_new/src/storage/sharedpreferences/shared_preferences_manager.dart';
 import 'package:telnow_mobile_new/src/utils/C.dart';
 import 'package:telnow_mobile_new/src/utils/U.dart';
+import 'package:telnow_mobile_new/src/utils/ui_service.dart';
 import 'package:telnow_mobile_new/src/utils/cache_manager.dart';
 import 'package:toggle_switch/toggle_switch.dart';
 import 'package:url_launcher/url_launcher.dart';
@@ -258,7 +259,8 @@ class _LoginPageState extends State<LoginPage> {
       }
 
       if (errMsg.isNotEmpty) {
-        showError(context, errMsg);
+        UIService.showError(errMsg);
+        // showError(context, errMsg);
         setState(()=>loading = false);
         return;
       }
@@ -482,7 +484,7 @@ class _ForceChgPassPageState extends State<ForceChgPassPage> {
   getTokenData() async {
     String accessToken = sharedPreferencesManager.getString(SharedPreferencesManager.keyAccessToken)!;
     var jwt = token.parseJwtPayLoad(accessToken);
-    var user = await apiAuthProvider.getData('/api/informants/${jwt['userId']}', null, context);
+    var user = await apiAuthProvider.getData('/api/informants/${jwt['userId']}', null);
     if(user!=null){
       setState((){
         tokenData = jwt;
@@ -493,11 +495,11 @@ class _ForceChgPassPageState extends State<ForceChgPassPage> {
   }
 
   getCompanyName() async {
-    var lics = await U.reloadLicense();
-    if (lics != null && mounted) {
+    var license = await U.reloadLicense();
+    if (license != null && mounted) {
       setState(() {
-        companyName = lics['companyName']??'';
-        serialNumber = lics['serialNumber']??'';
+        companyName = license['companyName']??'';
+        serialNumber = license['serialNumber']??'';
       });
     }
   }
@@ -645,7 +647,8 @@ class _ForceChgPassPageState extends State<ForceChgPassPage> {
               Token token = await apiAuthRepository.postLoginUser(loginBody);
               if (token.error != null) {
                 setState(()=>loading = false);
-                showError(context, token.error);
+                UIService.showError(token.error.toString());
+                // showError(context, token.error);
               } else {
                 await U.setChangedPassword(true);
                 var parsedToken = U.token.parseJwtPayLoad(token.accessToken!);
@@ -673,7 +676,9 @@ class _ForceChgPassPageState extends State<ForceChgPassPage> {
         }
       }
       else{
-        showError(context, 'cannotEmpty'.tr());
+        debugPrint("Mbuh");
+        UIService.showError('cannotEmpty'.tr());
+        // showError(context, 'cannotEmpty'.tr());
       }
     }
   }

+ 1 - 1
lib/src/layouts/components/auto_login.dart

@@ -100,7 +100,7 @@ class _AutoLoginPageState extends State<AutoLoginPage> {
       String accessToken = sharedPreferencesManager.getString(SharedPreferencesManager.keyAccessToken)!;
       var jwt = jwtToken.parseJwtPayLoad(accessToken);
       // print(jwt);
-      var user = await apiAuthProvider.getData('/api/informants/${jwt['userId']}', null, context);
+      var user = await apiAuthProvider.getData('/api/informants/${jwt['userId']}', null);
       if(user != null){
         closeLoading(context);
         setState((){

+ 0 - 12
lib/src/layouts/components/template.dart

@@ -144,18 +144,6 @@ Widget shimmerTopMenu(BuildContext context){
           borderRadius: BorderRadius.all(Radius.circular(20)),
         ),
       );
-
-      // return Shimmer.fromColors(
-      //   baseColor: Colors.grey[400]!,
-      //   highlightColor: Colors.white,
-      //   child: Container(
-      //     width: size, height: size,
-      //     decoration: BoxDecoration(
-      //       color: Colors.white,
-      //       borderRadius: BorderRadius.all(Radius.circular(20)),
-      //     ),
-      //   ),
-      // );
     }),
   );
 }

+ 1 - 1
lib/src/layouts/functions/account.dart

@@ -83,7 +83,7 @@ class AccountFunction{
         context.navigateToPath("/app/$pid/login");
       } else {
         var param = {'token': tkn, 'whiteListToken': false};
-        var res = await apiAuthProvider.postData('/api/fcmTokens/remove/', null, param, context);
+        var res = await apiAuthProvider.postData('/api/fcmTokens/remove/', null, param);
         if (res != null && res['success']) {
           Navigator.of(context).pop();
           closeLoading(context);

+ 1 - 1
lib/src/layouts/functions/detail.dart

@@ -86,7 +86,7 @@ class DetailFunction{
           'note': controllerNote.text.trim(),
         };
 
-        var res = await apiAuthProvider.postData('/api/requestHistories/search/request/cancel/'+list['ticketNo'], null, data, context);
+        var res = await apiAuthProvider.postData('/api/requestHistories/search/request/cancel/'+list['ticketNo'], null, data);
         if(res != null){
           closeLoading(context);
           navigateBack(context, exc: true);

+ 4 - 4
lib/src/layouts/functions/history.dart

@@ -39,7 +39,7 @@ class HistoryFunction{
         Provider.of<HistoryModule>(context, listen: false).setActiveForum(val['data']);
       }
 
-      var data = await apiAuthProvider.getData(urlForum, null, context);
+      var data = await apiAuthProvider.getData(urlForum, null);
       if (data != null) {
         Provider.of<HistoryModule>(context, listen: false).setActiveForum(data);
         CacheMan.writeData(urlForum, data);
@@ -109,7 +109,7 @@ class HistoryFunction{
           Provider.of<HistoryModule>(context, listen: false).setMisi(val['data']);
         }
 
-        var misi = await apiAuthProvider.getData(url, {'size': '30', 'page': Provider.of<HistoryModule>(context, listen: false).page().toString(), 'sort': sort, 'filter': filter}, context);
+        var misi = await apiAuthProvider.getData(url, {'size': '30', 'page': Provider.of<HistoryModule>(context, listen: false).page().toString(), 'sort': sort, 'filter': filter});
         if (misi != null) {
           List tempData = [];
           if (misi.containsKey('_embedded')) {
@@ -220,7 +220,7 @@ class HistoryFunction{
                   Provider.of<HistoryModule>(context, listen: false).selectedIndexes().forEach((e) {
                     params.add(Provider.of<HistoryModule>(context, listen: false).dataMisi()[e]["ticketNo"]);
                   });
-                  var res = await apiAuthProvider.postData("/api/requestHistories/deleteMyHistory", {"ticketNumbers": params}, null, context);
+                  var res = await apiAuthProvider.postData("/api/requestHistories/deleteMyHistory", {"ticketNumbers": params}, null);
                   if (res != null) {
                     onRefresh(context);
                   }
@@ -242,7 +242,7 @@ class HistoryFunction{
       }
       filter = '{"and":[{"f":["code","EQ","${Provider.of<HistoryModule>(context, listen: false).dataMisi()[i]['requestCode']}"]}$tenant]}';
 
-      var res = await apiAuthProvider.getData('/api/requests/search/customFind', {'filter': filter}, context);
+      var res = await apiAuthProvider.getData('/api/requests/search/customFind', {'filter': filter});
       if (res != null) {
         if (res.containsKey('_embedded')) {
           navigateTo(context, U.webView(context)?WebReqCreatePage(user: Provider.of<UserModule>(context, listen: false).user(), request: res['_embedded']['requests'][0]):MobReqCreatePage(user: Provider.of<UserModule>(context, listen: false).user(), request: res['_embedded']['requests'][0]));

+ 11 - 11
lib/src/layouts/functions/home.dart

@@ -53,7 +53,7 @@ class HomeFunction{
         Provider.of<ServiceModule>(context, listen: false).setScoope(val['data']);
       }
 
-      var res = await apiAuthProvider.getData(url, null, context);
+      var res = await apiAuthProvider.getData(url, null);
       if (res != null) {
         CacheMan.writeData(url, res);
         Provider.of<ServiceModule>(context, listen: false).setScoope(res);
@@ -100,7 +100,7 @@ class HomeFunction{
         Provider.of<ServiceModule>(context, listen: false).setSpecialOffer(val['data']);
       }
 
-      var res = await apiAuthProvider.getData(url, null, context);
+      var res = await apiAuthProvider.getData(url, null);
       if (res != null) {
         if (res.length > 0) {
           CacheMan.writeData(url, res);
@@ -125,7 +125,7 @@ class HomeFunction{
         Provider.of<ServiceModule>(context, listen: false).setReqGroup(val['data']['excludeTopMenu']);
       }
 
-      var res = await apiAuthProvider.getData(url, {'responseServantGroup': U.servantDisplay().toString()}, context);
+      var res = await apiAuthProvider.getData(url, {'responseServantGroup': U.servantDisplay().toString()});
       if (res != null) {
         CacheMan.writeData('$url?responseServantGroup=${U.servantDisplay()}', res);
         Provider.of<ServiceModule>(context, listen: false).setTopMenu(res['topMenu']);
@@ -147,7 +147,7 @@ class HomeFunction{
         Provider.of<ServiceModule>(context, listen: false).setTopMenu(val['data']);
       }
 
-      var res = await apiAuthProvider.getData(url, {'responseServantGroup': U.servantDisplay().toString()}, context);
+      var res = await apiAuthProvider.getData(url, {'responseServantGroup': U.servantDisplay().toString()});
       if (res != null) {
         List tempData = [];
         tempData.addAll(res);
@@ -178,7 +178,7 @@ class HomeFunction{
         Provider.of<ServiceModule>(context, listen: false).setReqGroup(val['data']);
       }
 
-      var res = await apiAuthProvider.getData(url, {'responseServantGroup': U.servantDisplay().toString()}, context);
+      var res = await apiAuthProvider.getData(url, {'responseServantGroup': U.servantDisplay().toString()});
       if (res != null) {
         List tempData = [];
         tempData.addAll(res);
@@ -206,7 +206,7 @@ class HomeFunction{
         Provider.of<ServiceModule>(context, listen: false).setData(val['data']);
       }
 
-      var res = await apiAuthProvider.getData(url, null, context);
+      var res = await apiAuthProvider.getData(url, null);
       if (res != null) {
         if (res.length > 0) {
           CacheMan.writeData(url, res);
@@ -230,7 +230,7 @@ class HomeFunction{
         Provider.of<ServiceModule>(context, listen: false).setBanner(val['data']);
       }
 
-      var res = await apiAuthProvider.getData(url, {'size': '20'}, context);
+      var res = await apiAuthProvider.getData(url, {'size': '20'});
       if (res != null) {
         if (res.length > 0) {
           CacheMan.writeData(url, res);
@@ -254,7 +254,7 @@ class HomeFunction{
         Provider.of<ServiceModule>(context, listen: false).setQuickAct(val['data']);
       }
 
-      var res = await apiAuthProvider.getData(url, null, context);
+      var res = await apiAuthProvider.getData(url, null);
       if (res != null) {
         if (res.length > 0) {
           CacheMan.writeData(url, res);
@@ -272,7 +272,7 @@ class HomeFunction{
   getContactCenter(BuildContext context) async {
     try{
       var url = "/api/contactCenter/whatsapp" ;
-      var res = await apiAuthProvider.getData(url, null, context);
+      var res = await apiAuthProvider.getData(url, null);
       if (res != null) {
         Provider.of<ServiceModule>(context, listen: false).setContactCenter(res);
       }
@@ -283,7 +283,7 @@ class HomeFunction{
 
   getUnreadMessages(BuildContext context) async {
     try {
-      var res = await apiAuthProvider.getData('/api/messages/search/myMessages', null, context);
+      var res = await apiAuthProvider.getData('/api/messages/search/myMessages', null);
       if (res != null) {
         List tempData = [];
         Provider.of<ServiceModule>(context, listen: false).setUnreadMessage(false);
@@ -308,7 +308,7 @@ class HomeFunction{
     if(await U.isCompatibleWith(VersionKey.multiBahasa) == false) return;
     try{
       String url = '/api/messages/search/myForum';
-      var res = await apiAuthProvider.getData(url, null, context);
+      var res = await apiAuthProvider.getData(url, null);
       if (res != null) {
         for (int i = 0; i < res.length; i++) {
           if (res[i]['readStatus'] == 'UNREAD' && res[i]['userId'] != Provider.of<UserModule>(context, listen: false).user()['userId']){

+ 4 - 4
lib/src/layouts/functions/message.dart

@@ -33,7 +33,7 @@ class MessageFunction{
       Provider.of<MessageModule>(context, listen: false).setData(val['data']);
     }
 
-    var res = await apiAuthProvider.getData(url, null, context);
+    var res = await apiAuthProvider.getData(url, null);
     if (res != null) {
       List tempData = [];
       if (res['_embedded'] != null) {
@@ -58,7 +58,7 @@ class MessageFunction{
       messageModule.setForum(val['data']);
     }
 
-    var res = await apiAuthProvider.getData(url, null, context);
+    var res = await apiAuthProvider.getData(url, null);
     if (res != null) {
       List tempData = [];
       for (int i = 0; i < res.length; i++) {
@@ -74,7 +74,7 @@ class MessageFunction{
   }
 
   setAsRead(context, ticketNo) async {
-    var res = await apiAuthProvider.postData('/api/notifications/readMyForum/$ticketNo', null, null, context);
+    var res = await apiAuthProvider.postData('/api/notifications/readMyForum/$ticketNo', null, null);
     if (res != null) {
     }
   }
@@ -89,7 +89,7 @@ class MessageFunction{
     }
 
     try{
-      var res = await apiAuthProvider.getData(url, {'isPaged': 'true', 'size': '1000', 'sort': 'description'}, context);
+      var res = await apiAuthProvider.getData(url, {'isPaged': 'true', 'size': '1000', 'sort': 'description'});
       if (res != null) {
         List tempData = [];
         if (res['_embedded'] != null) {

+ 4 - 4
lib/src/layouts/functions/request.dart

@@ -76,7 +76,7 @@ class RequestFunction{
         }
         List tempData = [];
 
-        var res = await apiAuthProvider.getData(url, {'filter': filter, 'nopage': 'true'}, context);
+        var res = await apiAuthProvider.getData(url, {'filter': filter, 'nopage': 'true'});
         if (res != null && res.toString() != "[]") {
           if (res.containsKey('_embedded')) {
             for (int i = 0; i < res['_embedded']['requests'].length; i++) {
@@ -102,7 +102,7 @@ class RequestFunction{
   }
 
   Future getSuggestionLocation(BuildContext context) async{
-    var res = await apiAuthProvider.getData('/api/requestHistories/search/location/suggestion', null, context);
+    var res = await apiAuthProvider.getData('/api/requestHistories/search/location/suggestion', null);
     if(res != null){
       Provider.of<CreateSerModule>(context, listen: false).setSuggestion(res);
     }
@@ -167,7 +167,7 @@ class RequestFunction{
       });
       data['images'] = imageEncode;
 
-      var res = await apiAuthProvider.postData('/api/requestHistories/search/request/' + widget.request['type'] + '/' + widget.request['id'].toString() + '/' + widget.request['noteFormat'] + '/submit', null, data, context);
+      var res = await apiAuthProvider.postData('/api/requestHistories/search/request/' + widget.request['type'] + '/' + widget.request['id'].toString() + '/' + widget.request['noteFormat'] + '/submit', null, data);
       if (res != null) {
         Future.delayed(Duration(seconds: 3), (){
           closeLoading(context);
@@ -222,7 +222,7 @@ class RequestFunction{
       data['req'][0]['images'] = imageEncode;
 
       try{
-        var res = await apiAuthProvider.postData('/api/receptionists/send/request', null, data, context);
+        var res = await apiAuthProvider.postData('/api/receptionists/send/request', null, data);
         print("res ##> $res");
         if (res != null) {
           Future.delayed(Duration(seconds: 3), (){

+ 3 - 3
lib/src/layouts/mobile/history_forum.dart

@@ -86,7 +86,7 @@ class _MobHistoryForumPageState extends State<MobHistoryForumPage> {
   }
 
   setAsRead(ticketNo) async {
-    var res = await apiAuthProvider.postData('/api/notifications/readMyForum/$ticketNo', null, null, context);
+    var res = await apiAuthProvider.postData('/api/notifications/readMyForum/$ticketNo', null, null);
     if (res != null) {
     }
   }
@@ -95,7 +95,7 @@ class _MobHistoryForumPageState extends State<MobHistoryForumPage> {
     if (!isLoad && !stopLoad) {
       setState(() => isLoad = true);
       setAsRead(widget.data['ticketNo']);
-      var mymess = await apiAuthProvider.getData('/api/messages/search/myMessages/${idChat!}', {'isPaged': 'true', 'page': page.toString(), 'size': '20'}, context);
+      var mymess = await apiAuthProvider.getData('/api/messages/search/myMessages/${idChat!}', {'isPaged': 'true', 'page': page.toString(), 'size': '20'});
       if (mymess.containsKey('_embedded')) {
         List data = mymess['_embedded']['myMessages'];
         for (int i = 0; i < data.length; i++) {
@@ -247,7 +247,7 @@ class _MobHistoryForumPageState extends State<MobHistoryForumPage> {
       scrollBottom = true;
     });
 
-    var res = await apiAuthProvider.postData('/api/messages', null, data, context);
+    var res = await apiAuthProvider.postData('/api/messages', null, data);
     if (res != null) {
       int index = messageData.indexWhere((element) => element['uniqueId'] == data['uniqueId']);
       setState(() {

+ 1 - 1
lib/src/layouts/mobile/history_rating.dart

@@ -156,7 +156,7 @@ class _MobHistoryRatingPageState extends State<MobHistoryRatingPage> {
                             data['aspect'] = controllerOptOther.text;
                           }
 
-                          var res = await ApiAuthProvider() .postData('/api/requestHistories/rateSatisfy', null, data, context);
+                          var res = await ApiAuthProvider() .postData('/api/requestHistories/rateSatisfy', null, data);
                           closeLoading(context);
                           if (res != null) {
                             Navigator.of(context).pop(tempRating);

+ 1 - 1
lib/src/layouts/mobile/menu_history.dart

@@ -606,7 +606,7 @@ class _MobHistoryPageState extends State<MobHistoryPage> with TickerProviderStat
                               if (tempRating > 0) {
                                 var data = {"ticketNo": list['ticketNo'], "rateSatisfy": tempRating};
 
-                                var res = await ApiAuthProvider() .postData('/api/requestHistories/rateSatisfy', null, data, contexts);
+                                var res = await ApiAuthProvider() .postData('/api/requestHistories/rateSatisfy', null, data);
                                 if (res != null) {
                                   Provider.of<HistoryModule>(context, listen: false).setSatisfaction(index, tempRating);
                                   navigateBack(contexts);

+ 1 - 1
lib/src/layouts/mobile/menu_home.dart

@@ -798,7 +798,7 @@ class _MobMenuEditorPageState extends State<MobMenuEditorPage> {
                   codes.add(element['code']);
                 }
 
-                var res = await ApiAuthProvider().postData('/api/informants/topMenu/${widget.scope}', {'topMenu': codes.join(';')}, null, context);
+                var res = await ApiAuthProvider().postData('/api/informants/topMenu/${widget.scope}', {'topMenu': codes.join(';')}, null);
                 if(res != null){
                   serviceModule.setTopMenu(data);
                   serviceModule.setReqGroup(available);

+ 1 - 1
lib/src/layouts/mobile/message_broadcast.dart

@@ -60,7 +60,7 @@ class _MobMessageBroadcastPageState extends State<MobMessageBroadcastPage> {
     setState(() {
       _isSending = true;
     });
-    var res = await _apiAuthProvider.postData('/api/messages/broadcast', params, data, context);
+    var res = await _apiAuthProvider.postData('/api/messages/broadcast', params, data);
     // print("res : ${res.toString()}");
     if (res != null && mounted) {
       Navigator.pop(context, 'pop');

+ 1 - 1
lib/src/layouts/mobile/message_chat.dart

@@ -83,7 +83,7 @@ class _MobMessageChatPageState extends State<MobMessageChatPage> {
     }
     if (!isLoad && !stopLoad) {
       setState(() => isLoad = true);
-      var mymess = await apiAuthProvider.getData('/api/messages/search/$url', {'isPaged': 'true', 'page': page.toString(), 'size': '20', 'filter': filter, 'tenant': widget.tenant}, context);
+      var mymess = await apiAuthProvider.getData('/api/messages/search/$url', {'isPaged': 'true', 'page': page.toString(), 'size': '20', 'filter': filter, 'tenant': widget.tenant});
       if (mymess.containsKey('_embedded') && mounted) {
         List data = mymess['_embedded']['myMessages'];
         for (int i = 0; i < data.length; i++) {

+ 1 - 1
lib/src/layouts/mobile/request_success.dart

@@ -34,7 +34,7 @@ class _MobReqSuccessPageState extends State<MobReqSuccessPage> {
   }
 
   getMission() async{
-    var data = await apiAuthProvider.getData('/api/requestHistories/'+widget.ticketNo, null, context);
+    var data = await apiAuthProvider.getData('/api/requestHistories/'+widget.ticketNo, null);
     if(data != null) {
       if (data['datetimeScheduled'] != null && data['datetimeScheduled'] != '' && data['noteFormat'] == 'DATE') {
         var date = data['datetimeScheduled'];

+ 3 - 3
lib/src/layouts/web/history_forum.dart

@@ -87,7 +87,7 @@ class _WebHistoryForumPageState extends State<WebHistoryForumPage> {
   }
 
   setAsRead(ticketNo) async {
-    var res = await apiAuthProvider.postData('/api/notifications/readMyForum/$ticketNo', null, null, context);
+    var res = await apiAuthProvider.postData('/api/notifications/readMyForum/$ticketNo', null, null);
     if (res != null) {
     }
   }
@@ -96,7 +96,7 @@ class _WebHistoryForumPageState extends State<WebHistoryForumPage> {
     if (!isLoad && !stopLoad) {
       setState(() => isLoad = true);
       setAsRead(widget.data['ticketNo']);
-      var mymess = await apiAuthProvider.getData('/api/messages/search/myMessages/' + idChat!, {'isPaged': 'true', 'page': page.toString(), 'size': '20'}, context);
+      var mymess = await apiAuthProvider.getData('/api/messages/search/myMessages/' + idChat!, {'isPaged': 'true', 'page': page.toString(), 'size': '20'});
       if (mymess.containsKey('_embedded')) {
         List data = mymess['_embedded']['myMessages'];
         for (int i = 0; i < data.length; i++) {
@@ -215,7 +215,7 @@ class _WebHistoryForumPageState extends State<WebHistoryForumPage> {
       scrollBottom = true;
     });
 
-    var res = await apiAuthProvider.postData('/api/messages', null, data, context);
+    var res = await apiAuthProvider.postData('/api/messages', null, data);
     if (res != null) {
       int index = messageData.indexWhere((element) => element['uniqueId'] == data['uniqueId']);
       setState(() {

+ 2 - 2
lib/src/layouts/web/menu_history.dart

@@ -631,7 +631,7 @@ class _WebHistoryPageState extends State<WebHistoryPage> with TickerProviderStat
                                     if (tempRating > 0) {
                                       var data = {"ticketNo": list['ticketNo'], "rateSatisfy": tempRating};
 
-                                      var res = await ApiAuthProvider() .postData('/api/requestHistories/rateSatisfy', null, data, contexts);
+                                      var res = await ApiAuthProvider() .postData('/api/requestHistories/rateSatisfy', null, data);
                                       if (res != null) {
                                         Provider.of<HistoryModule>(context, listen: false).setSatisfaction(index, tempRating);
                                         navigateBack(contexts);
@@ -799,7 +799,7 @@ class _WebHistoryPageState extends State<WebHistoryPage> with TickerProviderStat
                                         data['aspect'] = controllerOptOther.text;
                                       }
 
-                                      var res = await ApiAuthProvider() .postData('/api/requestHistories/rateSatisfy', null, data, contexts);
+                                      var res = await ApiAuthProvider() .postData('/api/requestHistories/rateSatisfy', null, data);
                                       if (res != null) {
                                         Provider.of<HistoryModule>(context, listen: false).setSatisfaction(index, tempRating);
                                         navigateBack(contexts);

+ 1 - 1
lib/src/layouts/web/menu_home.dart

@@ -906,7 +906,7 @@ class _WebMenuEditorPageState extends State<WebMenuEditorPage> {
                             codes.add(element['code']);
                           });
 
-                          var res = await ApiAuthProvider().postData('/api/informants/topMenu/${widget.scope}', {'topMenu': codes.join(';')}, null, context);
+                          var res = await ApiAuthProvider().postData('/api/informants/topMenu/${widget.scope}', {'topMenu': codes.join(';')}, null);
                           if(res != null){
                             Provider.of<ServiceModule>(context, listen: false).setTopMenu(data);
                             Provider.of<ServiceModule>(context, listen: false).setReqGroup(available);

+ 1 - 1
lib/src/layouts/web/message_broadcast.dart

@@ -67,7 +67,7 @@ class _WebMessageBroadcastPageState extends State<WebMessageBroadcastPage> {
     setState(() {
       isSending = true;
     });
-    var res = await ApiAuthProvider().postData('/api/messages/broadcast', params, data, context);
+    var res = await ApiAuthProvider().postData('/api/messages/broadcast', params, data);
     if (res != null) {
       Navigator.pop(context, 'pop');
     }

+ 3 - 3
lib/src/layouts/web/message_list.dart

@@ -144,7 +144,7 @@ class _WebMessageListPageState extends State<WebMessageListPage> {
     }
     if (!isLoad && !stopLoad) {
       isLoad = true;
-      var mymess = await apiAuthProvider.getData('/api/messages/search/$url', {'isPaged': 'true', 'page': page.toString(), 'size': '20', 'filter': filter, 'tenant': tenant}, context);
+      var mymess = await apiAuthProvider.getData('/api/messages/search/$url', {'isPaged': 'true', 'page': page.toString(), 'size': '20', 'filter': filter, 'tenant': tenant});
       if (mymess.containsKey('_embedded') && mounted) {
         List data = mymess['_embedded']['myMessages'];
         for (int i = 0; i < data.length; i++) {
@@ -188,7 +188,7 @@ class _WebMessageListPageState extends State<WebMessageListPage> {
     try{
       var mymess = await apiAuthProvider.getData(
           '/api/messages/search/myMessages/${forumChatId}',
-          {'isPaged': 'true', 'page': page.toString(), 'size': '20'}, context);
+          {'isPaged': 'true', 'page': page.toString(), 'size': '20'});
 
       if (mymess.containsKey('_embedded')) {
         List data = mymess['_embedded']['myMessages'];
@@ -996,7 +996,7 @@ class _WebMessageListPageState extends State<WebMessageListPage> {
       });
       scrollBottom = true;
 
-      var res = await apiAuthProvider.postData('/api/messages', null, data, context);
+      var res = await apiAuthProvider.postData('/api/messages', null, data);
       if (res != null) {
         int index = forumData.indexWhere((element) => element['uniqueId'] == data['uniqueId']);
         forumData[index]['read'] = false;

+ 1 - 1
lib/src/layouts/web/request_success.dart

@@ -33,7 +33,7 @@ class _WebReqSuccessPageState extends State<WebReqSuccessPage> {
   }
 
   getMission() async{
-    var data = await apiAuthProvider.getData('/api/requestHistories/'+widget.ticketNo, null, context);
+    var data = await apiAuthProvider.getData('/api/requestHistories/'+widget.ticketNo, null);
     if(data != null) {
       if (data['datetimeScheduled'] != null && data['datetimeScheduled'] != '' && data['noteFormat'] == 'DATE') {
         var date = data['datetimeScheduled'];

+ 3 - 3
lib/src/utils/U.dart

@@ -392,7 +392,7 @@ class U {
   static Map _otherLabelList = {};
   static getOtherLabelList(BuildContext context) async{
     if(newServerVersion(1725245109)){
-      var res = await ApiAuthProvider().getData('/api/systemSettings/search/additional', {'key': 'request-for-other'}, context);
+      var res = await ApiAuthProvider().getData('/api/systemSettings/search/additional', {'key': 'request-for-other'});
       if(res != null){
         _otherLabelList = res;
       }
@@ -587,7 +587,7 @@ class U {
         if(element['others']){
           data['req'][0]['uniqueId'] = element['uniqueId'];
           data['req'][0]['images'] = element['imageList'];
-          var res = await ApiAuthProvider().postData('/api/receptionists/send/request', null, data, context);
+          var res = await ApiAuthProvider().postData('/api/receptionists/send/request', null, data);
           if (res != null) {
             uniqueId.add(res['uniqueId']);
             // print('success send pending request others');
@@ -596,7 +596,7 @@ class U {
         else{
           data['uniqueId'] = element['uniqueId'];
           data['images'] = element['imageList'];
-          var res = await ApiAuthProvider().postData('/api/requestHistories/search/request/' + element['type'] + '/' + element['id'].toString() + '/' + element['noteFormat'] + '/submit', null, data, context);
+          var res = await ApiAuthProvider().postData('/api/requestHistories/search/request/${element['type']}/${element['id'].toString()}/${element['noteFormat']}/submit', null, data);
           if (res != null) {
             uniqueId.add(res['uniqueId']);
             // print('success send pending request');

+ 210 - 0
lib/src/utils/ui_service.dart

@@ -0,0 +1,210 @@
+import 'dart:convert';
+import 'package:another_flushbar/flushbar.dart';
+import 'package:auto_route/auto_route.dart';
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/material.dart';
+import 'package:page_transition/page_transition.dart';
+import 'package:telnow_mobile_new/src/injector/injector.dart';
+import 'package:telnow_mobile_new/src/layouts/auth/qr.dart';
+import 'package:telnow_mobile_new/src/layouts/mobile/history_forum.dart';
+import 'package:telnow_mobile_new/src/layouts/mobile/message_list.dart';
+import 'U.dart';
+import 'package:telnow_mobile_new/src/storage/sharedpreferences/shared_preferences_manager.dart';
+import 'package:telnow_mobile_new/src/api/jwt_token.dart';
+
+enum ErrorType {
+  noInternet, serverError, connectionError, invalidAccount, expiredAccount
+}
+final SharedPreferencesManager _sharedPreferencesManager = locator<SharedPreferencesManager>();
+final JwtToken token = JwtToken();
+
+class UIService {
+  static final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
+
+  static BuildContext? get context => navigatorKey.currentContext;
+
+  static void goNotification(Map<String, dynamic> list) {
+    final ctx = context;
+    if (ctx == null) return;
+
+    if (list['type'] == 'MESSAGE') {
+      Navigator.push(
+        ctx,
+        PageTransition(
+          type: PageTransitionType.rightToLeft,
+          child: MobMessageListPage(null),
+        ),
+      );
+    } else if (list['type'] == 'FORUM') {
+      Navigator.push(
+        ctx,
+        PageTransition(
+          type: PageTransitionType.rightToLeft,
+          child: MobHistoryForumPage(
+            data: jsonDecode(list['requestHistory']),
+          ),
+        ),
+      );
+    } else {
+      final pid = U.getPidFromUrl(ctx.router.currentUrl);
+      ctx.router.removeLast();
+      ctx.navigateToPath("/app/$pid/menu/history");
+    }
+  }
+
+  static void navigateTo(String routePath) {
+    final ctx = context;
+    if (ctx != null) {
+      AutoRouter.of(ctx).navigatePath(routePath);
+    }
+  }
+
+  static void showError(String message) {
+    final ctx = context;
+    if (ctx != null) {
+      Flushbar(
+        message: message,
+        icon: Icon(
+          Icons.info_outline,
+          size: 28.0,
+          color: Colors.red,
+        ),
+        duration: Duration(seconds: 5),
+        flushbarPosition: FlushbarPosition.BOTTOM,
+        margin: EdgeInsets.all(8),
+        borderRadius: BorderRadius.all(Radius.circular(8)),
+      ).show(ctx);
+    }
+  }
+
+  static bool get isCurrentRouteInactive {
+    final ctx = context;
+    final route = ModalRoute.of(ctx ?? navigatorKey.currentState?.context ?? ctx!);
+    return route?.isCurrent != true;
+  }
+
+  static void pop() {
+    navigatorKey.currentState?.maybePop();
+  }
+
+  static void handlingError(ErrorType type) {
+    var data = [
+      {
+        'image': 'NoInternet.png',
+        'title': 'noInternetTitle'.tr(),
+        'description': 'noInternetDesc'.tr()
+      },
+      {
+        'image': 'ErrorServer.png',
+        'title': 'errorServerTitle'.tr(),
+        'description': 'errorServerDesc'.tr()
+      },
+      {
+        'image': 'ErrorConnection.png',
+        'title': 'errorConnectTitle'.tr(),
+        'description': 'errorConnectDesc'.tr()
+      },
+      {
+        'image': 'ErrorAuth.png',
+        'title': 'invalidAccountTitle'.tr(),
+        'description': 'invalidAccountDesc'.tr()
+      },
+      {
+        'image': 'ErrorAuth.png',
+        'title': 'expAccountTitle'.tr(),
+        'description': 'expAccountDesc'.tr()
+      }
+    ];
+    int idx = type.index;
+
+    final ctx = context;
+    if (ctx == null) return;
+
+    void clearSharedPreferencesKey(){
+      _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyAccessCode);
+      _sharedPreferencesManager.clearKey(SharedPreferencesManager.keySerialCode);
+      _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyAccessToken);
+      _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyRefreshToken);
+      _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyUsername);
+      _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyIsLogin);
+      _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyScoope);
+      _sharedPreferencesManager.clearKey(SharedPreferencesManager.debugString);
+      _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyHistoryMark);
+    }
+
+    showModalBottomSheet<void>(
+      context: ctx,
+      backgroundColor: Colors.white,
+      isDismissible: false,
+      enableDrag: false,
+      builder: (BuildContext context) {
+        return SingleChildScrollView(
+          child: Column(
+            mainAxisSize: MainAxisSize.min,
+            children: <Widget>[
+              Container(
+                padding: const EdgeInsets.fromLTRB(15, 10, 15, 0),
+                alignment: Alignment.centerRight,
+                child: GestureDetector(
+                  child: Icon(Icons.clear),
+                  onTap: () => Navigator.of(context).pop(),
+                ),
+              ),
+              Container(
+                width: 200,
+                padding: const EdgeInsets.fromLTRB(15, 0, 15, 10),
+                child: Image(
+                  image: AssetImage('assets/image/error/${data[idx]['image']!}'))),
+              Padding(
+                padding: const EdgeInsets.fromLTRB(15, 0, 15, 10),
+                child: Text(data[idx]['title']!,
+                  style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
+                  textAlign: TextAlign.center),
+              ),
+              Padding(
+                padding: const EdgeInsets.fromLTRB(15, 0, 15, 10),
+                child: Text(data[idx]['description']!,
+                  style: TextStyle(fontSize: 14),
+                  textAlign: TextAlign.center),
+              ),
+              if (idx > 2)
+              Padding(
+                padding: const EdgeInsets.fromLTRB(15, 0, 15, 10),
+                child: SizedBox(
+                  width: double.infinity,
+                  height: 45,
+                  child: TextButton(
+                    style: ButtonStyle(
+                      backgroundColor:
+                      WidgetStateProperty.all<Color>(primaryColor),
+                      shape: WidgetStateProperty.all<
+                        RoundedRectangleBorder>(
+                        RoundedRectangleBorder(
+                          borderRadius: BorderRadius.circular(5),
+                        ))),
+                    child: Text('logout'.tr().toUpperCase(),
+                      style: TextStyle(color: Colors.white),
+                      textAlign: TextAlign.center),
+                    onPressed: () {
+                      if (idx == 4) {
+                        clearSharedPreferencesKey();
+                        Navigator.pushAndRemoveUntil(
+                          context,
+                          MaterialPageRoute(
+                            builder: (context) => NewQrPage()),
+                          ModalRoute.withName("/home"));
+                      } else {
+                        var pid = U.getPidFromUrl(context.router.currentUrl);
+                        token.logout();
+                        context.router.removeLast();
+                        context.navigateToPath("/app/$pid/login");
+                      }
+                    },
+                  )),
+              )
+            ],
+          ),
+        );
+      });
+  }
+}