|
|
|
|
import 'dart:convert';
|
|
|
|
|
import 'dart:developer';
|
|
|
|
|
|
|
|
|
|
import 'package:easy_localization/src/public_ext.dart';
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
|
|
|
import 'package:flutter_svg/svg.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/app_state/app_state.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/classes/inAppWebView.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/classes/utils.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/config/routes.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/main.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/models/dashboard/menu_entries.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/models/generic_response_model.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/models/sso_auth_model.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/ui/my_attendance/services_menu_list_screen.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
|
|
|
|
|
import 'package:provider/provider.dart';
|
|
|
|
|
import 'package:url_launcher/url_launcher.dart';
|
|
|
|
|
|
|
|
|
|
class ServicesWidget extends StatelessWidget {
|
|
|
|
|
MyInAppBrowser? myInAppBrowser;
|
|
|
|
|
var inAppBrowserOptions = InAppBrowserClassSettings(
|
|
|
|
|
webViewSettings: InAppWebViewSettings(
|
|
|
|
|
useShouldOverrideUrlLoading: false,
|
|
|
|
|
transparentBackground: false,
|
|
|
|
|
isInspectable: false,
|
|
|
|
|
applePayAPIEnabled: true,
|
|
|
|
|
cacheEnabled: false,
|
|
|
|
|
allowsBackForwardNavigationGestures: false,
|
|
|
|
|
),
|
|
|
|
|
browserSettings: InAppBrowserSettings(
|
|
|
|
|
hideUrlBar: true,
|
|
|
|
|
hideTitleBar: true,
|
|
|
|
|
hideDefaultMenuItems: true,
|
|
|
|
|
hideToolbarBottom: true,
|
|
|
|
|
hideToolbarTop: false,
|
|
|
|
|
hideCloseButton: false,
|
|
|
|
|
allowGoBackWithBackButton: false,
|
|
|
|
|
toolbarBottomBackgroundColor: Colors.black,
|
|
|
|
|
closeButtonColor: Colors.white,
|
|
|
|
|
presentationStyle: ModalPresentationStyle.FULL_SCREEN,
|
|
|
|
|
// toolbarTopBackgroundColor: Colors.black
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
List<String> namesT = [LocaleKeys.monthlyAttendance.tr(), LocaleKeys.workFromHome.tr(), LocaleKeys.ticketRequest.tr(), LocaleKeys.monthlyAttendance.tr()];
|
|
|
|
|
List<String> iconT = [
|
|
|
|
|
"assets/images/monthly_attendance.svg",
|
|
|
|
|
"assets/images/monthly_attendance.svg",
|
|
|
|
|
"assets/images/ticket_request.svg",
|
|
|
|
|
"assets/images/ticket_bal.svg",
|
|
|
|
|
"assets/images/vacation_rule.svg",
|
|
|
|
|
"assets/images/ticket_request.svg",
|
|
|
|
|
"assets/images/ticket_request.svg",
|
|
|
|
|
"assets/images/ticket_request.svg",
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return Consumer<DashboardProviderModel>(
|
|
|
|
|
builder: (context, data, child) {
|
|
|
|
|
return data.isServicesMenusLoading
|
|
|
|
|
? whileLoading()
|
|
|
|
|
: ListView.separated(
|
|
|
|
|
padding: const EdgeInsets.only(top: 0),
|
|
|
|
|
itemBuilder: (context, parentIndex) {
|
|
|
|
|
return Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
|
children: [
|
|
|
|
|
data.homeMenus![parentIndex].menuEntry.prompt!.toSectionHeading().paddingOnly(left: 21, right: 21),
|
|
|
|
|
SizedBox(
|
|
|
|
|
height: 105 + 26,
|
|
|
|
|
child: ListView.separated(
|
|
|
|
|
shrinkWrap: true,
|
|
|
|
|
physics: const BouncingScrollPhysics(),
|
|
|
|
|
padding: const EdgeInsets.only(left: 21, right: 21, top: 13, bottom: 13),
|
|
|
|
|
scrollDirection: Axis.horizontal,
|
|
|
|
|
itemBuilder: (cxt, index) {
|
|
|
|
|
return AspectRatio(
|
|
|
|
|
aspectRatio: 105 / 105,
|
|
|
|
|
child:
|
|
|
|
|
data.isServicesMenusLoading
|
|
|
|
|
? ServicesMenuShimmer()
|
|
|
|
|
: Container(
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
color: Colors.white,
|
|
|
|
|
borderRadius: BorderRadius.circular(15),
|
|
|
|
|
boxShadow: [BoxShadow(color: const Color(0xff000000).withOpacity(.05), blurRadius: 26, offset: const Offset(0, -3))],
|
|
|
|
|
),
|
|
|
|
|
child: Column(
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
SvgPicture.asset(
|
|
|
|
|
AppState().isArabic(context)
|
|
|
|
|
? getMenuIconAr(data.homeMenus![parentIndex].menuEntiesList[index].prompt!)
|
|
|
|
|
: getMenuIconEn(data.homeMenus![parentIndex].menuEntiesList[index].prompt!),
|
|
|
|
|
),
|
|
|
|
|
Row(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
|
|
children: [
|
|
|
|
|
Expanded(child: data.homeMenus![parentIndex].menuEntiesList[index].prompt!.toText11(isBold: true)),
|
|
|
|
|
RotatedBox(quarterTurns: AppState().isArabic(context) ? 2 : 4, child: SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4)),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
).paddingOnly(left: 10, right: 10, bottom: 10, top: 12),
|
|
|
|
|
).onPress(() {
|
|
|
|
|
handleOnPress(context, data.homeMenus![parentIndex].menuEntiesList[index]);
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
separatorBuilder: (cxt, index) => 9.width,
|
|
|
|
|
itemCount: data.homeMenus![parentIndex].menuEntiesList.length,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
separatorBuilder: (context, index) {
|
|
|
|
|
return 12.height;
|
|
|
|
|
},
|
|
|
|
|
shrinkWrap: true,
|
|
|
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
|
|
|
itemCount: data.homeMenus!.length,
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String getMenuIconAr(String name) {
|
|
|
|
|
String returnImage = "";
|
|
|
|
|
switch (name) {
|
|
|
|
|
case "الحضور الشهري":
|
|
|
|
|
returnImage = "assets/images/services_icons/monthly_attendance.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "كشف الراتب":
|
|
|
|
|
returnImage = "assets/images/services_icons/payslips.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "تغيير معلومات البنك":
|
|
|
|
|
returnImage = "assets/images/services_icons/change_bank_details.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "طلب بدل السكن مقدما":
|
|
|
|
|
returnImage = "assets/images/services_icons/housing_allowance.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "شهادات تعريف الموظف":
|
|
|
|
|
returnImage = "assets/images/services_icons/employee_certificates.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "البيانات الشخصية":
|
|
|
|
|
returnImage = "assets/images/personal-info.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "الحضور":
|
|
|
|
|
returnImage = "assets/images/services_icons/my_attendance.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "طلبات أخرى":
|
|
|
|
|
returnImage = "assets/images/services_icons/other_requests.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "الإجازات":
|
|
|
|
|
returnImage = "assets/images/services_icons/my_leaves.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "طلب تذكرة":
|
|
|
|
|
returnImage = "assets/images/services_icons/ticket_bal.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "قاعدة الاجازات":
|
|
|
|
|
returnImage = "assets/images/services_icons/vacation_rule.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "مستنداتي":
|
|
|
|
|
returnImage = "assets/images/document.svg";
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
returnImage = "assets/images/monthly_attendance.svg";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return returnImage;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String getMenuIconEn(String name) {
|
|
|
|
|
String returnImage = "";
|
|
|
|
|
switch (name) {
|
|
|
|
|
case "Monthly Attendance":
|
|
|
|
|
returnImage = "assets/images/services_icons/monthly_attendance.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "Payslip":
|
|
|
|
|
returnImage = "assets/images/services_icons/payslips.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "Change Bank Details":
|
|
|
|
|
returnImage = "assets/images/services_icons/change_bank_details.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "Housing Advance":
|
|
|
|
|
returnImage = "assets/images/services_icons/housing_allowance.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "Employee Certificate":
|
|
|
|
|
returnImage = "assets/images/services_icons/employee_certificates.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "Personal Information":
|
|
|
|
|
returnImage = "assets/images/personal-info.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "My Attendance":
|
|
|
|
|
returnImage = "assets/images/services_icons/my_attendance.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "Other Requests":
|
|
|
|
|
returnImage = "assets/images/services_icons/other_requests.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "My Leave":
|
|
|
|
|
returnImage = "assets/images/services_icons/my_leaves.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "Ticket Request":
|
|
|
|
|
returnImage = "assets/images/services_icons/ticket_bal.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "Vacation Rule":
|
|
|
|
|
returnImage = "assets/images/services_icons/vacation_rule.svg";
|
|
|
|
|
break;
|
|
|
|
|
case "My Documents":
|
|
|
|
|
returnImage = "assets/images/document.svg";
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
returnImage = "assets/images/monthly_attendance.svg";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return returnImage;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> handleOnPress(context, GetMenuEntriesList menuEntry) async {
|
|
|
|
|
var pro = Provider.of<DashboardProviderModel>(context, listen: false);
|
|
|
|
|
if (menuEntry.requestType == "MONTHLY_ATTENDANCE") {
|
|
|
|
|
Navigator.pushNamed(context, AppRoutes.monthlyAttendance);
|
|
|
|
|
return;
|
|
|
|
|
} else if (menuEntry.requestType == "VACATION_RULE") {
|
|
|
|
|
Navigator.pushNamed(context, AppRoutes.vacationRule);
|
|
|
|
|
return;
|
|
|
|
|
} else if (menuEntry.menuName == "MBL_PERINFO_SS") {
|
|
|
|
|
Navigator.of(context).pushNamed(AppRoutes.profile);
|
|
|
|
|
return;
|
|
|
|
|
} else if (menuEntry.menuName!.isNotEmpty && menuEntry.menuName!.substring(4, menuEntry.menuName!.length) == "MBL_EMPLOYEE_DOCUMENTS") {
|
|
|
|
|
Navigator.pushNamed(context, AppRoutes.myDocuments);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
List<GetMenuEntriesList> menuList = pro.getMenuEntriesList?.where((element) => element.parentMenuName == menuEntry.menuName && (element.menuEntryType == "FUNCTION")).toList() ?? [];
|
|
|
|
|
menuEntry.icon = "";
|
|
|
|
|
if (menuList.isEmpty) {
|
|
|
|
|
if (menuEntry.requestType == "EIT") {
|
|
|
|
|
Navigator.pushNamed(context, AppRoutes.dynamicScreen, arguments: DynamicListViewParams(menuEntry.prompt!, menuEntry.functionName!));
|
|
|
|
|
} else if (menuEntry.requestType == "PAYSLIP") {
|
|
|
|
|
Navigator.pushNamed(context, AppRoutes.monthlyPaySlip);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (menuEntry.menuName == "HMG_TICKET_REQUESTS") {
|
|
|
|
|
Utils.showLoading(context);
|
|
|
|
|
print("=========");
|
|
|
|
|
TicketBookingResult response = await pro.fetchTicketBooking();
|
|
|
|
|
Utils.hideLoading(context);
|
|
|
|
|
if (response.success) {
|
|
|
|
|
print("============ Allowed ============");
|
|
|
|
|
SSOAuthModel? ssoToken = await pro.fetchSSOAuthRedirection(clientID: response.clientId);
|
|
|
|
|
if (ssoToken != null) {
|
|
|
|
|
logger.d(ssoToken.data!.toJson());
|
|
|
|
|
logger.d(ssoToken.data!.accessToken);
|
|
|
|
|
|
|
|
|
|
dynamic valu = await pro.fetchURLRedirection(token: ssoToken.data!.accessToken!);
|
|
|
|
|
|
|
|
|
|
myInAppBrowser = MyInAppBrowser(
|
|
|
|
|
onExitCallback: () {
|
|
|
|
|
log("Browser Exited");
|
|
|
|
|
},
|
|
|
|
|
onLoadStartCallback: (String url) {
|
|
|
|
|
log("Browser LoadStart for : $url");
|
|
|
|
|
if (url.contains("https://ek.techmaster.in/")) {
|
|
|
|
|
// Handle the URL as needed
|
|
|
|
|
log("SSO URL Loaded: $url");
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
await myInAppBrowser!.openUrlRequest(
|
|
|
|
|
urlRequest: URLRequest(
|
|
|
|
|
url: WebUri(valu, forceToStringRawValue: true),
|
|
|
|
|
allowsCellularAccess: true,
|
|
|
|
|
allowsConstrainedNetworkAccess: true,
|
|
|
|
|
allowsExpensiveNetworkAccess: true,
|
|
|
|
|
// headers: {'Authorization': 'Bearer ${ssoToken.data!.accessToken}'},
|
|
|
|
|
),
|
|
|
|
|
settings: inAppBrowserOptions,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Navigator.of(context).push(
|
|
|
|
|
// MaterialPageRoute(
|
|
|
|
|
// builder:
|
|
|
|
|
// (context) => WebViewWidget(
|
|
|
|
|
// controller:
|
|
|
|
|
// WebViewController()
|
|
|
|
|
// ..setJavaScriptMode(JavaScriptMode.unrestricted)
|
|
|
|
|
// ..setNavigationDelegate(
|
|
|
|
|
// NavigationDelegate(
|
|
|
|
|
// onNavigationRequest: (NavigationRequest request) {
|
|
|
|
|
// return NavigationDecision.navigate;
|
|
|
|
|
// },
|
|
|
|
|
// onHttpError: (HttpResponseError response) {
|
|
|
|
|
// print(response.response!.statusCode);
|
|
|
|
|
// },
|
|
|
|
|
// onProgress: (int value) {
|
|
|
|
|
// print(value);
|
|
|
|
|
// },
|
|
|
|
|
// onWebResourceError: (WebResourceError error) {
|
|
|
|
|
// print(error.errorCode);
|
|
|
|
|
// print(error.description);
|
|
|
|
|
// },
|
|
|
|
|
// ),
|
|
|
|
|
// )
|
|
|
|
|
// ..loadRequest(Uri.parse("https://ek.techmaster.in/SSO/HMG"), headers: {'Authorization': 'Bearer ${ssoToken.data!.accessToken}'}),
|
|
|
|
|
// ),
|
|
|
|
|
// ),
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
// launchUrl(Uri.parse("https://ek.techmaster.in/SSO/HMG"),headers: {'Authorization': 'Bearer ${ssoToken.data!.accessToken}'}, mode: LaunchMode.inAppBrowserView);
|
|
|
|
|
// ddv
|
|
|
|
|
print("============ Token Fetched ============");
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
List<GetMenuEntriesList> _menuList =
|
|
|
|
|
pro.getMenuEntriesList?.where((element) => element.parentMenuName == menuEntry.menuName && (element.menuEntryType == "FUNCTION" || element.menuEntryType == "MENU")).toList() ?? [];
|
|
|
|
|
Navigator.pushNamed(context, AppRoutes.servicesMenuListScreen, arguments: ServicesMenuListScreenParams(menuEntry.prompt!, _menuList.isEmpty ? menuList : _menuList));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
List<GetMenuEntriesList> _menuList =
|
|
|
|
|
pro.getMenuEntriesList?.where((element) => element.parentMenuName == menuEntry.menuName && (element.menuEntryType == "FUNCTION" || element.menuEntryType == "MENU")).toList() ?? [];
|
|
|
|
|
Navigator.pushNamed(context, AppRoutes.servicesMenuListScreen, arguments: ServicesMenuListScreenParams(menuEntry.prompt!, _menuList.isEmpty ? menuList : _menuList));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String firstWord(String value) {
|
|
|
|
|
return value.split(" ").length > 1 ? value.split(" ")[0] : "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String lastWord(String value) {
|
|
|
|
|
var parts = value.split(" ");
|
|
|
|
|
if (parts.length == 1) {
|
|
|
|
|
return value;
|
|
|
|
|
} else {
|
|
|
|
|
int i = value.indexOf(" ");
|
|
|
|
|
return value.substring(i + 1).toCamelCase;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget whileLoading() {
|
|
|
|
|
return Column(
|
|
|
|
|
children: [
|
|
|
|
|
ServicesHeaderShimmer().paddingOnly(left: 21, right: 21, top: 21),
|
|
|
|
|
SizedBox(
|
|
|
|
|
height: 105 + 26,
|
|
|
|
|
child: ListView.separated(
|
|
|
|
|
shrinkWrap: true,
|
|
|
|
|
physics: const BouncingScrollPhysics(),
|
|
|
|
|
padding: const EdgeInsets.only(left: 21, right: 21, top: 13, bottom: 13),
|
|
|
|
|
scrollDirection: Axis.horizontal,
|
|
|
|
|
itemBuilder: (cxt, index) {
|
|
|
|
|
return AspectRatio(aspectRatio: 105 / 105, child: ServicesMenuShimmer());
|
|
|
|
|
},
|
|
|
|
|
separatorBuilder: (cxt, index) => 9.width,
|
|
|
|
|
itemCount: 4,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|