Merge branch 'master' into development_sikander
# Conflicts: # lib/app_state/app_state.dart # lib/classes/consts.dart # lib/config/routes.dart # lib/generated/locale_keys.g.dart # lib/main.dart # lib/models/generic_response_model.dart # lib/ui/login/login_screen.dart # lib/ui/login/verify_login_screen.dart # pubspec.yamlmerge-requests/1/merge
commit
e7a67cc58d
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="21.655" height="24.033" viewBox="0 0 21.655 24.033">
|
||||
<path id="Path_4726" data-name="Path 4726" d="M12.03.53C9.864-.713,8.107.305,8.107,2.8V21.229c0,2.5,1.757,3.516,3.923,2.275l16.106-9.237c2.167-1.243,2.167-3.258,0-4.5Z" transform="translate(-8.107 0)" fill="#fff"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 324 B |
@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="93.613" height="93.613" viewBox="0 0 93.613 93.613">
|
||||
<g id="fingerprint-scan_1_" data-name="fingerprint-scan (1)" transform="translate(0 0)" opacity="0.049">
|
||||
<path id="Path_4635" data-name="Path 4635" d="M243.282,223.494a2.743,2.743,0,0,0,2.743-2.742V207.5a2.743,2.743,0,1,0-5.485,0v13.255A2.743,2.743,0,0,0,243.282,223.494Z" transform="translate(-196.559 -167.317)" fill="#fff"/>
|
||||
<path id="Path_4636" data-name="Path 4636" d="M167.739,215.135A2.743,2.743,0,0,0,165,217.877c0,11.945-8.538,21.664-19.032,21.664s-19.032-9.718-19.032-21.664V202.967a2.743,2.743,0,1,0-5.485,0v14.911c0,14.97,11,27.149,24.517,27.149s24.517-12.179,24.517-27.149A2.743,2.743,0,0,0,167.739,215.135Z" transform="translate(-99.243 -163.615)" fill="#fff"/>
|
||||
<path id="Path_4637" data-name="Path 4637" d="M243.282,232.819c7.516,0,13.63-6.7,13.63-14.946V202.96a2.743,2.743,0,0,0-5.485,0v14.911c0,5.217-3.654,9.461-8.145,9.461a2.743,2.743,0,0,0,0,5.485Z" transform="translate(-196.559 -163.611)" fill="#fff"/>
|
||||
<path id="Path_4638" data-name="Path 4638" d="M90.871,24.37H79.481a39.852,39.852,0,0,0-7.619-12.733A33.489,33.489,0,0,0,46.722,0,33.49,33.49,0,0,0,21.581,11.639a39.854,39.854,0,0,0-7.617,12.73H2.743a2.743,2.743,0,1,0,0,5.485h9.609a43.839,43.839,0,0,0-1.033,9.5V54.262A41.449,41.449,0,0,0,21.581,81.974,33.49,33.49,0,0,0,46.722,93.613,33.49,33.49,0,0,0,71.864,81.974,41.45,41.45,0,0,0,82.126,54.262V39.345a43.839,43.839,0,0,0-1.033-9.49h9.777a2.743,2.743,0,0,0,0-5.485ZM46.722,5.485c11.747,0,21.933,7.705,26.826,18.885H67.158C62.762,17.043,55.243,12.2,46.722,12.2a2.743,2.743,0,0,0,0,5.485A17.967,17.967,0,0,1,60.456,24.37H19.9C24.788,13.19,34.974,5.485,46.722,5.485ZM76.641,54.262c0,18.674-13.421,33.866-29.919,33.866S16.8,72.936,16.8,54.262V39.351a37.925,37.925,0,0,1,1.2-9.5H36.2a15.572,15.572,0,0,0-3.107,9.5V54.262a2.743,2.743,0,1,0,5.485,0V39.351c0-5.217,3.654-9.461,8.145-9.461l17.1-.035a24.013,24.013,0,0,1,1.929,9.493h0a2.743,2.743,0,0,0,5.485,0h0a29.615,29.615,0,0,0-1.549-9.492h5.752a37.927,37.927,0,0,1,1.2,9.491V54.262Z" fill="#fff"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@ -0,0 +1,92 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:mohem_flutter_app/app_state/app_state.dart';
|
||||
import 'package:mohem_flutter_app/classes/consts.dart';
|
||||
import 'package:mohem_flutter_app/models/basic_member_information_model.dart';
|
||||
import 'package:mohem_flutter_app/models/check_mobile_app_version_model.dart';
|
||||
import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart';
|
||||
import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart';
|
||||
import 'package:mohem_flutter_app/models/generic_response_model.dart';
|
||||
import 'package:mohem_flutter_app/models/member_login_list_model.dart';
|
||||
|
||||
import 'api_client.dart';
|
||||
|
||||
class DashbaordApiClient {
|
||||
static final DashbaordApiClient _instance = DashbaordApiClient._internal();
|
||||
|
||||
DashbaordApiClient._internal();
|
||||
|
||||
factory DashbaordApiClient() => _instance;
|
||||
|
||||
Future<GetAttendanceTracking?> getAttendanceTracking() async {
|
||||
String url = "${ApiConsts.erpRest}GET_Attendance_Tracking";
|
||||
Map<String, dynamic> postParams = {};
|
||||
postParams.addAll(AppState().postParamsJson);
|
||||
return await ApiClient().postJsonForObject((json) {
|
||||
GenericResponseModel responseData = GenericResponseModel.fromJson(json);
|
||||
return responseData.getAttendanceTrackingList;
|
||||
}, url, postParams);
|
||||
}
|
||||
|
||||
Future<GenericResponseModel?> getOpenNotifications() async {
|
||||
String url = "${ApiConsts.erpRest}GET_OPEN_NOTIFICATIONS";
|
||||
Map<String, dynamic> postParams = {};
|
||||
postParams.addAll(AppState().postParamsJson);
|
||||
return await ApiClient().postJsonForObject((json) {
|
||||
GenericResponseModel responseData = GenericResponseModel.fromJson(json);
|
||||
return responseData;
|
||||
}, url, postParams);
|
||||
}
|
||||
|
||||
Future<ItgFormsModel?> getItgFormsPendingTask() async {
|
||||
String url = "${ApiConsts.cocRest}ITGFormsPendingTasks";
|
||||
Map<String, dynamic> postParams = {};
|
||||
postParams.addAll(AppState().postParamsJson);
|
||||
return await ApiClient().postJsonForObject((json) {
|
||||
ItgFormsModel responseData = ItgFormsModel.fromJson(json);
|
||||
return responseData;
|
||||
}, url, postParams);
|
||||
}
|
||||
|
||||
Future<GenericResponseModel?> getAccrualBalances() async {
|
||||
String url = "${ApiConsts.erpRest}GET_ACCRUAL_BALANCES";
|
||||
Map<String, dynamic> postParams = {"P_EFFECTIVE_DATE": "1/30/2022"};
|
||||
postParams.addAll(AppState().postParamsJson);
|
||||
return await ApiClient().postJsonForObject((json) {
|
||||
GenericResponseModel responseData = GenericResponseModel.fromJson(json);
|
||||
return responseData;
|
||||
}, url, postParams);
|
||||
}
|
||||
|
||||
Future<GenericResponseModel?> getOpenMissingSwipes() async {
|
||||
String url = "${ApiConsts.erpRest}GET_OPEN_MISSING_SWIPES";
|
||||
Map<String, dynamic> postParams = {};
|
||||
postParams.addAll(AppState().postParamsJson);
|
||||
return await ApiClient().postJsonForObject((json) {
|
||||
GenericResponseModel responseData = GenericResponseModel.fromJson(json);
|
||||
return responseData;
|
||||
}, url, postParams);
|
||||
}
|
||||
|
||||
//Menus List
|
||||
Future<GenericResponseModel?> getListMenu() async {
|
||||
String url = "${ApiConsts.erpRest}GET_MENU";
|
||||
Map<String, dynamic> postParams = {};
|
||||
postParams.addAll(AppState().postParamsJson);
|
||||
return await ApiClient().postJsonForObject((json) {
|
||||
GenericResponseModel responseData = GenericResponseModel.fromJson(json);
|
||||
return responseData;
|
||||
}, url, postParams);
|
||||
}
|
||||
|
||||
//GET_MENU_ENTRIES
|
||||
Future<GenericResponseModel?> getGetMenuEntries() async {
|
||||
String url = "${ApiConsts.erpRest}GET_MENU_ENTRIES";
|
||||
Map<String, dynamic> postParams = {"P_SELECTED_RESP_ID": -999,"P_MENU_TYPE":"E"};
|
||||
postParams.addAll(AppState().postParamsJson);
|
||||
return await ApiClient().postJsonForObject((json) {
|
||||
GenericResponseModel responseData = GenericResponseModel.fromJson(json);
|
||||
return responseData;
|
||||
}, url, postParams);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
class GetAccrualBalancesList {
|
||||
GetAccrualBalancesList({
|
||||
this.accrualNetEntitlement,
|
||||
this.accrualUsedEntitlement,
|
||||
this.accrualYearlyEntitlement,
|
||||
this.accuralPlanName,
|
||||
this.endDate,
|
||||
this.lastAccrualDate,
|
||||
this.startDate,
|
||||
});
|
||||
|
||||
double? accrualNetEntitlement;
|
||||
int? accrualUsedEntitlement;
|
||||
dynamic accrualYearlyEntitlement;
|
||||
String? accuralPlanName;
|
||||
String? endDate;
|
||||
String? lastAccrualDate;
|
||||
String? startDate;
|
||||
|
||||
factory GetAccrualBalancesList.fromJson(Map<String, dynamic> json) => GetAccrualBalancesList(
|
||||
accrualNetEntitlement: json["ACCRUAL_NET_ENTITLEMENT"] == null ? null : json["ACCRUAL_NET_ENTITLEMENT"].toDouble(),
|
||||
accrualUsedEntitlement: json["ACCRUAL_USED_ENTITLEMENT"] == null ? null : json["ACCRUAL_USED_ENTITLEMENT"],
|
||||
accrualYearlyEntitlement: json["ACCRUAL_YEARLY_ENTITLEMENT"],
|
||||
accuralPlanName: json["ACCURAL_PLAN_NAME"] == null ? null : json["ACCURAL_PLAN_NAME"],
|
||||
endDate: json["END_DATE"] == null ? null : json["END_DATE"],
|
||||
lastAccrualDate: json["LAST_ACCRUAL_DATE"] == null ? null : json["LAST_ACCRUAL_DATE"],
|
||||
startDate: json["START_DATE"] == null ? null : json["START_DATE"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"ACCRUAL_NET_ENTITLEMENT": accrualNetEntitlement == null ? null : accrualNetEntitlement,
|
||||
"ACCRUAL_USED_ENTITLEMENT": accrualUsedEntitlement == null ? null : accrualUsedEntitlement,
|
||||
"ACCRUAL_YEARLY_ENTITLEMENT": accrualYearlyEntitlement,
|
||||
"ACCURAL_PLAN_NAME": accuralPlanName == null ? null : accuralPlanName,
|
||||
"END_DATE": endDate == null ? null : endDate,
|
||||
"LAST_ACCRUAL_DATE": lastAccrualDate == null ? null : lastAccrualDate,
|
||||
"START_DATE": startDate == null ? null : startDate,
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
class GetAttendanceTracking {
|
||||
GetAttendanceTracking({
|
||||
this.pBreakHours,
|
||||
this.pLateInHours,
|
||||
this.pRemainingHours,
|
||||
this.pReturnMsg,
|
||||
this.pReturnStatus,
|
||||
this.pScheduledHours,
|
||||
this.pShtName,
|
||||
this.pSpentHours,
|
||||
this.pSwipesExemptedFlag,
|
||||
this.pSwipeIn,
|
||||
this.pSwipeOut,
|
||||
});
|
||||
|
||||
String? pBreakHours;
|
||||
String? pLateInHours;
|
||||
String? pRemainingHours;
|
||||
String? pReturnMsg;
|
||||
String? pReturnStatus;
|
||||
String? pScheduledHours;
|
||||
String? pShtName;
|
||||
String? pSpentHours;
|
||||
String? pSwipesExemptedFlag;
|
||||
dynamic pSwipeIn;
|
||||
dynamic pSwipeOut;
|
||||
|
||||
factory GetAttendanceTracking.fromMap(Map<String, dynamic> json) => GetAttendanceTracking(
|
||||
pBreakHours: json["P_BREAK_HOURS"] == null ? null : json["P_BREAK_HOURS"],
|
||||
pLateInHours: json["P_LATE_IN_HOURS"] == null ? null : json["P_LATE_IN_HOURS"],
|
||||
pRemainingHours: json["P_REMAINING_HOURS"] == null ? null : json["P_REMAINING_HOURS"],
|
||||
pReturnMsg: json["P_RETURN_MSG"] == null ? null : json["P_RETURN_MSG"],
|
||||
pReturnStatus: json["P_RETURN_STATUS"] == null ? null : json["P_RETURN_STATUS"],
|
||||
pScheduledHours: json["P_SCHEDULED_HOURS"] == null ? null : json["P_SCHEDULED_HOURS"],
|
||||
pShtName: json["P_SHT_NAME"] == null ? null : json["P_SHT_NAME"],
|
||||
pSpentHours: json["P_SPENT_HOURS"] == null ? null : json["P_SPENT_HOURS"],
|
||||
pSwipesExemptedFlag: json["P_SWIPES_EXEMPTED_FLAG"] == null ? null : json["P_SWIPES_EXEMPTED_FLAG"],
|
||||
pSwipeIn: json["P_SWIPE_IN"],
|
||||
pSwipeOut: json["P_SWIPE_OUT"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toMap() => {
|
||||
"P_BREAK_HOURS": pBreakHours == null ? null : pBreakHours,
|
||||
"P_LATE_IN_HOURS": pLateInHours == null ? null : pLateInHours,
|
||||
"P_REMAINING_HOURS": pRemainingHours == null ? null : pRemainingHours,
|
||||
"P_RETURN_MSG": pReturnMsg == null ? null : pReturnMsg,
|
||||
"P_RETURN_STATUS": pReturnStatus == null ? null : pReturnStatus,
|
||||
"P_SCHEDULED_HOURS": pScheduledHours == null ? null : pScheduledHours,
|
||||
"P_SHT_NAME": pShtName == null ? null : pShtName,
|
||||
"P_SPENT_HOURS": pSpentHours == null ? null : pSpentHours,
|
||||
"P_SWIPES_EXEMPTED_FLAG": pSwipesExemptedFlag == null ? null : pSwipesExemptedFlag,
|
||||
"P_SWIPE_IN": pSwipeIn,
|
||||
"P_SWIPE_OUT": pSwipeOut,
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
|
||||
class GetOpenMissingSwipesList {
|
||||
GetOpenMissingSwipesList({
|
||||
this.pOpenMissingSwipes,
|
||||
this.pReturnMsg,
|
||||
this.pReturnStatus,
|
||||
});
|
||||
|
||||
int? pOpenMissingSwipes;
|
||||
String? pReturnMsg;
|
||||
String? pReturnStatus;
|
||||
|
||||
factory GetOpenMissingSwipesList.fromJson(Map<String, dynamic> json) => GetOpenMissingSwipesList(
|
||||
pOpenMissingSwipes: json["P_OPEN_MISSING_SWIPES"] == null ? null : json["P_OPEN_MISSING_SWIPES"],
|
||||
pReturnMsg: json["P_RETURN_MSG"] == null ? null : json["P_RETURN_MSG"],
|
||||
pReturnStatus: json["P_RETURN_STATUS"] == null ? null : json["P_RETURN_STATUS"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"P_OPEN_MISSING_SWIPES": pOpenMissingSwipes == null ? null : pOpenMissingSwipes,
|
||||
"P_RETURN_MSG": pReturnMsg == null ? null : pReturnMsg,
|
||||
"P_RETURN_STATUS": pReturnStatus == null ? null : pReturnStatus,
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
class GetOpenNotificationsList {
|
||||
GetOpenNotificationsList({
|
||||
this.itemType,
|
||||
this.itemTypeDisplayName,
|
||||
this.openNtfNumber,
|
||||
});
|
||||
|
||||
String? itemType;
|
||||
String? itemTypeDisplayName;
|
||||
int? openNtfNumber;
|
||||
|
||||
factory GetOpenNotificationsList.fromMap(Map<String, dynamic> json) => GetOpenNotificationsList(
|
||||
itemType: json["ITEM_TYPE"] == null ? null : json["ITEM_TYPE"],
|
||||
itemTypeDisplayName: json["ITEM_TYPE_DISPLAY_NAME"] == null ? null : json["ITEM_TYPE_DISPLAY_NAME"],
|
||||
openNtfNumber: json["OPEN_NTF_NUMBER"] == null ? null : json["OPEN_NTF_NUMBER"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toMap() => {
|
||||
"ITEM_TYPE": itemType == null ? null : itemType,
|
||||
"ITEM_TYPE_DISPLAY_NAME": itemTypeDisplayName == null ? null : itemTypeDisplayName,
|
||||
"OPEN_NTF_NUMBER": openNtfNumber == null ? null : openNtfNumber,
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,189 @@
|
||||
// To parse this JSON data, do
|
||||
//
|
||||
// final itgFormsModel = itgFormsModelFromMap(jsonString);
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
ItgFormsModel itgFormsModelFromMap(String str) => ItgFormsModel.fromJson(json.decode(str));
|
||||
|
||||
String itgFormsModelToMap(ItgFormsModel data) => json.encode(data.toMap());
|
||||
|
||||
class ItgFormsModel {
|
||||
ItgFormsModel({
|
||||
this.date,
|
||||
this.languageId,
|
||||
this.serviceName,
|
||||
this.time,
|
||||
this.androidLink,
|
||||
this.authenticationTokenId,
|
||||
this.data,
|
||||
this.dataw,
|
||||
this.dietType,
|
||||
this.dietTypeId,
|
||||
this.errorCode,
|
||||
this.errorEndUserMessage,
|
||||
this.errorEndUserMessageN,
|
||||
this.errorMessage,
|
||||
this.errorType,
|
||||
this.foodCategory,
|
||||
this.iosLink,
|
||||
this.isAuthenticated,
|
||||
this.mealOrderStatus,
|
||||
this.mealType,
|
||||
this.messageStatus,
|
||||
this.numberOfResultRecords,
|
||||
this.patientBlodType,
|
||||
this.successMsg,
|
||||
this.successMsgN,
|
||||
this.vidaUpdatedResponse,
|
||||
this.itgRequest,
|
||||
this.itgFormAttachmentsList,
|
||||
this.message,
|
||||
this.mohemmItgDepartmentSectionsList,
|
||||
this.mohemmItgProjectDepartmentsList,
|
||||
this.mohemmItgResponseItem,
|
||||
this.mohemmItgSectionTopicsList,
|
||||
this.mohemmItgTicketDetailsList,
|
||||
this.mohemmItgTicketTransactionsList,
|
||||
this.mohemmItgTicketsByEmployeeList,
|
||||
this.mohemmItgProjectsList,
|
||||
this.mohemmItgTicketTypesList,
|
||||
this.referenceNumber,
|
||||
this.requestType,
|
||||
this.totalCount,
|
||||
this.statuseCode,
|
||||
});
|
||||
|
||||
dynamic date;
|
||||
int? languageId;
|
||||
int? serviceName;
|
||||
dynamic time;
|
||||
dynamic androidLink;
|
||||
dynamic authenticationTokenId;
|
||||
dynamic data;
|
||||
bool? dataw;
|
||||
int? dietType;
|
||||
int? dietTypeId;
|
||||
dynamic errorCode;
|
||||
dynamic errorEndUserMessage;
|
||||
dynamic errorEndUserMessageN;
|
||||
dynamic errorMessage;
|
||||
int? errorType;
|
||||
int? foodCategory;
|
||||
dynamic iosLink;
|
||||
bool? isAuthenticated;
|
||||
int? mealOrderStatus;
|
||||
int? mealType;
|
||||
int? messageStatus;
|
||||
int? numberOfResultRecords;
|
||||
dynamic patientBlodType;
|
||||
String? successMsg;
|
||||
dynamic successMsgN;
|
||||
dynamic vidaUpdatedResponse;
|
||||
dynamic itgRequest;
|
||||
dynamic itgFormAttachmentsList;
|
||||
String? message;
|
||||
dynamic mohemmItgDepartmentSectionsList;
|
||||
dynamic mohemmItgProjectDepartmentsList;
|
||||
dynamic mohemmItgResponseItem;
|
||||
dynamic mohemmItgSectionTopicsList;
|
||||
dynamic mohemmItgTicketDetailsList;
|
||||
dynamic mohemmItgTicketTransactionsList;
|
||||
dynamic mohemmItgTicketsByEmployeeList;
|
||||
dynamic mohemmItgProjectsList;
|
||||
dynamic mohemmItgTicketTypesList;
|
||||
DateTime? referenceNumber;
|
||||
dynamic requestType;
|
||||
int? totalCount;
|
||||
int? statuseCode;
|
||||
|
||||
factory ItgFormsModel.fromJson(Map<String, dynamic> json) => ItgFormsModel(
|
||||
date: json["Date"],
|
||||
languageId: json["LanguageID"] == null ? null : json["LanguageID"],
|
||||
serviceName: json["ServiceName"] == null ? null : json["ServiceName"],
|
||||
time: json["Time"],
|
||||
androidLink: json["AndroidLink"],
|
||||
authenticationTokenId: json["AuthenticationTokenID"],
|
||||
data: json["Data"],
|
||||
dataw: json["Dataw"] == null ? null : json["Dataw"],
|
||||
dietType: json["DietType"] == null ? null : json["DietType"],
|
||||
dietTypeId: json["DietTypeID"] == null ? null : json["DietTypeID"],
|
||||
errorCode: json["ErrorCode"],
|
||||
errorEndUserMessage: json["ErrorEndUserMessage"],
|
||||
errorEndUserMessageN: json["ErrorEndUserMessageN"],
|
||||
errorMessage: json["ErrorMessage"],
|
||||
errorType: json["ErrorType"] == null ? null : json["ErrorType"],
|
||||
foodCategory: json["FoodCategory"] == null ? null : json["FoodCategory"],
|
||||
iosLink: json["IOSLink"],
|
||||
isAuthenticated: json["IsAuthenticated"] == null ? null : json["IsAuthenticated"],
|
||||
mealOrderStatus: json["MealOrderStatus"] == null ? null : json["MealOrderStatus"],
|
||||
mealType: json["MealType"] == null ? null : json["MealType"],
|
||||
messageStatus: json["MessageStatus"] == null ? null : json["MessageStatus"],
|
||||
numberOfResultRecords: json["NumberOfResultRecords"] == null ? null : json["NumberOfResultRecords"],
|
||||
patientBlodType: json["PatientBlodType"],
|
||||
successMsg: json["SuccessMsg"] == null ? null : json["SuccessMsg"],
|
||||
successMsgN: json["SuccessMsgN"],
|
||||
vidaUpdatedResponse: json["VidaUpdatedResponse"],
|
||||
itgRequest: json["ITGRequest"],
|
||||
itgFormAttachmentsList: json["Itg_FormAttachmentsList"],
|
||||
message: json["Message"] == null ? null : json["Message"],
|
||||
mohemmItgDepartmentSectionsList: json["Mohemm_ITG_DepartmentSectionsList"],
|
||||
mohemmItgProjectDepartmentsList: json["Mohemm_ITG_ProjectDepartmentsList"],
|
||||
mohemmItgResponseItem: json["Mohemm_ITG_ResponseItem"],
|
||||
mohemmItgSectionTopicsList: json["Mohemm_ITG_SectionTopicsList"],
|
||||
mohemmItgTicketDetailsList: json["Mohemm_ITG_TicketDetailsList"],
|
||||
mohemmItgTicketTransactionsList: json["Mohemm_ITG_TicketTransactionsList"],
|
||||
mohemmItgTicketsByEmployeeList: json["Mohemm_ITG_TicketsByEmployeeList"],
|
||||
mohemmItgProjectsList: json["Mohemm_Itg_ProjectsList"],
|
||||
mohemmItgTicketTypesList: json["Mohemm_Itg_TicketTypesList"],
|
||||
referenceNumber: json["ReferenceNumber"] == null ? null : DateTime.parse(json["ReferenceNumber"]),
|
||||
requestType: json["RequestType"],
|
||||
totalCount: json["TotalCount"] == null ? null : json["TotalCount"],
|
||||
statuseCode: json["statuseCode"] == null ? null : json["statuseCode"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toMap() => {
|
||||
"Date": date,
|
||||
"LanguageID": languageId == null ? null : languageId,
|
||||
"ServiceName": serviceName == null ? null : serviceName,
|
||||
"Time": time,
|
||||
"AndroidLink": androidLink,
|
||||
"AuthenticationTokenID": authenticationTokenId,
|
||||
"Data": data,
|
||||
"Dataw": dataw == null ? null : dataw,
|
||||
"DietType": dietType == null ? null : dietType,
|
||||
"DietTypeID": dietTypeId == null ? null : dietTypeId,
|
||||
"ErrorCode": errorCode,
|
||||
"ErrorEndUserMessage": errorEndUserMessage,
|
||||
"ErrorEndUserMessageN": errorEndUserMessageN,
|
||||
"ErrorMessage": errorMessage,
|
||||
"ErrorType": errorType == null ? null : errorType,
|
||||
"FoodCategory": foodCategory == null ? null : foodCategory,
|
||||
"IOSLink": iosLink,
|
||||
"IsAuthenticated": isAuthenticated == null ? null : isAuthenticated,
|
||||
"MealOrderStatus": mealOrderStatus == null ? null : mealOrderStatus,
|
||||
"MealType": mealType == null ? null : mealType,
|
||||
"MessageStatus": messageStatus == null ? null : messageStatus,
|
||||
"NumberOfResultRecords": numberOfResultRecords == null ? null : numberOfResultRecords,
|
||||
"PatientBlodType": patientBlodType,
|
||||
"SuccessMsg": successMsg == null ? null : successMsg,
|
||||
"SuccessMsgN": successMsgN,
|
||||
"VidaUpdatedResponse": vidaUpdatedResponse,
|
||||
"ITGRequest": itgRequest,
|
||||
"Itg_FormAttachmentsList": itgFormAttachmentsList,
|
||||
"Message": message == null ? null : message,
|
||||
"Mohemm_ITG_DepartmentSectionsList": mohemmItgDepartmentSectionsList,
|
||||
"Mohemm_ITG_ProjectDepartmentsList": mohemmItgProjectDepartmentsList,
|
||||
"Mohemm_ITG_ResponseItem": mohemmItgResponseItem,
|
||||
"Mohemm_ITG_SectionTopicsList": mohemmItgSectionTopicsList,
|
||||
"Mohemm_ITG_TicketDetailsList": mohemmItgTicketDetailsList,
|
||||
"Mohemm_ITG_TicketTransactionsList": mohemmItgTicketTransactionsList,
|
||||
"Mohemm_ITG_TicketsByEmployeeList": mohemmItgTicketsByEmployeeList,
|
||||
"Mohemm_Itg_ProjectsList": mohemmItgProjectsList,
|
||||
"Mohemm_Itg_TicketTypesList": mohemmItgTicketTypesList,
|
||||
"ReferenceNumber": referenceNumber == null ? null : referenceNumber!.toIso8601String(),
|
||||
"RequestType": requestType,
|
||||
"TotalCount": totalCount == null ? null : totalCount,
|
||||
"statuseCode": statuseCode == null ? null : statuseCode,
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
class ListMenu {
|
||||
ListMenu({
|
||||
this.menuId,
|
||||
this.menuName,
|
||||
this.menuType,
|
||||
this.requestGroupId,
|
||||
this.requestGroupName,
|
||||
this.respId,
|
||||
this.subMenuName,
|
||||
});
|
||||
|
||||
int? menuId;
|
||||
String? menuName;
|
||||
String? menuType;
|
||||
int? requestGroupId;
|
||||
String? requestGroupName;
|
||||
dynamic? respId;
|
||||
String? subMenuName;
|
||||
|
||||
factory ListMenu.fromJson(Map<String, dynamic> json) => ListMenu(
|
||||
menuId: json["MENU_ID"] == null ? null : json["MENU_ID"],
|
||||
menuName: json["MENU_NAME"] == null ? null : json["MENU_NAME"],
|
||||
menuType: json["MENU_TYPE"] == null ? null : json["MENU_TYPE"],
|
||||
requestGroupId: json["REQUEST_GROUP_ID"] == null ? null : json["REQUEST_GROUP_ID"],
|
||||
requestGroupName: json["REQUEST_GROUP_NAME"] == null ? null : json["REQUEST_GROUP_NAME"],
|
||||
respId: json["RESP_ID"],
|
||||
subMenuName: json["SUB_MENU_NAME"] == null ? null : json["SUB_MENU_NAME"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"MENU_ID": menuId == null ? null : menuId,
|
||||
"MENU_NAME": menuName == null ? null : menuName,
|
||||
"MENU_TYPE": menuType == null ? null : menuType,
|
||||
"REQUEST_GROUP_ID": requestGroupId == null ? null : requestGroupId,
|
||||
"REQUEST_GROUP_NAME": requestGroupName == null ? null : requestGroupName,
|
||||
"RESP_ID": respId,
|
||||
"SUB_MENU_NAME": subMenuName == null ? null : subMenuName,
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
class GetMenuEntriesList {
|
||||
GetMenuEntriesList({
|
||||
this.addButton,
|
||||
this.deleteButton,
|
||||
this.entrySequence,
|
||||
this.functionName,
|
||||
this.icon,
|
||||
this.lvl,
|
||||
this.menuEntryType,
|
||||
this.menuName,
|
||||
this.parentMenuName,
|
||||
this.prompt,
|
||||
this.requestType,
|
||||
this.updateButton,
|
||||
});
|
||||
|
||||
String? addButton;
|
||||
String? deleteButton;
|
||||
int? entrySequence;
|
||||
String? functionName;
|
||||
String? icon;
|
||||
int? lvl;
|
||||
String? menuEntryType;
|
||||
String? menuName;
|
||||
String? parentMenuName;
|
||||
String? prompt;
|
||||
String? requestType;
|
||||
String? updateButton;
|
||||
|
||||
factory GetMenuEntriesList.fromJson(Map<String, dynamic> json) => GetMenuEntriesList(
|
||||
addButton: json["ADD_BUTTON"] == null ? null : json["ADD_BUTTON"],
|
||||
deleteButton: json["DELETE_BUTTON"] == null ? null : json["DELETE_BUTTON"],
|
||||
entrySequence: json["ENTRY_SEQUENCE"] == null ? null : json["ENTRY_SEQUENCE"],
|
||||
functionName: json["FUNCTION_NAME"] == null ? null : json["FUNCTION_NAME"],
|
||||
icon: json["ICON"] == null ? null : json["ICON"],
|
||||
lvl: json["LVL"] == null ? null : json["LVL"],
|
||||
menuEntryType: json["MENU_ENTRY_TYPE"] == null ? null : json["MENU_ENTRY_TYPE"],
|
||||
menuName: json["MENU_NAME"] == null ? null : json["MENU_NAME"],
|
||||
parentMenuName: json["PARENT_MENU_NAME"] == null ? null : json["PARENT_MENU_NAME"],
|
||||
prompt: json["PROMPT"] == null ? null : json["PROMPT"],
|
||||
requestType: json["REQUEST_TYPE"] == null ? null : json["REQUEST_TYPE"],
|
||||
updateButton: json["UPDATE_BUTTON"] == null ? null :json["UPDATE_BUTTON"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"ADD_BUTTON": addButton == null ? null :addButton,
|
||||
"DELETE_BUTTON": deleteButton == null ? null : deleteButton,
|
||||
"ENTRY_SEQUENCE": entrySequence == null ? null : entrySequence,
|
||||
"FUNCTION_NAME": functionName == null ? null : functionName,
|
||||
"ICON": icon == null ? null : icon,
|
||||
"LVL": lvl == null ? null : lvl,
|
||||
"MENU_ENTRY_TYPE": menuEntryType == null ? null : menuEntryType,
|
||||
"MENU_NAME": menuName == null ? null : menuName,
|
||||
"PARENT_MENU_NAME": parentMenuName == null ? null : parentMenuName,
|
||||
"PROMPT": prompt == null ? null : prompt,
|
||||
"REQUEST_TYPE": requestType == null ? null : requestType,
|
||||
"UPDATE_BUTTON": updateButton == null ? null : updateButton,
|
||||
};
|
||||
}
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
import 'package:mohem_flutter_app/models/dashboard/menu_entries.dart';
|
||||
|
||||
class Menus {
|
||||
GetMenuEntriesList menuEntry;
|
||||
List<GetMenuEntriesList> menuEntiesList;
|
||||
|
||||
Menus(this.menuEntry, this.menuEntiesList);
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,173 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
|
||||
import 'package:mohem_flutter_app/classes/utils.dart';
|
||||
import 'package:mohem_flutter_app/main.dart';
|
||||
import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart';
|
||||
import 'package:mohem_flutter_app/models/dashboard/itg_forms_model.dart';
|
||||
import 'package:mohem_flutter_app/models/dashboard/menu_entries.dart';
|
||||
import 'package:mohem_flutter_app/models/dashboard/menus.dart';
|
||||
import 'package:mohem_flutter_app/models/generic_response_model.dart';
|
||||
import 'package:mohem_flutter_app/widgets/Updater.dart';
|
||||
|
||||
/// Mix-in [DiagnosticableTreeMixin] to have access to [debugFillProperties] for the devtool
|
||||
// ignore: prefer_mixin
|
||||
class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
|
||||
//Attendance Tracking
|
||||
bool isAttendanceTrackingLoading = true;
|
||||
int endTime = 0, isTimeRemainingInSeconds = 0;
|
||||
GetAttendanceTracking? attendanceTracking;
|
||||
|
||||
//Work List
|
||||
bool isWorkListLoading = true;
|
||||
int workListCounter = 0;
|
||||
|
||||
//Misssing Swipe
|
||||
bool isMissingSwipeLoading = true;
|
||||
int missingSwipeCounter = 0;
|
||||
|
||||
//Leave and Ticket Balance
|
||||
bool isLeaveTicketBalanceLoading = true;
|
||||
double leaveBalance = 0;
|
||||
double ticketBalance = 0;
|
||||
|
||||
//Menu Entries
|
||||
bool isServicesMenusLoading = true;
|
||||
List<Menus>? homeMenus;
|
||||
List<GetMenuEntriesList>? getMenuEntriesList;
|
||||
|
||||
//Attendance Tracking API's & Methods
|
||||
fetchAttendanceTracking() async {
|
||||
try {
|
||||
attendanceTracking = await DashbaordApiClient().getAttendanceTracking();
|
||||
isAttendanceTrackingLoading = false;
|
||||
isTimeRemainingInSeconds = calculateSeconds("00:00:00");
|
||||
endTime = DateTime.now().millisecondsSinceEpoch + Duration(seconds: isTimeRemainingInSeconds).inMilliseconds;
|
||||
print("isTimeRemainingInSeconds " + isTimeRemainingInSeconds.toString());
|
||||
print("endTime " + endTime.toString());
|
||||
|
||||
// notifyListeners();
|
||||
} catch (ex) {
|
||||
Utils.handleException(ex, null);
|
||||
}
|
||||
}
|
||||
|
||||
int calculateSeconds(String time) {
|
||||
int hour = int.parse(time.split(":")[0]);
|
||||
int mints = int.parse(time.split(":")[1]);
|
||||
int seconds = int.parse(time.split(":")[2]);
|
||||
return ((hour * 60 * 60) + (mints * 60) + seconds);
|
||||
}
|
||||
|
||||
update() {
|
||||
isAttendanceTrackingLoading = !isAttendanceTrackingLoading;
|
||||
isWorkListLoading = !isWorkListLoading;
|
||||
attendanceTracking?.pSwipeIn = "a";
|
||||
isTimeRemainingInSeconds = calculateSeconds("00:10:30");
|
||||
endTime = DateTime.now().millisecondsSinceEpoch + Duration(seconds: isTimeRemainingInSeconds).inMilliseconds;
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
//Work List API's & Methods
|
||||
fetchWorkListCounter() async {
|
||||
try {
|
||||
GenericResponseModel? genericResponseModel = await DashbaordApiClient().getOpenNotifications();
|
||||
isWorkListLoading = false;
|
||||
workListCounter = genericResponseModel?.pOPENNTFNUMBER ?? 0;
|
||||
ItgFormsModel? itgFormsModel = await DashbaordApiClient().getItgFormsPendingTask();
|
||||
workListCounter = workListCounter + (itgFormsModel?.totalCount ?? 0);
|
||||
notifyListeners();
|
||||
} catch (ex) {
|
||||
isWorkListLoading = false;
|
||||
logger.wtf(ex);
|
||||
notifyListeners();
|
||||
Utils.handleException(ex, null);
|
||||
}
|
||||
}
|
||||
|
||||
//Missing Siwpe API's & Methods
|
||||
fetchMissingSwipe() async {
|
||||
try {
|
||||
GenericResponseModel? genericResponseModel = await DashbaordApiClient().getOpenMissingSwipes();
|
||||
isMissingSwipeLoading = false;
|
||||
missingSwipeCounter = genericResponseModel!.getOpenMissingSwipesList!.pOpenMissingSwipes ?? 0;
|
||||
notifyListeners();
|
||||
} catch (ex) {
|
||||
isMissingSwipeLoading = false;
|
||||
logger.wtf(ex);
|
||||
notifyListeners();
|
||||
Utils.handleException(ex, null);
|
||||
}
|
||||
}
|
||||
|
||||
//Leave and Ticket Balance API's & Methods
|
||||
fetchLeaveTicketBalance() async {
|
||||
try {
|
||||
GenericResponseModel? genericResponseModel = await DashbaordApiClient().getAccrualBalances();
|
||||
isLeaveTicketBalanceLoading = false;
|
||||
leaveBalance = genericResponseModel?.getAccrualBalancesList![0].accrualNetEntitlement ?? 0.0;
|
||||
ticketBalance = (genericResponseModel?.getAccrualBalancesList![1].accrualNetEntitlement ?? 0.0) + (genericResponseModel?.getAccrualBalancesList![2].accrualNetEntitlement ?? 0.0);
|
||||
notifyListeners();
|
||||
} catch (ex) {
|
||||
isLeaveTicketBalanceLoading = false;
|
||||
logger.wtf(ex);
|
||||
notifyListeners();
|
||||
Utils.handleException(ex, null);
|
||||
}
|
||||
}
|
||||
|
||||
//List Menu API's & Methods
|
||||
fetchListMenu() async {
|
||||
try {
|
||||
GenericResponseModel? genericResponseModel = await DashbaordApiClient().getListMenu();
|
||||
Map<String, String> map = {};
|
||||
print(jsonEncode(genericResponseModel!.listMenu));
|
||||
for (int i = 0; i < genericResponseModel!.listMenu!.length; i++) {
|
||||
print(genericResponseModel!.listMenu![i]!.menuName ?? "");
|
||||
map[genericResponseModel!.listMenu![i]!.menuName ?? ""] = i.toString();
|
||||
}
|
||||
logger.i(map);
|
||||
notifyListeners();
|
||||
} catch (ex) {
|
||||
logger.wtf(ex);
|
||||
notifyListeners();
|
||||
Utils.handleException(ex, null);
|
||||
}
|
||||
}
|
||||
|
||||
//Menu Entries API's & Methods
|
||||
fetchMenuEntries() async {
|
||||
try {
|
||||
GenericResponseModel? genericResponseModel = await DashbaordApiClient().getGetMenuEntries();
|
||||
getMenuEntriesList = genericResponseModel!.getMenuEntriesList;
|
||||
homeMenus = parseMenues(getMenuEntriesList ?? []);
|
||||
isServicesMenusLoading = false;
|
||||
notifyListeners();
|
||||
} catch (ex) {
|
||||
logger.wtf(ex);
|
||||
notifyListeners();
|
||||
Utils.handleException(ex, null);
|
||||
}
|
||||
}
|
||||
|
||||
List<Menus> parseMenues(List<GetMenuEntriesList> getMenuEntriesList) {
|
||||
List<Menus> menus = [];
|
||||
for (int i = 0; i < getMenuEntriesList.length; i++) {
|
||||
if (getMenuEntriesList[i].parentMenuName!.isEmpty) {
|
||||
menus.add(Menus(getMenuEntriesList[i], getMenuEntriesList.where((element) => getMenuEntriesList[i].menuName == element.parentMenuName).toList()));
|
||||
}
|
||||
}
|
||||
|
||||
//Verify Menus by printing in log
|
||||
// for(int i=0;i<menus.length;i++){
|
||||
// logger.i(jsonEncode(menus[i].menuEntry.prompt));
|
||||
// for(int j=0;j<menus[i].menuEntiesList.length;j++){
|
||||
// logger.e(menus[i].menuEntiesList[j].prompt);
|
||||
// }
|
||||
// }
|
||||
return menus;
|
||||
}
|
||||
}
|
||||
@ -1,467 +0,0 @@
|
||||
import 'package:easy_localization/src/public_ext.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:mohem_flutter_app/classes/colors.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/widgets/circular_avatar.dart';
|
||||
|
||||
class Dashboard extends StatefulWidget {
|
||||
Dashboard({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_DashboardState createState() {
|
||||
return _DashboardState();
|
||||
}
|
||||
}
|
||||
|
||||
class _DashboardState extends State<Dashboard> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<String> names = [
|
||||
LocaleKeys.workList.tr(),
|
||||
LocaleKeys.missingSwipes.tr(),
|
||||
LocaleKeys.leaveBalance.tr(),
|
||||
LocaleKeys.ticketBalance.tr()
|
||||
];
|
||||
List<double> namesInt = [118, 02, 18.5, 03];
|
||||
List<int> namesColor = [0xff125765, 0xff239D8F, 0xff2BB8A8, 0xff1D92AA];
|
||||
|
||||
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/work_from_home.svg",
|
||||
"assets/images/ticket_request.svg",
|
||||
"assets/images/work_from_home.svg"
|
||||
];
|
||||
|
||||
List<String> namesD = [
|
||||
"Nostalgia Perfume Perfume",
|
||||
"Al Nafoura",
|
||||
"AlJadi",
|
||||
"Nostalgia Perfume"
|
||||
];
|
||||
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
CircularAvatar(
|
||||
width: 34,
|
||||
height: 34,
|
||||
url:
|
||||
"https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png",
|
||||
),
|
||||
8.width,
|
||||
SvgPicture.asset("assets/images/side_nav.svg"),
|
||||
],
|
||||
).onPress(() {}),
|
||||
Expanded(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
//AppLogo(),
|
||||
8.width,
|
||||
LocaleKeys.mohemm.tr().toText14()
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 36,
|
||||
height: 36,
|
||||
child: Stack(
|
||||
alignment: Alignment.centerLeft,
|
||||
children: [
|
||||
SvgPicture.asset("assets/images/announcements.svg"),
|
||||
Positioned(
|
||||
right: 0,
|
||||
top: 0,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(left: 5, right: 5),
|
||||
decoration: BoxDecoration(
|
||||
color: MyColors.redColor,
|
||||
borderRadius: BorderRadius.circular(17)),
|
||||
child: "3".toText12(color: Colors.white),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
).paddingOnly(left: 21, right: 21, top: 48, bottom: 7),
|
||||
Expanded(
|
||||
child: ListView(
|
||||
padding: EdgeInsets.zero,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocaleKeys.goodMorning
|
||||
.tr()
|
||||
.toText14(color: MyColors.grey77Color),
|
||||
"Mahmoud Shrouf".toText24(isBold: true),
|
||||
16.height,
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: AspectRatio(
|
||||
aspectRatio: 159 / 159,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
gradient: const LinearGradient(
|
||||
transform: GradientRotation(.46),
|
||||
begin: Alignment.topRight,
|
||||
end: Alignment.bottomRight,
|
||||
colors: [
|
||||
MyColors.gradiantEndColor,
|
||||
MyColors.gradiantStartColor,
|
||||
]),
|
||||
),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
SvgPicture.asset("assets/images/"),
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocaleKeys.markAttendance
|
||||
.tr()
|
||||
.toText14(
|
||||
color: Colors.white,
|
||||
isBold: true),
|
||||
9.height,
|
||||
"07:55:12".toText14(
|
||||
color: Colors.white,
|
||||
isBold: true),
|
||||
LocaleKeys.timeLeftToday
|
||||
.tr()
|
||||
.toText12(color: Colors.white),
|
||||
9.height,
|
||||
const ClipRRect(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(20),
|
||||
),
|
||||
child: LinearProgressIndicator(
|
||||
value: 0.7,
|
||||
minHeight: 8,
|
||||
valueColor:
|
||||
const AlwaysStoppedAnimation<
|
||||
Color>(Colors.white),
|
||||
backgroundColor:
|
||||
const Color(0xff196D73),
|
||||
),
|
||||
),
|
||||
],
|
||||
).paddingOnly(
|
||||
top: 12, right: 15, left: 12),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocaleKeys.checkIn
|
||||
.tr()
|
||||
.toText12(
|
||||
color: Colors.white),
|
||||
"09:00".toText14(
|
||||
color: Colors.white,
|
||||
isBold: true),
|
||||
4.height
|
||||
],
|
||||
).paddingOnly(left: 12),
|
||||
),
|
||||
Container(
|
||||
width: 45,
|
||||
height: 45,
|
||||
padding: const EdgeInsets.only(
|
||||
left: 14, right: 14),
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xff259EA4),
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomRight:
|
||||
Radius.circular(15),
|
||||
),
|
||||
),
|
||||
child: SvgPicture.asset(
|
||||
"assets/images/stop.svg"),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
).onPress(() {
|
||||
Navigator.pushNamed(
|
||||
context, AppRoutes.todayAttendance);
|
||||
}),
|
||||
),
|
||||
),
|
||||
9.width,
|
||||
Expanded(
|
||||
child: GridView.builder(
|
||||
shrinkWrap: true,
|
||||
primary: false,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
gridDelegate:
|
||||
const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
childAspectRatio: 2 / 2,
|
||||
crossAxisSpacing: 9,
|
||||
mainAxisSpacing: 9),
|
||||
padding: EdgeInsets.zero,
|
||||
itemCount: 4,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(namesColor[index]),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
names[index].toText12(color: Colors.white),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: namesInt[index]
|
||||
.toStringAsFixed(1)
|
||||
.toText16(
|
||||
color: Colors.white,
|
||||
isBold: true),
|
||||
),
|
||||
SvgPicture.asset(
|
||||
"assets/images/arrow_next.svg",
|
||||
color: Colors.white)
|
||||
],
|
||||
)
|
||||
],
|
||||
).paddingOnly(
|
||||
left: 10, right: 10, bottom: 6, top: 6),
|
||||
).onPress(() {
|
||||
Navigator.pushNamed(
|
||||
context, AppRoutes.workList);
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
20.height,
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
"Other".tr().toText12(),
|
||||
LocaleKeys.services.tr().toText24(isBold: true),
|
||||
],
|
||||
),
|
||||
),
|
||||
LocaleKeys.viewAllServices
|
||||
.tr()
|
||||
.toText12(isUnderLine: true),
|
||||
],
|
||||
),
|
||||
],
|
||||
).paddingOnly(left: 21, right: 21, top: 7),
|
||||
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: 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(iconT[index]),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Expanded(
|
||||
child:
|
||||
namesT[index].toText11(isBold: true),
|
||||
),
|
||||
SvgPicture.asset(
|
||||
"assets/images/arrow_next.svg")
|
||||
.paddingOnly(bottom: 4)
|
||||
],
|
||||
)
|
||||
],
|
||||
).paddingOnly(
|
||||
left: 10, right: 10, bottom: 10, top: 12),
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (cxt, index) => 9.width,
|
||||
itemCount: 4),
|
||||
),
|
||||
8.height,
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.only(top: 31),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(50),
|
||||
topLeft: Radius.circular(50)),
|
||||
border:
|
||||
Border.all(color: MyColors.lightGreyEDColor, width: 1),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
LocaleKeys.offers.tr().toText12(),
|
||||
Row(
|
||||
children: [
|
||||
LocaleKeys.discounts
|
||||
.tr()
|
||||
.toText24(isBold: true),
|
||||
6.width,
|
||||
Container(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 8, right: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: MyColors.yellowColor,
|
||||
borderRadius:
|
||||
BorderRadius.circular(10),
|
||||
),
|
||||
child: LocaleKeys.newString
|
||||
.tr()
|
||||
.toText10(isBold: true)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
LocaleKeys.viewAllOffers
|
||||
.tr()
|
||||
.toText12(isUnderLine: true),
|
||||
],
|
||||
).paddingOnly(left: 21, right: 21),
|
||||
SizedBox(
|
||||
height: 103 + 33,
|
||||
child: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const BouncingScrollPhysics(),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 21, right: 21, top: 13),
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemBuilder: (cxt, index) {
|
||||
return SizedBox(
|
||||
width: 73,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 73,
|
||||
height: 73,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(100),
|
||||
),
|
||||
border: Border.all(
|
||||
color: MyColors.lightGreyEDColor,
|
||||
width: 1),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(50),
|
||||
),
|
||||
child: Image.network(
|
||||
"https://play-lh.googleusercontent.com/NPo88ojmhah4HDiposucJmfQIop4z4xc8kqJK9ITO9o-yCab2zxIp7PPB_XPj2iUojo",
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
4.height,
|
||||
Expanded(
|
||||
child: namesD[6 % (index + 1)].toText12(
|
||||
isCenter: true, maxLine: 2)),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (cxt, index) => 8.width,
|
||||
itemCount: 6),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,334 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:easy_localization/src/public_ext.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_countdown_timer/flutter_countdown_timer.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
|
||||
import 'package:mohem_flutter_app/classes/colors.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/models/dashboard/get_attendance_tracking_list_model.dart';
|
||||
import 'package:mohem_flutter_app/models/dashboard/menu_entries.dart';
|
||||
import 'package:mohem_flutter_app/models/dashboard/menus.dart';
|
||||
import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart';
|
||||
import 'package:mohem_flutter_app/theme/colors.dart';
|
||||
import 'package:mohem_flutter_app/ui/landing/widget/menus_widget.dart';
|
||||
import 'package:mohem_flutter_app/ui/landing/widget/services_widget.dart';
|
||||
import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
|
||||
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
|
||||
import '../../main.dart';
|
||||
|
||||
class DashboardScreen extends StatefulWidget {
|
||||
DashboardScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_DashboardScreenState createState() {
|
||||
return _DashboardScreenState();
|
||||
}
|
||||
}
|
||||
|
||||
class _DashboardScreenState extends State<DashboardScreen> {
|
||||
late var data;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
data = Provider.of<DashboardProviderModel>(context, listen: false);
|
||||
data.fetchAttendanceTracking();
|
||||
data.fetchWorkListCounter();
|
||||
data.fetchMissingSwipe();
|
||||
data.fetchLeaveTicketBalance();
|
||||
// data.fetchMenuEntries();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<String> namesD = ["Nostalgia Perfume Perfume", "Al Nafoura", "AlJadi", "Nostalgia Perfume"];
|
||||
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
CircularAvatar(
|
||||
width: 34,
|
||||
height: 34,
|
||||
url: "https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png",
|
||||
),
|
||||
8.width,
|
||||
SvgPicture.asset("assets/images/side_nav.svg"),
|
||||
],
|
||||
).onPress(() {}),
|
||||
Expanded(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
//AppLogo(),
|
||||
8.width,
|
||||
LocaleKeys.mohemm.tr().toText14()
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 36,
|
||||
height: 36,
|
||||
child: Stack(
|
||||
alignment: Alignment.centerLeft,
|
||||
children: [
|
||||
SvgPicture.asset("assets/images/announcements.svg"),
|
||||
Positioned(
|
||||
right: 0,
|
||||
top: 0,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(left: 5, right: 5),
|
||||
decoration: BoxDecoration(color: MyColors.redColor, borderRadius: BorderRadius.circular(17)),
|
||||
child: "3".toText12(color: Colors.white),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
).onPress(() {
|
||||
data.update();
|
||||
})
|
||||
],
|
||||
).paddingOnly(left: 21, right: 21, top: 48, bottom: 7),
|
||||
Expanded(
|
||||
child: Column(
|
||||
// padding: EdgeInsets.zero,
|
||||
// physics: NeverScrollableScrollPhysics(),
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocaleKeys.goodMorning.tr().toText14(color: MyColors.grey77Color),
|
||||
"Mahmoud Shrouf".toText24(isBold: true),
|
||||
16.height,
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: AspectRatio(
|
||||
aspectRatio: 159 / 159,
|
||||
child: Consumer<DashboardProviderModel>(
|
||||
builder: (context, model, child) {
|
||||
return (model.isAttendanceTrackingLoading
|
||||
? GetAttendanceTrackingShimmer()
|
||||
: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
gradient: const LinearGradient(transform: GradientRotation(.46), begin: Alignment.topRight, end: Alignment.bottomRight, colors: [
|
||||
MyColors.gradiantEndColor,
|
||||
MyColors.gradiantStartColor,
|
||||
]),
|
||||
),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
if (model.isTimeRemainingInSeconds == 0) SvgPicture.asset("assets/images/thumb.svg"),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true),
|
||||
if (model.isTimeRemainingInSeconds == 0) "01-02-2022".toText12(color: Colors.white),
|
||||
if (model.isTimeRemainingInSeconds != 0)
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
9.height,
|
||||
CountdownTimer(
|
||||
endTime: model.endTime,
|
||||
onEnd: null,
|
||||
endWidget: "00:00:00".toText14(color: Colors.white, isBold: true),
|
||||
textStyle: TextStyle(color: Colors.white, fontSize: 14, letterSpacing: -0.48, fontWeight: FontWeight.bold),
|
||||
),
|
||||
LocaleKeys.timeLeftToday.tr().toText12(color: Colors.white),
|
||||
9.height,
|
||||
const ClipRRect(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(20),
|
||||
),
|
||||
child: LinearProgressIndicator(
|
||||
value: 0.7,
|
||||
minHeight: 8,
|
||||
valueColor: const AlwaysStoppedAnimation<Color>(Colors.white),
|
||||
backgroundColor: const Color(0xff196D73),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
).paddingOnly(top: 12, right: 15, left: 12),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocaleKeys.checkIn.tr().toText12(color: Colors.white),
|
||||
(model.isTimeRemainingInSeconds == 0 ? "--:--" : "09:00").toText14(color: Colors.white, isBold: true),
|
||||
4.height
|
||||
],
|
||||
).paddingOnly(left: 12),
|
||||
),
|
||||
Container(
|
||||
width: 45,
|
||||
height: 45,
|
||||
padding: const EdgeInsets.only(left: 14, right: 14),
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xff259EA4),
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomRight: Radius.circular(15),
|
||||
),
|
||||
),
|
||||
child: SvgPicture.asset(model.isTimeRemainingInSeconds == 0 ? "assets/images/play.svg" : "assets/images/stop.svg"),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
).onPress(() {
|
||||
Navigator.pushNamed(context, AppRoutes.todayAttendance);
|
||||
}))
|
||||
.animatedSwither();
|
||||
},
|
||||
)),
|
||||
),
|
||||
9.width,
|
||||
Expanded(
|
||||
child: MenusWidget(),
|
||||
),
|
||||
],
|
||||
),
|
||||
20.height,
|
||||
],
|
||||
).paddingOnly(left: 21, right: 21, top: 7),
|
||||
ServicesWidget(),
|
||||
8.height,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.only(top: 31),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.only(topRight: Radius.circular(50), topLeft: Radius.circular(50)),
|
||||
border: Border.all(color: MyColors.lightGreyEDColor, width: 1),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
LocaleKeys.offers.tr().toText12(),
|
||||
Row(
|
||||
children: [
|
||||
LocaleKeys.discounts.tr().toText24(isBold: true),
|
||||
6.width,
|
||||
Container(
|
||||
padding: const EdgeInsets.only(left: 8, right: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: MyColors.yellowColor,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: LocaleKeys.newString.tr().toText10(isBold: true)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
LocaleKeys.viewAllOffers.tr().toText12(isUnderLine: true),
|
||||
],
|
||||
).paddingOnly(left: 21, right: 21),
|
||||
SizedBox(
|
||||
height: 103 + 33,
|
||||
child: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const BouncingScrollPhysics(),
|
||||
padding: const EdgeInsets.only(left: 21, right: 21, top: 13),
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemBuilder: (cxt, index) {
|
||||
return SizedBox(
|
||||
width: 73,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 73,
|
||||
height: 73,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(100),
|
||||
),
|
||||
border: Border.all(color: MyColors.lightGreyEDColor, width: 1),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(50),
|
||||
),
|
||||
child: Image.network(
|
||||
"https://play-lh.googleusercontent.com/NPo88ojmhah4HDiposucJmfQIop4z4xc8kqJK9ITO9o-yCab2zxIp7PPB_XPj2iUojo",
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
4.height,
|
||||
Expanded(
|
||||
child: namesD[6 % (index + 1)].toText12(isCenter: true, maxLine: 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (cxt, index) => 8.width,
|
||||
itemCount: 6),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,138 @@
|
||||
import 'package:easy_localization/src/public_ext.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:mohem_flutter_app/config/routes.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/provider/dashboard_provider_model.dart';
|
||||
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class MenusWidget extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<int> namesColor = [0xff125765, 0xff239D8F, 0xff2BB8A8, 0xff1D92AA];
|
||||
|
||||
return Consumer<DashboardProviderModel>(builder: (context, data, child) {
|
||||
return GridView(
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 2 / 2, crossAxisSpacing: 9, mainAxisSpacing: 9),
|
||||
padding: EdgeInsets.zero,
|
||||
shrinkWrap: true,
|
||||
primary: false,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
children: [
|
||||
data.isWorkListLoading
|
||||
? MenuShimmer().onPress(() {
|
||||
data.fetchWorkListCounter();
|
||||
})
|
||||
: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(namesColor[0]),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocaleKeys.workList.tr().toText12(color: Colors.white),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: data.workListCounter.toString().toText16(color: Colors.white, isBold: true),
|
||||
),
|
||||
SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white)
|
||||
],
|
||||
)
|
||||
],
|
||||
).paddingOnly(left: 10, right: 10, bottom: 6, top: 6),
|
||||
).onPress(() {
|
||||
// Navigator.pushNamed(context, AppRoutes.workList);
|
||||
data.fetchWorkListCounter();
|
||||
}),
|
||||
data.isMissingSwipeLoading
|
||||
? MenuShimmer().onPress(() {
|
||||
data.fetchWorkListCounter();
|
||||
})
|
||||
: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(namesColor[1]),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocaleKeys.missingSwipes.tr().toText12(color: Colors.white),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: data.missingSwipeCounter.toString().toText16(color: Colors.white, isBold: true),
|
||||
),
|
||||
SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white)
|
||||
],
|
||||
)
|
||||
],
|
||||
).paddingOnly(left: 10, right: 10, bottom: 6, top: 6),
|
||||
).onPress(() {
|
||||
Navigator.pushNamed(context, AppRoutes.workList);
|
||||
}),
|
||||
data.isLeaveTicketBalanceLoading
|
||||
? MenuShimmer().onPress(() {
|
||||
data.fetchWorkListCounter();
|
||||
})
|
||||
: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(namesColor[2]),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocaleKeys.leaveBalance.tr().toText12(color: Colors.white),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: data.leaveBalance.toString().toText16(color: Colors.white, isBold: true),
|
||||
),
|
||||
SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white)
|
||||
],
|
||||
)
|
||||
],
|
||||
).paddingOnly(left: 10, right: 10, bottom: 6, top: 6),
|
||||
).onPress(() {
|
||||
Navigator.pushNamed(context, AppRoutes.workList);
|
||||
}),
|
||||
data.isLeaveTicketBalanceLoading
|
||||
? MenuShimmer().onPress(() {
|
||||
data.fetchWorkListCounter();
|
||||
})
|
||||
: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(namesColor[3]),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocaleKeys.ticketBalance.tr().toText12(color: Colors.white),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: data.ticketBalance.toString().toText16(color: Colors.white, isBold: true),
|
||||
),
|
||||
SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white)
|
||||
],
|
||||
)
|
||||
],
|
||||
).paddingOnly(left: 10, right: 10, bottom: 6, top: 6),
|
||||
).onPress(() {
|
||||
Navigator.pushNamed(context, AppRoutes.workList);
|
||||
})
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,147 @@
|
||||
import 'package:easy_localization/src/public_ext.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.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/provider/dashboard_provider_model.dart';
|
||||
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class ServicesWidget extends StatelessWidget {
|
||||
@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/work_from_home.svg",
|
||||
"assets/images/ticket_request.svg",
|
||||
"assets/images/work_from_home.svg",
|
||||
"assets/images/work_from_home.svg",
|
||||
"assets/images/work_from_home.svg",
|
||||
"assets/images/work_from_home.svg",
|
||||
"assets/images/work_from_home.svg"
|
||||
];
|
||||
|
||||
return Consumer<DashboardProviderModel>(
|
||||
builder: (context, data, child) {
|
||||
return data.isServicesMenusLoading
|
||||
? whileLoading()
|
||||
: ListView.separated(
|
||||
itemBuilder: (context, parentIndex) {
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
firstWord(data.homeMenus![parentIndex].menuEntry.prompt!).toText12(),
|
||||
lastWord(data.homeMenus![parentIndex].menuEntry.prompt!).toText24(isBold: true),
|
||||
],
|
||||
),
|
||||
),
|
||||
LocaleKeys.viewAllServices.tr().toText12(isUnderLine: true),
|
||||
],
|
||||
).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(iconT[index]),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Expanded(
|
||||
child: data.homeMenus![parentIndex].menuEntiesList[index].prompt!.toText11(isBold: true),
|
||||
),
|
||||
SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4)
|
||||
],
|
||||
)
|
||||
],
|
||||
).paddingOnly(left: 10, right: 10, bottom: 10, top: 12),
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (cxt, index) => 9.width,
|
||||
itemCount: data.homeMenus![parentIndex].menuEntiesList.length),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return 12.height;
|
||||
},
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemCount: data.homeMenus!.length);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
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),
|
||||
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),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
/* ZiK */
|
||||
|
||||
import 'dart:async';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
typedef ChildProvider<E> = Widget Function(BuildContext context, E? data);
|
||||
|
||||
class Updater<T> extends StatelessWidget{
|
||||
final ChildProvider<T> childProvider;
|
||||
StreamController<T?>? sink;
|
||||
T? initialData;
|
||||
List<T?> _history = [];
|
||||
|
||||
Stream<T?>? _stream;
|
||||
Updater({T? initialData, required this.childProvider}){
|
||||
this.sink = StreamController<T?>();
|
||||
this.initialData = initialData;
|
||||
_stream = this.sink?.stream;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StreamBuilder<T?>(
|
||||
initialData: this.initialData,
|
||||
stream: _stream,
|
||||
builder: (ctx, snapshot){
|
||||
return childProvider(context, snapshot.data);
|
||||
});
|
||||
}
|
||||
|
||||
pushData(T? data) {
|
||||
_history.add(data);
|
||||
sink?.sink.add(data);
|
||||
}
|
||||
|
||||
List<T?> getDataHistory() => _history;
|
||||
T? getLatestData() => _history.last;
|
||||
|
||||
}
|
||||
@ -0,0 +1,189 @@
|
||||
import 'package:easy_localization/src/public_ext.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.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:shimmer/shimmer.dart';
|
||||
|
||||
class GetAttendanceTrackingShimmer extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
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: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
// SvgPicture.asset("assets/images/"),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocaleKeys.markAttendance.tr().toText14(color: Colors.white, isBold: true).toShimmer(),
|
||||
16.height,
|
||||
"07:55:12".toText10(color: Colors.white, isBold: true).toShimmer(),
|
||||
3.height,
|
||||
LocaleKeys.timeLeftToday.tr().toText10(color: Colors.white).toShimmer(),
|
||||
9.height,
|
||||
const ClipRRect(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(20),
|
||||
),
|
||||
child: LinearProgressIndicator(
|
||||
value: 0.7,
|
||||
minHeight: 8,
|
||||
valueColor: const AlwaysStoppedAnimation<Color>(Colors.white),
|
||||
backgroundColor: const Color(0xff196D73),
|
||||
),
|
||||
).toShimmer(),
|
||||
],
|
||||
).paddingOnly(top: 12, right: 15, left: 12),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocaleKeys.checkIn.tr().toText12(color: Colors.white).toShimmer(),
|
||||
],
|
||||
).paddingOnly(left: 12),
|
||||
),
|
||||
Container(
|
||||
width: 45,
|
||||
height: 45,
|
||||
// color: Colors.blue,
|
||||
padding: const EdgeInsets.only(left: 14, right: 14),
|
||||
).toShimmer(),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MenuShimmer extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
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: [
|
||||
LocaleKeys.workList.tr().toText12(color: Colors.white).toShimmer(),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: 123.toString().toText10(color: Colors.white, isBold: true).toShimmer(),
|
||||
),
|
||||
12.width,
|
||||
SvgPicture.asset("assets/images/arrow_next.svg", color: Colors.white).toShimmer()
|
||||
],
|
||||
)
|
||||
],
|
||||
).paddingOnly(left: 10, right: 10, bottom: 6, top: 6),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ServicesHeaderShimmer extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
"Other".tr().toText10().toShimmer(),
|
||||
6.height,
|
||||
LocaleKeys.services.tr().toText12(isBold: true).toShimmer(),
|
||||
],
|
||||
),
|
||||
),
|
||||
LocaleKeys.viewAllServices.tr().toText12(isUnderLine: true).toShimmer(),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ServicesMenuShimmer extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return 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("assets/images/monthly_attendance.svg").toShimmer(),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
"Attendan".toText11(isBold: false).toShimmer(),
|
||||
5.height,
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Expanded(
|
||||
child: "Attendance".toText11(isBold: false).toShimmer(),
|
||||
),
|
||||
6.width,
|
||||
SvgPicture.asset("assets/images/arrow_next.svg").paddingOnly(bottom: 4).toShimmer()
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
).paddingOnly(left: 10, right: 10, bottom: 10, top: 12),
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue