fist commit ftc staff app clone

This commit is contained in:
2024-08-01 13:46:46 +05:30
commit bf9064a9c9
515 changed files with 42796 additions and 0 deletions

View File

@@ -0,0 +1,326 @@
import 'package:flutter/material.dart';
import 'package:ftc_mobile_app/ftc_mobile_app.dart';
import 'package:ftc_mobile_app/models/appointmentsListResponse/AppointmentsListResponse.dart';
import 'package:ftc_mobile_app/models/clients/recent_incidents_model.dart';
import 'package:ftc_mobile_app/utilities/extensions/custom_extensions.dart';
import 'package:get/get.dart';
import 'widgets/appointment_details.dart';
import 'widgets/recent_incident_detail_dialog.dart';
class AppDialog {
static String areYouSureText = "Are you sure?";
static bool alreadyShownUnauthorizedAlert = false;
static Widget titleText(String title) {
return CustomTextWidget(
text: title,
textAlign: TextAlign.center,
fontSize: 20,
fontWeight: FontWeight.w700,
);
}
static Widget messageText(String message) {
return CustomTextWidget(
text: message,
textAlign: TextAlign.center,
fontSize: 12,
fontWeight: FontWeight.w400,
);
}
static Widget buttonsBar({
String button1Text = "No",
String button2Text = "Yes",
VoidCallback? onButton1Tap,
required VoidCallback onButton2Tap,
}) {
return SizedBox(
width: double.maxFinite,
height: 40.h,
child: Row(
children: [
Expanded(
child: CustomAppButton(
onTap: () {
if (onButton1Tap == null) {
Get.back();
} else {
onButton1Tap();
}
},
buttonText: button1Text,
textColor: Colors.black,
borderColor: Colors.grey,
buttonColor: Colors.white,
),
),
16.horizontalSpace,
Expanded(
child: CustomAppButton(
onTap: onButton2Tap,
buttonText: button2Text,
buttonColor: Get.theme.primaryColor,
),
),
],
),
);
}
static Future successDialog({
required String title,
required String message,
required String buttonText,
required VoidCallback onDoneButtonClick,
bool canDismiss = true,
}) {
return Get.generalDialog(
barrierLabel: "",
barrierDismissible: canDismiss,
pageBuilder: (_, a1, a2) {
return AlertDialog(
shape: 15.toRoundedRectRadius(),
backgroundColor: Colors.white,
elevation: 0,
contentPadding: REdgeInsets.symmetric(horizontal: 24, vertical: 32),
content: WillPopScope(
onWillPop: () async => canDismiss,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// SvgPicture.asset(
// Assets.svgIcCheck,
// width: 50.r,
// height: 50.r,
// ),
// 16.verticalSpace,
titleText(title),
12.verticalSpace,
messageText(message),
24.verticalSpace,
CustomAppButton(
onTap: onDoneButtonClick,
buttonText: buttonText,
buttonColor: Get.theme.primaryColor,
).addPaddingHorizontal(24),
],
),
),
);
},
);
}
static Future showDialogWithSingleActionButton(
{required String title,
required String message,
required VoidCallback onDoneButtonClick}) {
return Get.generalDialog(
barrierLabel: "",
barrierDismissible: true,
pageBuilder: (_, a1, a2) {
return AlertDialog(
shape: 15.toRoundedRectRadius(),
contentPadding: REdgeInsets.symmetric(horizontal: 32, vertical: 32),
backgroundColor: Colors.white,
elevation: 0,
insetPadding: REdgeInsets.all(24),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
12.verticalSpace,
titleText(title),
16.verticalSpace,
messageText(message),
32.verticalSpace,
CustomAppButton(
onTap: onDoneButtonClick,
buttonText: "Done",
buttonColor: Get.theme.primaryColor,
).addPaddingHorizontal(24),
],
),
);
},
);
}
static Future showDialogDeleteAccount(
{required VoidCallback onDeleteButtonClick}) {
return Get.generalDialog(
barrierLabel: "",
barrierDismissible: true,
pageBuilder: (_, a1, a2) {
return Center(
child: Card(
shape: 15.toRoundedRectRadius(),
color: Colors.white,
margin: REdgeInsets.symmetric(horizontal: 24),
child: Padding(
padding: REdgeInsets.symmetric(horizontal: 24.0, vertical: 32),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(width: double.maxFinite, height: 12.h),
titleText("Delete Account?"),
SizedBox(width: double.maxFinite, height: 16.h),
messageText("Are you sure you want to delete your account?"),
SizedBox(width: double.maxFinite, height: 32.h),
buttonsBar(onButton2Tap: onDeleteButtonClick),
],
),
),
),
);
},
);
}
static Future showUnauthorizedAlert() async {
if (alreadyShownUnauthorizedAlert) {
return;
}
alreadyShownUnauthorizedAlert = true;
await Get.dialog(
WillPopScope(
onWillPop: () async => false,
child: UnconstrainedBox(
child: SizedBox(
width: 1.0.sw,
child: AlertDialog(
shape: 15.toRoundedRectRadius(),
contentPadding:
REdgeInsets.symmetric(horizontal: 32, vertical: 32),
insetPadding:
REdgeInsets.symmetric(horizontal: 24, vertical: 24),
backgroundColor: Colors.white,
content: Column(
children: [
Icon(
Icons.warning_amber_rounded,
color: Colors.red,
size: 65.r,
),
24.verticalSpace,
titleText(
"Session Expired",
),
12.verticalSpace,
messageText(
"Your session has been expired. Please log-in again to continue using the app.",
),
48.verticalSpace,
CustomAppButton(
onTap: () {
Get.back();
alreadyShownUnauthorizedAlert = false;
// FrequentFunctions.logout();
},
buttonText: "Log In",
buttonColor: Get.theme.primaryColor,
)
],
),
),
),
),
),
barrierDismissible: false)
.then((value) {
alreadyShownUnauthorizedAlert = false;
});
}
static Future alertAndLogout(VoidCallback onTapYes) {
return _showLogoutAlert(onTapYes);
}
static Future _showLogoutAlert(Function() onTapYes) async {
// do not handle dialog dismiss, as it's already done
return openAlertDialog(
title: "Logout!",
message: "$areYouSureText Do you really want to logout from the app?",
onYesTap: onTapYes);
}
static Future<bool> showAlertAppExit() async {
var isOk = false;
await Get.generalDialog(
barrierLabel: "",
barrierDismissible: true,
pageBuilder: (_, a1, a2) {
return Center(
child: Card(
shape: 15.toRoundedRectRadius(),
color: Colors.white,
margin: REdgeInsets.symmetric(horizontal: 24),
child: Padding(
padding: REdgeInsets.symmetric(horizontal: 24.0, vertical: 32),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(width: double.maxFinite, height: 12.h),
titleText(areYouSureText),
SizedBox(width: double.maxFinite, height: 16.h),
titleText("Do you really want to exit from the app?"),
SizedBox(width: double.maxFinite, height: 32.h),
buttonsBar(onButton2Tap: () async {
isOk = true;
Get.back();
}),
],
),
),
),
);
},
);
return isOk;
}
static Future openAlertDialog(
{required String title,
required String message,
required VoidCallback onYesTap}) {
return Get.generalDialog(
barrierLabel: "",
barrierDismissible: true,
pageBuilder: (_, a1, a2) {
return Center(
child: Card(
shape: 15.toRoundedRectRadius(),
color: Colors.white,
margin: REdgeInsets.symmetric(horizontal: 24),
child: Padding(
padding: REdgeInsets.symmetric(horizontal: 24.0, vertical: 32),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(width: double.maxFinite, height: 12.h),
titleText(title),
16.verticalSpace,
messageText(message),
SizedBox(width: double.maxFinite, height: 32.h),
buttonsBar(onButton2Tap: onYesTap),
],
),
),
),
);
});
}
static showAppointmentDetailDialog(
{required AppointmentsListResponseData data}) {
Get.dialog(AppointmentDetailsDialog(data: data));
}
static showRecentIncidentDetailDialog({required RecentIncidentsModel data}) {
Get.dialog(RecentIncidentDetailDialog(data: data));
}
}

View File

@@ -0,0 +1,128 @@
import 'package:flutter/material.dart';
import 'package:ftc_mobile_app/ftc_mobile_app.dart';
import 'package:ftc_mobile_app/models/appointmentsListResponse/AppointmentsListResponse.dart';
import 'package:ftc_mobile_app/view/custom_widgets/common_cancel_button.dart';
import 'package:ftc_mobile_app/view/custom_widgets/my_circle_image.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
class AppointmentDetailsDialog extends StatelessWidget {
final AppointmentsListResponseData data;
const AppointmentDetailsDialog({super.key, required this.data});
@override
Widget build(BuildContext context) {
final appointmentDate = DateFormat("dd/MM/yyyy")
.format(DateTime.fromMillisecondsSinceEpoch(data.appointmentDate!));
final appointmentTime =
"${data.appointmentStartTime ?? "NA"} to ${data.appointmentEndTime ?? "NA"}";
final d = (data.appointmentMin ?? 0).minutes;
final duration =
"${d.inHours} hours and ${d.inMinutes - (d.inHours.hours.inMinutes)} minutes";
return AlertDialog(
insetPadding: REdgeInsets.all(18),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.r)),
backgroundColor: Colors.white,
surfaceTintColor: Colors.white,
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
data.appointmentTitle ?? "",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16.sp,
),
textAlign: TextAlign.left,
),
CustomTextWidget(
text: "$appointmentDate $appointmentTime",
fontSize: 13.sp,
textAlign: TextAlign.left,
),
16.verticalSpace,
CustomTextWidget(
text: "Appointment duration:",
fontSize: 14.sp,
fontColor: Colors.black,
fontWeight: FontWeight.w500,
textAlign: TextAlign.left,
),
CustomTextWidget(
text: duration,
fontSize: 13.sp,
textAlign: TextAlign.left,
),
16.verticalSpace,
Text.rich(
TextSpan(
text: "Detail: ",
style: TextStyle(
fontSize: 14.sp,
color: Colors.black,
fontWeight: FontWeight.w500,
),
children: [
TextSpan(
text: data.appointmentDetails ?? "",
style: TextStyle(
fontSize: 13.sp,
fontWeight: FontWeight.w400,
),
)
]),
),
16.verticalSpace,
CustomTextWidget(
text: "Staff:",
fontSize: 14.sp,
fontColor: Colors.black,
fontWeight: FontWeight.w500,
textAlign: TextAlign.left,
),
8.verticalSpace,
Row(
children: [
MyCircleImage(
imageSize: 32.r,
url: "${WebUrls.baseUrl}${data.staff?.profilePictureUrl ?? ""}",
errorWidget: CustomImageWidget(
imagePath: AssetsManager.kPersonMainIcon,
height: 32.r,
width: 32.r,
),
),
8.horizontalSpace,
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
data.staff?.name ?? "",
style: TextStyle(
fontSize: 13.sp,
fontWeight: FontWeight.w500
),
),
Text(
"Contact No. ${data.staff?.phoneNumber ?? ""}",
style: TextStyle(
fontSize: 13.sp,
),
),
],
),
],
),
],
),
actions: const [CommonCloseTextButton()],
);
}
}

View File

@@ -0,0 +1,75 @@
import 'package:flutter/material.dart';
import 'package:ftc_mobile_app/ftc_mobile_app.dart';
import 'package:ftc_mobile_app/view/custom_widgets/common_cancel_button.dart';
import 'package:ftc_mobile_app/view/custom_widgets/label_value_box_widget.dart';
class HolidayRequestSentDialog extends StatelessWidget {
const HolidayRequestSentDialog({
super.key,
required this.holidayStartDate,
required this.holidayEndDate,
required this.holidayTotalTime,
});
final String holidayStartDate;
final String holidayEndDate;
final String holidayTotalTime;
@override
Widget build(BuildContext context) {
return AlertDialog(
insetPadding: REdgeInsets.all(18),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.r)),
backgroundColor: Colors.white,
surfaceTintColor: Colors.white,
title: Center(
child: CustomTextWidget(
text: 'Your Holiday Request has been sent',
fontWeight: FontWeight.bold,
isExpanded: false,
alignment: Alignment.center,
fontSize: 16.sp,
),
),
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Expanded(
flex: 1,
child: LabelValueBoxWidget(
label: 'Start Date:',
value: holidayStartDate,
borderColor:
CustomAppColors.kLightGreyColor.withOpacity(0.3),
)),
5.horizontalSpace,
Expanded(
flex: 1,
child: LabelValueBoxWidget(
label: 'End Date',
value: holidayEndDate,
borderColor:
CustomAppColors.kLightGreyColor.withOpacity(0.3),
)),
],
),
10.verticalSpace,
SizedBox(
width: MediaQuery.of(context).size.width,
child: LabelValueBoxWidget(
label: 'Your remaining Holidays',
value: holidayTotalTime,
borderColor: CustomAppColors.kLightGreyColor.withOpacity(0.3),
)),
10.verticalSpace,
const CustomTextWidget(
text: "Kindly wait as we review your holiday request.")
],
),
actions: const [CommonCloseTextButton()],
);
}
}

View File

@@ -0,0 +1,69 @@
import 'package:flutter/material.dart';
import 'package:ftc_mobile_app/ftc_mobile_app.dart';
import 'package:ftc_mobile_app/view/custom_widgets/common_cancel_button.dart';
import 'package:ftc_mobile_app/view/custom_widgets/label_value_box_widget.dart';
class HolidaysDataDialog extends StatelessWidget {
const HolidaysDataDialog({
super.key,
required this.holidayModel,
});
final HolidayModel holidayModel;
@override
Widget build(BuildContext context) {
return AlertDialog(
insetPadding: REdgeInsets.all(18),
surfaceTintColor: CustomAppColors.kPrimaryColor,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2)),
backgroundColor: CustomAppColors.kWhiteColor,
title: Center(
child: CustomTextWidget(
text: 'Your Holidays',
fontWeight: FontWeight.w700,
isExpanded: false,
alignment: Alignment.center,
fontSize: 16.sp,
),
),
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
LabelValueBoxWidget(
label: 'Carried Over:',
value: holidayModel.carriedOver,
borderColor: CustomAppColors.kLightGreyColor.withOpacity(0.3),
),
10.verticalSpace,
LabelValueBoxWidget(
label: 'Holiday Entitlement',
value: holidayModel.holidayEntitlement,
borderColor: CustomAppColors.kLightGreyColor.withOpacity(0.3),
),
10.verticalSpace,
LabelValueBoxWidget(
label: 'Holiday Allowance',
value: holidayModel.holidayAllowance,
borderColor: CustomAppColors.kLightGreyColor.withOpacity(0.3),
),
10.verticalSpace,
LabelValueBoxWidget(
label: 'Your remaining Holidays',
value: holidayModel.remainingHolidays,
borderColor: CustomAppColors.kLightGreyColor.withOpacity(0.3),
),
10.verticalSpace,
LabelValueBoxWidget(
label: 'Time left before Year End:',
value: holidayModel.timeLeftBeforeYearEnd,
borderColor: CustomAppColors.kLightGreyColor.withOpacity(0.3),
),
10.verticalSpace,
const CommonCloseTextButton()
],
),
);
}
}

View File

@@ -0,0 +1,88 @@
import 'package:flutter/material.dart';
import 'package:ftc_mobile_app/ftc_mobile_app.dart';
import 'package:ftc_mobile_app/models/clients/recent_incidents_model.dart';
import 'package:ftc_mobile_app/utilities/extensions/custom_extensions.dart';
import 'package:ftc_mobile_app/view/custom_widgets/common_cancel_button.dart';
import 'package:quill_html_editor/quill_html_editor.dart';
class RecentIncidentDetailDialog extends StatelessWidget {
final RecentIncidentsModel data;
const RecentIncidentDetailDialog({super.key, required this.data});
@override
Widget build(BuildContext context) {
return AlertDialog(
insetPadding: REdgeInsets.all(18),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.r)),
backgroundColor: Colors.white,
surfaceTintColor: Colors.white,
contentPadding: EdgeInsets.zero,
content: SizedBox(
width: double.maxFinite,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
20.verticalSpace,
Text("Incident Date - Time",
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 14.sp,
color: Colors.black,
)).addPaddingHorizontal(16),
Text(
DateFormatter.ddMMyyyyhhmmFormat(
DateTime.parse(data.createdAt).toLocal()),
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 12.sp,
color: CustomAppColors.kBlackColor,
)).addPaddingHorizontal(16),
8.verticalSpace,
Divider(
color: CustomAppColors.kLightGreyColor,
),
8.verticalSpace,
CustomTextWidget(
text: data.incidentTitle.isNotEmpty
? data.incidentTitle
: "Untitled Incident",
isExpanded: false,
fontWeight: FontWeight.w600,
fontSize: 14.sp,
textAlign: TextAlign.left,
).addPaddingHorizontal(16),
4.verticalSpace,
Expanded(
child: QuillHtmlEditor(
text: data.note,
hintText: 'Hint text goes here',
controller: data.quillController,
isEnabled: false,
ensureVisible: false,
minHeight: 50.h,
autoFocus: false,
textStyle: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w400,
),
// hintTextStyle: _hintTextStyle,
hintTextAlign: TextAlign.start,
loadingBuilder: (context) {
return const Center(
child: CircularProgressIndicator(
strokeWidth: 1,
color: Colors.red,
));
},
).addPaddingHorizontal(16),
),
const CommonCloseTextButton().addPaddingAll(16),
8.verticalSpace,
],
),
));
}
}

View File

@@ -0,0 +1,128 @@
import 'package:flutter/material.dart';
import 'package:ftc_mobile_app/ftc_mobile_app.dart';
import 'package:ftc_mobile_app/models/rota/WeekArrayData.dart';
import 'package:ftc_mobile_app/view/custom_widgets/common_cancel_button.dart';
import 'package:ftc_mobile_app/view/custom_widgets/label_value_box_widget.dart';
class ShowRotaAlertDialog extends StatelessWidget {
final DaysArrayData data;
final Function? onClaimShiftTap;
final Function? onCancelShiftTap;
const ShowRotaAlertDialog(
{super.key,
required this.data,
this.onClaimShiftTap,
this.onCancelShiftTap});
@override
Widget build(BuildContext context) {
final isAvailableShift = (data.staffUserId == null);
return AlertDialog(
insetPadding: REdgeInsets.all(18),
contentPadding: REdgeInsets.all(15),
surfaceTintColor: CustomAppColors.kPrimaryColor,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.r)),
backgroundColor: CustomAppColors.kPrimaryColor,
title: Center(
child: CustomTextWidget(
text: isAvailableShift
? 'Available Shift'
: data.staffUserId?.staffMemberName ?? "",
fontWeight: FontWeight.bold,
isExpanded: false,
alignment: Alignment.center,
fontSize: 16.sp,
),
),
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
LabelValueBoxWidget(
label: 'Service User (Patient):',
value: data.serviceUserId?.displayName ?? 'Unassigned',
borderColor: CustomAppColors.kLightGreyColor.withOpacity(0.3),
),
10.verticalSpace,
// LabelValueBoxWidget(
// label: 'Worker Type:',
// value: data.workerType,
// borderColor: CustomAppColors.kLightGreyColor.withOpacity(0.3),
// ),
// 10.verticalSpace,
LabelValueBoxWidget(
label: 'Location:',
value: data.locationId?.shiftLocationName ?? '',
borderColor: CustomAppColors.kLightGreyColor.withOpacity(0.3),
),
// 10.verticalSpace,
// LabelValueBoxWidget(
// label: 'Staff Required:',
// value: data.staffRequired,
// borderColor: CustomAppColors.kLightGreyColor.withOpacity(0.3),
// ),
10.verticalSpace,
LabelValueBoxWidget(
label: 'Start Time:',
value: DateFormatter()
.roasterShiftFormattedTime(time: data.shiftStartTime ?? ""),
borderColor: CustomAppColors.kLightGreyColor.withOpacity(0.3),
),
10.verticalSpace,
LabelValueBoxWidget(
label: 'End Time:',
value: DateFormatter()
.roasterShiftFormattedTime(time: data.shiftEndTime ?? ""),
borderColor: CustomAppColors.kLightGreyColor.withOpacity(0.3),
),
10.verticalSpace,
// LabelValueBoxWidget(
// label: 'Break Time:',
// value: data.breakTime,
// borderColor: CustomAppColors.kLightGreyColor.withOpacity(0.3),
// ),
// 10.verticalSpace,
LabelValueBoxWidget(
label: 'Notes:',
value: data.note ?? "NA",
borderColor: CustomAppColors.kLightGreyColor.withOpacity(0.3),
),
10.verticalSpace,
ConstrainedBox(
constraints: BoxConstraints(minHeight: 30.h, maxHeight: 30.h),
child: Row(
children: [
data.isRequested == true
? FrequentFunctions.noWidget
: Expanded(
child: CustomAppButton(
onTap: () {
Navigator.of(context).pop();
if (isAvailableShift) {
if (onClaimShiftTap != null) {
onClaimShiftTap!.call();
}
} else {
if (onCancelShiftTap != null) {
onCancelShiftTap!.call();
}
}
},
buttonText:
isAvailableShift ? "Claim Shift" : "Cancel Shift",
textColor: Colors.white,
borderColor: Colors.transparent,
),
),
10.horizontalSpace,
const Expanded(child: CommonCloseTextButton()),
],
),
),
],
),
);
}
}