Merge branch 'master' of http://34.17.52.79/Haroon6138/mohemm-flutter-app into sultan-dev
commit
6d92a78843
@ -0,0 +1,6 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQg+oBl9YdOiMRXfQZe
|
||||
nIe6tR1tojoOvvcohNJmJtH+SsagCgYIKoZIzj0DAQehRANCAATDY9E82MAgMI/g
|
||||
bKF1t4zLHJ1Yt9uoOnedNYsfyZLhh3l3ZyXRj02uDXz04AsNbNFjkLJXPc4xY9ad
|
||||
+A4rY70x
|
||||
-----END PRIVATE KEY-----
|
@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="22.015" height="22.015" viewBox="0 0 22.015 22.015">
|
||||
<g id="Button" transform="translate(-75.66 64.04) rotate(-45)">
|
||||
<rect id="Rectangle_5860" data-name="Rectangle 5860" width="15.567" height="15.567" rx="7.783" transform="translate(91 16)" fill="#d85323"/>
|
||||
<g id="plus_1" data-name="plus 1" transform="translate(95.001 20.001)">
|
||||
<path id="Vector" d="M0,0V7.756" transform="translate(3.878)" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.2"/>
|
||||
<path id="Vector-2" data-name="Vector" d="M0,0H7.756" transform="translate(0 3.878)" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.2"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 757 B |
@ -0,0 +1,4 @@
|
||||
<svg id="google-docs" xmlns="http://www.w3.org/2000/svg" width="18.402" height="24.158" viewBox="0 0 18.402 24.158">
|
||||
<path id="Path_4955" data-name="Path 4955" d="M63.123,24.158H77.278A2.126,2.126,0,0,0,79.4,22.035V7.078H74.447a2.126,2.126,0,0,1-2.123-2.123V0h-9.2A2.126,2.126,0,0,0,61,2.123V22.035A2.126,2.126,0,0,0,63.123,24.158Zm2.831-14.2h8.493a.708.708,0,0,1,0,1.416H65.954a.708.708,0,1,1,0-1.416Zm0,2.831h8.493a.708.708,0,0,1,0,1.416H65.954a.708.708,0,1,1,0-1.416Zm0,2.831h8.493a.708.708,0,0,1,0,1.416H65.954a.708.708,0,1,1,0-1.416Zm0,2.831h5.662a.708.708,0,0,1,0,1.416H65.954a.708.708,0,1,1,0-1.416Z" transform="translate(-61)" fill="#125765"/>
|
||||
<path id="Path_4956" data-name="Path 4956" d="M331.708,14.036h4.54L331,8.789v4.54A.708.708,0,0,0,331.708,14.036Z" transform="translate(-318.26 -8.374)" fill="#2bb8a6"/>
|
||||
</svg>
|
After Width: | Height: | Size: 832 B |
@ -0,0 +1,96 @@
|
||||
class GetNotificationsResponseModel {
|
||||
int? id;
|
||||
int? recordId;
|
||||
int? patientID;
|
||||
bool? projectOutSA;
|
||||
String? deviceType;
|
||||
String? deviceToken;
|
||||
String? message;
|
||||
String? messageType;
|
||||
String? messageTypeData;
|
||||
dynamic videoURL;
|
||||
bool? isQueue;
|
||||
String? isQueueOn;
|
||||
String? createdOn;
|
||||
String? createdBy;
|
||||
String? notificationType;
|
||||
bool? isSent;
|
||||
String? isSentOn;
|
||||
bool? isRead;
|
||||
String? isReadOn;
|
||||
int? channelID;
|
||||
int? projectID;
|
||||
|
||||
GetNotificationsResponseModel(
|
||||
{this.id,
|
||||
this.recordId,
|
||||
this.patientID,
|
||||
this.projectOutSA,
|
||||
this.deviceType,
|
||||
this.deviceToken,
|
||||
this.message,
|
||||
this.messageType,
|
||||
this.messageTypeData,
|
||||
this.videoURL,
|
||||
this.isQueue,
|
||||
this.isQueueOn,
|
||||
this.createdOn,
|
||||
this.createdBy,
|
||||
this.notificationType,
|
||||
this.isSent,
|
||||
this.isSentOn,
|
||||
this.isRead,
|
||||
this.isReadOn,
|
||||
this.channelID,
|
||||
this.projectID});
|
||||
|
||||
GetNotificationsResponseModel.fromJson(Map<String, dynamic> json) {
|
||||
id = json['Id'];
|
||||
recordId = json['RecordId'];
|
||||
patientID = json['PatientID'];
|
||||
projectOutSA = json['ProjectOutSA'];
|
||||
deviceType = json['DeviceType'];
|
||||
deviceToken = json['DeviceToken'];
|
||||
message = json['Message'];
|
||||
messageType = json['MessageType'];
|
||||
messageTypeData = json['MessageTypeData'];
|
||||
videoURL = json['VideoURL'];
|
||||
isQueue = json['IsQueue'];
|
||||
isQueueOn = json['IsQueueOn'];
|
||||
createdOn = json['CreatedOn'];
|
||||
createdBy = json['CreatedBy'];
|
||||
notificationType = json['NotificationType'];
|
||||
isSent = json['IsSent'];
|
||||
isSentOn = json['IsSentOn'];
|
||||
isRead = json['IsRead'];
|
||||
isReadOn = json['IsReadOn'];
|
||||
channelID = json['ChannelID'];
|
||||
projectID = json['ProjectID'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['Id'] = this.id;
|
||||
data['RecordId'] = this.recordId;
|
||||
data['PatientID'] = this.patientID;
|
||||
data['ProjectOutSA'] = this.projectOutSA;
|
||||
data['DeviceType'] = this.deviceType;
|
||||
data['DeviceToken'] = this.deviceToken;
|
||||
data['Message'] = this.message;
|
||||
data['MessageType'] = this.messageType;
|
||||
data['MessageTypeData'] = this.messageTypeData;
|
||||
data['VideoURL'] = this.videoURL;
|
||||
data['IsQueue'] = this.isQueue;
|
||||
data['IsQueueOn'] = this.isQueueOn;
|
||||
data['CreatedOn'] = this.createdOn;
|
||||
data['CreatedBy'] = this.createdBy;
|
||||
data['NotificationType'] = this.notificationType;
|
||||
data['IsSent'] = this.isSent;
|
||||
data['IsSentOn'] = this.isSentOn;
|
||||
data['IsRead'] = this.isRead;
|
||||
data['IsReadOn'] = this.isReadOn;
|
||||
data['ChannelID'] = this.channelID;
|
||||
data['ProjectID'] = this.projectID;
|
||||
return data;
|
||||
}
|
||||
}
|
@ -1,99 +1,156 @@
|
||||
class Advertisement {
|
||||
int? advertisementId;
|
||||
String? advertisementTitle;
|
||||
int? durationInSeconds;
|
||||
bool? showDelete;
|
||||
dynamic acknowledgment;
|
||||
late bool isOptional;
|
||||
List<ViewAttachFileColl>? viewAttachFileColl;
|
||||
int? skipButtonId;
|
||||
List<ActionButtonsColl>? actionButtonsColl;
|
||||
bool? isActive;
|
||||
num? pageSize;
|
||||
num? pageNo;
|
||||
num? languageId;
|
||||
|
||||
Advertisement({
|
||||
this.advertisementId,
|
||||
this.advertisementTitle,
|
||||
this.durationInSeconds,
|
||||
this.showDelete,
|
||||
this.acknowledgment,
|
||||
required this.isOptional,
|
||||
// this.skipBtnTextEn,
|
||||
// this.skipBtnTextAr,
|
||||
this.viewAttachFileColl,
|
||||
this.skipButtonId,
|
||||
this.actionButtonsColl,
|
||||
this.isActive,
|
||||
this.pageSize,
|
||||
this.pageNo,
|
||||
this.languageId,
|
||||
});
|
||||
|
||||
final int? advertisementId;
|
||||
final String? advertisementTitle;
|
||||
final int? durationInSeconds;
|
||||
final bool? showDelete;
|
||||
final dynamic acknowledgment;
|
||||
final List<ViewAttachFileColl>? viewAttachFileColl;
|
||||
final bool? isActive;
|
||||
final dynamic pageSize;
|
||||
final dynamic pageNo;
|
||||
final dynamic languageId;
|
||||
|
||||
factory Advertisement.fromJson(Map<String, dynamic> json) => Advertisement(
|
||||
advertisementId: json["advertisementId"] == null ? null : json["advertisementId"],
|
||||
advertisementTitle: json["advertisementTitle"] == null ? null : json["advertisementTitle"],
|
||||
durationInSeconds: json["durationInSeconds"] == null ? null : json["durationInSeconds"],
|
||||
showDelete: json["showDelete"] == null ? null : json["showDelete"],
|
||||
acknowledgment: json["acknowledgment"],
|
||||
viewAttachFileColl: json["viewAttachFileColl"] == null ? null : List<ViewAttachFileColl>.from(json["viewAttachFileColl"].map((x) => ViewAttachFileColl.fromJson(x))),
|
||||
isActive: json["isActive"] == null ? null : json["isActive"],
|
||||
pageSize: json["pageSize"],
|
||||
pageNo: json["pageNo"],
|
||||
languageId: json["languageId"],
|
||||
);
|
||||
Advertisement.fromJson(Map<String, dynamic> json) {
|
||||
advertisementId = json['advertisementId'];
|
||||
advertisementTitle = json['advertisementTitle'];
|
||||
durationInSeconds = json['durationInSeconds'];
|
||||
showDelete = json['showDelete'];
|
||||
acknowledgment = json['acknowledgment'];
|
||||
isOptional = json['isOptional'];
|
||||
// skipBtnTextEn = json['skipBtnTextEn'];
|
||||
// skipBtnTextAr = json['skipBtnTextAr'];
|
||||
if (json['viewAttachFileColl'] != null) {
|
||||
viewAttachFileColl = <ViewAttachFileColl>[];
|
||||
json['viewAttachFileColl'].forEach((v) {
|
||||
viewAttachFileColl!.add(ViewAttachFileColl.fromJson(v));
|
||||
});
|
||||
}
|
||||
skipButtonId = json['skipButtonId'];
|
||||
if (json['actionButtonsColl'] != null) {
|
||||
actionButtonsColl = <ActionButtonsColl>[];
|
||||
json['actionButtonsColl'].forEach((v) {
|
||||
actionButtonsColl!.add(ActionButtonsColl.fromJson(v));
|
||||
});
|
||||
}
|
||||
isActive = json['isActive'];
|
||||
pageSize = json['pageSize'];
|
||||
pageNo = json['pageNo'];
|
||||
languageId = json['languageId'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"advertisementId": advertisementId == null ? null : advertisementId,
|
||||
"advertisementTitle": advertisementTitle == null ? null : advertisementTitle,
|
||||
"durationInSeconds": durationInSeconds == null ? null : durationInSeconds,
|
||||
"showDelete": showDelete == null ? null : showDelete,
|
||||
"acknowledgment": acknowledgment,
|
||||
"viewAttachFileColl": viewAttachFileColl == null ? null : List<dynamic>.from(viewAttachFileColl!.map((x) => x.toJson())),
|
||||
"isActive": isActive == null ? null : isActive,
|
||||
"pageSize": pageSize,
|
||||
"pageNo": pageNo,
|
||||
"languageId": languageId,
|
||||
};
|
||||
Map<String, dynamic> toJson() {
|
||||
Map<String, dynamic> data = Map<String, dynamic>();
|
||||
data['advertisementId'] = this.advertisementId;
|
||||
data['advertisementTitle'] = this.advertisementTitle;
|
||||
data['durationInSeconds'] = this.durationInSeconds;
|
||||
data['showDelete'] = this.showDelete;
|
||||
data['acknowledgment'] = this.acknowledgment;
|
||||
data['isOptional'] = this.isOptional;
|
||||
// data['skipBtnTextEn'] = this.skipBtnTextEn;
|
||||
// data['skipBtnTextAr'] = this.skipBtnTextAr;
|
||||
if (this.viewAttachFileColl != null) {
|
||||
data['viewAttachFileColl'] = this.viewAttachFileColl!.map((v) => v.toJson()).toList();
|
||||
}
|
||||
data['skipButtonId'] = this.skipButtonId;
|
||||
if (this.actionButtonsColl != null) {
|
||||
data['actionButtonsColl'] = this.actionButtonsColl!.map((v) => v.toJson()).toList();
|
||||
}
|
||||
data['isActive'] = this.isActive;
|
||||
data['pageSize'] = this.pageSize;
|
||||
data['pageNo'] = this.pageNo;
|
||||
data['languageId'] = this.languageId;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class ViewAttachFileColl {
|
||||
ViewAttachFileColl({
|
||||
this.attachmentId,
|
||||
this.fileName,
|
||||
this.contentType,
|
||||
this.attachFileStream,
|
||||
this.base64String,
|
||||
this.isActive,
|
||||
this.referenceItemId,
|
||||
this.content,
|
||||
this.filePath,
|
||||
});
|
||||
dynamic attachmentId;
|
||||
String? fileName;
|
||||
String? contentType;
|
||||
dynamic attachFileStream;
|
||||
String? base64String;
|
||||
dynamic isActive;
|
||||
dynamic referenceItemId;
|
||||
dynamic content;
|
||||
dynamic filePath;
|
||||
|
||||
ViewAttachFileColl({this.attachmentId, this.fileName, this.contentType, this.attachFileStream, this.base64String, this.isActive, this.referenceItemId, this.content, this.filePath});
|
||||
|
||||
ViewAttachFileColl.fromJson(Map<String, dynamic> json) {
|
||||
attachmentId = json['attachmentId'];
|
||||
fileName = json['fileName'];
|
||||
contentType = json['contentType'];
|
||||
attachFileStream = json['attachFileStream'];
|
||||
base64String = json['base64String'];
|
||||
isActive = json['isActive'];
|
||||
referenceItemId = json['referenceItemId'];
|
||||
content = json['content'];
|
||||
filePath = json['filePath'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['attachmentId'] = this.attachmentId;
|
||||
data['fileName'] = this.fileName;
|
||||
data['contentType'] = this.contentType;
|
||||
data['attachFileStream'] = this.attachFileStream;
|
||||
data['base64String'] = this.base64String;
|
||||
data['isActive'] = this.isActive;
|
||||
data['referenceItemId'] = this.referenceItemId;
|
||||
data['content'] = this.content;
|
||||
data['filePath'] = this.filePath;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class ActionButtonsColl {
|
||||
late int actionButtonId;
|
||||
late String btnTextEn;
|
||||
late String btnTextAr;
|
||||
late String actionValue;
|
||||
late dynamic iconOrImage;
|
||||
late int orderNo;
|
||||
|
||||
final dynamic attachmentId;
|
||||
final String? fileName;
|
||||
final String? contentType;
|
||||
final dynamic attachFileStream;
|
||||
final String? base64String;
|
||||
final dynamic isActive;
|
||||
final dynamic referenceItemId;
|
||||
final dynamic content;
|
||||
final dynamic filePath;
|
||||
ActionButtonsColl({required this.actionButtonId, required this.btnTextEn, required this.btnTextAr, required this.actionValue, required this.iconOrImage, required this.orderNo});
|
||||
|
||||
factory ViewAttachFileColl.fromJson(Map<String, dynamic> json) => ViewAttachFileColl(
|
||||
attachmentId: json["attachmentId"],
|
||||
fileName: json["fileName"] == null ? null : json["fileName"],
|
||||
contentType: json["contentType"] == null ? null : json["contentType"],
|
||||
attachFileStream: json["attachFileStream"],
|
||||
base64String: json["base64String"] == null ? null : json["base64String"],
|
||||
isActive: json["isActive"],
|
||||
referenceItemId: json["referenceItemId"],
|
||||
content: json["content"],
|
||||
filePath: json["filePath"],
|
||||
);
|
||||
ActionButtonsColl.fromJson(Map<String, dynamic> json) {
|
||||
actionButtonId = json['actionButtonId'];
|
||||
btnTextEn = json['btnTextEn'];
|
||||
btnTextAr = json['btnTextAr'];
|
||||
actionValue = json['actionValue'];
|
||||
iconOrImage = json['iconOrImage'];
|
||||
orderNo = json['orderNo'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"attachmentId": attachmentId,
|
||||
"fileName": fileName == null ? null : fileName,
|
||||
"contentType": contentType == null ? null : contentType,
|
||||
"attachFileStream": attachFileStream,
|
||||
"base64String": base64String == null ? null : base64String,
|
||||
"isActive": isActive,
|
||||
"referenceItemId": referenceItemId,
|
||||
"content": content,
|
||||
"filePath": filePath,
|
||||
};
|
||||
Map<String, dynamic> toJson() {
|
||||
Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['actionButtonId'] = this.actionButtonId;
|
||||
data['btnTextEn'] = this.btnTextEn;
|
||||
data['btnTextAr'] = this.btnTextAr;
|
||||
data['actionValue'] = this.actionValue;
|
||||
data['iconOrImage'] = this.iconOrImage;
|
||||
data['orderNo'] = this.orderNo;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
class EmployeeDocumentsList {
|
||||
String? dOCUMENTREQUIREDSTATUS;
|
||||
String? dOCUMENTSTATUS;
|
||||
String? dOCUMENTTYPE;
|
||||
String? dOCUMENTTYPENAME;
|
||||
String? eNTITLEDTOAPPLYFLAG;
|
||||
String? fUNCTIONNAME;
|
||||
|
||||
EmployeeDocumentsList(
|
||||
{this.dOCUMENTREQUIREDSTATUS,
|
||||
this.dOCUMENTSTATUS,
|
||||
this.dOCUMENTTYPE,
|
||||
this.dOCUMENTTYPENAME,
|
||||
this.eNTITLEDTOAPPLYFLAG,
|
||||
this.fUNCTIONNAME});
|
||||
|
||||
EmployeeDocumentsList.fromJson(Map<String, dynamic> json) {
|
||||
dOCUMENTREQUIREDSTATUS = json['DOCUMENT_REQUIRED_STATUS'];
|
||||
dOCUMENTSTATUS = json['DOCUMENT_STATUS'];
|
||||
dOCUMENTTYPE = json['DOCUMENT_TYPE'];
|
||||
dOCUMENTTYPENAME = json['DOCUMENT_TYPE_NAME'];
|
||||
eNTITLEDTOAPPLYFLAG = json['ENTITLED_TO_APPLY_FLAG'];
|
||||
fUNCTIONNAME = json['FUNCTION_NAME'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['DOCUMENT_REQUIRED_STATUS'] = this.dOCUMENTREQUIREDSTATUS;
|
||||
data['DOCUMENT_STATUS'] = this.dOCUMENTSTATUS;
|
||||
data['DOCUMENT_TYPE'] = this.dOCUMENTTYPE;
|
||||
data['DOCUMENT_TYPE_NAME'] = this.dOCUMENTTYPENAME;
|
||||
data['ENTITLED_TO_APPLY_FLAG'] = this.eNTITLEDTOAPPLYFLAG;
|
||||
data['FUNCTION_NAME'] = this.fUNCTIONNAME;
|
||||
return data;
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lottie/lottie.dart';
|
||||
import 'package:mohem_flutter_app/models/get_notifications_response_model.dart';
|
||||
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
|
||||
|
||||
class NotificationsDetailsPage extends StatefulWidget {
|
||||
final GetNotificationsResponseModel notification;
|
||||
|
||||
NotificationsDetailsPage({required this.notification});
|
||||
|
||||
@override
|
||||
State<NotificationsDetailsPage> createState() => _NotificationsDetailsPageState();
|
||||
}
|
||||
|
||||
class _NotificationsDetailsPageState extends State<NotificationsDetailsPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
appBar: AppBarWidget(
|
||||
context,
|
||||
title: "Notification Details",
|
||||
),
|
||||
body: ListView(
|
||||
physics: BouncingScrollPhysics(),
|
||||
padding: EdgeInsets.all(21),
|
||||
children: [
|
||||
Text(
|
||||
widget.notification.createdOn!,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xff2E303A),
|
||||
letterSpacing: -0.64,
|
||||
),
|
||||
),
|
||||
if (widget.notification.messageTypeData != null)
|
||||
if (widget.notification.messageTypeData!.isNotEmpty && widget.notification.notificationType != "2")
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 18),
|
||||
child: Image.network(widget.notification.messageTypeData!, loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) {
|
||||
if (loadingProgress == null) return child;
|
||||
return Center(
|
||||
child: SizedBox(
|
||||
width: 40.0,
|
||||
height: 40.0,
|
||||
child: showLoadingAnimation(),
|
||||
),
|
||||
);
|
||||
}, fit: BoxFit.fill),
|
||||
),
|
||||
SizedBox(height: 18),
|
||||
Text(
|
||||
widget.notification.message!.trim(),
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xff575757),
|
||||
letterSpacing: -0.48,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget showLoadingAnimation() {
|
||||
return Lottie.asset(
|
||||
'assets/lottie/loading.json',
|
||||
repeat: true,
|
||||
reverse: false,
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,174 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dotted_border/dotted_border.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:mohem_flutter_app/app_state/app_state.dart';
|
||||
import 'package:mohem_flutter_app/classes/colors.dart';
|
||||
import 'package:mohem_flutter_app/classes/utils.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/my_documents/employee_documents_list_model.dart';
|
||||
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
|
||||
import 'package:mohem_flutter_app/widgets/button/default_button.dart';
|
||||
import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart';
|
||||
import 'package:mohem_flutter_app/widgets/my_document_item.dart';
|
||||
import 'package:sizer/sizer.dart';
|
||||
|
||||
class MyDocumentDetailScreen extends StatefulWidget {
|
||||
EmployeeDocumentsList document;
|
||||
final Color color;
|
||||
|
||||
MyDocumentDetailScreen(this.document, this.color, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_MyDocumentDetailScreenState createState() {
|
||||
return _MyDocumentDetailScreenState();
|
||||
}
|
||||
}
|
||||
|
||||
class _MyDocumentDetailScreenState extends State<MyDocumentDetailScreen> {
|
||||
DateTime? expiryDate;
|
||||
List<XFile> imagesList = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
appBar: AppBarWidget(context, title: widget.document.dOCUMENTTYPE!, showHomeButton: true),
|
||||
body: Column(
|
||||
children: [
|
||||
ListView(
|
||||
padding: const EdgeInsets.all(21),
|
||||
children: [
|
||||
MyDocumentItem(widget.document, widget.color,isNotInDetailView: false),
|
||||
20.height,
|
||||
DynamicTextFieldWidget(
|
||||
LocaleKeys.employeeNumber.tr(),
|
||||
AppState().getUserName!,
|
||||
isInputTypeNum: true,
|
||||
isReadOnly: true,
|
||||
),
|
||||
12.height,
|
||||
PopupMenuButton(
|
||||
child: DynamicTextFieldWidget(
|
||||
"Document Type*",
|
||||
"National ID",
|
||||
isEnable: false,
|
||||
isPopup: true,
|
||||
isInputTypeNum: true,
|
||||
// isReadOnly: true,
|
||||
),
|
||||
itemBuilder: (_) => <PopupMenuItem<int>>[],
|
||||
onSelected: (int popipIndex) async {}),
|
||||
12.height,
|
||||
DynamicTextFieldWidget(
|
||||
"Expiry Date",
|
||||
expiryDate == null ? LocaleKeys.dateRequired.tr() : Utils.getMonthNamedFormat(expiryDate!).replaceAll("-", " "),
|
||||
suffixIconData: Icons.calendar_today,
|
||||
isEnable: false,
|
||||
onTap: () async {
|
||||
DateTime date = await Utils.selectDate(context, expiryDate ?? DateTime.now());
|
||||
String dateString = date.toString().split(' ').first;
|
||||
if (date != expiryDate) {
|
||||
expiryDate = date;
|
||||
setState(() {});
|
||||
}
|
||||
},
|
||||
),
|
||||
12.height,
|
||||
DottedBorder(
|
||||
borderType: BorderType.RRect,
|
||||
radius: const Radius.circular(10),
|
||||
padding: const EdgeInsets.all(12),
|
||||
dashPattern: const <double>[2, 1],
|
||||
color: MyColors.selectedBorderColor,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Transform.rotate(
|
||||
angle: 45,
|
||||
child: const Icon(Icons.attach_file_rounded, size: 16, color: MyColors.selectedBorderColor),
|
||||
),
|
||||
4.width,
|
||||
"Attach Image".toText14(color: MyColors.selectedBorderColor),
|
||||
],
|
||||
).center,
|
||||
).onPress(() async {
|
||||
ImagePicker picker = ImagePicker();
|
||||
List<XFile> list = await picker.pickMultiImage();
|
||||
if (list.isNotEmpty) {
|
||||
imagesList.addAll(list);
|
||||
var seen = <String>{};
|
||||
imagesList = imagesList.where((image) => seen.add(image.name)).toList();
|
||||
setState(() {});
|
||||
}
|
||||
}),
|
||||
12.height,
|
||||
GridView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
itemCount: imagesList.length,
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return Stack(
|
||||
alignment: Alignment.topRight,
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: Image.file(
|
||||
File(imagesList[index].path),
|
||||
fit: BoxFit.cover,
|
||||
errorBuilder: (BuildContext context, Object error, StackTrace? stackTrace) {
|
||||
return const Center(child: Text('This image type is not supported'));
|
||||
},
|
||||
),
|
||||
).paddingOnly(top: 6, right: 6),
|
||||
Container(
|
||||
height: 16,
|
||||
width: 16,
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Color(0xffd85323),
|
||||
),
|
||||
child: const Icon(Icons.clear, color: Colors.white, size: 12),
|
||||
).onPress(() {
|
||||
imagesList.removeAt(index);
|
||||
setState(() {});
|
||||
}),
|
||||
],
|
||||
);
|
||||
},
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 4,
|
||||
mainAxisSpacing: 8,
|
||||
crossAxisSpacing: 8,
|
||||
childAspectRatio: 1,
|
||||
),
|
||||
)
|
||||
],
|
||||
).expanded,
|
||||
const Divider(height: 1, color: MyColors.lightGreyEFColor),
|
||||
DefaultButton(
|
||||
LocaleKeys.submit.tr(),
|
||||
widget.document.dOCUMENTSTATUS == "Exist" ? null : () {},
|
||||
).paddingOnly(left: 21, right: 21, bottom: 21, top: 14),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mohem_flutter_app/api/profile_api_client.dart';
|
||||
import 'package:mohem_flutter_app/app_state/app_state.dart';
|
||||
import 'package:mohem_flutter_app/classes/colors.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/models/my_documents/employee_documents_list_model.dart';
|
||||
import 'package:mohem_flutter_app/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart';
|
||||
import 'package:mohem_flutter_app/ui/screens/my_documents/my_document_detail_screen.dart';
|
||||
import 'package:mohem_flutter_app/widgets/my_document_item.dart';
|
||||
|
||||
class MyDocumentsFragment extends StatefulWidget {
|
||||
List<EmployeeDocumentsList>? list;
|
||||
|
||||
MyDocumentsFragment(this.list, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_MyDocumentsFragmentState createState() {
|
||||
return _MyDocumentsFragmentState();
|
||||
}
|
||||
}
|
||||
|
||||
class _MyDocumentsFragmentState extends State<MyDocumentsFragment> {
|
||||
int selectedIndex = 0;
|
||||
List<EmployeeDocumentsList>? documentsList;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
documentsList = widget.list;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant MyDocumentsFragment oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (oldWidget.list != widget.list) {
|
||||
documentsList = widget.list;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<EmployeeDocumentsList> documentfilteredList = getTagBySelectedTab(selectedIndex);
|
||||
return Column(
|
||||
children: [
|
||||
GridView.count(
|
||||
crossAxisSpacing: 6,
|
||||
crossAxisCount: 4,
|
||||
childAspectRatio: 79 / 79,
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
padding: const EdgeInsets.only(left: 21, right: 21, bottom: 11, top: 21),
|
||||
children: [
|
||||
gridViewItem(LocaleKeys.allDocuments.tr(), getTagBySelectedTab(0).length.toString(), 0, MyColors.darkTextColor),
|
||||
gridViewItem(LocaleKeys.expiredDocuments.tr(), getTagBySelectedTab(1).length.toString(), 1, MyColors.redA3Color),
|
||||
gridViewItem(LocaleKeys.missingDocuments.tr(), getTagBySelectedTab(2).length.toString(), 2, MyColors.yellowColor00),
|
||||
gridViewItem(LocaleKeys.uploadedDocuments.tr(), getTagBySelectedTab(3).length.toString(), 3, MyColors.greenColor),
|
||||
],
|
||||
),
|
||||
documentsList == null
|
||||
? const SizedBox()
|
||||
: (documentfilteredList.isNotEmpty
|
||||
? ListView.separated(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
padding: const EdgeInsets.only(left: 21, right: 21, bottom: 21, top: 11),
|
||||
itemBuilder: (cxt, index) {
|
||||
return MyDocumentItem(documentfilteredList[index], getColorByDocumentStatus(documentfilteredList[index].dOCUMENTSTATUS!)).onPress(() {
|
||||
if (documentfilteredList[index].eNTITLEDTOAPPLYFLAG != 'Y') return;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.addDynamicInput,
|
||||
arguments: DynamicListViewParams(documentfilteredList[index].dOCUMENTTYPE!, documentfilteredList[index].fUNCTIONNAME!,
|
||||
selectedEmp: AppState().getUserName, isAttachmentMandatory: true),
|
||||
);
|
||||
});
|
||||
},
|
||||
separatorBuilder: (cxt, index) => 12.height,
|
||||
itemCount: documentfilteredList.length)
|
||||
: Utils.getNoDataWidget(context).center)
|
||||
.expanded,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget gridViewItem(String title, String value, int index, Color color) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: const Color(0xff000000).withOpacity(.05),
|
||||
blurRadius: 26,
|
||||
offset: const Offset(0, 0),
|
||||
),
|
||||
],
|
||||
border: Border.all(color: selectedIndex == index ? MyColors.selectedBorderColor : Colors.white, width: 2),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
title.toText10(),
|
||||
value.toText18(isBold: true, color: color),
|
||||
],
|
||||
),
|
||||
).onPress(() {
|
||||
setState(() {
|
||||
selectedIndex = index;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Color getColorByDocumentStatus(String status) {
|
||||
Color _color;
|
||||
switch (status) {
|
||||
case "Expired":
|
||||
_color = MyColors.redA3Color;
|
||||
break;
|
||||
case "Exist":
|
||||
_color = MyColors.greenColor;
|
||||
break;
|
||||
case "Missing":
|
||||
_color = MyColors.yellowColor00;
|
||||
break;
|
||||
case "Not Exist":
|
||||
_color = MyColors.redA3Color;
|
||||
break;
|
||||
default:
|
||||
_color = MyColors.darkTextColor;
|
||||
break;
|
||||
}
|
||||
return _color;
|
||||
}
|
||||
|
||||
List<EmployeeDocumentsList> getTagBySelectedTab(int index) {
|
||||
List<EmployeeDocumentsList> list = [];
|
||||
switch (index) {
|
||||
case 1:
|
||||
list = documentsList?.where((element) => element.dOCUMENTSTATUS == "Expired").toList() ?? [];
|
||||
break;
|
||||
case 2:
|
||||
list = documentsList?.where((element) => element.dOCUMENTSTATUS == "Missing").toList() ?? [];
|
||||
break;
|
||||
case 3:
|
||||
list = documentsList?.where((element) => element.dOCUMENTSTATUS == "Exist").toList() ?? [];
|
||||
break;
|
||||
default:
|
||||
list = documentsList ?? [];
|
||||
break;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mohem_flutter_app/api/profile_api_client.dart';
|
||||
import 'package:mohem_flutter_app/classes/colors.dart';
|
||||
import 'package:mohem_flutter_app/classes/utils.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/my_documents/employee_documents_list_model.dart';
|
||||
import 'package:mohem_flutter_app/ui/screens/my_documents/my_documents_fragment.dart';
|
||||
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
|
||||
|
||||
class MyDocumentsScreen extends StatefulWidget {
|
||||
MyDocumentsScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_MyDocumentsScreenState createState() {
|
||||
return _MyDocumentsScreenState();
|
||||
}
|
||||
}
|
||||
|
||||
class _MyDocumentsScreenState extends State<MyDocumentsScreen> {
|
||||
int tabIndex = 0;
|
||||
PageController controller = PageController();
|
||||
|
||||
List<EmployeeDocumentsList>? documentsList;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
getDocuments();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void getDocuments() async {
|
||||
try {
|
||||
documentsList?.clear();
|
||||
Utils.showLoading(context);
|
||||
documentsList = await ProfileApiClient().getEmployeeDocuments();
|
||||
Utils.hideLoading(context);
|
||||
setState(() {});
|
||||
} catch (ex) {
|
||||
Utils.hideLoading(context);
|
||||
Utils.handleException(ex, context, null);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var requiredDocumentsList;
|
||||
var optionalDocumentsList;
|
||||
|
||||
if (documentsList?.isNotEmpty ?? false) {
|
||||
requiredDocumentsList = <EmployeeDocumentsList>[];
|
||||
optionalDocumentsList = <EmployeeDocumentsList>[];
|
||||
documentsList!.forEach((element) {
|
||||
if (element.dOCUMENTREQUIREDSTATUS == "Required") {
|
||||
requiredDocumentsList.add(element);
|
||||
} else {
|
||||
optionalDocumentsList.add(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
appBar: AppBarWidget(context, title: LocaleKeys.myDocuments.tr(), showHomeButton: true),
|
||||
body: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.only(left: 21, right: 21, top: 16, bottom: 16),
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(25),
|
||||
bottomRight: Radius.circular(25),
|
||||
),
|
||||
gradient: LinearGradient(
|
||||
transform: GradientRotation(.83),
|
||||
begin: Alignment.topRight,
|
||||
end: Alignment.bottomLeft,
|
||||
colors: [
|
||||
MyColors.gradiantEndColor,
|
||||
MyColors.gradiantStartColor,
|
||||
],
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [myTab(LocaleKeys.requiredDocuments.tr(), 0), myTab(LocaleKeys.optionalDocuments.tr(), 1)],
|
||||
),
|
||||
),
|
||||
PageView(
|
||||
controller: controller,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
onPageChanged: (int pageIndex) {
|
||||
setState(() {
|
||||
tabIndex = pageIndex;
|
||||
});
|
||||
},
|
||||
children: [MyDocumentsFragment(requiredDocumentsList), MyDocumentsFragment(optionalDocumentsList)],
|
||||
).expanded,
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget myTab(String title, int index) {
|
||||
bool isSelected = (index == tabIndex);
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
title.toText12(color: isSelected ? Colors.white : Colors.white.withOpacity(.74), isCenter: true),
|
||||
4.height,
|
||||
Container(
|
||||
height: 8,
|
||||
width: 8,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: isSelected ? Colors.white : Colors.transparent,
|
||||
),
|
||||
),
|
||||
],
|
||||
).onPress(() {
|
||||
controller.jumpToPage(index);
|
||||
}).expanded;
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_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/models/my_documents/employee_documents_list_model.dart';
|
||||
import 'package:sizer/sizer.dart';
|
||||
|
||||
class MyDocumentItem extends StatelessWidget {
|
||||
EmployeeDocumentsList document;
|
||||
final Color color;
|
||||
final bool isNotInDetailView;
|
||||
|
||||
MyDocumentItem(this.document, this.color, {Key? key,this.isNotInDetailView = true}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: document.eNTITLEDTOAPPLYFLAG != 'Y' ? Colors.grey.shade300 : Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: const Color(0xff000000).withOpacity(.05),
|
||||
blurRadius: 26,
|
||||
offset: const Offset(0, -3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: -35,
|
||||
child: Container(
|
||||
width: 45,
|
||||
height: 45,
|
||||
transform: Matrix4.rotationZ(0.8),
|
||||
color: color,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SvgPicture.asset('assets/images/document.svg').paddingOnly(top: 6),
|
||||
12.width,
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
document.dOCUMENTTYPENAME!.toText16(),
|
||||
document.dOCUMENTSTATUS!.toText10(color: color),
|
||||
],
|
||||
).expanded,
|
||||
],
|
||||
).expanded,
|
||||
if (isNotInDetailView)
|
||||
const Icon(
|
||||
Icons.arrow_forward,
|
||||
size: 20,
|
||||
color: Color(0xff2E303A),
|
||||
)
|
||||
],
|
||||
).paddingOnly(top: 14, bottom: 18, right: 14, left: 24),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue